mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-22 00:06:12 -05:00
[FEATURE] QGIS - GeoNode Integration: Integrate with QGIS Browser Panel (#4816)
* add Geonode connection menu to the toolbar * add header files for geonode-qgis client * add action to launch geonode connection dialog from menubar * Move to proper directory * Add geonodeconnection class. * Add unit test for geonode connection. * Use const static to avoid typo. * Get list layers from geonode. * Add get maps method. * Geonode connection dialog (#13) * add new geonode connection dialog * apply functionality to the geonode connection manager dialog * add save and load geonode connection functionality * edit baseKey and credentialBaseKey * remove auto-connect slots * Add unit test for geonode connection. * Add wms url getter. * Add uuid and layer name in the table. * Add handler for the list layer clicked. WIP. * Use new style connect, better hacky to get wms url. * update gitignore * Make QGIS able to add WMS layer from geonode. With hacky code. * Fix Docstring. * Show web service type (WMS/WFS) in layer table. * fix http and toolbar menu * add geonode data item to the browser panel as an extention of ows provider * [WIP] Add WFS. * Add geonode get service url. * combobox functionality and test geonode connection * Add WFS. * Disable add button if it's a map. Currently we can't do anything for map. * Add busy cursor when add layer. * get service uri capabilitites * add available layers to the geonode browser panel * remove debugging footprint and replace old style connect * add actions (new, edit, delete) to geonode browser panel * fix getLayers by WMS url * add Geonode connection menu to the toolbar * Filter out invalid layer / map. * Fix service url method. * Add service url for XYZ for GeoNode QGIS Server backend. * Add XYZ url to geonode connection dialog. * Add XYZ layer to QGIS. * fix double geonode submenu * add wfs/wms layers from browser panel using its native provider * comply with qgis3 new class naming * Handle different prefix for layer in GeoNode QGIS Server backend. * base class for cms connection * make geonode connection as a derived class from cms connection * update cmakelists * move geonode connection to geocms dir * update CMakeLists * Handle geonode 2.7 with new API. * Handle multiple geoserver url in one geonode. * Fix add xyz for qgis server. Fix add wms, wfs, xyz for geoserver in geonode 2.7 * Refactor serviceURL to return QStringList. * add 'add geonode layer' icon * add geonode to the data source manager dialog * [GeoNode-Client] Fix add WFS layer. * fix wms url parameter * add xyz dataitems * Use new style connect. * [GeoNode Client] Handle qgis server specific typename to make add WFS works. * Code improvement. * [GeoNode Client] Make geonode dialog in add universal layer can add layer. * Open universal add layer when click Add GeoNode layer. * Make sure the geonode url has protocol. * Handle geonode version in a better way. * make sure the serviceUrl method has scheme in its urls * add services option to the dialog * remove version label if not wfs * construct wms url with parameters for geonode connection * handle layer from multi service urls for every wfs, wms, & xyz services * fix new style connect using static_cast * hode close button if dialog is in embedded mode * fix xyz layer naming in the browser tree * create base class for geocms dataitems * fix compiling warning * Use struct instead QVariantMap. * tidy up code * Tidy up code, use QgsStringMap instead QVariantMap. * Add spellok for catalogue. * update sip * update sip * Use naming convention for QgsGeoCmsConnection and use QUuid. * Async by using GeoNodeRequest class. * Move geonode to src/gui. * Use stack not heap. * Remove unused includes. * Use signal to handle request. * Use QStringLiteral. * Switch to use Q_FOREACH. * Use Q_FOREACH and addressing PR's review. * Set private for data members. * update sip * Update sip. * Update sip. * Fix sip problem to make it buildable again. * Remove geocms * Tidy up code. * Use QgsSetting Scope::Provider. * Fix missing zip.h
This commit is contained in:
parent
5614df4b6e
commit
bea89b32ca
2
.gitignore
vendored
2
.gitignore
vendored
@ -23,7 +23,7 @@
|
||||
/CMakeLists.txt.user
|
||||
/CMakeLists.txt.user.*
|
||||
api_doc
|
||||
build*
|
||||
*build*
|
||||
debian/*.debhelper
|
||||
debian/*.substvars
|
||||
desktop.ini
|
||||
|
@ -135,6 +135,7 @@
|
||||
<file>themes/default/mActionAddWcsLayer.svg</file>
|
||||
<file>themes/default/mActionAddWfsLayer.svg</file>
|
||||
<file>themes/default/mActionAddWmsLayer.svg</file>
|
||||
<file>themes/default/mActionAddGeonodeLayer.svg</file>
|
||||
<file>themes/default/mActionAddDelimitedTextLayer.svg</file>
|
||||
<file>themes/default/mActionAddVirtualLayer.svg</file>
|
||||
<file>themes/default/mActionAlignBottom.svg</file>
|
||||
@ -359,6 +360,7 @@
|
||||
<file>themes/default/mIconFieldInteger.svg</file>
|
||||
<file>themes/default/mIconFieldText.svg</file>
|
||||
<file>themes/default/mIconFieldTime.svg</file>
|
||||
<file>themes/default/mIconGeonode.svg</file>
|
||||
<file>themes/default/mIconInfo.svg</file>
|
||||
<file>themes/default/mIconImport.gif</file>
|
||||
<file>themes/default/mIconLabelQuadrantCenter.svg</file>
|
||||
|
407
images/themes/default/mActionAddGeonodeLayer.svg
Normal file
407
images/themes/default/mActionAddGeonodeLayer.svg
Normal file
@ -0,0 +1,407 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="425px" height="425px" viewBox="0 0 425 425" enable-background="new 0 0 425 425" xml:space="preserve"> <image id="image0" width="425" height="425" x="0" y="0"
|
||||
xlink:href="data:image/png;base64,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" />
|
||||
</svg>
|
After Width: | Height: | Size: 31 KiB |
13
images/themes/default/mIconGeonode.svg
Normal file
13
images/themes/default/mIconGeonode.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="400px" height="400px" viewBox="0 0 4000 4000" preserveAspectRatio="xMidYMid meet">
|
||||
<g id="layer1" fill="#1177a3" stroke="none">
|
||||
<path d="M1863 3990 c-62 -9 -113 -30 -113 -47 0 -7 -5 -13 -11 -13 -14 0 -59 -47 -59 -61 0 -5 -6 -9 -13 -9 -8 0 -19 -12 -26 -27 -8 -16 -17 -36 -22 -45 -5 -10 -9 -29 -9 -42 0 -13 -7 -26 -15 -30 -12 -4 -15 -27 -15 -121 0 -94 3 -117 15 -121 12 -5 15 -26 15 -99 0 -52 4 -97 10 -100 6 -3 10 -50 10 -105 0 -55 4 -102 10 -105 6 -3 10 -50 10 -106 0 -79 3 -101 15 -105 9 -4 15 -19 15 -40 0 -35 -1 -34 149 -146 20 -15 41 -27 48 -28 7 0 10 -7 7 -15 -4 -10 0 -15 12 -15 11 0 30 -9 44 -20 32 -25 78 -25 110 0 14 11 31 20 38 20 6 0 12 6 12 14 0 7 16 21 35 31 20 9 50 29 68 43 18 15 49 40 70 55 30 23 37 34 37 62 0 19 5 37 10 40 6 3 10 46 10 94 0 67 4 92 15 101 11 10 15 36 15 111 0 54 4 101 10 104 6 3 10 48 10 100 0 52 4 97 10 100 6 4 10 55 10 120 0 65 -4 116 -10 120 -5 3 -10 19 -10 35 0 16 -4 32 -10 35 -5 3 -10 13 -10 22 0 8 -10 27 -22 41 -55 60 -115 118 -137 130 -53 28 -223 39 -338 22z"/>
|
||||
<path d="M435 3260 c-3 -5 -19 -10 -36 -10 -16 0 -29 -4 -29 -10 0 -5 -7 -10 -15 -10 -9 0 -18 -7 -21 -15 -4 -8 -12 -15 -19 -15 -16 0 -115 -96 -132 -129 -7 -13 -13 -29 -13 -36 0 -7 -7 -15 -15 -19 -8 -3 -15 -14 -15 -25 0 -11 -4 -23 -10 -26 -6 -4 -10 -57 -10 -125 0 -68 4 -121 10 -125 5 -3 10 -15 10 -26 0 -11 7 -22 15 -25 8 -4 15 -11 15 -18 1 -23 71 -106 117 -137 26 -18 49 -36 51 -41 2 -4 20 -15 40 -24 20 -9 45 -20 54 -25 10 -5 26 -9 37 -9 10 0 22 -7 25 -16 4 -10 14 -14 25 -11 12 3 22 -1 25 -9 3 -8 14 -14 25 -14 11 0 23 -4 26 -10 3 -5 17 -10 30 -10 13 0 27 -4 30 -10 3 -5 14 -10 25 -10 10 0 20 -7 24 -15 3 -8 14 -15 25 -15 11 0 23 -4 26 -10 3 -5 17 -10 30 -10 13 0 27 -4 30 -10 3 -5 14 -10 25 -10 10 0 20 -7 24 -15 3 -8 12 -15 21 -15 8 0 24 -4 35 -10 11 -5 29 -14 40 -20 11 -5 29 -10 39 -10 11 0 23 -4 26 -10 3 -5 14 -10 25 -10 10 0 20 -7 24 -15 3 -8 17 -15 31 -15 14 0 25 -4 25 -10 0 -5 14 -10 30 -10 27 0 42 5 90 31 21 12 80 39 110 51 14 6 33 14 42 19 10 5 25 9 33 9 9 0 18 7 21 15 4 8 14 15 24 15 36 0 50 32 50 118 0 44 -4 84 -10 87 -6 3 -10 50 -10 105 0 97 -1 99 -31 129 -38 39 -153 121 -168 121 -6 0 -11 6 -11 13 0 12 -62 57 -80 57 -5 0 -15 9 -22 21 -7 11 -27 27 -45 36 -18 8 -42 25 -55 37 -13 12 -68 54 -123 92 -55 38 -107 76 -117 86 -9 9 -33 24 -55 34 -21 10 -42 24 -46 31 -4 7 -15 13 -23 13 -8 0 -23 5 -34 10 -11 6 -29 15 -40 20 -11 6 -65 10 -119 10 -56 0 -103 -4 -106 -10z"/>
|
||||
<path d="M3335 3260 c-3 -5 -14 -10 -24 -10 -21 0 -81 -28 -81 -38 0 -4 -17 -15 -39 -24 -21 -9 -54 -31 -72 -47 -18 -17 -38 -31 -44 -31 -5 0 -23 -12 -40 -26 -16 -14 -50 -40 -75 -57 -25 -17 -54 -39 -65 -48 -36 -32 -156 -119 -164 -119 -4 0 -21 -12 -38 -27 -17 -16 -65 -51 -106 -80 -94 -65 -107 -89 -107 -203 0 -69 -3 -89 -15 -94 -12 -4 -15 -24 -15 -90 l0 -85 38 -17 c20 -10 41 -24 45 -31 4 -7 15 -13 23 -13 8 0 22 -4 32 -9 9 -5 28 -13 42 -19 30 -12 89 -39 110 -51 47 -26 62 -31 84 -31 14 0 28 5 31 10 3 6 17 10 31 10 14 0 27 7 30 15 4 8 12 15 20 15 8 0 23 5 34 10 11 6 29 15 40 20 11 6 29 10 39 10 11 0 23 5 26 10 3 6 15 10 26 10 11 0 22 7 25 15 4 8 14 15 24 15 11 0 22 5 25 10 3 6 17 10 30 10 13 0 27 5 30 10 3 6 15 10 26 10 11 0 22 7 25 15 4 8 14 15 24 15 11 0 22 5 25 10 3 6 15 10 26 10 10 0 28 5 39 10 11 6 29 15 40 20 11 6 27 10 35 10 9 0 18 7 21 15 4 8 14 15 24 15 11 0 22 5 25 10 3 6 14 10 24 10 21 0 81 28 81 38 0 4 20 19 43 34 49 31 127 118 127 142 0 8 5 18 10 21 6 3 10 14 10 25 0 10 7 20 15 24 12 4 15 29 15 131 0 102 -3 127 -15 131 -8 4 -15 12 -15 20 0 22 -39 86 -76 124 -19 20 -34 40 -34 46 0 6 -16 16 -35 24 -19 8 -35 17 -35 21 0 11 -59 39 -81 39 -10 0 -21 5 -24 10 -3 6 -52 10 -110 10 -58 0 -107 -4 -110 -10z"/>
|
||||
<path d="M1948 2448 c-28 -26 -54 -42 -113 -72 -22 -12 -51 -31 -65 -43 -13 -13 -30 -23 -37 -23 -17 0 -56 -22 -66 -37 -4 -7 -13 -10 -21 -7 -32 12 -36 -20 -34 -267 3 -242 3 -244 26 -254 12 -5 22 -13 22 -17 0 -5 8 -8 18 -8 9 0 28 -9 42 -20 14 -11 31 -20 38 -20 6 0 12 -4 12 -9 0 -6 28 -23 63 -40 34 -16 71 -38 83 -48 43 -39 65 -46 93 -32 14 7 37 23 51 34 14 12 49 33 77 46 29 13 53 30 53 37 0 6 7 12 16 12 9 0 28 8 42 18 15 10 41 24 57 32 17 8 40 23 53 34 22 19 22 23 22 251 l0 231 -27 20 c-16 11 -50 31 -78 44 -27 14 -51 28 -53 32 -2 4 -31 21 -65 37 -34 16 -71 38 -83 48 -54 48 -89 54 -126 21z"/>
|
||||
<path d="M1130 1890 c0 -5 -11 -10 -25 -10 -14 0 -28 -7 -31 -15 -4 -8 -12 -15 -20 -15 -8 0 -22 -4 -32 -9 -9 -5 -30 -14 -47 -21 -16 -7 -38 -16 -47 -21 -10 -5 -25 -9 -33 -9 -9 0 -18 -7 -21 -15 -4 -8 -15 -15 -25 -15 -11 0 -27 -4 -37 -9 -9 -5 -30 -14 -47 -21 -16 -7 -37 -16 -45 -21 -19 -11 -77 -38 -110 -51 -14 -6 -33 -14 -42 -19 -10 -5 -25 -9 -33 -9 -9 0 -18 -7 -21 -15 -4 -8 -15 -15 -25 -15 -11 0 -28 -4 -39 -10 -11 -5 -29 -14 -40 -20 -11 -5 -27 -10 -35 -10 -9 0 -18 -7 -21 -15 -4 -8 -12 -15 -20 -15 -19 0 -164 -145 -164 -164 0 -8 -7 -16 -15 -20 -8 -3 -15 -14 -15 -25 0 -11 -4 -23 -10 -26 -6 -4 -10 -57 -10 -125 0 -68 4 -121 10 -125 6 -3 10 -17 10 -30 0 -13 6 -28 13 -32 6 -4 18 -21 26 -36 13 -24 57 -68 149 -149 12 -11 28 -18 36 -15 8 3 17 -1 20 -9 3 -8 18 -14 35 -14 16 0 33 -4 36 -10 3 -6 48 -10 100 -10 52 0 97 4 100 10 3 6 20 10 36 10 17 0 32 6 35 15 4 8 10 12 16 9 5 -3 21 6 35 20 14 14 31 26 38 26 6 0 20 9 30 20 9 10 46 38 81 61 35 23 64 45 64 50 0 5 5 9 11 9 5 0 41 25 79 55 38 30 73 55 77 55 4 0 18 11 30 23 11 13 42 34 67 47 25 13 46 29 46 35 0 7 15 20 34 29 18 9 55 34 82 56 27 22 53 40 59 40 21 0 35 57 35 145 0 50 5 96 10 101 6 6 10 45 8 93 -3 80 -4 83 -33 99 -16 9 -31 20 -33 24 -2 4 -20 15 -40 24 -20 9 -45 20 -54 25 -10 5 -27 9 -37 9 -11 0 -23 5 -26 10 -3 6 -14 10 -25 10 -10 0 -20 7 -24 15 -3 8 -14 15 -25 15 -11 0 -23 5 -26 10 -3 6 -22 10 -41 10 -19 0 -34 -4 -34 -10z"/>
|
||||
<path d="M2785 1890 c-3 -5 -15 -10 -26 -10 -11 0 -22 -7 -25 -15 -4 -8 -14 -15 -24 -15 -11 0 -22 -4 -25 -10 -3 -5 -15 -10 -26 -10 -10 0 -28 -4 -39 -10 -11 -5 -29 -14 -40 -20 -11 -5 -27 -10 -35 -10 -9 0 -18 -7 -21 -15 -4 -8 -14 -15 -24 -15 -36 0 -50 -32 -50 -119 0 -63 3 -83 15 -87 12 -5 15 -25 15 -94 0 -121 3 -126 148 -230 23 -17 54 -42 68 -55 15 -14 32 -25 38 -25 6 0 29 -15 51 -32 21 -18 58 -46 81 -63 57 -41 158 -117 164 -124 3 -3 17 -12 32 -20 14 -7 40 -26 57 -42 17 -15 47 -36 66 -45 19 -9 35 -20 35 -24 0 -13 60 -40 86 -40 13 0 26 -4 29 -10 3 -6 52 -10 110 -10 58 0 107 4 110 10 3 6 14 10 24 10 24 0 81 29 81 41 0 5 7 9 15 9 20 0 119 99 144 144 12 20 21 45 21 55 0 10 7 21 15 25 22 8 22 254 0 262 -8 4 -15 14 -15 24 0 11 -4 22 -10 25 -5 3 -10 14 -10 25 0 19 -130 145 -167 163 -13 6 -23 14 -23 19 0 4 -9 8 -19 8 -11 0 -23 5 -26 10 -3 6 -17 10 -30 10 -13 0 -27 5 -30 10 -3 6 -14 10 -25 10 -10 0 -20 7 -24 15 -3 8 -12 15 -21 15 -8 0 -23 4 -33 9 -9 5 -28 13 -42 18 -52 21 -85 36 -100 44 -8 5 -22 12 -30 15 -35 14 -66 27 -82 35 -10 5 -24 9 -32 9 -8 0 -16 7 -20 15 -3 8 -12 15 -21 15 -8 0 -23 4 -33 9 -9 5 -30 14 -47 21 -16 7 -38 16 -47 21 -10 5 -24 9 -32 9 -8 0 -16 7 -20 15 -3 8 -16 15 -30 15 -14 0 -28 5 -31 10 -3 6 -19 10 -35 10 -16 0 -32 -4 -35 -10z"/>
|
||||
<path d="M1960 1435 c-7 -8 -18 -15 -25 -15 -7 0 -24 -11 -39 -25 -14 -13 -47 -38 -73 -56 -27 -18 -59 -42 -73 -54 -14 -13 -34 -25 -45 -27 -16 -2 -21 -12 -23 -48 -2 -26 -10 -48 -18 -53 -11 -6 -14 -32 -14 -107 0 -55 -4 -102 -10 -105 -6 -3 -10 -48 -10 -100 0 -52 -4 -97 -10 -100 -6 -3 -10 -48 -10 -100 0 -73 -3 -94 -15 -99 -12 -4 -15 -27 -15 -116 0 -89 3 -112 15 -116 8 -4 15 -18 15 -33 0 -44 43 -117 101 -174 71 -68 91 -78 172 -85 37 -2 70 -9 73 -13 7 -12 74 -12 74 0 0 4 33 11 73 13 84 6 106 17 167 79 82 83 110 124 110 165 0 12 5 26 10 29 6 4 10 55 10 120 0 65 -4 116 -10 120 -6 3 -10 50 -10 105 0 55 -4 102 -10 105 -6 3 -10 50 -10 106 0 81 -3 99 -15 99 -12 0 -15 18 -15 98 0 54 -4 102 -9 108 -5 5 -11 27 -13 48 -2 33 -9 43 -37 59 -19 10 -53 34 -75 53 -22 19 -52 39 -68 46 -15 7 -28 18 -28 24 0 11 -66 47 -106 59 -13 3 -26 -1 -34 -10z"/>
|
||||
</g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 7.7 KiB |
@ -112,6 +112,7 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/src/core/fieldformatter
|
||||
${CMAKE_SOURCE_DIR}/src/core/dxf
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/geonode
|
||||
${CMAKE_SOURCE_DIR}/src/core/gps
|
||||
${CMAKE_SOURCE_DIR}/src/core/layertree
|
||||
${CMAKE_SOURCE_DIR}/src/core/layout
|
||||
@ -141,6 +142,7 @@ IF (WITH_GUI)
|
||||
${CMAKE_SOURCE_DIR}/src/gui/editorwidgets
|
||||
${CMAKE_SOURCE_DIR}/src/gui/editorwidgets/core
|
||||
${CMAKE_SOURCE_DIR}/src/gui/effects
|
||||
${CMAKE_SOURCE_DIR}/src/gui/geonode
|
||||
${CMAKE_SOURCE_DIR}/src/gui/layertree
|
||||
${CMAKE_SOURCE_DIR}/src/gui/layout
|
||||
${CMAKE_SOURCE_DIR}/src/gui/locator
|
||||
|
@ -284,6 +284,8 @@
|
||||
%Include fieldformatter/qgsrelationreferencefieldformatter.sip
|
||||
%Include fieldformatter/qgsvaluemapfieldformatter.sip
|
||||
%Include fieldformatter/qgsvaluerelationfieldformatter.sip
|
||||
%Include geonode/qgsgeonodeconnection.sip
|
||||
%Include geonode/qgsgeonoderequest.sip
|
||||
%Include gps/qgsqtlocationconnection.sip
|
||||
%Include gps/qgsgpsconnectionregistry.sip
|
||||
%Include qgsapplication.sip
|
||||
|
0
python/core/geonode/qgsdataitemprovider.sip
Normal file
0
python/core/geonode/qgsdataitemprovider.sip
Normal file
86
python/core/geonode/qgsgeonodeconnection.sip
Normal file
86
python/core/geonode/qgsgeonodeconnection.sip
Normal file
@ -0,0 +1,86 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/geonode/qgsgeonodeconnection.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsGeoNodeConnection : QObject
|
||||
{
|
||||
%Docstring
|
||||
!
|
||||
GeoNode Connections management
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsgeonodeconnection.h"
|
||||
%End
|
||||
public:
|
||||
explicit QgsGeoNodeConnection( const QString &connName );
|
||||
%Docstring
|
||||
Constructor
|
||||
%End
|
||||
|
||||
~QgsGeoNodeConnection();
|
||||
%Docstring
|
||||
Destructor
|
||||
%End
|
||||
|
||||
QString connName() const;
|
||||
%Docstring
|
||||
:rtype: str
|
||||
%End
|
||||
void setConnName( const QString &connName );
|
||||
|
||||
QgsDataSourceUri uri();
|
||||
%Docstring
|
||||
:rtype: QgsDataSourceUri
|
||||
%End
|
||||
void setUri( const QgsDataSourceUri &uri );
|
||||
|
||||
static QStringList connectionList();
|
||||
%Docstring
|
||||
Retrieve all geonode connection
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
static void deleteConnection( const QString &name );
|
||||
%Docstring
|
||||
Delete connection with name, name
|
||||
%End
|
||||
|
||||
static QString selectedConnection();
|
||||
%Docstring
|
||||
Get selected connection
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
static void setSelectedConnection( const QString &name );
|
||||
%Docstring
|
||||
Set selected connection
|
||||
%End
|
||||
|
||||
static QString pathGeoNodeConnection();
|
||||
%Docstring
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
static QString pathGeoNodeConnectionDetails();
|
||||
%Docstring
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/geonode/qgsgeonodeconnection.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
121
python/core/geonode/qgsgeonoderequest.sip
Normal file
121
python/core/geonode/qgsgeonoderequest.sip
Normal file
@ -0,0 +1,121 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/geonode/qgsgeonoderequest.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
struct QgsServiceLayerDetail
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsgeonoderequest.h>
|
||||
%End
|
||||
QUuid uuid;
|
||||
QString name;
|
||||
QString typeName;
|
||||
QString title;
|
||||
QString wmsURL;
|
||||
QString wfsURL;
|
||||
QString xyzURL;
|
||||
};
|
||||
|
||||
class QgsGeoNodeRequest : QObject
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsgeonoderequest.h"
|
||||
%End
|
||||
public:
|
||||
explicit QgsGeoNodeRequest( bool forceRefresh, QObject *parent = 0 );
|
||||
QgsGeoNodeRequest( const QString &baseUrl, /*const QgsWmsAuthorization &auth,*/ bool forceRefresh, QObject *parent = 0 );
|
||||
virtual ~QgsGeoNodeRequest();
|
||||
|
||||
bool request( QString endPoint );
|
||||
%Docstring
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool getLayers();
|
||||
%Docstring
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QList<QgsServiceLayerDetail> parseLayers( QByteArray layerResponse );
|
||||
%Docstring
|
||||
:rtype: list of QgsServiceLayerDetail
|
||||
%End
|
||||
|
||||
QStringList serviceUrls( QString serviceType );
|
||||
%Docstring
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
QgsStringMap serviceUrlData( QString serviceType );
|
||||
%Docstring
|
||||
:rtype: QgsStringMap
|
||||
%End
|
||||
|
||||
QString lastError() const;
|
||||
%Docstring
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
QByteArray response() const;
|
||||
%Docstring
|
||||
:rtype: QByteArray
|
||||
%End
|
||||
|
||||
QNetworkReply *reply() const;
|
||||
%Docstring
|
||||
:rtype: QNetworkReply
|
||||
%End
|
||||
|
||||
void abort();
|
||||
%Docstring
|
||||
Abort network request immediately
|
||||
%End
|
||||
|
||||
QString getProtocol() const;
|
||||
%Docstring
|
||||
:rtype: str
|
||||
%End
|
||||
void setProtocol( const QString &protocol );
|
||||
|
||||
signals:
|
||||
void statusChanged( const QString &statusQString );
|
||||
%Docstring
|
||||
emit a signal to be caught by qgisapp and display a statusQString on status bar
|
||||
%End
|
||||
|
||||
void requestFinished();
|
||||
%Docstring
|
||||
emit a signal once the request is finished
|
||||
%End
|
||||
|
||||
protected slots:
|
||||
void replyFinished();
|
||||
void replyProgress( qint64, qint64 );
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/geonode/qgsgeonoderequest.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -49,6 +49,11 @@ Caller takes responsibility of deleting created items.
|
||||
:rtype: QgsDataItem
|
||||
%End
|
||||
|
||||
virtual QVector<QgsDataItem *> createDataItems( const QString &path, QgsDataItem *parentItem );
|
||||
%Docstring
|
||||
Caller takes responsibility of deleting created items.
|
||||
:rtype: list of QgsDataItem
|
||||
%End
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
|
51
python/gui/geonode/qgsgeonodenewconnection.sip
Normal file
51
python/gui/geonode/qgsgeonodenewconnection.sip
Normal file
@ -0,0 +1,51 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/geonode/qgsgeonodenewconnection.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsGeoNodeNewConnection : QDialog
|
||||
{
|
||||
%Docstring
|
||||
*************************************************************************
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify *
|
||||
it under the terms of the GNU General Public License as published by *
|
||||
the Free Software Foundation; either version 2 of the License, or *
|
||||
(at your option) any later version. *
|
||||
*
|
||||
**************************************************************************
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsgeonodenewconnection.h"
|
||||
%End
|
||||
public:
|
||||
QgsGeoNodeNewConnection( QWidget *parent = 0, const QString &connName = QString::null, Qt::WindowFlags fl = QgsGuiUtils::ModalDialogFlags );
|
||||
%Docstring
|
||||
Constructor
|
||||
%End
|
||||
|
||||
public slots:
|
||||
virtual void accept();
|
||||
|
||||
void okButtonBehavior( const QString & );
|
||||
void testConnection();
|
||||
%Docstring
|
||||
Test the connection using the parameters supplied
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/geonode/qgsgeonodenewconnection.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
64
python/gui/geonode/qgsgeonodesourceselect.sip
Normal file
64
python/gui/geonode/qgsgeonodesourceselect.sip
Normal file
@ -0,0 +1,64 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/geonode/qgsgeonodesourceselect.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsGeonodeItemDelegate : QItemDelegate
|
||||
{
|
||||
%Docstring
|
||||
*************************************************************************
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify *
|
||||
it under the terms of the GNU General Public License as published by *
|
||||
the Free Software Foundation; either version 2 of the License, or *
|
||||
(at your option) any later version. *
|
||||
*
|
||||
**************************************************************************
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsgeonodesourceselect.h"
|
||||
%End
|
||||
public:
|
||||
explicit QgsGeonodeItemDelegate( QObject *parent = 0 );
|
||||
};
|
||||
|
||||
class QgsGeoNodeSourceSelect: QDialog
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsgeonodesourceselect.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsGeoNodeSourceSelect( QWidget *parent, Qt::WindowFlags fl, bool embeddedMode = false );
|
||||
~QgsGeoNodeSourceSelect();
|
||||
|
||||
signals:
|
||||
void connectionsChanged();
|
||||
void addRasterLayer( const QString &rasterLayerPath,
|
||||
const QString &baseName,
|
||||
const QString &providerKey );
|
||||
void addRasterLayer();
|
||||
|
||||
void addWfsLayer(
|
||||
const QString &uri,
|
||||
const QString &layerName,
|
||||
const QString &providerKey );
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/geonode/qgsgeonodesourceselect.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -42,6 +42,8 @@
|
||||
%Include auth/qgsauthtrustedcasdialog.sip
|
||||
%Include editorwidgets/core/qgseditorwidgetfactory.sip
|
||||
%Include editorwidgets/core/qgseditorwidgetautoconf.sip
|
||||
%Include geonode/qgsgeonodenewconnection.sip
|
||||
%Include geonode/qgsgeonodesourceselect.sip
|
||||
%Include layertree/qgslayertreeembeddedconfigwidget.sip
|
||||
%Include layertree/qgslayertreeembeddedwidgetregistry.sip
|
||||
%Include layout/qgslayoutviewmouseevent.sip
|
||||
|
@ -31,6 +31,7 @@ class QgsManageConnectionsDialog : QDialog
|
||||
DB2,
|
||||
WCS,
|
||||
Oracle,
|
||||
GeoNode
|
||||
};
|
||||
|
||||
QgsManageConnectionsDialog( QWidget *parent /TransferThis/ = 0, Mode mode = Export, Type type = WMS, const QString &fileName = "" );
|
||||
|
@ -519,6 +519,7 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/src/gui/symbology
|
||||
${CMAKE_SOURCE_DIR}/src/gui/attributetable
|
||||
${CMAKE_SOURCE_DIR}/src/gui/auth
|
||||
${CMAKE_SOURCE_DIR}/src/gui/geonode
|
||||
${CMAKE_SOURCE_DIR}/src/gui/ogr
|
||||
${CMAKE_SOURCE_DIR}/src/gui/raster
|
||||
${CMAKE_SOURCE_DIR}/src/gui/editorwidgets
|
||||
@ -565,6 +566,7 @@ INCLUDE_DIRECTORIES(
|
||||
../gui/symbology
|
||||
../gui/attributetable
|
||||
../gui/auth
|
||||
../gui/geonode
|
||||
../gui/ogr
|
||||
../gui/raster
|
||||
../gui/editorwidgets
|
||||
|
@ -294,6 +294,7 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
|
||||
#include "qgsuserprofile.h"
|
||||
|
||||
#include "qgssublayersdialog.h"
|
||||
#include "geonode/qgsgeonodesourceselect.h"
|
||||
#include "ogr/qgsvectorlayersaveasdialog.h"
|
||||
|
||||
#include "qgsosmdownloaddialog.h"
|
||||
@ -782,9 +783,9 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
|
||||
|
||||
endProfile();
|
||||
|
||||
functionProfile( &QgisApp::createMenus, this, QStringLiteral( "Create menus" ) );
|
||||
functionProfile( &QgisApp::createActions, this, QStringLiteral( "Create actions" ) );
|
||||
functionProfile( &QgisApp::createActionGroups, this, QStringLiteral( "Create action group" ) );
|
||||
functionProfile( &QgisApp::createMenus, this, QStringLiteral( "Create menus" ) );
|
||||
functionProfile( &QgisApp::createToolBars, this, QStringLiteral( "Toolbars" ) );
|
||||
functionProfile( &QgisApp::createStatusBar, this, QStringLiteral( "Status bar" ) );
|
||||
functionProfile( &QgisApp::createCanvasTools, this, QStringLiteral( "Create canvas tools" ) );
|
||||
@ -1021,6 +1022,11 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
|
||||
mActionInstallFromZip = nullptr;
|
||||
}
|
||||
|
||||
// add geonode menu under web menu
|
||||
addPluginToWebMenu( mGeonodeMenu->title(), mActionAddGeonodeLayer );
|
||||
mActionAddGeonodeLayer = new QAction( tr( "Add GeoNode Layers..." ), this );
|
||||
mGeonodeMenu->addAction( mActionAddGeonodeLayer );
|
||||
|
||||
// Set icon size of toolbars
|
||||
if ( settings.contains( QStringLiteral( "IconSize" ) ) )
|
||||
{
|
||||
@ -1789,6 +1795,8 @@ void QgisApp::createActions()
|
||||
connect( mActionLabeling, &QAction::triggered, this, &QgisApp::labeling );
|
||||
connect( mActionStatisticalSummary, &QAction::triggered, this, &QgisApp::showStatisticsDockWidget );
|
||||
|
||||
// Web Menu Items
|
||||
|
||||
// Layer Menu Items
|
||||
|
||||
connect( mActionDataSourceManager, &QAction::triggered, this, [ = ]() { dataSourceManager(); } );
|
||||
@ -1814,6 +1822,7 @@ void QgisApp::createActions()
|
||||
connect( mActionAddAmsLayer, &QAction::triggered, this, [ = ] { dataSourceManager( QStringLiteral( "arcgismapserver" ) ); } );
|
||||
connect( mActionAddDelimitedText, &QAction::triggered, this, [ = ] { dataSourceManager( QStringLiteral( "delimitedtext" ) ); } );
|
||||
connect( mActionAddVirtualLayer, &QAction::triggered, this, [ = ] { dataSourceManager( QStringLiteral( "virtual" ) ); } );
|
||||
connect( mActionAddGeonodeLayer, &QAction::triggered, this, [ = ] { dataSourceManager( QStringLiteral( "geonode" ) ); } );
|
||||
connect( mActionOpenTable, &QAction::triggered, this, &QgisApp::attributeTable );
|
||||
connect( mActionOpenFieldCalc, &QAction::triggered, this, &QgisApp::fieldCalculator );
|
||||
connect( mActionToggleEditing, &QAction::triggered, this, [ = ] { toggleEditing(); } );
|
||||
@ -2089,6 +2098,12 @@ void QgisApp::createMenus()
|
||||
mToolbarMenu = new QMenu( tr( "Toolbars" ), this );
|
||||
mToolbarMenu->setObjectName( QStringLiteral( "mToolbarMenu" ) );
|
||||
|
||||
// Geonode Submenu
|
||||
mGeonodeMenu = new QMenu( tr( "GeoNode" ), this );
|
||||
mGeonodeMenu->setObjectName( QStringLiteral( "mGeonodeMenu" ) );
|
||||
// Geonode Action
|
||||
mActionAddGeonodeLayer = new QAction( tr( "Add GeoNode Layers..." ), this );
|
||||
|
||||
// Get platform for menu layout customization (Gnome, Kde, Mac, Win)
|
||||
QDialogButtonBox::ButtonLayout layout =
|
||||
QDialogButtonBox::ButtonLayout( style()->styleHint( QStyle::SH_DialogButtonLayout, nullptr, this ) );
|
||||
@ -4426,6 +4441,20 @@ void QgisApp::askUserForOGRSublayers( QgsVectorLayer *layer )
|
||||
}
|
||||
}
|
||||
|
||||
void QgisApp::addGeonodeLayer()
|
||||
{
|
||||
QgsGeoNodeSourceSelect *geonodes = new QgsGeoNodeSourceSelect( this, 0, true );
|
||||
if ( !geonodes )
|
||||
{
|
||||
QMessageBox::warning( this, tr( "Geonode" ), tr( "Cannot get Geonode select dialog." ) );
|
||||
return;
|
||||
}
|
||||
connect( geonodes, static_cast<void ( QgsGeoNodeSourceSelect::* )()>( &QgsGeoNodeSourceSelect::addRasterLayer ), this, static_cast<void ( QgisApp::* )()>( &QgisApp::addRasterLayer ) );
|
||||
connect( geonodes, &QgsGeoNodeSourceSelect::addWfsLayer, this, &QgisApp::addVectorLayer );
|
||||
geonodes->exec();
|
||||
delete geonodes;
|
||||
}
|
||||
|
||||
void QgisApp::addDatabaseLayer()
|
||||
{
|
||||
#ifdef HAVE_POSTGRESQL
|
||||
|
@ -439,6 +439,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
||||
QAction *actionShowBookmarks() { return mActionShowBookmarks; }
|
||||
QAction *actionDraw() { return mActionDraw; }
|
||||
|
||||
QAction *actionAddGeonodeLayer() { return mActionAddGeonodeLayer; }
|
||||
|
||||
QAction *actionDataSourceManager() { return mActionDataSourceManager; }
|
||||
QAction *actionNewVectorLayer() { return mActionNewVectorLayer; }
|
||||
QAction *actionNewSpatialLiteLayer() { return mActionNewSpatiaLiteLayer; }
|
||||
@ -893,6 +895,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
||||
void sponsors();
|
||||
//! About QGIS
|
||||
void about();
|
||||
//! Add a Geonode layer to the map
|
||||
void addGeonodeLayer();
|
||||
//#ifdef HAVE_POSTGRESQL
|
||||
//! Add a databaselayer to the map
|
||||
void addDatabaseLayer();
|
||||
@ -1746,6 +1750,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
||||
QAction *mActionPluginSeparator1 = nullptr;
|
||||
QAction *mActionPluginSeparator2 = nullptr;
|
||||
QAction *mActionRasterSeparator = nullptr;
|
||||
QAction *mActionAddGeonodeLayer = nullptr;
|
||||
|
||||
// action groups ----------------------------------
|
||||
QActionGroup *mMapToolGroup = nullptr;
|
||||
@ -1758,6 +1763,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
||||
#endif
|
||||
QMenu *mPanelMenu = nullptr;
|
||||
QMenu *mToolbarMenu = nullptr;
|
||||
QMenu *mGeonodeMenu = nullptr;
|
||||
|
||||
// docks ------------------------------------------
|
||||
QgsDockWidget *mLayerTreeDock = nullptr;
|
||||
|
@ -652,6 +652,10 @@ QAction *QgisAppInterface::actionNewBookmark() { return qgis->actionNewBookmark(
|
||||
QAction *QgisAppInterface::actionShowBookmarks() { return qgis->actionShowBookmarks(); }
|
||||
QAction *QgisAppInterface::actionDraw() { return qgis->actionDraw(); }
|
||||
|
||||
//! Web menu actions
|
||||
QAction *QgisAppInterface::actionAddGeonodeLayer() { return qgis->actionAddGeonodeLayer(); }
|
||||
|
||||
//! Layer menu actions
|
||||
QAction *QgisAppInterface::actionNewVectorLayer() { return qgis->actionNewVectorLayer(); }
|
||||
QAction *QgisAppInterface::actionAddOgrLayer() { return qgis->actionAddOgrLayer(); }
|
||||
QAction *QgisAppInterface::actionAddRasterLayer() { return qgis->actionAddRasterLayer(); }
|
||||
|
@ -399,6 +399,9 @@ class APP_EXPORT QgisAppInterface : public QgisInterface
|
||||
virtual QAction *actionShowBookmarks() override;
|
||||
virtual QAction *actionDraw() override;
|
||||
|
||||
//! Web menu actions
|
||||
virtual QAction *actionAddGeonodeLayer();
|
||||
|
||||
//! Layer menu actions
|
||||
virtual QAction *actionNewVectorLayer() override;
|
||||
virtual QAction *actionAddOgrLayer() override;
|
||||
|
@ -458,7 +458,6 @@ SET(QGIS_CORE_SRCS
|
||||
geometry/qgswkbptr.cpp
|
||||
geometry/qgswkbtypes.cpp
|
||||
|
||||
|
||||
fieldformatter/qgsdatetimefieldformatter.cpp
|
||||
fieldformatter/qgsfallbackfieldformatter.cpp
|
||||
fieldformatter/qgskeyvaluefieldformatter.cpp
|
||||
@ -467,6 +466,9 @@ SET(QGIS_CORE_SRCS
|
||||
fieldformatter/qgsvaluemapfieldformatter.cpp
|
||||
fieldformatter/qgsvaluerelationfieldformatter.cpp
|
||||
|
||||
geonode/qgsgeonodeconnection.cpp
|
||||
geonode/qgsgeonoderequest.cpp
|
||||
|
||||
${CMAKE_CURRENT_BINARY_DIR}/qgsexpression_texts.cpp
|
||||
|
||||
qgsuserprofile.cpp
|
||||
@ -707,7 +709,11 @@ SET(QGIS_CORE_MOC_HDRS
|
||||
layertree/qgslayertreemodellegendnode.h
|
||||
layertree/qgslayertreenode.h
|
||||
layertree/qgslayertreeregistrybridge.h
|
||||
|
||||
qgsuserprofilemanager.h
|
||||
|
||||
geonode/qgsgeonodeconnection.h
|
||||
geonode/qgsgeonoderequest.h
|
||||
)
|
||||
|
||||
IF (NOT WITH_QTWEBKIT)
|
||||
@ -1084,6 +1090,9 @@ SET(QGIS_CORE_HDRS
|
||||
fieldformatter/qgsvaluemapfieldformatter.h
|
||||
fieldformatter/qgsvaluerelationfieldformatter.h
|
||||
|
||||
geonode/qgsgeonodeconnection.h
|
||||
geonode/qgsgeonoderequest.h
|
||||
|
||||
metadata/qgslayermetadata.h
|
||||
metadata/qgslayermetadatavalidator.h
|
||||
)
|
||||
@ -1098,6 +1107,7 @@ ENDIF (QT_MOBILITY_LOCATION_FOUND OR Qt5Positioning_FOUND)
|
||||
INCLUDE_DIRECTORIES(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${LIBZIP_INCLUDE_DIR}
|
||||
annotations
|
||||
auth
|
||||
composer
|
||||
@ -1106,6 +1116,7 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
fieldformatter
|
||||
geometry
|
||||
geonode
|
||||
layertree
|
||||
layout
|
||||
metadata
|
||||
|
117
src/core/geonode/qgsgeonodeconnection.cpp
Normal file
117
src/core/geonode/qgsgeonodeconnection.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
/***************************************************************************
|
||||
qgsgeonodeconnection.cpp
|
||||
---------------------
|
||||
begin : Feb 2017
|
||||
copyright : (C) 2017 by Muhammad Yarjuna Rohmat, Ismail Sunni
|
||||
email : rohmat at kartoza dot com, ismail at kartoza dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgssettings.h"
|
||||
#include "qgsgeonodeconnection.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
|
||||
const QString QgsGeoNodeConnection::mPathGeoNodeConnection = "qgis/connections-geonode";
|
||||
const QString QgsGeoNodeConnection::mPathGeoNodeConnectionDetails = "qgis/GeoNode";
|
||||
|
||||
QgsGeoNodeConnection::QgsGeoNodeConnection( const QString &connName )
|
||||
: mConnName( connName )
|
||||
{
|
||||
QgsSettings settings;
|
||||
|
||||
|
||||
// settings.Section
|
||||
QString key = "qgis/connections-geonode/" + mConnName;
|
||||
QString credentialsKey = "qgis/geonode/" + mConnName;
|
||||
|
||||
QStringList connStringParts;
|
||||
|
||||
mUri.setParam( QStringLiteral( "url" ), settings.value( key + "/url", "", QgsSettings::Providers ).toString() );
|
||||
|
||||
// Check for credentials and prepend to the connection info
|
||||
QString username = settings.value( credentialsKey + "/username", "", QgsSettings::Providers ).toString();
|
||||
QString password = settings.value( credentialsKey + "/password", "", QgsSettings::Providers ).toString();
|
||||
if ( !username.isEmpty() )
|
||||
{
|
||||
mUri.setParam( QStringLiteral( "username" ), username );
|
||||
mUri.setParam( QStringLiteral( "password" ), password );
|
||||
}
|
||||
|
||||
QString authcfg = settings.value( credentialsKey + "/authcfg", "", QgsSettings::Providers ).toString();
|
||||
if ( !authcfg.isEmpty() )
|
||||
{
|
||||
mUri.setParam( QStringLiteral( "authcfg" ), authcfg );
|
||||
}
|
||||
|
||||
QgsDebugMsg( QString( "encodedUri: '%1'." ).arg( QString( mUri.encodedUri() ) ) );
|
||||
}
|
||||
|
||||
QgsGeoNodeConnection::~QgsGeoNodeConnection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QgsDataSourceUri QgsGeoNodeConnection::uri()
|
||||
{
|
||||
return mUri;
|
||||
}
|
||||
|
||||
QStringList QgsGeoNodeConnection::connectionList()
|
||||
{
|
||||
QgsSettings settings;
|
||||
// Add Section manually
|
||||
settings.beginGroup( "providers/qgis/connections-geonode" );
|
||||
return settings.childGroups();
|
||||
}
|
||||
|
||||
void QgsGeoNodeConnection::deleteConnection( const QString &name )
|
||||
{
|
||||
QgsSettings settings;
|
||||
// Add Section manually
|
||||
settings.remove( "providers/qgis/connections-geonode/" + name );
|
||||
settings.remove( "providers/qgis/geonode/" + name );
|
||||
}
|
||||
|
||||
QString QgsGeoNodeConnection::selectedConnection()
|
||||
{
|
||||
QgsSettings settings;
|
||||
return settings.value( "qgis/connections-geonode/selected", "", QgsSettings::Providers ).toString();
|
||||
}
|
||||
|
||||
void QgsGeoNodeConnection::setSelectedConnection( const QString &name )
|
||||
{
|
||||
QgsSettings settings;
|
||||
settings.setValue( "qgis/connections-geonode/selected", name, QgsSettings::Providers );
|
||||
}
|
||||
|
||||
QString QgsGeoNodeConnection::pathGeoNodeConnection()
|
||||
{
|
||||
return mPathGeoNodeConnection;
|
||||
}
|
||||
|
||||
QString QgsGeoNodeConnection::pathGeoNodeConnectionDetails()
|
||||
{
|
||||
return mPathGeoNodeConnectionDetails;
|
||||
}
|
||||
|
||||
QString QgsGeoNodeConnection::connName() const
|
||||
{
|
||||
return mConnName;
|
||||
}
|
||||
|
||||
void QgsGeoNodeConnection::setConnName( const QString &connName )
|
||||
{
|
||||
mConnName = connName;
|
||||
}
|
||||
|
||||
void QgsGeoNodeConnection::setUri( const QgsDataSourceUri &uri )
|
||||
{
|
||||
mUri = uri;
|
||||
}
|
72
src/core/geonode/qgsgeonodeconnection.h
Normal file
72
src/core/geonode/qgsgeonodeconnection.h
Normal file
@ -0,0 +1,72 @@
|
||||
/***************************************************************************
|
||||
qgsgeonodeconnection.h
|
||||
---------------------
|
||||
begin : Feb 2017
|
||||
copyright : (C) 2017 by Muhammad Yarjuna Rohmat, Ismail Sunni
|
||||
email : rohmat at kartoza dot com, ismail at kartoza dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSGEONODECONNECTION_H
|
||||
#define QGSGEONODECONNECTION_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
|
||||
|
||||
/*!
|
||||
* \brief GeoNode Connections management
|
||||
*/
|
||||
class CORE_EXPORT QgsGeoNodeConnection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
explicit QgsGeoNodeConnection( const QString &connName );
|
||||
|
||||
//! Destructor
|
||||
~QgsGeoNodeConnection();
|
||||
|
||||
QString connName() const;
|
||||
void setConnName( const QString &connName );
|
||||
|
||||
QgsDataSourceUri uri();
|
||||
void setUri( const QgsDataSourceUri &uri );
|
||||
|
||||
//! Retrieve all geonode connection
|
||||
static QStringList connectionList();
|
||||
|
||||
//! Delete connection with name, name
|
||||
static void deleteConnection( const QString &name );
|
||||
|
||||
//! Get selected connection
|
||||
static QString selectedConnection();
|
||||
|
||||
//! Set selected connection
|
||||
static void setSelectedConnection( const QString &name );
|
||||
|
||||
static QString pathGeoNodeConnection();
|
||||
|
||||
static QString pathGeoNodeConnectionDetails();
|
||||
|
||||
private:
|
||||
// Path in QSetting
|
||||
static const QString mPathGeoNodeConnection;
|
||||
static const QString mPathGeoNodeConnectionDetails;
|
||||
|
||||
//! The connection name
|
||||
QString mConnName;
|
||||
|
||||
//! Property of mUri
|
||||
QgsDataSourceUri mUri;
|
||||
};
|
||||
|
||||
|
||||
#endif //QGSGEONODECONNECTION_H
|
420
src/core/geonode/qgsgeonoderequest.cpp
Normal file
420
src/core/geonode/qgsgeonoderequest.cpp
Normal file
@ -0,0 +1,420 @@
|
||||
/***************************************************************************
|
||||
qgsgeonoderequest.h
|
||||
---------------------
|
||||
begin : Jul 2017
|
||||
copyright : (C) 2017 by Muhammad Yarjuna Rohmat, Ismail Sunni
|
||||
email : rohmat at kartoza dot com, ismail at kartoza dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsnetworkaccessmanager.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsgeonoderequest.h"
|
||||
|
||||
#include <QEventLoop>
|
||||
#include <QNetworkCacheMetaData>
|
||||
#include <QByteArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QUrl>
|
||||
#include <QDomDocument>
|
||||
|
||||
QgsGeoNodeRequest::QgsGeoNodeRequest( bool forceRefresh, QObject *parent )
|
||||
: QObject( parent )
|
||||
, mForceRefresh( forceRefresh )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QgsGeoNodeRequest::QgsGeoNodeRequest( const QString &baseUrl, /*const QgsWmsAuthorization &auth,*/ bool forceRefresh, QObject *parent )
|
||||
: QObject( parent )
|
||||
, mBaseUrl( baseUrl )
|
||||
, mGeoNodeReply( nullptr )
|
||||
, mIsAborted( false )
|
||||
, mForceRefresh( forceRefresh )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QgsGeoNodeRequest::~QgsGeoNodeRequest()
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
void QgsGeoNodeRequest::abort()
|
||||
{
|
||||
mIsAborted = true;
|
||||
if ( mGeoNodeReply )
|
||||
{
|
||||
mGeoNodeReply->deleteLater();
|
||||
mGeoNodeReply = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsGeoNodeRequest::getLayers()
|
||||
{
|
||||
return request( QStringLiteral( "/api/layers/" ) );
|
||||
}
|
||||
|
||||
void QgsGeoNodeRequest::replyProgress( qint64 bytesReceived, qint64 bytesTotal )
|
||||
{
|
||||
QString msg = tr( "%1 of %2 bytes of request downloaded." ).arg( bytesReceived ).arg( bytesTotal < 0 ? QStringLiteral( "unknown number of" ) : QString::number( bytesTotal ) );
|
||||
QgsDebugMsg( msg );
|
||||
QgsMessageLog::logMessage( QStringLiteral( "Reply in progress" ), tr( "GeoNode" ) );
|
||||
QgsMessageLog::logMessage( msg, tr( "GeoNode" ) );
|
||||
emit statusChanged( msg );
|
||||
}
|
||||
|
||||
QString QgsGeoNodeRequest::getProtocol() const
|
||||
{
|
||||
return mProtocol;
|
||||
}
|
||||
|
||||
void QgsGeoNodeRequest::setProtocol( const QString &protocol )
|
||||
{
|
||||
mProtocol = protocol;
|
||||
}
|
||||
|
||||
|
||||
void QgsGeoNodeRequest::replyFinished()
|
||||
{
|
||||
QgsMessageLog::logMessage( QStringLiteral( "Reply finished" ), tr( "GeoNode" ) );
|
||||
if ( !mIsAborted && mGeoNodeReply )
|
||||
{
|
||||
if ( mGeoNodeReply->error() == QNetworkReply::NoError )
|
||||
{
|
||||
QgsDebugMsg( "reply OK" );
|
||||
QVariant redirect = mGeoNodeReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
|
||||
if ( !redirect.isNull() )
|
||||
{
|
||||
|
||||
emit statusChanged( QStringLiteral( "GeoNode request redirected." ) );
|
||||
|
||||
const QUrl &toUrl = redirect.toUrl();
|
||||
mGeoNodeReply->request();
|
||||
if ( toUrl == mGeoNodeReply->url() )
|
||||
{
|
||||
mError = tr( "Redirect loop detected: %1" ).arg( toUrl.toString() );
|
||||
QgsMessageLog::logMessage( mError, tr( "GeoNode" ) );
|
||||
mHttpGeoNodeResponse.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
QNetworkRequest request( toUrl );
|
||||
|
||||
request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, mForceRefresh ? QNetworkRequest::AlwaysNetwork : QNetworkRequest::PreferCache );
|
||||
request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
|
||||
|
||||
mGeoNodeReply->deleteLater();
|
||||
mGeoNodeReply = nullptr;
|
||||
|
||||
QgsDebugMsg( QString( "redirected getcapabilities: %1 forceRefresh=%2" ).arg( redirect.toString() ).arg( mForceRefresh ) );
|
||||
mGeoNodeReply = QgsNetworkAccessManager::instance()->get( request );
|
||||
|
||||
connect( mGeoNodeReply, &QNetworkReply::finished, this, &QgsGeoNodeRequest::replyFinished, Qt::DirectConnection );
|
||||
connect( mGeoNodeReply, &QNetworkReply::downloadProgress, this, &QgsGeoNodeRequest::replyProgress, Qt::DirectConnection );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const QgsNetworkAccessManager *nam = QgsNetworkAccessManager::instance();
|
||||
|
||||
if ( nam->cache() )
|
||||
{
|
||||
QNetworkCacheMetaData cmd = nam->cache()->metaData( mGeoNodeReply->request().url() );
|
||||
|
||||
QNetworkCacheMetaData::RawHeaderList hl;
|
||||
Q_FOREACH ( const QNetworkCacheMetaData::RawHeader &h, cmd.rawHeaders() )
|
||||
{
|
||||
if ( h.first != "Cache-Control" )
|
||||
hl.append( h );
|
||||
}
|
||||
cmd.setRawHeaders( hl );
|
||||
|
||||
QgsDebugMsg( QString( "expirationDate:%1" ).arg( cmd.expirationDate().toString() ) );
|
||||
if ( cmd.expirationDate().isNull() )
|
||||
{
|
||||
QgsSettings settings;
|
||||
cmd.setExpirationDate( QDateTime::currentDateTime().addSecs( settings.value( QStringLiteral( "qgis/defaultCapabilitiesExpiry" ), "24", QgsSettings::Providers ).toInt() * 60 * 60 ) );
|
||||
}
|
||||
|
||||
nam->cache()->updateMetaData( cmd );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "No cache for capabilities!" );
|
||||
}
|
||||
|
||||
mHttpGeoNodeResponse = mGeoNodeReply->readAll();
|
||||
|
||||
if ( mHttpGeoNodeResponse.isEmpty() )
|
||||
{
|
||||
mError = tr( "empty of capabilities: %1" ).arg( mGeoNodeReply->errorString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mError = tr( "Request failed: %1" ).arg( mGeoNodeReply->errorString() );
|
||||
QgsMessageLog::logMessage( mError, tr( "GeoNode" ) );
|
||||
mHttpGeoNodeResponse.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if ( mGeoNodeReply )
|
||||
{
|
||||
mGeoNodeReply->deleteLater();
|
||||
mGeoNodeReply = nullptr;
|
||||
}
|
||||
|
||||
emit requestFinished();
|
||||
|
||||
}
|
||||
|
||||
QList<QgsServiceLayerDetail> QgsGeoNodeRequest::parseLayers( QByteArray layerResponse )
|
||||
{
|
||||
QList<QgsServiceLayerDetail> layers;
|
||||
if ( layerResponse.isEmpty() )
|
||||
{
|
||||
return layers;
|
||||
}
|
||||
|
||||
QJsonDocument jsonDocument = QJsonDocument::fromJson( layerResponse );
|
||||
QJsonObject jsonObject = jsonDocument.object();
|
||||
QVariantMap jsonVariantMap = jsonObject.toVariantMap();
|
||||
QVariantList layerList = jsonVariantMap["objects"].toList();
|
||||
qint16 majorVersion;
|
||||
qint16 minorVersion;
|
||||
if ( jsonVariantMap.contains( QStringLiteral( "geonode_version" ) ) )
|
||||
{
|
||||
QStringList geonodeVersionSplit = jsonVariantMap["geonode_version"].toString().split( "." );
|
||||
majorVersion = geonodeVersionSplit[0].toInt();
|
||||
minorVersion = geonodeVersionSplit[1].toInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
majorVersion = 2;
|
||||
minorVersion = 6;
|
||||
}
|
||||
|
||||
if ( majorVersion == 2 && minorVersion == 6 )
|
||||
{
|
||||
Q_FOREACH ( QVariant layer, layerList )
|
||||
{
|
||||
QgsServiceLayerDetail layerStruct;
|
||||
QVariantMap layerMap = layer.toMap();
|
||||
// Find WMS and WFS. XYZ is not available
|
||||
// Trick to get layer's typename from distribution_url or detail_url
|
||||
QString layerTypeName = layerMap["detail_url"].toString().split( "/" ).last();
|
||||
if ( layerTypeName.length() == 0 )
|
||||
{
|
||||
layerTypeName = layerMap["distribution_url"].toString().split( "/" ).last();
|
||||
}
|
||||
// On this step, layerTypeName is in WORKSPACE%3ALAYERNAME or WORKSPACE:LAYERNAME format
|
||||
if ( layerTypeName.contains( "%3A" ) )
|
||||
{
|
||||
layerTypeName.replace( "%3A", ":" );
|
||||
}
|
||||
// On this step, layerTypeName is in WORKSPACE:LAYERNAME format
|
||||
QStringList splitURL = layerTypeName.split( ":" );
|
||||
QString layerWorkspace = splitURL[0];
|
||||
QString layerName = splitURL[1];
|
||||
|
||||
layerStruct.name = layerName;
|
||||
layerStruct.typeName = layerTypeName;
|
||||
layerStruct.uuid = layerMap["uuid"].toString();
|
||||
layerStruct.title = layerMap["title"].toString();;
|
||||
|
||||
// WMS url : BASE_URI/geoserver/WORKSPACE/wms
|
||||
layerStruct.wmsURL = mBaseUrl + "/geoserver/" + layerWorkspace + "/wms";
|
||||
// WFS url : BASE_URI/geoserver/WORKSPACE/wfs
|
||||
layerStruct.wfsURL = mBaseUrl + "/geoserver/" + layerWorkspace + "/wfs";
|
||||
// XYZ url : set to empty string
|
||||
layerStruct.xyzURL = "";
|
||||
|
||||
layers.append( layerStruct );
|
||||
}
|
||||
}
|
||||
// Geonode version 2.7 or newer
|
||||
else if ( ( majorVersion == 2 && minorVersion >= 7 ) || ( majorVersion >= 3 ) )
|
||||
{
|
||||
Q_FOREACH ( QVariant layer, layerList )
|
||||
{
|
||||
QgsServiceLayerDetail layerStruct;
|
||||
QVariantMap layerMap = layer.toMap();
|
||||
// Find WMS, WFS, and XYZ link
|
||||
QVariantList layerLinks = layerMap["links"].toList();
|
||||
layerStruct.wmsURL = QStringLiteral( "" );
|
||||
layerStruct.wfsURL = QStringLiteral( "" );
|
||||
layerStruct.xyzURL = QStringLiteral( "" );
|
||||
Q_FOREACH ( QVariant link, layerLinks )
|
||||
{
|
||||
QVariantMap linkMap = link.toMap();
|
||||
if ( linkMap.contains( "link_type" ) )
|
||||
{
|
||||
if ( linkMap["link_type"] == "OGC:WMS" )
|
||||
{
|
||||
layerStruct.wmsURL = linkMap["url"].toString();
|
||||
}
|
||||
if ( linkMap["link_type"] == "OGC:WFS" )
|
||||
{
|
||||
layerStruct.wfsURL = linkMap["url"].toString();
|
||||
}
|
||||
if ( linkMap["link_type"] == "image" )
|
||||
{
|
||||
if ( linkMap.contains( "name" ) && linkMap["name"] == "Tiles" )
|
||||
{
|
||||
layerStruct.xyzURL = linkMap["url"].toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( layerMap["typename"].toString().length() == 0 )
|
||||
{
|
||||
QStringList splitURL = layerMap["detail_url"].toString().split( "/" );
|
||||
layerStruct.typeName = splitURL[ splitURL.length() - 1];
|
||||
}
|
||||
layerStruct.uuid = layerMap["uuid"].toString();
|
||||
layerStruct.name = layerMap["name"].toString();
|
||||
layerStruct.typeName = layerMap["typename"].toString();
|
||||
layerStruct.title = layerMap["title"].toString();
|
||||
layers.append( layerStruct );
|
||||
}
|
||||
}
|
||||
return layers;
|
||||
}
|
||||
|
||||
|
||||
QStringList QgsGeoNodeRequest::serviceUrls( QString serviceType )
|
||||
{
|
||||
QStringList urls;
|
||||
bool success = getLayers();
|
||||
|
||||
if ( !success )
|
||||
{
|
||||
return urls;
|
||||
}
|
||||
|
||||
QList<QgsServiceLayerDetail> layers = parseLayers( this->response() );
|
||||
|
||||
Q_FOREACH ( QgsServiceLayerDetail layer, layers )
|
||||
{
|
||||
QString url;
|
||||
if ( serviceType.toLower() == "wms" )
|
||||
{
|
||||
url = layer.wmsURL;
|
||||
}
|
||||
else if ( serviceType.toLower() == "wfs" )
|
||||
{
|
||||
url = layer.wfsURL;
|
||||
}
|
||||
else if ( serviceType.toLower() == "xyz" )
|
||||
{
|
||||
url = layer.xyzURL;
|
||||
}
|
||||
else
|
||||
{
|
||||
url = "";
|
||||
}
|
||||
|
||||
if ( !url.contains( QLatin1String( "://" ) ) && url.length() > 0 )
|
||||
{
|
||||
url.prepend( getProtocol() );
|
||||
}
|
||||
if ( !urls.contains( url ) && url.length() > 0 )
|
||||
{
|
||||
urls.append( url );
|
||||
}
|
||||
}
|
||||
|
||||
return urls;
|
||||
}
|
||||
|
||||
|
||||
QgsStringMap QgsGeoNodeRequest::serviceUrlData( QString serviceType )
|
||||
{
|
||||
QgsStringMap urls;
|
||||
bool success = getLayers();
|
||||
|
||||
if ( !success )
|
||||
{
|
||||
return urls;
|
||||
}
|
||||
QList<QgsServiceLayerDetail> layers = parseLayers( this->response() );
|
||||
|
||||
Q_FOREACH ( QgsServiceLayerDetail layer, layers )
|
||||
{
|
||||
QString url;
|
||||
|
||||
if ( serviceType.toLower() == "wms" )
|
||||
{
|
||||
url = layer.wmsURL;
|
||||
}
|
||||
else if ( serviceType.toLower() == "wfs" )
|
||||
{
|
||||
url = layer.wfsURL;
|
||||
}
|
||||
else if ( serviceType.toLower() == "xyz" )
|
||||
{
|
||||
url = layer.xyzURL;
|
||||
}
|
||||
else
|
||||
{
|
||||
url = "";
|
||||
}
|
||||
|
||||
QString layerName = layer.name;
|
||||
if ( !url.contains( QLatin1String( "://" ) ) && url.length() > 0 )
|
||||
{
|
||||
url.prepend( getProtocol() );
|
||||
}
|
||||
if ( !urls.contains( url ) && url.length() > 0 )
|
||||
{
|
||||
urls.insert( layerName, url );
|
||||
}
|
||||
}
|
||||
|
||||
return urls;
|
||||
}
|
||||
|
||||
|
||||
bool QgsGeoNodeRequest::request( QString endPoint )
|
||||
{
|
||||
abort();
|
||||
mIsAborted = false;
|
||||
QgsMessageLog::logMessage( mBaseUrl, tr( "GeoNode" ) );
|
||||
QString url = mBaseUrl + endPoint;
|
||||
QgsMessageLog::logMessage( url, tr( "GeoNode" ) );
|
||||
setProtocol( url.split( "://" )[0] );
|
||||
QUrl layerUrl( url );
|
||||
layerUrl.setScheme( getProtocol() );
|
||||
|
||||
mError.clear();
|
||||
|
||||
QNetworkRequest request( url );
|
||||
// Add authentication check here
|
||||
|
||||
request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, mForceRefresh ? QNetworkRequest::AlwaysNetwork : QNetworkRequest::PreferCache );
|
||||
request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
|
||||
|
||||
mGeoNodeReply = QgsNetworkAccessManager::instance()->get( request );
|
||||
|
||||
connect( mGeoNodeReply, &QNetworkReply::finished, this, &QgsGeoNodeRequest::replyFinished, Qt::DirectConnection );
|
||||
connect( mGeoNodeReply, &QNetworkReply::downloadProgress, this, &QgsGeoNodeRequest::replyProgress, Qt::DirectConnection );
|
||||
|
||||
QEventLoop loop;
|
||||
connect( this, &QgsGeoNodeRequest::requestFinished, &loop, &QEventLoop::quit );
|
||||
|
||||
loop.exec( QEventLoop::ExcludeUserInputEvents );
|
||||
|
||||
return mError.isEmpty();
|
||||
}
|
112
src/core/geonode/qgsgeonoderequest.h
Normal file
112
src/core/geonode/qgsgeonoderequest.h
Normal file
@ -0,0 +1,112 @@
|
||||
/***************************************************************************
|
||||
qgsgeonoderequest.h
|
||||
---------------------
|
||||
begin : Jul 2017
|
||||
copyright : (C) 2017 by Muhammad Yarjuna Rohmat, Ismail Sunni
|
||||
email : rohmat at kartoza dot com, ismail at kartoza dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSGEONODEREQUEST_H
|
||||
#define QGSGEONODEREQUEST_H
|
||||
|
||||
#include "qgis.h"
|
||||
#include "qgis_core.h"
|
||||
#include <qnetworkreply.h>
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <QUuid>
|
||||
|
||||
struct CORE_EXPORT QgsServiceLayerDetail
|
||||
{
|
||||
#ifdef SIP_RUN
|
||||
% TypeHeaderCode
|
||||
#include <qgsgeonoderequest.h>
|
||||
% End
|
||||
#endif
|
||||
QUuid uuid;
|
||||
QString name;
|
||||
QString typeName;
|
||||
QString title;
|
||||
QString wmsURL;
|
||||
QString wfsURL;
|
||||
QString xyzURL;
|
||||
};
|
||||
|
||||
class CORE_EXPORT QgsGeoNodeRequest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QgsGeoNodeRequest( bool forceRefresh, QObject *parent = nullptr );
|
||||
QgsGeoNodeRequest( const QString &baseUrl, /*const QgsWmsAuthorization &auth,*/ bool forceRefresh, QObject *parent = nullptr );
|
||||
virtual ~QgsGeoNodeRequest();
|
||||
|
||||
bool request( QString endPoint );
|
||||
|
||||
bool getLayers();
|
||||
|
||||
QList<QgsServiceLayerDetail> parseLayers( QByteArray layerResponse );
|
||||
|
||||
// Obtain list of unique URL in the geonode
|
||||
QStringList serviceUrls( QString serviceType );
|
||||
|
||||
// Obtain map of layer name and url for a service type
|
||||
QgsStringMap serviceUrlData( QString serviceType );
|
||||
|
||||
QString lastError() const { return mError; }
|
||||
|
||||
QByteArray response() const { return mHttpGeoNodeResponse; }
|
||||
|
||||
QNetworkReply *reply() const { return mGeoNodeReply; }
|
||||
|
||||
//! Abort network request immediately
|
||||
void abort();
|
||||
|
||||
QString getProtocol() const;
|
||||
void setProtocol( const QString &protocol );
|
||||
|
||||
signals:
|
||||
//! \brief emit a signal to be caught by qgisapp and display a statusQString on status bar
|
||||
void statusChanged( const QString &statusQString );
|
||||
|
||||
//! \brief emit a signal once the request is finished
|
||||
void requestFinished();
|
||||
|
||||
protected slots:
|
||||
void replyFinished();
|
||||
void replyProgress( qint64, qint64 );
|
||||
|
||||
protected:
|
||||
|
||||
//! URL part of URI (httpuri)
|
||||
QString mProtocol;
|
||||
|
||||
//! URL part of URI (httpuri)
|
||||
QString mBaseUrl;
|
||||
|
||||
// QgsWmsAuthorization mAuth;
|
||||
|
||||
//! The reply to the geonode request
|
||||
QNetworkReply *mGeoNodeReply = nullptr;
|
||||
|
||||
//! The error message associated with the last error.
|
||||
QString mError;
|
||||
|
||||
//! The mime type of the message
|
||||
QString mErrorFormat;
|
||||
|
||||
//! Response
|
||||
QByteArray mHttpGeoNodeResponse;
|
||||
|
||||
bool mIsAborted;
|
||||
bool mForceRefresh;
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSGEONODEREQUEST_H
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgis.h"
|
||||
#include "qgsdataitem.h"
|
||||
|
||||
class QgsDataItem;
|
||||
|
||||
@ -50,6 +51,9 @@ class CORE_EXPORT QgsDataItemProvider
|
||||
//! Caller takes responsibility of deleting created items.
|
||||
virtual QgsDataItem *createDataItem( const QString &path, QgsDataItem *parentItem ) = 0 SIP_FACTORY;
|
||||
|
||||
//! Create a vector of instances of QgsDataItem (or null) for given path and parent item.
|
||||
//! Caller takes responsibility of deleting created items.
|
||||
virtual QVector<QgsDataItem *> createDataItems( const QString &path, QgsDataItem *parentItem ) { Q_UNUSED( path ); Q_UNUSED( parentItem ); return QVector<QgsDataItem *>(); }
|
||||
};
|
||||
|
||||
#endif // QGSDATAITEMPROVIDER_H
|
||||
|
@ -150,6 +150,9 @@ SET(QGIS_GUI_SRCS
|
||||
editorwidgets/qgsvaluerelationsearchwidgetwrapper.cpp
|
||||
editorwidgets/qgsvaluerelationwidgetfactory.cpp
|
||||
|
||||
geonode/qgsgeonodenewconnection.cpp
|
||||
geonode/qgsgeonodesourceselect.cpp
|
||||
|
||||
layertree/qgscustomlayerorderwidget.cpp
|
||||
layertree/qgslayertreeembeddedconfigwidget.cpp
|
||||
layertree/qgslayertreeembeddedwidgetregistry.cpp
|
||||
@ -644,6 +647,9 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
editorwidgets/qgsvaluerelationsearchwidgetwrapper.h
|
||||
editorwidgets/qgsvaluerelationwidgetwrapper.h
|
||||
|
||||
geonode/qgsgeonodenewconnection.h
|
||||
geonode/qgsgeonodesourceselect.h
|
||||
|
||||
layertree/qgscustomlayerorderwidget.h
|
||||
layertree/qgslayertreeembeddedconfigwidget.h
|
||||
layertree/qgslayertreeembeddedwidgetsimpl.h
|
||||
@ -763,6 +769,9 @@ SET(QGIS_GUI_HDRS
|
||||
editorwidgets/qgsvaluemapwidgetfactory.h
|
||||
editorwidgets/qgsvaluerelationwidgetfactory.h
|
||||
|
||||
geonode/qgsgeonodenewconnection.h
|
||||
geonode/qgsgeonodesourceselect.h
|
||||
|
||||
layertree/qgslayertreeembeddedconfigwidget.h
|
||||
layertree/qgslayertreeembeddedwidgetregistry.h
|
||||
|
||||
@ -813,6 +822,7 @@ SET(QGIS_GUI_UI_HDRS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgssqlcomposerdialogbase.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgssublayersdialogbase.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgstablewidgetuibase.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsgeonodesourceselectbase.h
|
||||
)
|
||||
|
||||
IF(ENABLE_MODELTEST)
|
||||
@ -832,12 +842,14 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/src/gui/layertree
|
||||
${CMAKE_SOURCE_DIR}/src/gui/layout
|
||||
${CMAKE_SOURCE_DIR}/src/gui/effects
|
||||
${CMAKE_SOURCE_DIR}/src/gui/geonode
|
||||
${CMAKE_SOURCE_DIR}/src/gui/ogr
|
||||
${CMAKE_SOURCE_DIR}/src/core
|
||||
${CMAKE_SOURCE_DIR}/src/core/annotations
|
||||
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||
${CMAKE_SOURCE_DIR}/src/core/composer
|
||||
${CMAKE_SOURCE_DIR}/src/core/fieldformatter
|
||||
${CMAKE_SOURCE_DIR}/src/core/geonode
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/layertree
|
||||
${CMAKE_SOURCE_DIR}/src/core/layout
|
||||
|
266
src/gui/geonode/qgsgeonodenewconnection.cpp
Normal file
266
src/gui/geonode/qgsgeonodenewconnection.cpp
Normal file
@ -0,0 +1,266 @@
|
||||
/***************************************************************************
|
||||
qgsgeonodenewconnection.cpp
|
||||
-------------------
|
||||
begin : Feb 2017
|
||||
copyright : (C) 2017 by Muhammad Yarjuna Rohmat, Ismail Sunni
|
||||
email : rohmat at kartoza dot com, ismail at kartoza dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QUrl>
|
||||
#include "qgslogger.h"
|
||||
|
||||
#include "qgsgeonodenewconnection.h"
|
||||
#include "qgsauthmanager.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
#include "qgsgeonodeconnection.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsgeonoderequest.h"
|
||||
|
||||
QgsGeoNodeNewConnection::QgsGeoNodeNewConnection( QWidget *parent, const QString &connName, Qt::WindowFlags fl )
|
||||
: QDialog( parent, fl )
|
||||
, mOriginalConnName( connName )
|
||||
, mAuthConfigSelect( nullptr )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
mBaseKey = QgsGeoNodeConnection::pathGeoNodeConnection();
|
||||
mCredentialsBaseKey = QgsGeoNodeConnection::pathGeoNodeConnection();
|
||||
|
||||
mAuthConfigSelect = new QgsAuthConfigSelect( this );
|
||||
tabAuth->insertTab( 1, mAuthConfigSelect, tr( "Configurations" ) );
|
||||
|
||||
cmbDpiMode->clear();
|
||||
cmbDpiMode->addItem( tr( "all" ) );
|
||||
cmbDpiMode->addItem( tr( "off" ) );
|
||||
cmbDpiMode->addItem( tr( "QGIS" ) );
|
||||
cmbDpiMode->addItem( tr( "UMN" ) );
|
||||
cmbDpiMode->addItem( tr( "GeoServer" ) );
|
||||
|
||||
cmbVersion->clear();
|
||||
cmbVersion->addItem( tr( "Auto-detect" ) );
|
||||
cmbVersion->addItem( tr( "1.0" ) );
|
||||
cmbVersion->addItem( tr( "1.1" ) );
|
||||
cmbVersion->addItem( tr( "2.0" ) );
|
||||
|
||||
if ( !connName.isEmpty() )
|
||||
{
|
||||
// populate the dialog with the information stored for the connection
|
||||
// populate the fields with the stored setting parameters
|
||||
QgsSettings settings;
|
||||
|
||||
QString key = mBaseKey + '/' + connName;
|
||||
QString credentialsKey = mCredentialsBaseKey + '/' + connName;
|
||||
txtName->setText( connName );
|
||||
txtUrl->setText( settings.value( key + "/url", "", QgsSettings::Providers ).toString() );
|
||||
|
||||
cbxIgnoreGetMapURI->setChecked( settings.value( key + "/wms/ignoreGetMapURI", false, QgsSettings::Providers ).toBool() );
|
||||
cbxWfsIgnoreAxisOrientation->setChecked( settings.value( key + "/wfs/ignoreAxisOrientation", false, QgsSettings::Providers ).toBool() );
|
||||
cbxWmsIgnoreAxisOrientation->setChecked( settings.value( key + "/wms/ignoreAxisOrientation", false, QgsSettings::Providers ).toBool() );
|
||||
cbxWfsInvertAxisOrientation->setChecked( settings.value( key + "/wfs/invertAxisOrientation", false, QgsSettings::Providers ).toBool() );
|
||||
cbxWmsInvertAxisOrientation->setChecked( settings.value( key + "/wms/invertAxisOrientation", false, QgsSettings::Providers ).toBool() );
|
||||
cbxIgnoreGetFeatureInfoURI->setChecked( settings.value( key + "/wms/ignoreGetFeatureInfoURI", false, QgsSettings::Providers ).toBool() );
|
||||
cbxSmoothPixmapTransform->setChecked( settings.value( key + "/wms/smoothPixmapTransform", false, QgsSettings::Providers ).toBool() );
|
||||
|
||||
int dpiIdx;
|
||||
switch ( settings.value( key + "/dpiMode", 7, QgsSettings::Providers ).toInt() )
|
||||
{
|
||||
case 0: // off
|
||||
dpiIdx = 1;
|
||||
break;
|
||||
case 1: // QGIS
|
||||
dpiIdx = 2;
|
||||
break;
|
||||
case 2: // UMN
|
||||
dpiIdx = 3;
|
||||
break;
|
||||
case 4: // GeoServer
|
||||
dpiIdx = 4;
|
||||
break;
|
||||
default: // other => all
|
||||
dpiIdx = 0;
|
||||
break;
|
||||
}
|
||||
cmbDpiMode->setCurrentIndex( dpiIdx );
|
||||
|
||||
QString version = settings.value( key + "/version", QLatin1String( "1.0.0" ), QgsSettings::Providers ).toString();
|
||||
int versionIdx = 0; // AUTO
|
||||
if ( version == QLatin1String( "1.0.0" ) )
|
||||
versionIdx = 1;
|
||||
else if ( version == QLatin1String( "1.1.0" ) )
|
||||
versionIdx = 2;
|
||||
else if ( version == QLatin1String( "2.0.0" ) )
|
||||
versionIdx = 3;
|
||||
cmbVersion->setCurrentIndex( versionIdx );
|
||||
|
||||
txtReferer->setText( settings.value( key + "/referer", "", QgsSettings::Providers ).toString() );
|
||||
txtMaxNumFeatures->setText( settings.value( key + "/maxnumfeatures", QgsSettings::Providers ).toString() );
|
||||
|
||||
txtUserName->setText( settings.value( credentialsKey + "/username", "", QgsSettings::Providers ).toString() );
|
||||
txtPassword->setText( settings.value( credentialsKey + "/password", "", QgsSettings::Providers ).toString() );
|
||||
|
||||
QString authcfg = settings.value( credentialsKey + "/authcfg", "", QgsSettings::Providers ).toString();
|
||||
mAuthConfigSelect->setConfigId( authcfg );
|
||||
if ( !authcfg.isEmpty() )
|
||||
{
|
||||
tabAuth->setCurrentIndex( tabAuth->indexOf( mAuthConfigSelect ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust height
|
||||
int w = width();
|
||||
adjustSize();
|
||||
resize( w, height() );
|
||||
|
||||
buttonBox->button( QDialogButtonBox::Ok )->setDisabled( true );
|
||||
connect( txtName, &QLineEdit::textChanged, this, &QgsGeoNodeNewConnection::okButtonBehavior );
|
||||
connect( txtUrl, &QLineEdit::textChanged, this, &QgsGeoNodeNewConnection::okButtonBehavior );
|
||||
connect( btnConnect, &QPushButton::clicked, this, &QgsGeoNodeNewConnection::testConnection );
|
||||
}
|
||||
|
||||
void QgsGeoNodeNewConnection::accept()
|
||||
{
|
||||
QgsSettings settings;
|
||||
QString key = mBaseKey + '/' + txtName->text();
|
||||
QString credentialsKey = mCredentialsBaseKey + '/' + txtName->text();
|
||||
|
||||
// warn if entry was renamed to an existing connection
|
||||
if ( ( mOriginalConnName.isNull() || mOriginalConnName.compare( txtName->text(), Qt::CaseInsensitive ) != 0 ) &&
|
||||
settings.contains( key + "/url", QgsSettings::Providers ) &&
|
||||
QMessageBox::question( this,
|
||||
tr( "Save connection" ),
|
||||
tr( "Should the existing connection %1 be overwritten?" ).arg( txtName->text() ),
|
||||
QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !txtPassword->text().isEmpty() &&
|
||||
QMessageBox::question( this,
|
||||
tr( "Saving passwords" ),
|
||||
trUtf8( "WARNING: You have entered a password. It will be stored in unsecured plain text in your project files and your home directory (Unix-like OS) or user profile (Windows). If you want to avoid this, press Cancel and either:\n\na) Don't provide a password in the connection settings — it will be requested interactively when needed;\nb) Use the Configuration tab to add your credentials in an HTTP Basic Authentication method and store them in an encrypted database." ),
|
||||
QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// on rename delete original entry first
|
||||
if ( !mOriginalConnName.isNull() && mOriginalConnName != key )
|
||||
{
|
||||
// Manually add Section here
|
||||
settings.remove( "providers/" + mBaseKey + '/' + mOriginalConnName );
|
||||
settings.remove( "providers/qgis//" + mCredentialsBaseKey + '/' + mOriginalConnName );
|
||||
settings.sync();
|
||||
}
|
||||
|
||||
if ( !txtUrl->text().contains( "://" ) &&
|
||||
QMessageBox::information(
|
||||
this,
|
||||
tr( "Invalid URL" ),
|
||||
tr( "Your URL doesn't contains protocol (e.g. http or https). Please add the protocol." ) ) == QMessageBox::Ok )
|
||||
{
|
||||
return;
|
||||
}
|
||||
QUrl url( txtUrl->text() );
|
||||
|
||||
settings.setValue( key + "/url", url.toString(), QgsSettings::Providers );
|
||||
|
||||
settings.setValue( key + "/wfs/ignoreAxisOrientation", cbxWfsIgnoreAxisOrientation->isChecked(), QgsSettings::Providers );
|
||||
settings.setValue( key + "/wms/ignoreAxisOrientation", cbxWmsIgnoreAxisOrientation->isChecked(), QgsSettings::Providers );
|
||||
settings.setValue( key + "/wfs/invertAxisOrientation", cbxWfsInvertAxisOrientation->isChecked(), QgsSettings::Providers );
|
||||
settings.setValue( key + "/wms/invertAxisOrientation", cbxWmsInvertAxisOrientation->isChecked(), QgsSettings::Providers );
|
||||
|
||||
settings.setValue( key + "/wms/ignoreGetMapURI", cbxIgnoreGetMapURI->isChecked(), QgsSettings::Providers );
|
||||
settings.setValue( key + "/wms/smoothPixmapTransform", cbxSmoothPixmapTransform->isChecked(), QgsSettings::Providers );
|
||||
settings.setValue( key + "/wms/ignoreGetFeatureInfoURI", cbxIgnoreGetFeatureInfoURI->isChecked(), QgsSettings::Providers );
|
||||
|
||||
int dpiMode = 0;
|
||||
switch ( cmbDpiMode->currentIndex() )
|
||||
{
|
||||
case 0: // all => QGIS|UMN|GeoServer
|
||||
dpiMode = 7;
|
||||
break;
|
||||
case 1: // off
|
||||
dpiMode = 0;
|
||||
break;
|
||||
case 2: // QGIS
|
||||
dpiMode = 1;
|
||||
break;
|
||||
case 3: // UMN
|
||||
dpiMode = 2;
|
||||
break;
|
||||
case 4: // GeoServer
|
||||
dpiMode = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
settings.setValue( key + "/wms/dpiMode", dpiMode, QgsSettings::Providers );
|
||||
settings.setValue( key + "/wms/referer", txtReferer->text(), QgsSettings::Providers );
|
||||
|
||||
QString version = QStringLiteral( "auto" );
|
||||
switch ( cmbVersion->currentIndex() )
|
||||
{
|
||||
case 0:
|
||||
version = QStringLiteral( "auto" );
|
||||
break;
|
||||
case 1:
|
||||
version = QStringLiteral( "1.0.0" );
|
||||
break;
|
||||
case 2:
|
||||
version = QStringLiteral( "1.1.0" );
|
||||
break;
|
||||
case 3:
|
||||
version = QStringLiteral( "2.0.0" );
|
||||
break;
|
||||
}
|
||||
|
||||
settings.setValue( key + "/wfs/version", version, QgsSettings::Providers );
|
||||
settings.setValue( key + "/wfs/maxnumfeatures", txtMaxNumFeatures->text(), QgsSettings::Providers );
|
||||
|
||||
settings.setValue( credentialsKey + "/username", txtUserName->text(), QgsSettings::Providers );
|
||||
settings.setValue( credentialsKey + "/password", txtPassword->text(), QgsSettings::Providers );
|
||||
|
||||
settings.setValue( credentialsKey + "/authcfg", mAuthConfigSelect->configId(), QgsSettings::Providers );
|
||||
|
||||
settings.setValue( mBaseKey + "/selected", txtName->text(), QgsSettings::Providers );
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void QgsGeoNodeNewConnection::okButtonBehavior( const QString &text )
|
||||
{
|
||||
Q_UNUSED( text );
|
||||
buttonBox->button( QDialogButtonBox::Ok )->setDisabled( txtName->text().isEmpty() || txtUrl->text().isEmpty() );
|
||||
buttonBox->button( QDialogButtonBox::Ok )->setEnabled( !txtName->text().isEmpty() && !txtUrl->text().isEmpty() );
|
||||
}
|
||||
|
||||
void QgsGeoNodeNewConnection::testConnection()
|
||||
{
|
||||
QApplication::setOverrideCursor( Qt::BusyCursor );
|
||||
QString url = txtUrl->text();
|
||||
QgsGeoNodeRequest geonodeRequest( url, true );
|
||||
bool success = geonodeRequest.getLayers();
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
if ( success )
|
||||
{
|
||||
QMessageBox::information( this,
|
||||
tr( "Test connection" ),
|
||||
tr( "\nConnection to %1 was successful, \n\n%1 is a valid geonode instance.\n\n" ).arg( txtUrl->text() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::information( this,
|
||||
tr( "Test connection" ),
|
||||
tr( "\nConnection failed, \n\nplease check whether %1 is a valid geonode instance.\n\n" ).arg( txtUrl->text() ) );
|
||||
}
|
||||
}
|
47
src/gui/geonode/qgsgeonodenewconnection.h
Normal file
47
src/gui/geonode/qgsgeonodenewconnection.h
Normal file
@ -0,0 +1,47 @@
|
||||
/***************************************************************************
|
||||
qgsgeonodenewconnection.h
|
||||
-------------------
|
||||
begin : Feb 2017
|
||||
copyright : (C) 2017 by Muhammad Yarjuna Rohmat, Ismail Sunni
|
||||
email : rohmat at kartoza dot com, ismail at kartoza dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSGEONODENEWCONNECTION_H
|
||||
#define QGSGEONODENEWCONNECTION_H
|
||||
|
||||
#include "ui_qgsnewgeonodeconnectionbase.h"
|
||||
#include "qgis_gui.h"
|
||||
#include "qgsguiutils.h"
|
||||
#include "qgsauthconfigselect.h"
|
||||
|
||||
class GUI_EXPORT QgsGeoNodeNewConnection : public QDialog, private Ui::QgsNewGeoNodeConnectionBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
QgsGeoNodeNewConnection( QWidget *parent = nullptr, const QString &connName = QString::null, Qt::WindowFlags fl = QgsGuiUtils::ModalDialogFlags );
|
||||
|
||||
public slots:
|
||||
void accept() override;
|
||||
void okButtonBehavior( const QString & );
|
||||
//! Test the connection using the parameters supplied
|
||||
void testConnection();
|
||||
|
||||
private:
|
||||
QString mBaseKey;
|
||||
QString mCredentialsBaseKey;
|
||||
QString mOriginalConnName; //store initial name to delete entry in case of rename
|
||||
QgsAuthConfigSelect *mAuthConfigSelect = nullptr;
|
||||
};
|
||||
|
||||
#endif //QGSGEONODENEWCONNECTION_H
|
505
src/gui/geonode/qgsgeonodesourceselect.cpp
Normal file
505
src/gui/geonode/qgsgeonodesourceselect.cpp
Normal file
@ -0,0 +1,505 @@
|
||||
/***************************************************************************
|
||||
qgsgeonodesourceselect.cpp
|
||||
-------------------
|
||||
begin : Feb 2017
|
||||
copyright : (C) 2017 by Muhammad Yarjuna Rohmat, Ismail Sunni
|
||||
email : rohmat at kartoza dot com, ismail at kartoza dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgsproviderregistry.h"
|
||||
|
||||
#include "qgsgeonodesourceselect.h"
|
||||
#include "qgsgeonodeconnection.h"
|
||||
#include "qgsgeonoderequest.h"
|
||||
|
||||
#include "qgsgeonodenewconnection.h"
|
||||
#include "qgsmanageconnectionsdialog.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QListWidgetItem>
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
|
||||
enum
|
||||
{
|
||||
MODEL_IDX_TITLE,
|
||||
MODEL_IDX_NAME,
|
||||
MODEL_IDX_TYPE,
|
||||
MODEL_IDX_WEB_SERVICE
|
||||
};
|
||||
|
||||
QgsGeoNodeSourceSelect::QgsGeoNodeSourceSelect( QWidget *parent, Qt::WindowFlags fl, bool embeddedMode )
|
||||
: QDialog( parent, fl )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
if ( embeddedMode != QgsProviderRegistry::WidgetMode::None )
|
||||
{
|
||||
// For some obscure reasons hiding does not work!
|
||||
// buttonBox->button( QDialogButtonBox::Close )->hide();
|
||||
buttonBox->removeButton( buttonBox->button( QDialogButtonBox::Close ) );
|
||||
}
|
||||
|
||||
mAddButton = new QPushButton( tr( "&Add" ) );
|
||||
mAddButton->setEnabled( false );
|
||||
|
||||
buttonBox->addButton( mAddButton, QDialogButtonBox::ActionRole );
|
||||
|
||||
populateConnectionList();
|
||||
|
||||
connect( buttonBox, &QDialogButtonBox::rejected, this, &QgsGeoNodeSourceSelect::reject );
|
||||
connect( btnNew, &QPushButton::clicked, this, &QgsGeoNodeSourceSelect::addConnectionsEntryList );
|
||||
connect( btnEdit, &QPushButton::clicked, this, &QgsGeoNodeSourceSelect::modifyConnectionsEntryList );
|
||||
connect( btnDelete, &QPushButton::clicked, this, &QgsGeoNodeSourceSelect::deleteConnectionsEntryList );
|
||||
connect( btnConnect, &QPushButton::clicked, this, &QgsGeoNodeSourceSelect::connectToGeonodeConnection );
|
||||
connect( btnSave, &QPushButton::clicked, this, &QgsGeoNodeSourceSelect::saveGeonodeConnection );
|
||||
connect( btnLoad, &QPushButton::clicked, this, &QgsGeoNodeSourceSelect::loadGeonodeConnection );
|
||||
connect( lineFilter, &QLineEdit::textChanged, this, &QgsGeoNodeSourceSelect::filterChanged );
|
||||
connect( treeView, &QTreeView::clicked, this, &QgsGeoNodeSourceSelect::treeViewSelectionChanged );
|
||||
connect( mAddButton, &QPushButton::clicked, this, &QgsGeoNodeSourceSelect::addButtonClicked );
|
||||
|
||||
mItemDelegate = new QgsGeonodeItemDelegate( treeView );
|
||||
treeView->setItemDelegate( mItemDelegate );
|
||||
|
||||
mModel = new QStandardItemModel();
|
||||
mModel->setHorizontalHeaderItem( MODEL_IDX_TITLE, new QStandardItem( tr( "Title" ) ) );
|
||||
mModel->setHorizontalHeaderItem( MODEL_IDX_NAME, new QStandardItem( tr( "Name" ) ) );
|
||||
mModel->setHorizontalHeaderItem( MODEL_IDX_TYPE, new QStandardItem( tr( "Type" ) ) );
|
||||
mModel->setHorizontalHeaderItem( MODEL_IDX_WEB_SERVICE, new QStandardItem( tr( "Web Service" ) ) );
|
||||
|
||||
mModelProxy = new QSortFilterProxyModel( this );
|
||||
mModelProxy->setSourceModel( mModel );
|
||||
mModelProxy->setSortCaseSensitivity( Qt::CaseInsensitive );
|
||||
treeView->setModel( mModelProxy );
|
||||
}
|
||||
|
||||
QgsGeoNodeSourceSelect::~QgsGeoNodeSourceSelect() {}
|
||||
|
||||
void QgsGeoNodeSourceSelect::addConnectionsEntryList()
|
||||
{
|
||||
QgsGeoNodeNewConnection *nc = new QgsGeoNodeNewConnection( this );
|
||||
|
||||
if ( nc->exec() )
|
||||
{
|
||||
populateConnectionList();
|
||||
emit connectionsChanged();
|
||||
}
|
||||
|
||||
delete nc;
|
||||
}
|
||||
|
||||
void QgsGeoNodeSourceSelect::modifyConnectionsEntryList()
|
||||
{
|
||||
QgsGeoNodeNewConnection *nc = new QgsGeoNodeNewConnection( this, cmbConnections->currentText() );
|
||||
nc->setWindowTitle( tr( "Modify GeoNode connection" ) );
|
||||
|
||||
if ( nc->exec() )
|
||||
{
|
||||
populateConnectionList();
|
||||
emit connectionsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGeoNodeSourceSelect::deleteConnectionsEntryList()
|
||||
{
|
||||
QString msg = tr( "Are you sure you want to remove the %1 connection and all associated settings?" )
|
||||
.arg( cmbConnections->currentText() );
|
||||
QMessageBox::StandardButton result = QMessageBox::information( this, tr( "Confirm Delete" ), msg, QMessageBox::Ok | QMessageBox::Cancel );
|
||||
if ( result == QMessageBox::Ok )
|
||||
{
|
||||
QgsGeoNodeConnection::deleteConnection( cmbConnections->currentText() );
|
||||
cmbConnections->removeItem( cmbConnections->currentIndex() );
|
||||
if ( mModel )
|
||||
{
|
||||
mModel->removeRows( 0, mModel->rowCount() );
|
||||
}
|
||||
emit connectionsChanged();
|
||||
|
||||
if ( cmbConnections->count() > 0 )
|
||||
{
|
||||
// Connections available - enable various buttons
|
||||
btnConnect->setEnabled( true );
|
||||
btnEdit->setEnabled( true );
|
||||
btnDelete->setEnabled( true );
|
||||
btnSave->setEnabled( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
// No connections available - disable various buttons
|
||||
btnConnect->setEnabled( false );
|
||||
btnEdit->setEnabled( false );
|
||||
btnDelete->setEnabled( false );
|
||||
btnSave->setEnabled( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGeoNodeSourceSelect::populateConnectionList()
|
||||
{
|
||||
cmbConnections->clear();
|
||||
cmbConnections->addItems( QgsGeoNodeConnection::connectionList() );
|
||||
|
||||
setConnectionListPosition();
|
||||
}
|
||||
|
||||
void QgsGeoNodeSourceSelect::setConnectionListPosition()
|
||||
{
|
||||
QString toSelect = QgsGeoNodeConnection::selectedConnection();
|
||||
|
||||
cmbConnections->setCurrentIndex( cmbConnections->findText( toSelect ) );
|
||||
|
||||
if ( cmbConnections->currentIndex() < 0 )
|
||||
{
|
||||
if ( toSelect.isNull() )
|
||||
cmbConnections->setCurrentIndex( 0 );
|
||||
else
|
||||
cmbConnections->setCurrentIndex( cmbConnections->count() - 1 );
|
||||
}
|
||||
|
||||
if ( cmbConnections->count() == 0 )
|
||||
{
|
||||
// No connections - disable various buttons
|
||||
btnConnect->setEnabled( false );
|
||||
btnEdit->setEnabled( false );
|
||||
btnDelete->setEnabled( false );
|
||||
btnSave->setEnabled( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Connections - enable various buttons
|
||||
btnConnect->setEnabled( true );
|
||||
btnEdit->setEnabled( true );
|
||||
btnDelete->setEnabled( true );
|
||||
btnSave->setEnabled( true );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGeoNodeSourceSelect::connectToGeonodeConnection()
|
||||
{
|
||||
QApplication::setOverrideCursor( Qt::BusyCursor );
|
||||
QgsGeoNodeConnection connection( cmbConnections->currentText() );
|
||||
|
||||
QString url = connection.uri().param( "url" );
|
||||
QgsGeoNodeRequest geonodeRequest( url, true );
|
||||
|
||||
QApplication::setOverrideCursor( Qt::WaitCursor );
|
||||
bool success = geonodeRequest.getLayers();
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
if ( success )
|
||||
{
|
||||
QgsMessageLog::logMessage( QStringLiteral( "Success" ), tr( "GeoNode" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsMessageLog::logMessage( QStringLiteral( "Failed" ), tr( "GeoNode" ) );
|
||||
}
|
||||
|
||||
QByteArray ba = geonodeRequest.response();
|
||||
|
||||
QList<QgsServiceLayerDetail> layers = geonodeRequest.parseLayers( ba );
|
||||
|
||||
if ( mModel )
|
||||
{
|
||||
mModel->removeRows( 0, mModel->rowCount() );
|
||||
}
|
||||
|
||||
if ( !layers.isEmpty() )
|
||||
{
|
||||
Q_FOREACH ( const QgsServiceLayerDetail &layer, layers )
|
||||
{
|
||||
QUuid uuid = layer.uuid;
|
||||
|
||||
QString layerName = layer.name;
|
||||
|
||||
QString wmsURL = layer.wmsURL;
|
||||
QString wfsURL = layer.wfsURL;
|
||||
QString xyzURL = layer.xyzURL;
|
||||
|
||||
if ( wmsURL.length() > 0 )
|
||||
{
|
||||
QStandardItem *titleItem = new QStandardItem( layer.title );
|
||||
QStandardItem *nameItem;
|
||||
if ( layer.name > 0 )
|
||||
{
|
||||
nameItem = new QStandardItem( layer.name );
|
||||
}
|
||||
else
|
||||
{
|
||||
nameItem = new QStandardItem( layer.title );
|
||||
}
|
||||
QStandardItem *serviceTypeItem = new QStandardItem( tr( "Layer" ) );
|
||||
QStandardItem *webServiceTypeItem = new QStandardItem( tr( "WMS" ) );
|
||||
|
||||
QString typeName = layer.typeName;
|
||||
|
||||
titleItem->setData( uuid, Qt::UserRole + 1 );
|
||||
titleItem->setData( wmsURL, Qt::UserRole + 2 );
|
||||
titleItem->setData( typeName, Qt::UserRole + 3 );
|
||||
typedef QList< QStandardItem * > StandardItemList;
|
||||
mModel->appendRow( StandardItemList() << titleItem << nameItem << serviceTypeItem << webServiceTypeItem );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Layer " << layer.title << " does not have WMS url.";
|
||||
}
|
||||
if ( wfsURL.length() > 0 )
|
||||
{
|
||||
QStandardItem *titleItem = new QStandardItem( layer.title );
|
||||
QStandardItem *nameItem;
|
||||
if ( layer.name.length() > 0 )
|
||||
{
|
||||
nameItem = new QStandardItem( layer.name );
|
||||
}
|
||||
else
|
||||
{
|
||||
nameItem = new QStandardItem( layer.title );
|
||||
}
|
||||
QStandardItem *serviceTypeItem = new QStandardItem( tr( "Layer" ) );
|
||||
QStandardItem *webServiceTypeItem = new QStandardItem( tr( "WFS" ) );
|
||||
|
||||
QString typeName = layer.typeName;
|
||||
|
||||
titleItem->setData( uuid, Qt::UserRole + 1 );
|
||||
titleItem->setData( wfsURL, Qt::UserRole + 2 );
|
||||
titleItem->setData( typeName, Qt::UserRole + 3 );
|
||||
typedef QList< QStandardItem * > StandardItemList;
|
||||
mModel->appendRow( StandardItemList() << titleItem << nameItem << serviceTypeItem << webServiceTypeItem );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Layer " << layer.title << " does not have WFS url.";
|
||||
}
|
||||
if ( xyzURL.length() > 0 )
|
||||
{
|
||||
QStandardItem *titleItem = new QStandardItem( layer.title );
|
||||
QStandardItem *nameItem;
|
||||
if ( layer.name.length() > 0 )
|
||||
{
|
||||
nameItem = new QStandardItem( layer.name );
|
||||
}
|
||||
else
|
||||
{
|
||||
nameItem = new QStandardItem( layer.title );
|
||||
}
|
||||
QStandardItem *serviceTypeItem = new QStandardItem( tr( "Layer" ) );
|
||||
QStandardItem *webServiceTypeItem = new QStandardItem( tr( "XYZ" ) );
|
||||
|
||||
QString typeName = layer.typeName;
|
||||
|
||||
titleItem->setData( uuid, Qt::UserRole + 1 );
|
||||
titleItem->setData( xyzURL, Qt::UserRole + 2 );
|
||||
titleItem->setData( typeName, Qt::UserRole + 3 );
|
||||
typedef QList< QStandardItem * > StandardItemList;
|
||||
mModel->appendRow( StandardItemList() << titleItem << nameItem << serviceTypeItem << webServiceTypeItem );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Layer " << layer.title << " does not have XYZ url.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
QMessageBox *box = new QMessageBox( QMessageBox::Critical, tr( "Error" ), tr( "Cannot get any feature services" ), QMessageBox::Ok, this );
|
||||
box->setAttribute( Qt::WA_DeleteOnClose );
|
||||
box->setModal( true );
|
||||
box->setObjectName( QStringLiteral( "GeonodeCapabilitiesErrorBox" ) );
|
||||
box->open();
|
||||
}
|
||||
|
||||
treeView->resizeColumnToContents( MODEL_IDX_TITLE );
|
||||
treeView->resizeColumnToContents( MODEL_IDX_NAME );
|
||||
treeView->resizeColumnToContents( MODEL_IDX_TYPE );
|
||||
treeView->resizeColumnToContents( MODEL_IDX_WEB_SERVICE );
|
||||
for ( int i = MODEL_IDX_TITLE; i < MODEL_IDX_WEB_SERVICE; i++ )
|
||||
{
|
||||
if ( treeView->columnWidth( i ) > 210 )
|
||||
{
|
||||
treeView->setColumnWidth( i, 210 );
|
||||
}
|
||||
}
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void QgsGeoNodeSourceSelect::saveGeonodeConnection()
|
||||
{
|
||||
QgsManageConnectionsDialog dlg( this, QgsManageConnectionsDialog::Export, QgsManageConnectionsDialog::GeoNode );
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void QgsGeoNodeSourceSelect::loadGeonodeConnection()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName( this, tr( "Load connections" ), QDir::homePath(),
|
||||
tr( "XML files (*.xml *XML)" ) );
|
||||
if ( fileName.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsManageConnectionsDialog dlg( this, QgsManageConnectionsDialog::Import, QgsManageConnectionsDialog::GeoNode, fileName );
|
||||
dlg.exec();
|
||||
populateConnectionList();
|
||||
emit connectionsChanged();
|
||||
}
|
||||
|
||||
void QgsGeoNodeSourceSelect::filterChanged( const QString &text )
|
||||
{
|
||||
QRegExp::PatternSyntax mySyntax = QRegExp::PatternSyntax( QRegExp::RegExp );
|
||||
Qt::CaseSensitivity myCaseSensitivity = Qt::CaseInsensitive;
|
||||
QRegExp myRegExp( text, myCaseSensitivity, mySyntax );
|
||||
mModelProxy->setFilterRegExp( myRegExp );
|
||||
mModelProxy->sort( mModelProxy->sortColumn(), mModelProxy->sortOrder() );
|
||||
}
|
||||
|
||||
void QgsGeoNodeSourceSelect::treeViewSelectionChanged()
|
||||
{
|
||||
QModelIndex currentIndex = treeView->selectionModel()->currentIndex();
|
||||
if ( !currentIndex.isValid() )
|
||||
{
|
||||
qDebug() << "Current index is invalid";
|
||||
return;
|
||||
}
|
||||
mAddButton->setEnabled( false );
|
||||
QModelIndexList modelIndexList = treeView->selectionModel()->selectedRows();
|
||||
for ( int i = 0; i < modelIndexList.size(); i++ )
|
||||
{
|
||||
QModelIndex idx = mModelProxy->mapToSource( modelIndexList[i] );
|
||||
if ( !idx.isValid() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int row = idx.row();
|
||||
QString typeItem = mModel->item( row, MODEL_IDX_TYPE )->text();
|
||||
if ( typeItem == tr( "Layer" ) )
|
||||
{
|
||||
// Enable if there is a layer selected
|
||||
mAddButton->setEnabled( true );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void QgsGeoNodeSourceSelect::addButtonClicked()
|
||||
{
|
||||
qDebug() << "Add button clicked";
|
||||
QApplication::setOverrideCursor( Qt::BusyCursor );
|
||||
// Get selected entry in treeview
|
||||
QModelIndex currentIndex = treeView->selectionModel()->currentIndex();
|
||||
if ( !currentIndex.isValid() )
|
||||
{
|
||||
qDebug() << "Current index is invalid";
|
||||
return;
|
||||
}
|
||||
|
||||
QgsGeoNodeConnection connection( cmbConnections->currentText() );
|
||||
QModelIndexList modelIndexList = treeView->selectionModel()->selectedRows();
|
||||
for ( int i = 0; i < modelIndexList.size(); i++ )
|
||||
{
|
||||
QModelIndex idx = mModelProxy->mapToSource( modelIndexList[i] );
|
||||
if ( !idx.isValid() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int row = idx.row();
|
||||
|
||||
qDebug() << "Model index row " << row;
|
||||
|
||||
QString typeItem = mModel->item( row, MODEL_IDX_TYPE )->text();
|
||||
if ( typeItem == tr( "Map" ) )
|
||||
{
|
||||
qDebug() << "Skip adding map.";
|
||||
continue;
|
||||
}
|
||||
QString serviceURL = mModel->item( row, MODEL_IDX_TITLE )->data( Qt::UserRole + 2 ).toString();
|
||||
QString titleName = mModel->item( row, MODEL_IDX_TITLE )->text();
|
||||
QString layerName = mModel->item( row, MODEL_IDX_NAME )->text();
|
||||
QString webServiceType = mModel->item( row, MODEL_IDX_WEB_SERVICE )->text();
|
||||
|
||||
if ( cbxUseTitleLayerName->isChecked() && !titleName.isEmpty() )
|
||||
{
|
||||
QString layerName = titleName;
|
||||
}
|
||||
|
||||
qDebug() << "Layer name: " << layerName << " Type: " << webServiceType;
|
||||
|
||||
if ( webServiceType == "WMS" )
|
||||
{
|
||||
qDebug() << "Adding WMS layer of " << layerName;
|
||||
QgsDataSourceUri uri;
|
||||
uri.setParam( QStringLiteral( "url" ), serviceURL );
|
||||
|
||||
// Set static first, to see that it works. Need to think about the UI also.
|
||||
QString format( "image/png" );
|
||||
QString crs( "EPSG:4326" );
|
||||
QString styles( "" );
|
||||
QString contextualWMSLegend( "0" );
|
||||
|
||||
uri.setParam( QStringLiteral( "contextualWMSLegend" ), contextualWMSLegend );
|
||||
uri.setParam( QStringLiteral( "layers" ), layerName );
|
||||
uri.setParam( QStringLiteral( "styles" ), styles );
|
||||
uri.setParam( QStringLiteral( "format" ), format );
|
||||
uri.setParam( QStringLiteral( "crs" ), crs );
|
||||
|
||||
QgsDebugMsg( "Add WMS from GeoNode : " + uri.encodedUri() );
|
||||
emit addRasterLayer( uri.encodedUri(), layerName, QStringLiteral( "wms" ) );
|
||||
}
|
||||
else if ( webServiceType == "WFS" )
|
||||
{
|
||||
qDebug() << "Adding WFS layer of " << layerName;
|
||||
|
||||
// Set static first, to see that it works. Need to think about the UI also.
|
||||
QString typeName = mModel->item( row, 0 )->data( Qt::UserRole + 3 ).toString();
|
||||
QString crs( "EPSG:4326" );
|
||||
|
||||
// typeName, titleName, sql,
|
||||
// Build url for WFS
|
||||
// restrictToRequestBBOX='1' srsname='EPSG:26719' typename='geonode:cab_mun' url='http://demo.geonode.org/geoserver/geonode/wms' table=\"\" sql="
|
||||
QString uri;
|
||||
uri += QStringLiteral( " restrictToRequestBBOX='1'" );
|
||||
uri += QStringLiteral( " srsname='%1'" ).arg( crs );
|
||||
if ( serviceURL.contains( "qgis-server" ) )
|
||||
{
|
||||
// I need to do this since the typename used in qgis-server is without the workspace.
|
||||
QString qgisServerTypeName = QString( typeName ).split( ":" ).last();
|
||||
uri += QStringLiteral( " typename='%1'" ).arg( qgisServerTypeName );
|
||||
}
|
||||
else
|
||||
{
|
||||
uri += QStringLiteral( " typename='%1'" ).arg( typeName );
|
||||
}
|
||||
uri += QStringLiteral( " url='%1'" ).arg( serviceURL );
|
||||
uri += QStringLiteral( " table=\"\"" );
|
||||
uri += QStringLiteral( " sql=" );
|
||||
|
||||
QgsMessageLog::logMessage( "Add WFS from GeoNode : " + uri + " and typename: " + typeName, tr( "GeoNode" ) );
|
||||
emit addWfsLayer( uri, typeName, "WFS" );
|
||||
}
|
||||
else if ( webServiceType == "XYZ" )
|
||||
{
|
||||
QgsDebugMsg( "XYZ Url: " + serviceURL );
|
||||
QgsDebugMsg( "Add XYZ from GeoNode : " + serviceURL );
|
||||
QgsDataSourceUri uri;
|
||||
uri.setParam( QStringLiteral( "url" ), serviceURL );
|
||||
uri.setParam( QStringLiteral( "type" ), QStringLiteral( "xyz" ) );
|
||||
uri.setParam( QStringLiteral( "zmin" ), "0" );
|
||||
uri.setParam( QStringLiteral( "zmax" ), "18" );
|
||||
emit addRasterLayer( uri.encodedUri(), layerName, QStringLiteral( "wms" ) );
|
||||
}
|
||||
}
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
88
src/gui/geonode/qgsgeonodesourceselect.h
Normal file
88
src/gui/geonode/qgsgeonodesourceselect.h
Normal file
@ -0,0 +1,88 @@
|
||||
/***************************************************************************
|
||||
qgsgeonodesourceselect.h
|
||||
-------------------
|
||||
begin : Feb 2017
|
||||
copyright : (C) 2017 by Muhammad Yarjuna Rohmat, Ismail Sunni
|
||||
email : rohmat at kartoza dot com, ismail at kartoza dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSGEONODESOURCESELECT_H
|
||||
#define QGSGEONODESOURCESELECT_H
|
||||
|
||||
#include <QItemDelegate>
|
||||
#include <QStandardItemModel>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include "ui_qgsgeonodesourceselectbase.h"
|
||||
#include "qgis_gui.h"
|
||||
|
||||
class GUI_EXPORT QgsGeonodeItemDelegate : public QItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsGeonodeItemDelegate( QObject *parent = nullptr ) : QItemDelegate( parent ) { }
|
||||
};
|
||||
|
||||
class GUI_EXPORT QgsGeoNodeSourceSelect: public QDialog, private Ui::QgsGeonodeSourceSelectBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
QgsGeoNodeSourceSelect( QWidget *parent, Qt::WindowFlags fl, bool embeddedMode = false );
|
||||
~QgsGeoNodeSourceSelect();
|
||||
|
||||
signals:
|
||||
void connectionsChanged();
|
||||
void addRasterLayer( const QString &rasterLayerPath,
|
||||
const QString &baseName,
|
||||
const QString &providerKey );
|
||||
void addRasterLayer();
|
||||
|
||||
void addWfsLayer(
|
||||
const QString &uri,
|
||||
const QString &layerName,
|
||||
const QString &providerKey );
|
||||
|
||||
private:
|
||||
QgsGeoNodeSourceSelect(); //default constructor is forbidden
|
||||
|
||||
/** Stores the available CRS for a server connections.
|
||||
The first string is the typename, the corresponding list
|
||||
stores the CRS for the typename in the form 'EPSG:XXXX'*/
|
||||
QMap<QString, QStringList > mAvailableCRS;
|
||||
QString mUri; // data source URI
|
||||
QgsGeonodeItemDelegate *mItemDelegate = nullptr;
|
||||
QStandardItemModel *mModel = nullptr;
|
||||
QSortFilterProxyModel *mModelProxy = nullptr;
|
||||
QPushButton *mBuildQueryButton = nullptr;
|
||||
QPushButton *mAddButton = nullptr;
|
||||
QModelIndex mSQLIndex;
|
||||
|
||||
private slots:
|
||||
void addConnectionsEntryList();
|
||||
void modifyConnectionsEntryList();
|
||||
void deleteConnectionsEntryList();
|
||||
void connectToGeonodeConnection();
|
||||
void saveGeonodeConnection();
|
||||
void loadGeonodeConnection();
|
||||
void filterChanged( const QString &text );
|
||||
void treeViewSelectionChanged();
|
||||
void addButtonClicked();
|
||||
|
||||
void populateConnectionList();
|
||||
void setConnectionListPosition();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -27,6 +27,7 @@
|
||||
#include "qgsmapcanvas.h"
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgsgui.h"
|
||||
#include "qgsgeonodesourceselect.h"
|
||||
|
||||
QgsDataSourceManagerDialog::QgsDataSourceManagerDialog( QgsBrowserModel *browserModel, QWidget *parent, QgsMapCanvas *canvas, Qt::WindowFlags fl ) :
|
||||
QgsOptionsDialogBase( QStringLiteral( "Data Source Manager" ), parent, fl ),
|
||||
@ -71,6 +72,15 @@ QgsDataSourceManagerDialog::QgsDataSourceManagerDialog( QgsBrowserModel *browser
|
||||
addProviderDialog( dlg, provider->providerKey(), provider->text(), provider->icon( ), provider->toolTip( ) );
|
||||
}
|
||||
|
||||
|
||||
QDialog *geonodeDialog = new QgsGeoNodeSourceSelect( this, Qt::Widget, QgsProviderRegistry::WidgetMode::Embedded );
|
||||
dlg = addDialog( geonodeDialog, QStringLiteral( "geonode" ), tr( "GeoNode" ), QStringLiteral( "/mActionAddGeonodeLayer.svg" ) );
|
||||
|
||||
if ( dlg )
|
||||
{
|
||||
connect( dlg, SIGNAL( addRasterLayer( QString, QString, QString ) ), this, SLOT( rasterLayerAdded( QString, QString, QString ) ) );
|
||||
connect( dlg, SIGNAL( addWfsLayer( QString, QString, QString ) ), this, SLOT( vectorLayerAdded( QString, QString, QString ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
QgsDataSourceManagerDialog::~QgsDataSourceManagerDialog()
|
||||
@ -121,6 +131,15 @@ void QgsDataSourceManagerDialog::vectorLayersAdded( const QStringList &layerQStr
|
||||
emit addVectorLayers( layerQStringList, enc, dataSourceType );
|
||||
}
|
||||
|
||||
QDialog *QgsDataSourceManagerDialog::addDialog( QDialog *dialog, QString const key, QString const name, QString const icon, QString title )
|
||||
{
|
||||
mPageNames.append( key );
|
||||
ui->mOptionsStackedWidget->addWidget( dialog );
|
||||
QListWidgetItem *layerItem = new QListWidgetItem( name, ui->mOptionsListWidget );
|
||||
layerItem->setToolTip( title.isEmpty() ? tr( "Add %1 layer" ).arg( name ) : title );
|
||||
layerItem->setIcon( QgsApplication::getThemeIcon( icon ) );
|
||||
return dialog;
|
||||
}
|
||||
|
||||
void QgsDataSourceManagerDialog::addProviderDialog( QgsAbstractDataSourceWidget *dlg, const QString &providerKey, const QString &providerName, const QIcon &icon, const QString &toolTip )
|
||||
{
|
||||
|
@ -116,7 +116,11 @@ class GUI_EXPORT QgsDataSourceManagerDialog : public QgsOptionsDialogBase, priva
|
||||
void providerDialogsRefreshRequested();
|
||||
|
||||
private:
|
||||
void addProviderDialog( QgsAbstractDataSourceWidget *dlg, const QString &providerKey, const QString &providerName, const QIcon &icon, const QString &toolTip = QString() );
|
||||
//! Add a provider dialog
|
||||
QDialog *addDialog( QDialog *dialog, QString const key, QString const name, QString const icon, QString title = QString() );
|
||||
|
||||
|
||||
void addProviderDialog( QgsAbstractDataSourceWidget *dlg, const QString &providerKey, const QString &providerName, const QIcon &icon, QString toolTip = QString() );
|
||||
void makeConnections( QgsAbstractDataSourceWidget *dlg, const QString &providerKey );
|
||||
Ui::QgsDataSourceManagerDialog *ui;
|
||||
QgsBrowserDockWidget *mBrowserWidget = nullptr;
|
||||
|
@ -130,6 +130,9 @@ void QgsManageConnectionsDialog::doExportImport()
|
||||
case DB2:
|
||||
doc = saveDb2Connections( items );
|
||||
break;
|
||||
case GeoNode:
|
||||
doc = saveGeonodeConnections( items );
|
||||
break;
|
||||
}
|
||||
|
||||
QFile file( mFileName );
|
||||
@ -195,6 +198,9 @@ void QgsManageConnectionsDialog::doExportImport()
|
||||
case DB2:
|
||||
loadDb2Connections( doc, items );
|
||||
break;
|
||||
case GeoNode:
|
||||
loadGeonodeConnections( doc, items );
|
||||
break;
|
||||
}
|
||||
// clear connections list and close window
|
||||
listConnections->clear();
|
||||
@ -233,6 +239,9 @@ bool QgsManageConnectionsDialog::populateConnections()
|
||||
case DB2:
|
||||
settings.beginGroup( QStringLiteral( "/DB2/connections" ) );
|
||||
break;
|
||||
case GeoNode:
|
||||
settings.beginGroup( QStringLiteral( "/qgis/connections-geonode" ) );
|
||||
break;
|
||||
}
|
||||
QStringList keys = settings.childGroups();
|
||||
QStringList::Iterator it = keys.begin();
|
||||
@ -336,6 +345,14 @@ bool QgsManageConnectionsDialog::populateConnections()
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case GeoNode:
|
||||
if ( root.tagName() != QLatin1String( "qgsGeoNodeConnections" ) )
|
||||
{
|
||||
QMessageBox::information( this, tr( "Loading connections" ),
|
||||
tr( "The file is not a GeoNode connections exchange file." ) );
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
QDomElement child = root.firstChildElement();
|
||||
@ -580,6 +597,31 @@ QDomDocument QgsManageConnectionsDialog::saveDb2Connections( const QStringList &
|
||||
return doc;
|
||||
}
|
||||
|
||||
QDomDocument QgsManageConnectionsDialog::saveGeonodeConnections( const QStringList &connections )
|
||||
{
|
||||
QDomDocument doc( QStringLiteral( "connections" ) );
|
||||
QDomElement root = doc.createElement( QStringLiteral( "qgsGeoNodeConnections" ) );
|
||||
root.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0" ) );
|
||||
doc.appendChild( root );
|
||||
|
||||
QgsSettings settings;
|
||||
QString path;
|
||||
for ( int i = 0; i < connections.count(); ++i )
|
||||
{
|
||||
path = QStringLiteral( "/qgis/connections-geonode/" );
|
||||
QDomElement el = doc.createElement( QStringLiteral( "geonode" ) );
|
||||
el.setAttribute( QStringLiteral( "name" ), connections[ i ] );
|
||||
el.setAttribute( QStringLiteral( "url" ), settings.value( path + connections[ i ] + "/url", "" ).toString() );
|
||||
|
||||
path = QStringLiteral( "/qgis/GeoNode/" );
|
||||
el.setAttribute( QStringLiteral( "username" ), settings.value( path + connections[ i ] + "/username", "" ).toString() );
|
||||
el.setAttribute( QStringLiteral( "password" ), settings.value( path + connections[ i ] + "/password", "" ).toString() );
|
||||
root.appendChild( el );
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
void QgsManageConnectionsDialog::loadOWSConnections( const QDomDocument &doc, const QStringList &items, const QString &service )
|
||||
{
|
||||
QDomElement root = doc.documentElement();
|
||||
@ -1103,6 +1145,87 @@ void QgsManageConnectionsDialog::loadDb2Connections( const QDomDocument &doc, co
|
||||
child = child.nextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsManageConnectionsDialog::loadGeonodeConnections( const QDomDocument &doc, const QStringList &items )
|
||||
{
|
||||
QDomElement root = doc.documentElement();
|
||||
if ( root.tagName() != QLatin1String( "qgsGeoNodeConnections" ) )
|
||||
{
|
||||
QMessageBox::information( this, tr( "Loading connections" ),
|
||||
tr( "The file is not a GeoNode connections exchange file." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
QString connectionName;
|
||||
QgsSettings settings;
|
||||
settings.beginGroup( QStringLiteral( "/qgis/connections-geonode" ) );
|
||||
QStringList keys = settings.childGroups();
|
||||
settings.endGroup();
|
||||
QDomElement child = root.firstChildElement();
|
||||
bool prompt = true;
|
||||
bool overwrite = true;
|
||||
|
||||
while ( !child.isNull() )
|
||||
{
|
||||
connectionName = child.attribute( QStringLiteral( "name" ) );
|
||||
if ( !items.contains( connectionName ) )
|
||||
{
|
||||
child = child.nextSiblingElement();
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for duplicates
|
||||
if ( keys.contains( connectionName ) && prompt )
|
||||
{
|
||||
int res = QMessageBox::warning( this,
|
||||
tr( "Loading connections" ),
|
||||
tr( "Connection with name '%1' already exists. Overwrite?" )
|
||||
.arg( connectionName ),
|
||||
QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
|
||||
|
||||
switch ( res )
|
||||
{
|
||||
case QMessageBox::Cancel:
|
||||
return;
|
||||
case QMessageBox::No:
|
||||
child = child.nextSiblingElement();
|
||||
continue;
|
||||
case QMessageBox::Yes:
|
||||
overwrite = true;
|
||||
break;
|
||||
case QMessageBox::YesToAll:
|
||||
prompt = false;
|
||||
overwrite = true;
|
||||
break;
|
||||
case QMessageBox::NoToAll:
|
||||
prompt = false;
|
||||
overwrite = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( keys.contains( connectionName ) && !overwrite )
|
||||
{
|
||||
child = child.nextSiblingElement();
|
||||
continue;
|
||||
}
|
||||
|
||||
// no dups detected or overwrite is allowed
|
||||
settings.beginGroup( QStringLiteral( "/qgis/connections-geonode" ) );
|
||||
settings.setValue( QString( '/' + connectionName + "/url" ), child.attribute( QStringLiteral( "url" ) ) );
|
||||
settings.endGroup();
|
||||
|
||||
if ( !child.attribute( QStringLiteral( "username" ) ).isEmpty() )
|
||||
{
|
||||
settings.beginGroup( "/qgis/GeoNode/" + connectionName );
|
||||
settings.setValue( QStringLiteral( "/username" ), child.attribute( QStringLiteral( "username" ) ) );
|
||||
settings.setValue( QStringLiteral( "/password" ), child.attribute( QStringLiteral( "password" ) ) );
|
||||
settings.endGroup();
|
||||
}
|
||||
child = child.nextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsManageConnectionsDialog::selectAll()
|
||||
{
|
||||
listConnections->selectAll();
|
||||
|
@ -47,6 +47,7 @@ class GUI_EXPORT QgsManageConnectionsDialog : public QDialog, private Ui::QgsMan
|
||||
DB2,
|
||||
WCS,
|
||||
Oracle,
|
||||
GeoNode
|
||||
};
|
||||
|
||||
// constructor
|
||||
@ -69,6 +70,7 @@ class GUI_EXPORT QgsManageConnectionsDialog : public QDialog, private Ui::QgsMan
|
||||
QDomDocument saveMssqlConnections( const QStringList &connections );
|
||||
QDomDocument saveOracleConnections( const QStringList &connections );
|
||||
QDomDocument saveDb2Connections( const QStringList &connections );
|
||||
QDomDocument saveGeonodeConnections( const QStringList &connections );
|
||||
|
||||
void loadOWSConnections( const QDomDocument &doc, const QStringList &items, const QString &service );
|
||||
void loadWfsConnections( const QDomDocument &doc, const QStringList &items );
|
||||
@ -76,6 +78,7 @@ class GUI_EXPORT QgsManageConnectionsDialog : public QDialog, private Ui::QgsMan
|
||||
void loadMssqlConnections( const QDomDocument &doc, const QStringList &items );
|
||||
void loadOracleConnections( const QDomDocument &doc, const QStringList &items );
|
||||
void loadDb2Connections( const QDomDocument &doc, const QStringList &items );
|
||||
void loadGeonodeConnections( const QDomDocument &doc, const QStringList &items );
|
||||
|
||||
QString mFileName;
|
||||
Mode mDialogMode;
|
||||
|
@ -172,6 +172,7 @@ QgsNewHttpConnection::QgsNewHttpConnection(
|
||||
|
||||
if ( mBaseKey != QLatin1String( "qgis/connections-wfs/" ) )
|
||||
{
|
||||
lblVersion->setVisible( false );
|
||||
cmbVersion->setVisible( false );
|
||||
mGroupBox->layout()->removeWidget( cmbVersion );
|
||||
lblMaxNumFeatures->setVisible( false );
|
||||
|
@ -1,21 +1,25 @@
|
||||
SET(OWS_SRCS
|
||||
qgsowsprovider.cpp
|
||||
qgsowsdataitems.cpp
|
||||
)
|
||||
qgsgeonodedataitems.cpp)
|
||||
SET(OWS_MOC_HDRS
|
||||
qgsowsprovider.h
|
||||
qgsowsdataitems.h
|
||||
qgsgeonodedataitems.h
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES (
|
||||
${CMAKE_SOURCE_DIR}/src/gui/geonode
|
||||
${CMAKE_SOURCE_DIR}/src/core
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/geonode
|
||||
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/gui
|
||||
${CMAKE_SOURCE_DIR}/src/gui/auth
|
||||
|
||||
${CMAKE_BINARY_DIR}/src/app
|
||||
${CMAKE_BINARY_DIR}/src/core
|
||||
${CMAKE_BINARY_DIR}/src/gui
|
||||
${CMAKE_BINARY_DIR}/src/ui
|
||||
@ -30,6 +34,8 @@ ADD_LIBRARY (owsprovider MODULE ${OWS_SRCS} ${OWS_MOC_SRCS})
|
||||
|
||||
TARGET_LINK_LIBRARIES (owsprovider
|
||||
qgis_core
|
||||
qgis_gui
|
||||
qgis_app
|
||||
)
|
||||
|
||||
IF (WITH_GUI)
|
||||
|
273
src/providers/ows/qgsgeonodedataitems.cpp
Normal file
273
src/providers/ows/qgsgeonodedataitems.cpp
Normal file
@ -0,0 +1,273 @@
|
||||
/***************************************************************************
|
||||
qgsgeonodedataitems.cpp
|
||||
---------------------
|
||||
begin : Feb 2017
|
||||
copyright : (C) 2017 by Muhammad Yarjuna Rohmat, Ismail Sunni
|
||||
email : rohmat at kartoza dot com, ismail at kartoza dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsowsdataitems.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsgeonodedataitems.h"
|
||||
#include "qgsproviderregistry.h"
|
||||
#include "qgsnewhttpconnection.h"
|
||||
#include "qgsgeonodenewconnection.h"
|
||||
#include "qgsgeonoderequest.h"
|
||||
|
||||
typedef QList<QgsDataItemProvider *> dataItemProviders_t();
|
||||
|
||||
QgsGeoNodeConnectionItem::QgsGeoNodeConnectionItem( QgsDataItem *parent, QString name, QString path, QgsGeoNodeConnection *conn )
|
||||
: QgsDataCollectionItem( parent, name, path )
|
||||
, mGeoNodeName( parent->name() )
|
||||
, mUri( conn->uri().uri() )
|
||||
, mConnection( conn )
|
||||
{
|
||||
mIconName = QStringLiteral( "mIconConnect.png" );
|
||||
}
|
||||
|
||||
QVector<QgsDataItem *> QgsGeoNodeConnectionItem::createChildren()
|
||||
{
|
||||
QVector<QgsDataItem *> services;
|
||||
|
||||
QString url = mConnection->uri().param( "url" );
|
||||
QgsGeoNodeRequest geonodeRequest( url, true );
|
||||
|
||||
QStringList wmsUrl = geonodeRequest.serviceUrls( QStringLiteral( "WMS" ) );
|
||||
QStringList wfsUrl = geonodeRequest.serviceUrls( QStringLiteral( "WFS" ) );
|
||||
QStringList xyzUrl = geonodeRequest.serviceUrls( QStringLiteral( "XYZ" ) );
|
||||
|
||||
if ( !wmsUrl.isEmpty() )
|
||||
{
|
||||
QString path = mPath + "/wms";
|
||||
QgsDataItem *service = new QgsGeoNodeServiceItem( this, mConnection, QStringLiteral( "WMS" ), path );
|
||||
services.append( service );
|
||||
}
|
||||
|
||||
if ( !wfsUrl.isEmpty() )
|
||||
{
|
||||
QString path = mPath + "/wfs";
|
||||
QgsDataItem *service = new QgsGeoNodeServiceItem( this, mConnection, QStringLiteral( "WFS" ), path );
|
||||
services.append( service );
|
||||
}
|
||||
|
||||
if ( !xyzUrl.isEmpty() )
|
||||
{
|
||||
QString path = mPath + "/xyz";
|
||||
QgsDataItem *service = new QgsGeoNodeServiceItem( this, mConnection, QStringLiteral( "XYZ" ), path );
|
||||
services.append( service );
|
||||
}
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
QList<QAction *> QgsGeoNodeConnectionItem::actions()
|
||||
{
|
||||
QAction *actionEdit = new QAction( tr( "Edit..." ), this );
|
||||
QAction *actionDelete = new QAction( tr( "Delete" ), this );
|
||||
connect( actionEdit, &QAction::triggered, this, &QgsGeoNodeConnectionItem::editConnection );
|
||||
connect( actionDelete, &QAction::triggered, this, &QgsGeoNodeConnectionItem::deleteConnection );
|
||||
return QList<QAction *>() << actionEdit << actionDelete;
|
||||
}
|
||||
|
||||
void QgsGeoNodeConnectionItem::editConnection()
|
||||
{
|
||||
QgsGeoNodeNewConnection *nc = new QgsGeoNodeNewConnection( nullptr, mConnection->connName() );
|
||||
nc->setWindowTitle( tr( "Modify GeoNode connection" ) );
|
||||
|
||||
if ( nc->exec() )
|
||||
{
|
||||
// the parent should be updated
|
||||
mParent->refresh();
|
||||
}
|
||||
}
|
||||
|
||||
QgsGeoNodeServiceItem::QgsGeoNodeServiceItem( QgsDataItem *parent, QgsGeoNodeConnection *conn, QString serviceName, QString path )
|
||||
: QgsDataCollectionItem( parent, serviceName, path )
|
||||
, mName( conn->connName() )
|
||||
, mServiceName( serviceName )
|
||||
, mConnection( conn )
|
||||
{
|
||||
if ( serviceName == QStringLiteral( "WMS" ) || serviceName == QStringLiteral( "XYZ" ) )
|
||||
{
|
||||
mIconName = QStringLiteral( "mIconWms.svg" );
|
||||
}
|
||||
else
|
||||
{
|
||||
mIconName = QStringLiteral( "mIconWfs.svg" );
|
||||
}
|
||||
}
|
||||
|
||||
QVector<QgsDataItem *> QgsGeoNodeServiceItem::createChildren()
|
||||
{
|
||||
QVector<QgsDataItem *> children;
|
||||
QHash<QgsDataItem *, QString> serviceItems; // service/provider key
|
||||
|
||||
int layerCount = 0;
|
||||
// Try to open with service provider
|
||||
bool skipProvider = false;
|
||||
|
||||
QgsGeoNodeConnectionItem *parentItem = dynamic_cast<QgsGeoNodeConnectionItem *>( mParent );
|
||||
QString pathPrefix = parentItem->mGeoNodeName.toLower() + ":/";
|
||||
|
||||
while ( !skipProvider )
|
||||
{
|
||||
const QString &key = mServiceName != QString( "WFS" ) ? QString( "WMS" ).toLower() : mServiceName;
|
||||
std::unique_ptr< QLibrary > library( QgsProviderRegistry::instance()->createProviderLibrary( key ) );
|
||||
if ( !library )
|
||||
{
|
||||
skipProvider = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
dataItemProviders_t *dataItemProvidersFn = reinterpret_cast< dataItemProviders_t * >( cast_to_fptr( library->resolve( "dataItemProviders" ) ) );
|
||||
dataItem_t *dItem = ( dataItem_t * ) cast_to_fptr( library->resolve( "dataItem" ) );
|
||||
if ( !dItem && !dataItemProvidersFn )
|
||||
{
|
||||
skipProvider = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
QString path = pathPrefix + mName;
|
||||
|
||||
QVector<QgsDataItem *> items;
|
||||
Q_FOREACH ( QgsDataItemProvider *pr, dataItemProvidersFn() )
|
||||
{
|
||||
items = pr->name().startsWith( mServiceName ) ? pr->createDataItems( path, this ) : items;
|
||||
if ( !items.isEmpty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( items.isEmpty() )
|
||||
{
|
||||
skipProvider = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( mServiceName == QStringLiteral( "XYZ" ) )
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
Q_FOREACH ( QgsDataItem *item, items )
|
||||
{
|
||||
item->populate( true ); // populate in foreground - this is already run in a thread
|
||||
|
||||
layerCount += item->rowCount();
|
||||
if ( item->rowCount() > 0 )
|
||||
{
|
||||
serviceItems.insert( item, key );
|
||||
}
|
||||
else
|
||||
{
|
||||
//delete item;
|
||||
}
|
||||
}
|
||||
|
||||
skipProvider = true;
|
||||
}
|
||||
|
||||
Q_FOREACH ( QgsDataItem *item, serviceItems.keys() )
|
||||
{
|
||||
QString providerKey = serviceItems.value( item );
|
||||
|
||||
// Add layers directly to service item
|
||||
Q_FOREACH ( QgsDataItem *subItem, item->children() )
|
||||
{
|
||||
if ( subItem->path().endsWith( QString( "error" ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
item->removeChildItem( subItem );
|
||||
subItem->setParent( this );
|
||||
replacePath( subItem, providerKey.toLower() + ":/", pathPrefix );
|
||||
children.append( subItem );
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
// reset path recursively
|
||||
void QgsGeoNodeServiceItem::replacePath( QgsDataItem *item, QString before, QString after )
|
||||
{
|
||||
item->setPath( item->path().replace( before, after ) );
|
||||
Q_FOREACH ( QgsDataItem *subItem, item->children() )
|
||||
{
|
||||
replacePath( subItem, before, after );
|
||||
}
|
||||
}
|
||||
|
||||
QgsGeoNodeRootItem::QgsGeoNodeRootItem( QgsDataItem *parent, QString name, QString path ) : QgsDataCollectionItem( parent, name, path )
|
||||
{
|
||||
mCapabilities |= Fast;
|
||||
{
|
||||
mIconName = QStringLiteral( "mIconGeonode.svg" );
|
||||
}
|
||||
populate();
|
||||
}
|
||||
|
||||
QVector<QgsDataItem *> QgsGeoNodeRootItem::createChildren()
|
||||
{
|
||||
QVector<QgsDataItem *> connections;
|
||||
|
||||
Q_FOREACH ( const QString &connName, QgsGeoNodeConnection::connectionList() )
|
||||
{
|
||||
QgsGeoNodeConnection *connection = nullptr;
|
||||
connection = new QgsGeoNodeConnection( connName );
|
||||
QString path = mPath + "/" + connName;
|
||||
QgsDataItem *conn = new QgsGeoNodeConnectionItem( this, connName, path, connection );
|
||||
connections.append( conn );
|
||||
}
|
||||
return connections;
|
||||
}
|
||||
|
||||
QList<QAction *> QgsGeoNodeRootItem::actions()
|
||||
{
|
||||
QAction *actionNew = new QAction( tr( "New Connection..." ), this );
|
||||
connect( actionNew, &QAction::triggered, this, &QgsGeoNodeRootItem::newConnection );
|
||||
return QList<QAction *>() << actionNew;
|
||||
}
|
||||
|
||||
void QgsGeoNodeRootItem::newConnection()
|
||||
{
|
||||
QgsGeoNodeNewConnection *nc = new QgsGeoNodeNewConnection( nullptr );
|
||||
|
||||
if ( nc->exec() )
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QgsDataItem *QgsGeoNodeDataItemProvider::createDataItem( const QString &path, QgsDataItem *parentItem )
|
||||
{
|
||||
QgsDebugMsg( "thePath = " + path );
|
||||
if ( path.isEmpty() )
|
||||
{
|
||||
return new QgsGeoNodeRootItem( parentItem, QStringLiteral( "GeoNode" ), QStringLiteral( "geonode:" ) );
|
||||
}
|
||||
|
||||
// path schema: geonode:/connection name (used by OWS)
|
||||
if ( path.startsWith( QLatin1String( "geonode:/" ) ) )
|
||||
{
|
||||
QString connectionName = path.split( '/' ).last();
|
||||
if ( QgsGeoNodeConnection::connectionList().contains( connectionName ) )
|
||||
{
|
||||
QgsGeoNodeConnection *connection = new QgsGeoNodeConnection( connectionName );
|
||||
return new QgsGeoNodeConnectionItem( parentItem, QStringLiteral( "GeoNode" ), path, connection );
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
87
src/providers/ows/qgsgeonodedataitems.h
Normal file
87
src/providers/ows/qgsgeonodedataitems.h
Normal file
@ -0,0 +1,87 @@
|
||||
/***************************************************************************
|
||||
qgsgeonodedataitems.h
|
||||
---------------------
|
||||
begin : Feb 2017
|
||||
copyright : (C) 2017 by Muhammad Yarjuna Rohmat, Ismail Sunni
|
||||
email : rohmat at kartoza dot com, ismail at kartoza dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSGEONODEDATAITEMS_H
|
||||
#define QGSGEONODEDATAITEMS_H
|
||||
|
||||
#include "qgsdataitem.h"
|
||||
#include "qgsdataitemprovider.h"
|
||||
#include "qgsdataprovider.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
#include "qgsgeonodeconnection.h"
|
||||
|
||||
class QgsGeoNodeConnectionItem : public QgsDataCollectionItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsGeoNodeConnectionItem( QgsDataItem *parent, QString name, QString path, QgsGeoNodeConnection *conn );
|
||||
QVector<QgsDataItem *> createChildren() override;
|
||||
virtual QList<QAction *> actions() override;
|
||||
|
||||
QString mGeoNodeName;
|
||||
|
||||
private:
|
||||
void editConnection();
|
||||
void deleteConnection()
|
||||
{
|
||||
QgsGeoNodeConnection::deleteConnection( mParent->name() );
|
||||
mParent->refresh();
|
||||
};
|
||||
|
||||
QString mUri;
|
||||
QgsGeoNodeConnection *mConnection = nullptr;
|
||||
};
|
||||
|
||||
class QgsGeoNodeServiceItem : public QgsDataCollectionItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsGeoNodeServiceItem( QgsDataItem *parent, QgsGeoNodeConnection *conn, QString serviceName, QString path );
|
||||
QVector<QgsDataItem *> createChildren() override;
|
||||
|
||||
private:
|
||||
void replacePath( QgsDataItem *item, QString before, QString after );
|
||||
QString mName;
|
||||
QString mServiceName;
|
||||
QString mUri;
|
||||
QgsGeoNodeConnection *mConnection = nullptr;
|
||||
};
|
||||
|
||||
class QgsGeoNodeRootItem : public QgsDataCollectionItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsGeoNodeRootItem( QgsDataItem *parent, QString name, QString path );
|
||||
|
||||
QVector<QgsDataItem *> createChildren() override;
|
||||
|
||||
virtual QList<QAction *> actions() override;
|
||||
|
||||
private slots:
|
||||
void newConnection();
|
||||
};
|
||||
|
||||
//! Provider for Geonode root data item
|
||||
class QgsGeoNodeDataItemProvider : public QgsDataItemProvider
|
||||
{
|
||||
public:
|
||||
virtual QString name() override { return QStringLiteral( "GeoNode" ); }
|
||||
|
||||
virtual int capabilities() override { return QgsDataProvider::Net; }
|
||||
|
||||
virtual QgsDataItem *createDataItem( const QString &path, QgsDataItem *parentItem ) override;
|
||||
};
|
||||
|
||||
#endif //QGSGEONODEDATAITEMS_H
|
@ -23,6 +23,9 @@
|
||||
#include "qgsnewhttpconnection.h"
|
||||
#include "qgsowssourceselect.h"
|
||||
#endif
|
||||
#include "qgsgeonodeconnection.h"
|
||||
#include "qgsgeonodenewconnection.h"
|
||||
#include "qgsgeonodedataitems.h"
|
||||
|
||||
#include "qgsapplication.h"
|
||||
|
||||
@ -259,12 +262,14 @@ void QgsOWSRootItem::newConnection()
|
||||
static QStringList extensions = QStringList();
|
||||
static QStringList wildcards = QStringList();
|
||||
|
||||
QGISEXTERN int dataCapabilities()
|
||||
QGISEXTERN QList<QgsDataItemProvider *> dataItemProviders()
|
||||
{
|
||||
return QgsDataProvider::Net;
|
||||
return QList<QgsDataItemProvider *>()
|
||||
<< new QgsOwsDataItemProvider
|
||||
<< new QgsGeoNodeDataItemProvider;
|
||||
}
|
||||
|
||||
QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
|
||||
QgsDataItem *QgsOwsDataItemProvider::createDataItem( const QString &path, QgsDataItem *parentItem )
|
||||
{
|
||||
if ( path.isEmpty() )
|
||||
{
|
||||
@ -272,13 +277,3 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//QGISEXTERN QgsOWSSourceSelect * selectWidget( QWidget * parent, Qt::WindowFlags fl )
|
||||
QGISEXTERN QDialog *selectWidget( QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode widgetMode )
|
||||
{
|
||||
Q_UNUSED( parent );
|
||||
Q_UNUSED( fl );
|
||||
Q_UNUSED( widgetMode );
|
||||
//return new QgsOWSSourceSelect( parent, fl, widgetMode );
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -16,7 +16,11 @@
|
||||
#define QGSOWSDATAITEMS_H
|
||||
|
||||
#include "qgsdataitem.h"
|
||||
#include "qgsdataitemprovider.h"
|
||||
#include "qgsdataprovider.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
#include "qgsgeonodeconnection.h"
|
||||
|
||||
class QgsOWSConnectionItem : public QgsDataCollectionItem
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -63,4 +67,15 @@ class QgsOWSRootItem : public QgsDataCollectionItem
|
||||
#endif
|
||||
};
|
||||
|
||||
//! Provider for ows root data item
|
||||
class QgsOwsDataItemProvider : public QgsDataItemProvider
|
||||
{
|
||||
public:
|
||||
virtual QString name() override { return QStringLiteral( "OWS" ); }
|
||||
|
||||
virtual int capabilities() override { return QgsDataProvider::Net; }
|
||||
|
||||
virtual QgsDataItem *createDataItem( const QString &path, QgsDataItem *parentItem ) override;
|
||||
};
|
||||
|
||||
#endif // QGSOWSDATAITEMS_H
|
||||
|
@ -50,6 +50,7 @@ INCLUDE_DIRECTORIES (
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/symbology # needed by qgsvectorfilewriter.h
|
||||
${CMAKE_SOURCE_DIR}/src/core/geonode
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/gui
|
||||
${CMAKE_SOURCE_DIR}/src/gui/auth
|
||||
|
@ -12,6 +12,7 @@
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include "qgsdataitemprovider.h"
|
||||
#include "qgsdataprovider.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgswfsconstants.h"
|
||||
@ -20,6 +21,8 @@
|
||||
#include "qgswfsdataitems.h"
|
||||
#include "qgswfsdatasourceuri.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsgeonodeconnection.h"
|
||||
#include "qgsgeonoderequest.h"
|
||||
|
||||
#ifdef HAVE_GUI
|
||||
#include "qgsnewhttpconnection.h"
|
||||
@ -192,6 +195,84 @@ void QgsWfsRootItem::newConnection()
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//////
|
||||
|
||||
|
||||
QgsDataItem *QgsWfsDataItemProvider::createDataItem( const QString &path, QgsDataItem *parentItem )
|
||||
{
|
||||
QgsDebugMsg( "thePath = " + path );
|
||||
if ( path.isEmpty() )
|
||||
{
|
||||
return new QgsWfsRootItem( parentItem, QStringLiteral( "WFS" ), QStringLiteral( "wfs:" ) );
|
||||
}
|
||||
|
||||
// path schema: wfs:/connection name (used by OWS)
|
||||
if ( path.startsWith( QLatin1String( "wfs:/" ) ) )
|
||||
{
|
||||
QString connectionName = path.split( '/' ).last();
|
||||
if ( QgsWfsConnection::connectionList().contains( connectionName ) )
|
||||
{
|
||||
QgsWfsConnection connection( connectionName );
|
||||
return new QgsWfsConnectionItem( parentItem, QStringLiteral( "WFS" ), path, connection.uri().uri() );
|
||||
}
|
||||
}
|
||||
else if ( path.startsWith( QLatin1String( "geonode:/" ) ) )
|
||||
{
|
||||
QString connectionName = path.split( '/' ).last();
|
||||
if ( QgsGeoNodeConnection::connectionList().contains( connectionName ) )
|
||||
{
|
||||
QgsGeoNodeConnection connection( connectionName );
|
||||
|
||||
QString url = connection.uri().param( "url" );
|
||||
QgsGeoNodeRequest geonodeRequest( url, true );
|
||||
|
||||
QgsWFSDataSourceURI sourceUri( geonodeRequest.serviceUrls( QStringLiteral( "WFS" ) )[0] );
|
||||
|
||||
QgsDebugMsg( QString( "WFS full uri: '%1'." ).arg( QString( sourceUri.uri() ) ) );
|
||||
|
||||
return new QgsWfsConnectionItem( parentItem, QStringLiteral( "WFS" ), path, sourceUri.uri() );
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QVector<QgsDataItem *> QgsWfsDataItemProvider::createDataItems( const QString &path, QgsDataItem *parentItem )
|
||||
{
|
||||
QVector<QgsDataItem *> items;
|
||||
if ( path.startsWith( QLatin1String( "geonode:/" ) ) )
|
||||
{
|
||||
QString connectionName = path.split( '/' ).last();
|
||||
if ( QgsGeoNodeConnection::connectionList().contains( connectionName ) )
|
||||
{
|
||||
QgsGeoNodeConnection connection( connectionName );
|
||||
|
||||
QString url = connection.uri().param( "url" );
|
||||
QgsGeoNodeRequest geonodeRequest( url, true );
|
||||
|
||||
QStringList encodedUris( geonodeRequest.serviceUrls( QStringLiteral( "WFS" ) ) );
|
||||
|
||||
if ( !encodedUris.isEmpty() )
|
||||
{
|
||||
Q_FOREACH ( QString encodedUri, encodedUris )
|
||||
{
|
||||
QgsWFSDataSourceURI uri( encodedUri );
|
||||
QgsDebugMsg( QString( "WFS full uri: '%1'." ).arg( QString( uri.uri() ) ) );
|
||||
|
||||
QgsDataItem *item = new QgsWfsConnectionItem( parentItem, QStringLiteral( "WFS" ), path, uri.uri() );
|
||||
if ( item )
|
||||
{
|
||||
items.append( item );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#ifdef HAVE_GUI
|
||||
@ -227,3 +308,9 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QGISEXTERN QList<QgsDataItemProvider *> dataItemProviders()
|
||||
{
|
||||
return QList<QgsDataItemProvider *>()
|
||||
<< new QgsWfsDataItemProvider;
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
#define QGSWFSDATAITEMS_H
|
||||
|
||||
#include "qgsdataitem.h"
|
||||
#include "qgsdataitemprovider.h"
|
||||
#include "qgsdataprovider.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
#include "qgswfscapabilities.h"
|
||||
|
||||
@ -80,4 +82,18 @@ class QgsWfsLayerItem : public QgsLayerItem
|
||||
};
|
||||
|
||||
|
||||
//! Provider for WFS root data item
|
||||
class QgsWfsDataItemProvider : public QgsDataItemProvider
|
||||
{
|
||||
public:
|
||||
virtual QString name() override { return QStringLiteral( "WFS" ); }
|
||||
|
||||
virtual int capabilities() override { return QgsDataProvider::Net; }
|
||||
|
||||
virtual QgsDataItem *createDataItem( const QString &path, QgsDataItem *parentItem ) override;
|
||||
|
||||
virtual QVector<QgsDataItem *> createDataItems( const QString &path, QgsDataItem *parentItem ) override;
|
||||
};
|
||||
|
||||
|
||||
#endif // QGSWFSDATAITEMS_H
|
||||
|
@ -38,6 +38,7 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/geonode
|
||||
${CMAKE_SOURCE_DIR}/src/core/raster
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/gui
|
||||
|
@ -28,6 +28,9 @@
|
||||
#include "qgstilescalewidget.h"
|
||||
#include "qgsxyzconnectiondialog.h"
|
||||
#endif
|
||||
#include "qgsgeonodeconnection.h"
|
||||
#include "qgsgeonoderequest.h"
|
||||
#include "qgssettings.h"
|
||||
|
||||
#include <QInputDialog>
|
||||
|
||||
@ -546,3 +549,89 @@ void QgsXyzLayerItem::deleteConnection()
|
||||
mParent->refreshConnections();
|
||||
}
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
QVector<QgsDataItem *> QgsWmsDataItemProvider::createDataItems( const QString &path, QgsDataItem *parentItem )
|
||||
{
|
||||
QVector<QgsDataItem *> items;
|
||||
if ( path.startsWith( QLatin1String( "geonode:/" ) ) )
|
||||
{
|
||||
QString connectionName = path.split( '/' ).last();
|
||||
if ( QgsGeoNodeConnection::connectionList().contains( connectionName ) )
|
||||
{
|
||||
QgsGeoNodeConnection connection( connectionName );
|
||||
|
||||
QString url = connection.uri().param( "url" );
|
||||
QgsGeoNodeRequest geonodeRequest( url, true );
|
||||
|
||||
QStringList encodedUris( geonodeRequest.serviceUrls( QStringLiteral( "WMS" ) ) );
|
||||
|
||||
if ( !encodedUris.isEmpty() )
|
||||
{
|
||||
Q_FOREACH ( QString encodedUri, encodedUris )
|
||||
{
|
||||
QgsDebugMsg( encodedUri );
|
||||
QgsDataSourceUri uri;
|
||||
QgsSettings settings;
|
||||
QString key( connection.pathGeoNodeConnection() + "/" + connectionName );
|
||||
|
||||
QString dpiMode = settings.value( key + "/wms/dpiMode", "all", QgsSettings::Providers ).toString();
|
||||
uri.setParam( QStringLiteral( "url" ), encodedUri );
|
||||
if ( !dpiMode.isEmpty() )
|
||||
{
|
||||
uri.setParam( QStringLiteral( "dpiMode" ), dpiMode );
|
||||
}
|
||||
|
||||
QgsDebugMsg( QString( "WMS full uri: '%1'." ).arg( QString( uri.encodedUri() ) ) );
|
||||
|
||||
QgsDataItem *item = new QgsWMSConnectionItem( parentItem, QStringLiteral( "WMS" ), path, uri.encodedUri() );
|
||||
if ( item )
|
||||
{
|
||||
items.append( item );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
QVector<QgsDataItem *> QgsXyzTileDataItemProvider::createDataItems( const QString &path, QgsDataItem *parentItem )
|
||||
{
|
||||
QVector<QgsDataItem *> items;
|
||||
if ( path.startsWith( QLatin1String( "geonode:/" ) ) )
|
||||
{
|
||||
QString connectionName = path.split( '/' ).last();
|
||||
if ( QgsGeoNodeConnection::connectionList().contains( connectionName ) )
|
||||
{
|
||||
QgsGeoNodeConnection connection( connectionName );
|
||||
|
||||
QString url = connection.uri().param( "url" );
|
||||
QgsGeoNodeRequest geonodeRequest( url, true );
|
||||
|
||||
QgsStringMap urlData( geonodeRequest.serviceUrlData( QStringLiteral( "XYZ" ) ) );
|
||||
|
||||
if ( !urlData.isEmpty() )
|
||||
{
|
||||
Q_FOREACH ( QString layerName, urlData.keys() )
|
||||
{
|
||||
QgsDebugMsg( urlData[ layerName] );
|
||||
QgsDataSourceUri uri;
|
||||
uri.setParam( QStringLiteral( "type" ), QStringLiteral( "xyz" ) );
|
||||
uri.setParam( QStringLiteral( "url" ), urlData[ layerName ] );
|
||||
|
||||
QgsDataItem *item = new QgsXyzLayerItem( parentItem, layerName, path, uri.encodedUri() );
|
||||
if ( item )
|
||||
{
|
||||
items.append( item );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "qgsdataitemprovider.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
#include "qgswmsprovider.h"
|
||||
#include "qgsgeonodeconnection.h"
|
||||
|
||||
class QgsWmsCapabilitiesDownload;
|
||||
|
||||
@ -122,6 +123,8 @@ class QgsWmsDataItemProvider : public QgsDataItemProvider
|
||||
virtual int capabilities() override { return QgsDataProvider::Net; }
|
||||
|
||||
virtual QgsDataItem *createDataItem( const QString &path, QgsDataItem *parentItem ) override;
|
||||
|
||||
virtual QVector<QgsDataItem *> createDataItems( const QString &path, QgsDataItem *parentItem ) override;
|
||||
};
|
||||
|
||||
|
||||
@ -177,6 +180,8 @@ class QgsXyzTileDataItemProvider : public QgsDataItemProvider
|
||||
return new QgsXyzTileRootItem( parentItem, QStringLiteral( "XYZ Tiles" ), QStringLiteral( "xyz:" ) );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual QVector<QgsDataItem *> createDataItems( const QString &path, QgsDataItem *parentItem ) override;
|
||||
};
|
||||
|
||||
|
||||
|
217
src/ui/qgsgeonodesourceselectbase.ui
Normal file
217
src/ui/qgsgeonodesourceselectbase.ui
Normal file
@ -0,0 +1,217 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsGeonodeSourceSelectBase</class>
|
||||
<widget class="QDialog" name="QgsGeonodeSourceSelectBase">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>592</width>
|
||||
<height>439</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Add Geonode Layer</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="GroupBox1">
|
||||
<property name="title">
|
||||
<string>Geonode connections</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QComboBox" name="cmbConnections"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnConnect">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Connect to selected service</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>C&onnect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnNew">
|
||||
<property name="toolTip">
|
||||
<string>Create a new service connection</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&New</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnEdit">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Edit selected service connection</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Edit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnDelete">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Remove connection to selected service</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>171</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnLoad">
|
||||
<property name="toolTip">
|
||||
<string>Load connections from file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSave">
|
||||
<property name="toolTip">
|
||||
<string>Save connections to file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QTreeView" name="treeView">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbxUseTitleLayerName">
|
||||
<property name="text">
|
||||
<string>Use title for layer name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutFilter">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFilter">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Filter</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineFilter</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineFilter">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Display WFS FeatureTypes containing this word in the title, name or abstract</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>Display WFS FeatureTypes containing this word in the title, name or abstract</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>cmbConnections</tabstop>
|
||||
<tabstop>btnConnect</tabstop>
|
||||
<tabstop>btnNew</tabstop>
|
||||
<tabstop>btnEdit</tabstop>
|
||||
<tabstop>btnDelete</tabstop>
|
||||
<tabstop>btnLoad</tabstop>
|
||||
<tabstop>btnSave</tabstop>
|
||||
<tabstop>lineFilter</tabstop>
|
||||
<tabstop>treeView</tabstop>
|
||||
<tabstop>cbxUseTitleLayerName</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
355
src/ui/qgsnewgeonodeconnectionbase.ui
Normal file
355
src/ui/qgsnewgeonodeconnectionbase.ui
Normal file
@ -0,0 +1,355 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsNewGeoNodeConnectionBase</class>
|
||||
<widget class="QDialog" name="QgsNewGeoNodeConnectionBase">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>448</width>
|
||||
<height>475</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Create a new Geonode connection</string>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="mGroupBox">
|
||||
<property name="title">
|
||||
<string>Connection details</string>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
<item row="8" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>WFS Options</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblVersion">
|
||||
<property name="text">
|
||||
<string>Version</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cmbVersion">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Select protocol version</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblMaxNumFeatures">
|
||||
<property name="text">
|
||||
<string>Max. number of features</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="txtMaxNumFeatures">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enter a number to limit the maximum number of features retrieved in a single GetFeature request. If let to empty, server default will apply.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnConnect">
|
||||
<property name="text">
|
||||
<string>&Test Connection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QCheckBox" name="cbxWfsIgnoreAxisOrientation">
|
||||
<property name="text">
|
||||
<string>Ignore axis orientation (WFS 1.1/WFS 2.0)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="QTabWidget" name="tabAuth">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Authentication</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>If the service requires basic authentication, enter a user name and optional password</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>&User name</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtUserName</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="txtUserName"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Password</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtPassword</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QgsPasswordLineEdit" name="txtPassword">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<widget class="QCheckBox" name="cbxWmsIgnoreAxisOrientation">
|
||||
<property name="text">
|
||||
<string>Ignore axis orientation (WMS 1.3/WMTS)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0">
|
||||
<widget class="QCheckBox" name="cbxWmsInvertAxisOrientation">
|
||||
<property name="text">
|
||||
<string>Invert axis orientation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>WMS Options</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="txtReferer"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblReferer">
|
||||
<property name="text">
|
||||
<string>Referer</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtReferer</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cmbDpiMode"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblDpiMode">
|
||||
<property name="text">
|
||||
<string>DPI-Mode</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>cmbDpiMode</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QCheckBox" name="cbxWfsInvertAxisOrientation">
|
||||
<property name="text">
|
||||
<string>Invert axis orientation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="0">
|
||||
<widget class="QCheckBox" name="cbxIgnoreGetFeatureInfoURI">
|
||||
<property name="text">
|
||||
<string>Ignore GetFeatureInfo URI reported in capabilities</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="TextLabel1_2">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtName</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="txtName">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Name of the new connection</string>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="TextLabel1">
|
||||
<property name="text">
|
||||
<string>URL</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtUrl</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="txtUrl">
|
||||
<property name="toolTip">
|
||||
<string>HTTP address of the Web Map Server</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<widget class="QCheckBox" name="cbxIgnoreGetMapURI">
|
||||
<property name="text">
|
||||
<string>Ignore GetMap/GetTile URI reported in capabilities</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="0">
|
||||
<widget class="QCheckBox" name="cbxSmoothPixmapTransform">
|
||||
<property name="text">
|
||||
<string>Smooth pixmap transform</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsPasswordLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>qgspasswordlineedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>tabAuth</tabstop>
|
||||
<tabstop>txtUserName</tabstop>
|
||||
<tabstop>txtPassword</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>QgsNewGeoNodeConnectionBase</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>421</x>
|
||||
<y>453</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>430</x>
|
||||
<y>98</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>QgsNewGeoNodeConnectionBase</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>330</x>
|
||||
<y>453</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>426</x>
|
||||
<y>38</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -229,7 +229,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="liblVersion">
|
||||
<widget class="QLabel" name="lblVersion">
|
||||
<property name="text">
|
||||
<string>Version</string>
|
||||
</property>
|
||||
|
@ -14,6 +14,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/layout
|
||||
${CMAKE_SOURCE_DIR}/src/core/geonode
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/core/effects
|
||||
${CMAKE_SOURCE_DIR}/src/core/layertree
|
||||
@ -118,6 +119,7 @@ SET(TESTS
|
||||
testqgsgeometryimport.cpp
|
||||
testqgsgeometry.cpp
|
||||
testqgsgeometryutils.cpp
|
||||
testqgsgeonodeconnection.cpp
|
||||
testqgsgml.cpp
|
||||
testqgsgradients.cpp
|
||||
testqgsgraduatedsymbolrenderer.cpp
|
||||
|
126
tests/src/core/testqgsgeonodeconnection.cpp
Normal file
126
tests/src/core/testqgsgeonodeconnection.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
/***************************************************************************
|
||||
testqgsgeonodeconnection.cpp
|
||||
--------------------------------------
|
||||
Date : Saturday, 25 March 2017
|
||||
Copyright: (C) 2017
|
||||
Email: ismail@kartoza.com
|
||||
***************************************************************************
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "qgstest.h"
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <QtTest/QSignalSpy>
|
||||
#include <QString>
|
||||
#include <QMultiMap>
|
||||
#include <iostream>
|
||||
|
||||
//#include "qgis_core.h"
|
||||
#include "qgsgeonodeconnection.h"
|
||||
#include "qgssettings.h"
|
||||
|
||||
/** \ingroup UnitTests
|
||||
* This is a unit test for the QgsGeoConnection class.
|
||||
*/
|
||||
|
||||
class TestQgsGeoNodeConnection: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
// will be called before the first testfunction is executed.
|
||||
void initTestCase();
|
||||
// will be called after the last testfunction was executed.
|
||||
void cleanupTestCase()
|
||||
{
|
||||
QgsGeoNodeConnection::deleteConnection( mGeoNodeConnectionName );
|
||||
QgsGeoNodeConnection::deleteConnection( mDemoGeoNodeName );
|
||||
QgsGeoNodeConnection::deleteConnection( mKartozaGeoNodeQGISServerName );
|
||||
}
|
||||
// will be called before each testfunction is executed.
|
||||
void init() {}
|
||||
// will be called after every testfunction.
|
||||
void cleanup() {}
|
||||
|
||||
// Check if we can create geonode connection from database.
|
||||
void testCreation();
|
||||
|
||||
private:
|
||||
QString mGeoNodeConnectionName;
|
||||
QString mGeoNodeConnectionURL;
|
||||
|
||||
QString mDemoGeoNodeName;
|
||||
QString mDemoGeoNodeURL;
|
||||
|
||||
QString mKartozaGeoNodeQGISServerName;
|
||||
QString mKartozaGeoNodeQGISServerURL;
|
||||
|
||||
QString mKartozaGeoNodeGeoServerName;
|
||||
QString mKartozaGeoNodeGeoServerURL;
|
||||
|
||||
bool mSkipRemoteTest;
|
||||
};
|
||||
|
||||
// Runs before all unit tests
|
||||
void TestQgsGeoNodeConnection::initTestCase()
|
||||
{
|
||||
std::cout << "CTEST_FULL_OUTPUT" << std::endl;
|
||||
mGeoNodeConnectionName = QStringLiteral( "ThisIsAGeoNodeConnection" );
|
||||
mGeoNodeConnectionURL = QStringLiteral( "www.thisisageonodeurl.com" );
|
||||
mDemoGeoNodeName = QStringLiteral( "Demo GeoNode" );
|
||||
mDemoGeoNodeURL = QStringLiteral( "demo.geonode.org" );
|
||||
mKartozaGeoNodeQGISServerName = QStringLiteral( "Staging Kartoza GeoNode QGIS Server" );
|
||||
mKartozaGeoNodeQGISServerURL = QStringLiteral( "staging.geonode.kartoza.com" );
|
||||
mKartozaGeoNodeGeoServerName = QStringLiteral( "Staging Kartoza GeoNode GeoServer" );
|
||||
mKartozaGeoNodeGeoServerURL = QStringLiteral( "staginggs.geonode.kartoza.com" );
|
||||
|
||||
// Change it to skip remote testing
|
||||
mSkipRemoteTest = true;
|
||||
|
||||
// Add Demo GeoNode Connection
|
||||
QgsSettings settings;
|
||||
|
||||
// Testing real server, demo.geonode.org. Need to be changed later.
|
||||
settings.setValue( QgsGeoNodeConnection::pathGeoNodeConnection() + QStringLiteral( "/%1/url" ).arg( mDemoGeoNodeName ), mDemoGeoNodeURL, QgsSettings::Providers );
|
||||
// Testing real server, staging.geonode.kartoza.com. Need to be changed later.
|
||||
settings.setValue( QgsGeoNodeConnection::pathGeoNodeConnection() + QStringLiteral( "/%1/url" ).arg( mKartozaGeoNodeQGISServerName ), mKartozaGeoNodeQGISServerURL, QgsSettings::Providers );
|
||||
// Testing real server, staginggs.geonode.kartoza.com. Need to be changed later.
|
||||
settings.setValue( QgsGeoNodeConnection::pathGeoNodeConnection() + QStringLiteral( "/%1/url" ).arg( mKartozaGeoNodeGeoServerName ), mKartozaGeoNodeGeoServerURL, QgsSettings::Providers );
|
||||
}
|
||||
|
||||
// Test the creation of geonode connection
|
||||
void TestQgsGeoNodeConnection::testCreation()
|
||||
{
|
||||
if ( mSkipRemoteTest )
|
||||
{
|
||||
QSKIP( "Skip remote test for faster testing" );
|
||||
}
|
||||
|
||||
QStringList connectionList = QgsGeoNodeConnection::connectionList();
|
||||
int numberOfConnection = connectionList.count();
|
||||
// Verify if the demo.geonode.org is created properly
|
||||
QVERIFY( connectionList.contains( mDemoGeoNodeName ) );
|
||||
QVERIFY( !connectionList.contains( mGeoNodeConnectionName ) );
|
||||
|
||||
// Add new GeoNode Connection
|
||||
QgsSettings settings;
|
||||
|
||||
settings.setValue( QgsGeoNodeConnection::pathGeoNodeConnection() + QStringLiteral( "/%1/url" ).arg( mGeoNodeConnectionName ), mGeoNodeConnectionURL, QgsSettings::Providers );
|
||||
|
||||
QStringList newConnectionList = QgsGeoNodeConnection::connectionList();
|
||||
int newNumberOfConnection = newConnectionList.count();
|
||||
|
||||
// Check the number is increased by 1
|
||||
QCOMPARE( numberOfConnection + 1, newNumberOfConnection );
|
||||
|
||||
// Verify if the new connection is created properly
|
||||
QVERIFY( newConnectionList.contains( mGeoNodeConnectionName ) );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsGeoNodeConnection )
|
||||
#include "testqgsgeonodeconnection.moc"
|
Loading…
x
Reference in New Issue
Block a user