Skip to content
Permalink
Browse files

Fix clipboard handling on OSX

Clipboard was wrongly using QClipboard::Selection for storage/retrieval
when this is not available on OSX

Also improve docs
  • Loading branch information
nyalldawson committed Mar 1, 2016
1 parent 28d725c commit 0d2df8097bd5de4a8d3aacb8e9d210b025b784da
Showing with 37 additions and 70 deletions.
  1. +4 −4 src/app/qgisapp.cpp
  2. +21 −35 src/app/qgsclipboard.cpp
  3. +12 −27 src/app/qgsclipboard.h
  4. +0 −4 tests/src/app/testqgisappclipboard.cpp
@@ -9840,9 +9840,9 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionRotateLabel->setEnabled( enableRotate );
mActionChangeLabelProperties->setEnabled( enableChange );

mMenuPasteAs->setEnabled( clipboard() && !clipboard()->empty() );
mActionPasteAsNewVector->setEnabled( clipboard() && !clipboard()->empty() );
mActionPasteAsNewMemoryVector->setEnabled( clipboard() && !clipboard()->empty() );
mMenuPasteAs->setEnabled( clipboard() && !clipboard()->isEmpty() );
mActionPasteAsNewVector->setEnabled( clipboard() && !clipboard()->isEmpty() );
mActionPasteAsNewMemoryVector->setEnabled( clipboard() && !clipboard()->isEmpty() );

updateLayerModifiedActions();

@@ -9990,7 +9990,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
updateUndoActions();
}

mActionPasteFeatures->setEnabled( isEditable && canAddFeatures && !clipboard()->empty() );
mActionPasteFeatures->setEnabled( isEditable && canAddFeatures && !clipboard()->isEmpty() );

mActionAddFeature->setEnabled( isEditable && canAddFeatures );
mActionCircularStringCurvePoint->setEnabled( isEditable && ( canAddFeatures || canChangeGeometry ) && vlayer->geometryType() != QGis::Point );
@@ -137,7 +137,7 @@ void QgsClipboard::setSystemClipboard()
// docs). With a Linux X server, ::Clipboard was required.
// The simple solution was to put the text into both clipboards.

#ifndef Q_OS_WIN
#ifdef Q_OS_LINUX
cb->setText( textCopy, QClipboard::Selection );
#endif
cb->setText( textCopy, QClipboard::Clipboard );
@@ -180,7 +180,7 @@ QgsFields QgsClipboard::retrieveFields() const
{
QClipboard *cb = QApplication::clipboard();

#ifndef Q_OS_WIN
#ifdef Q_OS_LINUX
QString string = cb->text( QClipboard::Selection );
#else
QString string = cb->text( QClipboard::Clipboard );
@@ -189,29 +189,21 @@ QgsFields QgsClipboard::retrieveFields() const
return QgsOgrUtils::stringToFields( string, QTextCodec::codecForName( "System" ) );
}

QgsFeatureList QgsClipboard::copyOf( const QgsFields &fields )
QgsFeatureList QgsClipboard::copyOf( const QgsFields &fields ) const
{
QgsDebugMsg( "returning clipboard." );
if ( !mUseSystemClipboard )
return mFeatureClipboard;

QClipboard *cb = QApplication::clipboard();

#ifndef Q_OS_WIN
#ifdef Q_OS_LINUX
QString text = cb->text( QClipboard::Selection );
#else
QString text = cb->text( QClipboard::Clipboard );
#endif

QgsFeatureList features = stringToFeatureList( text, fields );

if ( features.isEmpty() )
return mFeatureClipboard;

if ( !fields.isEmpty() )
mFeatureFields = fields;

return features;
return stringToFeatureList( text, fields );
}

void QgsClipboard::clear()
@@ -222,7 +214,7 @@ void QgsClipboard::clear()
emit changed();
}

