Skip to content

Commit e267893

Browse files
myarjunarnyalldawson
authored andcommittedSep 23, 2017
[FEATURE][geonode] integration - copy style action
Allows copying styles directly from geonode layers for pasting into project layers.
1 parent 54e5bfd commit e267893

File tree

9 files changed

+135
-5
lines changed

9 files changed

+135
-5
lines changed
 

‎python/core/qgsdataitem.sip

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,17 @@ Create new data item.
141141
:rtype: list of QAction
142142
%End
143143

144+
virtual QList<QMenu *> menus( QWidget *parent );
145+
%Docstring
146+
Returns the list of menus available for this item. This is usually used for the popup menu on right-clicking
147+
the item. Subclasses should override this to provide actions. Subclasses should ensure that ownership of
148+
created menus is correctly handled by parenting them to the specified parent widget.
149+
\param parent a parent widget of the menu
150+
:return: list of menus
151+
.. versionadded:: 3.0
152+
:rtype: list of QMenu
153+
%End
154+
144155
virtual bool acceptDrop();
145156
%Docstring
146157
Returns whether the item accepts drag and dropped layers - e.g. for importing a dataset to a provider.

‎python/core/symbology/qgsstyle.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
typedef QMap<QString, QgsColorRamp * > QgsVectorColorRampMap;
1616
typedef QMap<int, QString> QgsSymbolGroupMap;
1717

18+
1819
typedef QMultiMap<QString, QString> QgsSmartConditionMap;
1920

2021
enum SymbolTable { SymbolId, SymbolName, SymbolXML, SymbolFavoriteId };

‎src/app/qgsclipboard.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,6 @@
4646
class QgsVectorLayer;
4747
class QgsFeatureStore;
4848

49-
/*
50-
* Constants used to describe copy-paste MIME types
51-
*/
52-
#define QGSCLIPBOARD_STYLE_MIME "application/qgis.style"
53-
5449
class APP_EXPORT QgsClipboard : public QObject
5550
{
5651
Q_OBJECT

‎src/core/qgsdataitem.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,12 @@ void QgsDataItem::setState( State state )
558558
updateIcon();
559559
}
560560

561+
QList<QMenu *> QgsDataItem::menus( QWidget *parent )
562+
{
563+
Q_UNUSED( parent );
564+
return QList<QMenu *>();
565+
}
566+
561567
// ---------------------------------------------------------------------
562568

563569
QgsLayerItem::QgsLayerItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &uri, LayerType layerType, const QString &providerKey )

‎src/core/qgsdataitem.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,15 @@ class CORE_EXPORT QgsDataItem : public QObject
148148
*/
149149
virtual QList<QAction *> actions( QWidget *parent );
150150

151+
/** Returns the list of menus available for this item. This is usually used for the popup menu on right-clicking
152+
* the item. Subclasses should override this to provide actions. Subclasses should ensure that ownership of
153+
* created menus is correctly handled by parenting them to the specified parent widget.
154+
* \param parent a parent widget of the menu
155+
* \returns list of menus
156+
* \since QGIS 3.0
157+
*/
158+
virtual QList<QMenu *> menus( QWidget *parent );
159+
151160
/** Returns whether the item accepts drag and dropped layers - e.g. for importing a dataset to a provider.
152161
* Subclasses should override this and handleDrop() to accept dropped layers.
153162
* \see handleDrop()

‎src/core/symbology/qgsstyle.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ class QDomElement;
3636
typedef QMap<QString, QgsColorRamp * > QgsVectorColorRampMap;
3737
typedef QMap<int, QString> QgsSymbolGroupMap;
3838

39+
/*
40+
* Constants used to describe copy-paste MIME types
41+
*/
42+
#define QGSCLIPBOARD_STYLE_MIME "application/qgis.style"
43+
3944
/** \ingroup core
4045
* A multimap to hold the smart group conditions as constraint and parameter pairs.
4146
* Both the key and the value of the map are QString. The key is the constraint of the condition and the value is the parameter which is applied for the constraint.

‎src/gui/qgsbrowserdockwidget.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,17 @@ void QgsBrowserDockWidget::showContextMenu( QPoint pt )
209209
menu->addAction( tr( "Add a Directory..." ), this, SLOT( addFavoriteDirectory() ) );
210210
}
211211

212+
const QList<QMenu *> menus = item->menus( menu );
212213
QList<QAction *> actions = item->actions( menu );
214+
215+
if ( !menus.isEmpty() )
216+
{
217+
for ( QMenu *mn : menus )
218+
{
219+
menu->addMenu( mn );
220+
}
221+
}
222+
213223
if ( !actions.isEmpty() )
214224
{
215225
if ( !menu->actions().isEmpty() )

‎src/providers/wfs/qgswfsdataitems.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
* (at your option) any later version. *
1313
* *
1414
***************************************************************************/
15+
16+
#include <QClipboard>
17+
#include <QMenu>
18+
1519
#include "qgsdataitemprovider.h"
1620
#include "qgsdataprovider.h"
1721
#include "qgslogger.h"
@@ -23,6 +27,7 @@
2327
#include "qgssettings.h"
2428
#include "qgsgeonodeconnection.h"
2529
#include "qgsgeonoderequest.h"
30+
#include "qgsstyle.h"
2631

