Skip to content

Commit

Permalink
Clipboard: Add WKB option to clipboard
Browse files Browse the repository at this point in the history
  • Loading branch information
lbartoletti committed Apr 12, 2024
1 parent 902f91f commit 5cf4dcd
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/app/options/qgsoptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOpti

mComboCopyFeatureFormat->addItem( tr( "Plain Text, No Geometry" ), QgsClipboard::AttributesOnly );
mComboCopyFeatureFormat->addItem( tr( "Plain Text, WKT Geometry" ), QgsClipboard::AttributesWithWKT );
mComboCopyFeatureFormat->addItem( tr( "Plain Text, WKB Geometry" ), QgsClipboard::AttributesWithWKB );
mComboCopyFeatureFormat->addItem( tr( "GeoJSON" ), QgsClipboard::GeoJSON );
mComboCopyFeatureFormat->setCurrentIndex( mComboCopyFeatureFormat->findData( mSettings->enumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesWithWKT ) ) );
leNullValue->setText( QgsApplication::nullRepresentation() );
Expand Down
29 changes: 21 additions & 8 deletions src/app/qgsclipboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,18 +131,22 @@ void QgsClipboard::generateClipboardText( QString &textContent, QString &htmlCon
{
case AttributesOnly:
case AttributesWithWKT:
case AttributesWithWKB:
{
QStringList textLines, htmlLines;
QStringList textFields, htmlFields;

// first do the field names
if ( format == AttributesWithWKT )
if ( ( format == AttributesWithWKB ) || ( format == AttributesWithWKT ) )
{
// only include the "wkt_geom" field IF we have other fields -- otherwise it's redundant and we should just set the clipboard to WKT text directly
const QLatin1String geometryHeading = format == AttributesWithWKB ? QLatin1String( "wkb_geom" ) : QLatin1String( "wkt_geom" );
// only include the "wkx_geom" field IF we have other fields -- otherwise it's redundant and we should just set the clipboard to WKT/WKB text directly
if ( !mFeatureFields.isEmpty() )
textFields += QLatin1String( "wkt_geom" );
{
textFields += geometryHeading;
}

htmlFields += QLatin1String( "<td>wkt_geom</td>" );
htmlFields += QLatin1String( "<td>" ) + geometryHeading + QLatin1String( "</td>" );
}

textFields.reserve( mFeatureFields.size() );
Expand All @@ -164,13 +168,22 @@ void QgsClipboard::generateClipboardText( QString &textContent, QString &htmlCon
const QgsAttributes attributes = it->attributes();

// TODO: Set up Paste Transformations to specify the order in which fields are added.
if ( format == AttributesWithWKT )
if ( ( format == AttributesWithWKB ) || ( format == AttributesWithWKT ) )
{
if ( it->hasGeometry() )
{
const QString wkt = it->geometry().asWkt();
textFields += wkt;
htmlFields += QStringLiteral( "<td>%1</td>" ).arg( wkt );
if ( format == AttributesWithWKT )
{
const QString wkt = it->geometry().asWkt();
textFields += wkt;
htmlFields += QStringLiteral( "<td>%1</td>" ).arg( wkt );
}
else if ( format == AttributesWithWKB )
{
const QString wkb = it->geometry().asWkb().toHex();
textFields += wkb;
htmlFields += QStringLiteral( "<td>%1</td>" ).arg( wkb );
}
}
else
{
Expand Down
3 changes: 2 additions & 1 deletion src/app/qgsclipboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class APP_EXPORT QgsClipboard : public QObject
{
AttributesOnly, //!< Tab delimited text, attributes only
AttributesWithWKT, //!< Tab delimited text, with geometry in WKT format
AttributesWithWKB, //!< Tab delimited text, with geometry in WKB format
GeoJSON, //!< GeoJSON FeatureCollection format
};
Q_ENUM( CopyFormat )
Expand Down Expand Up @@ -165,7 +166,7 @@ class APP_EXPORT QgsClipboard : public QObject
void generateClipboardText( QString &textContent, QString &htmlContent ) const;

/**
* Attempts to convert a string to a list of features, by parsing the string as WKT and GeoJSON
* Attempts to convert a string to a list of features, by parsing the string as WKT/WKB and GeoJSON
* \param string string to convert
* \param fields fields for resultant features
* \returns list of features if conversion was successful
Expand Down
19 changes: 17 additions & 2 deletions tests/src/app/testqgisappclipboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,15 @@ void TestQgisAppClipboard::copyToText()
mQgisApp->clipboard()->generateClipboardText( result, resultHtml );
QCOMPARE( result, QString( "wkt_geom\tint_field\tstring_field\nPoint (5 6)\t9\tval\nPoint (7 8)\t19\tval2" ) );

// attributes with WKB
settings.setEnumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesWithWKB );
mQgisApp->clipboard()->generateClipboardText( result, resultHtml );
QCOMPARE( result, QString( "wkb_geom\tint_field\tstring_field\n010100000000000000000014400000000000001840\t9\tval\n01010000000000000000001c400000000000002040\t19\tval2" ) );

// HTML test
mQgisApp->clipboard()->replaceWithCopyOf( feats );
result = mQgisApp->clipboard()->data( "text/html" );
QCOMPARE( result, QString( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"><html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/></head><body><table border=\"1\"><tr><td>wkt_geom</td><td>int_field</td><td>string_field</td></tr><tr><td>Point (5 6)</td><td>9</td><td>val</td></tr><tr><td>Point (7 8)</td><td>19</td><td>val2</td></tr></table></body></html>" ) );
QCOMPARE( result, QString( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"><html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/></head><body><table border=\"1\"><tr><td>wkb_geom</td><td>int_field</td><td>string_field</td></tr><tr><td>010100000000000000000014400000000000001840</td><td>9</td><td>val</td></tr><tr><td>01010000000000000000001c400000000000002040</td><td>19</td><td>val2</td></tr></table></body></html>" ) );

// GeoJSON
settings.setEnumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::GeoJSON );
Expand Down Expand Up @@ -229,6 +234,11 @@ void TestQgisAppClipboard::copyToText()
mQgisApp->clipboard()->generateClipboardText( result, resultHtml );
QCOMPARE( result, QString( "wkt_geom\tint_field\tstring_field\nPoint (5 6)\t1\tSingle line text\nPoint (7 8)\t2\t\"Unix Multiline \nText\"\nPoint (9 10)\t3\t\"Windows Multiline \r\nText\"" ) );

// attributes with WKB
settings.setEnumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesWithWKB );
mQgisApp->clipboard()->generateClipboardText( result, resultHtml );
QCOMPARE( result, QString( "wkb_geom\tint_field\tstring_field\n010100000000000000000014400000000000001840\t1\tSingle line text\n01010000000000000000001c400000000000002040\t2\t\"Unix Multiline \nText\"\n010100000000000000000022400000000000002440\t3\t\"Windows Multiline \r\nText\"" ) );

}

void TestQgisAppClipboard::copyToTextNoFields()
Expand All @@ -253,10 +263,15 @@ void TestQgisAppClipboard::copyToTextNoFields()
mQgisApp->clipboard()->generateClipboardText( result, resultHtml );
QCOMPARE( result, QStringLiteral( "Point (5 6)\nPoint (7 8)" ) );

// attributes with WKB
settings.setEnumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesWithWKB );
mQgisApp->clipboard()->generateClipboardText( result, resultHtml );
QCOMPARE( result, QStringLiteral( "010100000000000000000014400000000000001840\n01010000000000000000001c400000000000002040" ) );

// HTML test
mQgisApp->clipboard()->replaceWithCopyOf( feats );
result = mQgisApp->clipboard()->data( "text/html" );
QCOMPARE( result, QStringLiteral( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"><html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/></head><body><table border=\"1\"><tr><td>wkt_geom</td></tr><tr><td>Point (5 6)</td></tr><tr><td>Point (7 8)</td></tr></table></body></html>" ) );
QCOMPARE( result, QStringLiteral( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"><html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/></head><body><table border=\"1\"><tr><td>wkb_geom</td></tr><tr><td>010100000000000000000014400000000000001840</td></tr><tr><td>01010000000000000000001c400000000000002040</td></tr></table></body></html>" ) );

// GeoJSON
settings.setEnumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::GeoJSON );
Expand Down

0 comments on commit 5cf4dcd

Please sign in to comment.