void QgsClipboard::insert( QgsFeature& feature )
void QgsClipboard::insert( const QgsFeature& feature )
{
mFeatureClipboard.push_back( feature );

@@ -231,18 +223,18 @@ void QgsClipboard::insert( QgsFeature& feature )
emit changed();
}

bool QgsClipboard::empty()
bool QgsClipboard::isEmpty() const
{
QClipboard *cb = QApplication::clipboard();
#ifndef Q_OS_WIN
#ifdef Q_OS_LINUX
QString text = cb->text( QClipboard::Selection );
#else
QString text = cb->text( QClipboard::Clipboard );
#endif
return text.isEmpty() && mFeatureClipboard.empty();
}

QgsFeatureList QgsClipboard::transformedCopyOf( const QgsCoordinateReferenceSystem& destCRS, const QgsFields &fields )
QgsFeatureList QgsClipboard::transformedCopyOf( const QgsCoordinateReferenceSystem& destCRS, const QgsFields &fields ) const
{
QgsFeatureList featureList = copyOf( fields );
QgsCoordinateTransform ct( crs(), destCRS );
@@ -256,47 +248,41 @@ QgsFeatureList QgsClipboard::transformedCopyOf( const QgsCoordinateReferenceSyst
return featureList;
}

QgsCoordinateReferenceSystem QgsClipboard::crs()
QgsCoordinateReferenceSystem QgsClipboard::crs() const
{
return mCRS;
}

void QgsClipboard::setData( const QString& mimeType, const QByteArray& data, const QString* text )
void QgsClipboard::setData( const QString& mimeType, const QByteArray& data, const QString& text )
{
mUseSystemClipboard = true;
QMimeData *mdata = new QMimeData();
mdata->setData( mimeType, data );
if ( text )
if ( !text.isEmpty() )
{
mdata->setText( *text );
mdata->setText( text );
}
// Transfers ownership to the clipboard object
#ifndef Q_OS_WIN
#ifdef Q_OS_LINUX
QApplication::clipboard()->setMimeData( mdata, QClipboard::Selection );
#endif
QApplication::clipboard()->setMimeData( mdata, QClipboard::Clipboard );
}

void QgsClipboard::setData( const QString& mimeType, const QByteArray& data, const QString& text )
{
setData( mimeType, data, &text );
}

void QgsClipboard::setData( const QString& mimeType, const QByteArray& data )
{
setData( mimeType, data, nullptr );
}

void QgsClipboard::setText( const QString& text )
{
setData( "text/plain", text.toLocal8Bit(), nullptr );
#ifdef Q_OS_LINUX
QApplication::clipboard()->setText( text, QClipboard::Selection );
#endif
QApplication::clipboard()->setText( text, QClipboard::Clipboard );
}

bool QgsClipboard::hasFormat( const QString& mimeType )
bool QgsClipboard::hasFormat( const QString& mimeType ) const
{
return QApplication::clipboard()->mimeData()->hasFormat( mimeType );
}

QByteArray QgsClipboard::data( const QString& mimeType )
QByteArray QgsClipboard::data( const QString& mimeType ) const
{
return QApplication::clipboard()->mimeData()->data( mimeType );
}
@@ -40,7 +40,6 @@
As this class matures it should also be able to accept CSV repesentations
of features in and out of the system clipboard (QClipboard).
TODO: Make it work
*/

class QgsVectorLayer;
@@ -63,8 +62,8 @@ class APP_EXPORT QgsClipboard : public QObject
virtual ~QgsClipboard();

/**
* Place a copy of features on the internal clipboard,
* destroying the previous contents.
* Place a copy of the selected features from the specified layer on
* the internal clipboard, destroying the previous contents.
*/
void replaceWithCopyOf( QgsVectorLayer *src );

@@ -75,11 +74,9 @@ class APP_EXPORT QgsClipboard : public QObject
void replaceWithCopyOf( QgsFeatureStore & featureStore );

/**
* Returns a copy of features on the internal clipboard,
* the caller assumes responsibility for destroying the contents
* when it's done with it.
* Returns a copy of features on the internal clipboard.
*/
QgsFeatureList copyOf( const QgsFields &fields = QgsFields() );
QgsFeatureList copyOf( const QgsFields &fields = QgsFields() ) const;

/**
* Clears the internal clipboard.
@@ -89,40 +86,28 @@ class APP_EXPORT QgsClipboard : public QObject
/**
* Inserts a copy of the feature on the internal clipboard.
*/
void insert( QgsFeature& feature );
void insert( const QgsFeature& feature );

/**
* Returns true if the internal clipboard is empty, else false.
*/
bool empty();
bool isEmpty() const;

/**
* Returns a copy of features on the internal clipboard, transformed
* from the clipboard CRS to the destCRS.
* The caller assumes responsibility for destroying the contents
* when it's done with it.
*/
QgsFeatureList transformedCopyOf( const QgsCoordinateReferenceSystem& destCRS, const QgsFields &fields = QgsFields() );
QgsFeatureList transformedCopyOf( const QgsCoordinateReferenceSystem& destCRS, const QgsFields &fields = QgsFields() ) const;

/**
* Get the clipboard CRS
*/
QgsCoordinateReferenceSystem crs();
QgsCoordinateReferenceSystem crs() const;

/**
* Stores a MimeData together with a text into the system clipboard
*/
void setData( const QString& mimeType, const QByteArray& data, const QString* text = nullptr );

/**
* Stores a MimeData together with a text into the system clipboard
*/
void setData( const QString& mimeType, const QByteArray& data, const QString& text );

/**
* Stores a MimeData into the system clipboard
*/
void setData( const QString& mimeType, const QByteArray& data );
void setData( const QString& mimeType, const QByteArray& data, const QString& text = QString() );

/**
* Stores a text into the system clipboard
@@ -133,18 +118,18 @@ class APP_EXPORT QgsClipboard : public QObject
* Proxy to QMimeData::hasFormat
* Tests whether the system clipboard contains data of a given MIME type
*/
bool hasFormat( const QString& mimeType );
bool hasFormat( const QString& mimeType ) const;

/**
* Retrieve data from the system clipboard.
* No copy is involved, since the return QByteArray is implicitly shared
*/
QByteArray data( const QString& mimeType );
QByteArray data( const QString& mimeType ) const;

/**
* Source fields
*/
QgsFields fields() { return !mUseSystemClipboard ? mFeatureFields : retrieveFields(); }
QgsFields fields() const { return !mUseSystemClipboard ? mFeatureFields : retrieveFields(); }

private slots:

@@ -114,7 +114,6 @@ void TestQgisAppClipboard::copyPaste()

void TestQgisAppClipboard::pasteWkt()
{
mQgisApp->clipboard()->clear();
mQgisApp->clipboard()->setText( "POINT (125 10)\nPOINT (111 30)" );

QgsFeatureList features = mQgisApp->clipboard()->copyOf();
@@ -133,7 +132,6 @@ void TestQgisAppClipboard::pasteWkt()

void TestQgisAppClipboard::pasteGeoJson()
{
mQgisApp->clipboard()->clear();
QgsFields fields;
fields.append( QgsField( "name", QVariant::String ) );
mQgisApp->clipboard()->setText( "{\n\"type\": \"Feature\",\"geometry\": {\"type\": \"Point\",\"coordinates\": [125, 10]},\"properties\": {\"name\": \"Dinagat Islands\"}}" );
@@ -150,8 +148,6 @@ void TestQgisAppClipboard::pasteGeoJson()

void TestQgisAppClipboard::retrieveFields()
{
mQgisApp->clipboard()->clear();

//empty string
mQgisApp->clipboard()->setText( "" );

0 comments on commit 0d2df80

Please sign in to comment.
You can’t perform that action at this time.