1 /***************************************************************************
2   qgsvectortiledataitemguiprovider.cpp
3   --------------------------------------
4   Date                 : March 2020
5   Copyright            : (C) 2020 by Martin Dobias
6   Email                : wonder dot sk at gmail dot com
7  ***************************************************************************
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 
16 #include "qgsvectortiledataitemguiprovider.h"
17 
18 #include "qgsvectortiledataitems.h"
19 #include "qgsvectortileconnectiondialog.h"
20 #include "qgsarcgisvectortileconnectiondialog.h"
21 #include "qgsvectortileconnection.h"
22 #include "qgsmanageconnectionsdialog.h"
23 
24 #include <QFileDialog>
25 #include <QMessageBox>
26 
27 ///@cond PRIVATE
28 
populateContextMenu(QgsDataItem * item,QMenu * menu,const QList<QgsDataItem * > &,QgsDataItemGuiContext)29 void QgsVectorTileDataItemGuiProvider::populateContextMenu( QgsDataItem *item, QMenu *menu, const QList<QgsDataItem *> &, QgsDataItemGuiContext )
30 {
31   if ( QgsVectorTileLayerItem *layerItem = qobject_cast< QgsVectorTileLayerItem * >( item ) )
32   {
33     QAction *actionEdit = new QAction( tr( "Edit Connection…" ), menu );
34     connect( actionEdit, &QAction::triggered, this, [layerItem] { editConnection( layerItem ); } );
35     menu->addAction( actionEdit );
36 
37     QAction *actionDelete = new QAction( tr( "Remove Connection" ), menu );
38     connect( actionDelete, &QAction::triggered, this, [layerItem] { deleteConnection( layerItem ); } );
39     menu->addAction( actionDelete );
40   }
41 
42   if ( QgsVectorTileRootItem *rootItem = qobject_cast< QgsVectorTileRootItem * >( item ) )
43   {
44     QAction *actionNew = new QAction( tr( "New Generic Connection…" ), menu );
45     connect( actionNew, &QAction::triggered, this, [rootItem] { newConnection( rootItem ); } );
46     menu->addAction( actionNew );
47 
48     QAction *actionNewArcGISConnection = new QAction( tr( "New ArcGIS Vector Tile Service Connection…" ), menu );
49     connect( actionNewArcGISConnection, &QAction::triggered, this, [rootItem] { newArcGISConnection( rootItem ); } );
50     menu->addAction( actionNewArcGISConnection );
51 
52     menu->addSeparator();
53 
54     QAction *actionSaveXyzTilesServers = new QAction( tr( "Save Connections…" ), menu );
55     connect( actionSaveXyzTilesServers, &QAction::triggered, this, [] { saveXyzTilesServers(); } );
56     menu->addAction( actionSaveXyzTilesServers );
57 
58     QAction *actionLoadXyzTilesServers = new QAction( tr( "Load Connections…" ), menu );
59     connect( actionLoadXyzTilesServers, &QAction::triggered, this, [rootItem] { loadXyzTilesServers( rootItem ); } );
60     menu->addAction( actionLoadXyzTilesServers );
61   }
62 }
63 
editConnection(QgsDataItem * item)64 void QgsVectorTileDataItemGuiProvider::editConnection( QgsDataItem *item )
65 {
66   const QgsVectorTileProviderConnection::Data connection = QgsVectorTileProviderConnection::connection( item->name() );
67   const QString uri = QgsVectorTileProviderConnection::encodedUri( connection );
68 
69   switch ( connection.serviceType )
70   {
71     case QgsVectorTileProviderConnection::Generic:
72     {
73       QgsVectorTileConnectionDialog dlg;
74 
75       dlg.setConnection( item->name(), uri );
76       if ( !dlg.exec() )
77         return;
78 
79       QgsVectorTileProviderConnection::deleteConnection( item->name() );
80       const QgsVectorTileProviderConnection::Data conn = QgsVectorTileProviderConnection::decodedUri( dlg.connectionUri() );
81       QgsVectorTileProviderConnection::addConnection( dlg.connectionName(), conn );
82       break;
83     }
84 
85     case QgsVectorTileProviderConnection::ArcgisVectorTileService:
86     {
87       QgsArcgisVectorTileConnectionDialog dlg;
88 
89       dlg.setConnection( item->name(), uri );
90       if ( !dlg.exec() )
91         return;
92 
93       QgsVectorTileProviderConnection::deleteConnection( item->name() );
94       const QgsVectorTileProviderConnection::Data conn = QgsVectorTileProviderConnection::decodedUri( dlg.connectionUri() );
95       QgsVectorTileProviderConnection::addConnection( dlg.connectionName(), conn );
96       break;
97     }
98   }
99 
100   item->parent()->refreshConnections();
101 }
102 
deleteConnection(QgsDataItem * item)103 void QgsVectorTileDataItemGuiProvider::deleteConnection( QgsDataItem *item )
104 {
105   if ( QMessageBox::question( nullptr, tr( "Remove Connection" ), tr( "Are you sure you want to remove the connection “%1”?" ).arg( item->name() ),
106                               QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes )
107     return;
108 
109   QgsVectorTileProviderConnection::deleteConnection( item->name() );
110 
111   item->parent()->refreshConnections();
112 }
113 
newConnection(QgsDataItem * item)114 void QgsVectorTileDataItemGuiProvider::newConnection( QgsDataItem *item )
115 {
116   QgsVectorTileConnectionDialog dlg;
117   if ( !dlg.exec() )
118     return;
119 
120   const QgsVectorTileProviderConnection::Data conn = QgsVectorTileProviderConnection::decodedUri( dlg.connectionUri() );
121   QgsVectorTileProviderConnection::addConnection( dlg.connectionName(), conn );
122 
123   item->refreshConnections();
124 }
125 
newArcGISConnection(QgsDataItem * item)126 void QgsVectorTileDataItemGuiProvider::newArcGISConnection( QgsDataItem *item )
127 {
128   QgsArcgisVectorTileConnectionDialog dlg;
129   if ( !dlg.exec() )
130     return;
131 
132   const QgsVectorTileProviderConnection::Data conn = QgsVectorTileProviderConnection::decodedUri( dlg.connectionUri() );
133   QgsVectorTileProviderConnection::addConnection( dlg.connectionName(), conn );
134 
135   item->refreshConnections();
136 }
137 
saveXyzTilesServers()138 void QgsVectorTileDataItemGuiProvider::saveXyzTilesServers()
139 {
140   QgsManageConnectionsDialog dlg( nullptr, QgsManageConnectionsDialog::Export, QgsManageConnectionsDialog::VectorTile );
141   dlg.exec();
142 }
143 
loadXyzTilesServers(QgsDataItem * item)144 void QgsVectorTileDataItemGuiProvider::loadXyzTilesServers( QgsDataItem *item )
145 {
146   const QString fileName = QFileDialog::getOpenFileName( nullptr, tr( "Load Connections" ), QDir::homePath(),
147                            tr( "XML files (*.xml *.XML)" ) );
148   if ( fileName.isEmpty() )
149   {
150     return;
151   }
152 
153   QgsManageConnectionsDialog dlg( nullptr, QgsManageConnectionsDialog::Import, QgsManageConnectionsDialog::VectorTile, fileName );
154   if ( dlg.exec() == QDialog::Accepted )
155     item->refreshConnections();
156 }
157 
158 ///@endcond
159