2732
#ifdef HAVE_GUI
2833
#include "qgsnewhttpconnection.h"
@@ -44,12 +49,86 @@ QgsWfsLayerItem::QgsWfsLayerItem( QgsDataItem *parent, QString name, const QgsDa
4449
mUri = QgsWFSDataSourceURI::build( uri.uri(), featureType, crsString, QString(), useCurrentViewExtent );
4550
setState( Populated );
4651
mIconName = QStringLiteral( "mIconConnect.png" );
52+
mBaseUri = uri.param( QString( "url" ) );
4753
}
4854

4955
QgsWfsLayerItem::~QgsWfsLayerItem()
5056
{
5157
}
5258

59+
QList<QMenu *> QgsWfsLayerItem::menus( QWidget *parent )
60+
{
61+
QList<QMenu *> menus;
62+
63+
if ( mPath.startsWith( QLatin1String( "geonode:/" ) ) )
64+
{
65+
QMenu *menuStyleManager = new QMenu( tr( "Styles" ), parent );
66+
67+
QAction *actionCopyStyle = new QAction( tr( "Copy Style" ), menuStyleManager );
68+
connect( actionCopyStyle, &QAction::triggered, this, &QgsWfsLayerItem::copyStyle );
69+
70+
menuStyleManager->addAction( actionCopyStyle );
71+
menus << menuStyleManager;
72+
}
73+
74+
return menus;
75+
}
76+
77+
void QgsWfsLayerItem::copyStyle()
78+
{
79+
std::unique_ptr< QgsGeoNodeConnection > connection;
80+
const QStringList connections = QgsGeoNodeConnectionUtils::connectionList();
81+
for ( const QString &connName : connections )
82+
{
83+
connection.reset( new QgsGeoNodeConnection( connName ) );
84+
if ( mBaseUri.contains( connection->uri().param( QString( "url" ) ) ) )
85+
break;
86+
else
87+
connection.reset( nullptr );
88+
}
89+
90+
if ( !connection )
91+
{
92+
QString errorMsg( QStringLiteral( "Cannot get style for layer %1" ).arg( this->name() ) );
93+
QgsDebugMsg( " Cannot get style: " + errorMsg );
94+
#if 0
95+
// TODO: how to emit message from provider (which does not know about QgisApp)
96+
QgisApp::instance()->messageBar()->pushMessage( tr( "Cannot copy style" ),
97+
errorMsg,
98+
QgsMessageBar::CRITICAL, messageTimeout() );
99+
#endif
100+
return;
101+
}
102+
103+
QString url( connection->uri().encodedUri() );
104+
QgsGeoNodeRequest geoNodeRequest( url.replace( QString( "url=" ), QString() ), true );
105+
QgsGeoNodeStyle style = geoNodeRequest.fetchDefaultStyleBlocking( this->name() );
106+
if ( style.name.isEmpty() )
107+
{
108+
QString errorMsg( QStringLiteral( "Cannot get style for layer %1" ).arg( this->name() ) );
109+
QgsDebugMsg( " Cannot get style: " + errorMsg );
110+
#if 0
111+
// TODO: how to emit message from provider (which does not know about QgisApp)
112+
QgisApp::instance()->messageBar()->pushMessage( tr( "Cannot copy style" ),
113+
errorMsg,
114+
QgsMessageBar::CRITICAL, messageTimeout() );
115+
#endif
116+
return;
117+
}
118+
119+
QClipboard *clipboard = QApplication::clipboard();
120+
121+
QMimeData *mdata = new QMimeData();
122+
mdata->setData( QGSCLIPBOARD_STYLE_MIME, style.body.toByteArray() );
123+
mdata->setText( style.body.toString() );
124+
// Copies data in text form as well, so the XML can be pasted into a text editor
125+
if ( clipboard->supportsSelection() )
126+
clipboard->setMimeData( mdata, QClipboard::Selection );
127+
clipboard->setMimeData( mdata, QClipboard::Clipboard );
128+
// Enables the paste menu element
129+
// actionPasteStyle->setEnabled( true );
130+
}
131+
53132
//
54133
// QgsWfsConnectionItem
55134
//

‎src/providers/wfs/qgswfsdataitems.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ class QgsWfsLayerItem : public QgsLayerItem
7979
QgsWfsLayerItem( QgsDataItem *parent, QString name, const QgsDataSourceUri &uri, QString featureType, QString title, QString crsString );
8080
~QgsWfsLayerItem();
8181

82+
virtual QList<QMenu *> menus( QWidget *parent ) override;
83+
84+
protected:
85+
QString mBaseUri;
86+
87+
private slots:
88+
89+
/** Get style of the active data item (geonode layer item) and copy it to the clipboard.
90+
*/
91+
void copyStyle();
92+
93+
/** Paste style on the clipboard to the active data item (geonode layer item) and push it to the source.
94+
*/
95+
// void pasteStyle();
8296
};
8397

8498

0 commit comments

Comments
 (0)
Please sign in to comment.