From 79e05e727544d030a60dcd7501c512ca8fe0b328 Mon Sep 17 00:00:00 2001 From: doublebyte Date: Mon, 8 Dec 2025 12:40:57 +0000 Subject: [PATCH 01/10] - updated invalid columnspan to colspan attribute --- pygeoapi_config_dialog_base.ui | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pygeoapi_config_dialog_base.ui b/pygeoapi_config_dialog_base.ui index 3cc6bcb..b98a434 100644 --- a/pygeoapi_config_dialog_base.ui +++ b/pygeoapi_config_dialog_base.ui @@ -1767,7 +1767,7 @@ - + @@ -1965,7 +1965,7 @@ - + @@ -2078,7 +2078,7 @@ - + From 985c15537a92e266e6d127ac93002f0176bdc86e Mon Sep 17 00:00:00 2001 From: doublebyte Date: Mon, 8 Dec 2025 13:50:55 +0000 Subject: [PATCH 02/10] - added layout and scrollable area to top level widget --- pygeoapi_config_dialog_base.ui | 5000 ++++++++++++++------------------ 1 file changed, 2100 insertions(+), 2900 deletions(-) diff --git a/pygeoapi_config_dialog_base.ui b/pygeoapi_config_dialog_base.ui index b98a434..7d2856d 100644 --- a/pygeoapi_config_dialog_base.ui +++ b/pygeoapi_config_dialog_base.ui @@ -7,7 +7,7 @@ 0 0 870 - 490 + 947 @@ -17,50 +17,41 @@ icon.pngicon.png - - - - - QDialogButtonBox::Close|QDialogButtonBox::Open|QDialogButtonBox::Save - - - - - - - - Liberation Serif - - - - Brought to you with ❤️ by ByteRoad - - - Qt::MarkdownText - - - - - - - 0 - - - - Server - - - - 50 + + + + + + + true + + + + + 0 + 0 + 834 + 992 + - - - - bind* - - - - + + + + + 0 + + + + Server + + + + 50 + + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -69,41 +60,38 @@ padding: 10px; } - - - - - - - - - - - host* - - - - - - - port* - - - - - - - - - - - - - - - - - + + + bind* + + + + + + + + + host* + + + + + + + port* + + + + + + + + + + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -112,85 +100,72 @@ padding: 10px; } - - - - - - - - - - url* - - - - - - - - - - - - - + + + + + - - - encoding* - - + + + + + url* + + + + + + + - - + - - utf-8 - + + + encoding* + + - - - - - - - - - - - - - mimetype* - - + + + + + utf-8 + + + + + - + - - application/json; charset=UTF-8 - + + + mimetype* + + + + + + + + application/json; charset=UTF-8 + + + - - - - - - - - - - - - - - - map* - - - + + + + + + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -199,40 +174,38 @@ padding: 10px; } - - - - - - - - - attribution* - - - - - - - - - - url* - - - - - - - - - - - - logging* - - - + + + map* + + + + + + + + + attribution* + + + + + + + + + + url* + + + + + + + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -241,137 +214,124 @@ padding: 10px; } - - - - + + + logging* + + - - - level* - - + + + level* + + - - - - - + + + + + - - - - logfile - - + + + logfile + + - - - - - - - - 📂 - - - - - - - - - 50 - 100 - - - - - - - - - + + + + + + + + + 50 + 100 + + - logformat + 📂 + + + + .. - + + + + + + + + logformat + + - - - - - + + + + + - - - - dateformat - - + + + dateformat + + - - - - - + + + + + - - - - rotation - - - false - - + + + false + + + rotation + + - - - - - - Qt::ScrollBarAlwaysOff - - - - 1000 - 22 - - - - QAbstractItemView::NoEditTriggers - - - false - - - - - + + + + + false + + + + 1000 + 22 + + + + Qt::ScrollBarAlwaysOff + + + QAbstractItemView::NoEditTriggers + + + + - - - - - - - - - - - - - - + + + + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -380,144 +340,126 @@ padding: 10px; } - - - - - - - - language - - - - - - - - - - - languages - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 10 - - - - - + + + + + + + + + language + + + + + + + + + + languages + + + + + - + + + + + Qt::Vertical + + + + 20 + 10 + + + + + + - + en-US - + - + en-GB - + - + fr-CA - + - + fr-FR - + - + pt-PT - + - - + - - + - Add + Add - + - - - - - - - - - - - Qt::Vertical - - - - 20 - 10 - - - - - - - - - - - 1000 - 80 - - - + - - - Delete Selected - - + + + + + Qt::Vertical + + + + 20 + 10 + + + + + + + + + 1000 + 80 + + + + + + + + Delete Selected + + + + - - - - - - - - - - - - - - limits - - - + + + + + + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -526,132 +468,125 @@ padding: 10px; } - - - - - - - - default - - - true - - - - - - - 9999 - - - - - - - - - - - on exceed - - - - - - - - - - - - - - - maximum - - - true - - - - - - - 9999 - - - - - - - - + + + limits + + + + + + + + default + + + true + + + + + + + 9999 + + + + + + + + + + + on exceed + + + + + + + + + + + + + + maximum + + + true + + + + + + + 9999 + + + + + + + + + false + - max_distance_x + max_distance_x + + + + - false + false - - - - + + + + - false + false - - - - - - max_distance_y + max_distance_y + + + + - false + false - - - - + + + + - false + false - - - - - - max_distance_units + max_distance_units + + + + - false - - - - - - - false - - - - - - - - - - - - - templates - - - + false + + + + + + + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -660,81 +595,72 @@ padding: 10px; } - - - + + + templates + + - - - path - - + + + path + + - + - - - - 📂 - - - - - - - - - - 50 - 100 - - - + + + + 50 + 100 + + + + 📂 + + + + .. + + - - - - static - - + + + static + + - + - - - 📂 - - - - - - - - - - 50 - 100 - - - + + + + 50 + 100 + + + + 📂 + + + + .. + + - - - - - - - - - - - - + + + + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -743,244 +669,222 @@ padding: 10px; } - - - + + + + + - - - admin - - + + + admin + + - - - - - - + + + + + + - - - - gzip - - + + + gzip + + - - - - - - - + + + + + + - - - - pretty print - - + + + pretty print + + - - - - - - + + + + + + - - - - cors - - + + + cors + + - - - - - - + + + + + + - - - - ogc_schemas_location - - - false - - + + + false + + + ogc_schemas_location + + - - - - - false - - - - + + + + + false + + + + - - - - - - icon - - - false - - - - - - - false - - - - - - - - logo - - - false - - - - - - - false - - - - - - - - locale_dir - - - false - - - - - - - false - - - - - - - - api_rules - - - false - - - - - - - - - - Qt::ScrollBarAlwaysOff - - - - 1000 - 22 - - - - QAbstractItemView::NoEditTriggers - - - false - - - - - - - - - - manager - - - false - - - - - - - - - - Qt::ScrollBarAlwaysOff - - - - 1000 - 22 - - - - QAbstractItemView::NoEditTriggers - - - false - - - - - - - - - - - - - - - - - - - Metadata - - - - - 50 - - - - - - identification* - - - + + + + false + + + icon + + + + + + + false + + + + + + + false + + + logo + + + + + + + false + + + + + + + false + + + locale_dir + + + + + + + false + + + + + + + false + + + api_rules + + + + + + + + + false + + + + 1000 + 22 + + + + Qt::ScrollBarAlwaysOff + + + QAbstractItemView::NoEditTriggers + + + + + + + + + false + + + manager + + + + + + + + + false + + + + 1000 + 22 + + + + Qt::ScrollBarAlwaysOff + + + QAbstractItemView::NoEditTriggers + + + + + + + + + + + + + Metadata + + + + 50 + + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -989,365 +893,324 @@ padding: 10px; } - - - - - - - title* - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - + + + identification* + + + + + + title* + + - - - + + - - - + - - - - en + + + Qt::Vertical - - - - pt + + + 20 + 40 + + + + + + + + + + + + en + + + + + pt + + + + + fr + + + + + + + + Enter title + + + + - - fr - + + + Add + + - + - - - - - Enter title - - - - - - + - - - Add - - + + + + + + 1000 + 200 + + + + + + + + Delete Selected + + + + - + - - - - - - - - - - - 1000 - 200 - - - - - - - - Delete Selected - - - - - - - - - - - - - - description* - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - + + + + description* + + - - - + + - - - + - - - - en + + + Qt::Vertical - - - - pt + + + 20 + 40 + + + + + + + + + + + + en + + + + + pt + + + + + fr + + + + + + + + Enter description + + + + - - fr - + + + Add + + - + - - - - - Enter description - - - - - - + - - - Add - - + + + + + + 1000 + 200 + + + + + + + + Delete Selected + + + + - + - - - - - - - - - - - 1000 - 200 - - - - - - - - Delete Selected - - - - - - - - - - - - - keywords* - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - + + + + keywords* + + - - - + + - - - + - - - - en + + + Qt::Vertical - - - - pt + + + 20 + 40 + + + + + + + + + + + + en + + + + + pt + + + + + fr + + + + + + + + Enter keyword + + + + - - fr - + + + Add + + - + - - - - - Enter keyword - - - - - - + - - - Add - - + + + + + + 1000 + 200 + + + + + + + + Delete Selected + + + + - + - - - - - - - - - - - 1000 - 200 - - - - - - - - Delete Selected - - - - - - - - - - - - - keywords type - - - - - - - - - - - - terms of service - - - - - - - - - - - - url* - - - - - - - - - - - - - - - - - - license* - - - + + + + keywords type + + + + + + + + + + terms of service + + + + + + + + + + url* + + + + + + + + + + + + + + 800 + 150 + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -1356,52 +1219,44 @@ padding: 10px; } - - - - 800 - 150 - - - - - - - - name* - - - - - - - - - - - - url - - - - - - - - - - - - - - - - - - provider* - - - + + + license* + + + + + + name* + + + + + + + + + + url + + + + + + + + + + + + + + 800 + 150 + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -1410,52 +1265,44 @@ padding: 10px; } - - - - 800 - 150 - - - - - - - - name* - - - - - - - - - - - - url - - - - - - - - - - - - - - - - - - contact* - - - + + + provider* + + + + + + name* + + + + + + + + + + url + + + + + + + + + + + + + + 300 + 500 + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -1464,205 +1311,165 @@ padding: 10px; } - - - - 300 - 500 - - - - - - - - name* - - - - - - - - - - - - position - - - - - - - - - - - - address - - - - - - - - - - - - city - - - - - - - - - - - - stateorprovince - - - - - - - - - - - - postalcode - - - - - - - - - - - - country - - - - - - - - - - - - phone - - - - - - - - - - - - fax - - - - - - - - - - - - email - - - - - - - - - - - - url - - - - - - - - - - - - hours - - - - - - - - - - - - instructions - - - - - - - - - - - - role - - - - - - - - - - - - - - - - - - - - - Resources - - - - - - select collection - - - + + + contact* + + + + + + name* + + + + + + + + + + position + + + + + + + + + + address + + + + + + + + + + city + + + + + + + + + + stateorprovince + + + + + + + + + + postalcode + + + + + + + + + + country + + + + + + + + + + phone + + + + + + + + + + fax + + + + + + + + + + email + + + + + + + + + + url + + + + + + + + + + hours + + + + + + + + + + instructions + + + + + + + + + + role + + + + + + + + + + + + + + Resources + + + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -1671,53 +1478,53 @@ padding: 10px; } - - - - - - Search by name - - - - - - - QAbstractItemView::NoEditTriggers - - - - - - - Load - - - - - - - Delete - - - - - - - New - - - - - - - - - - collection details - - - + + + select collection + + + + + + Search by name + + + + + + + QAbstractItemView::NoEditTriggers + + + + + + + Load + + + + + + + Delete + + + + + + + New + + + + + + + + + + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -1726,76 +1533,76 @@ padding: 10px; } - - - - - - title - - - - - - - true - - - - - - - description - - - - - - - true - - - - 0 - 0 - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - - - - - - - - - - - - false - - - collection details - - - - 50 - - - - - - + + + collection details + + + + + + title + + + + + + + true + + + + + + + description + + + + + + + + 0 + 0 + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + + + + + + + false + + + collection details + + + + 50 + + + + + + 400 + 150 + + - + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -1805,62 +1612,44 @@ } - - - 400 - 150 - - - - - - - - alias* - - - - - - - - - - - - type* - - - - - - - - - - - - visibility - - - - - - - + + + + + alias* + + + + + + + + + + type* + + + + + + + + + + visibility + + + + + + - - - - - - - - - title* - + + + + - + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -1870,109 +1659,100 @@ } - - - - - - - - - + + title* + + + + + + + + + Qt::Vertical - - + + - 20 - 40 + 20 + 40 - + - - - - - - - + + + + + + - + - en + en - - + + - pt + pt - - + + - fr + fr - + - - - + + - + Enter title - - - - - - - - - - Add - + - + - - - - - - - - - - - 1000 - 80 - - - - - - - - Delete Selected - - - + + + + + Add + + + - + + + + + + + + + + 1000 + 80 + + + + + + + + Delete Selected + + + + + - - - - - - - - - - - - description* - + + + + + + - + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -1982,110 +1762,100 @@ } - - - - - - - - - - + + description* + + + + + + + + + Qt::Vertical - - + + - 20 - 40 + 20 + 40 - + - - - - - - - + + + + + + - + - en + en - - + + - pt + pt - - + + - fr + fr - + - - - + + - + Enter description - - - - - - - - - - Add - + - + - - - - - - - - - - - 1000 - 80 - - - - - - - - Delete Selected - - - + + + + + Add + + + - + + + + + + + + + + 1000 + 80 + + + + + + + + Delete Selected + + + + + - - - - - - - - - - - - keywords* - + + + + + + - + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -2095,109 +1865,100 @@ } - - - - - - - - - - + + keywords* + + + + + + + + + Qt::Vertical - - + + - 20 - 40 + 20 + 40 - + - - - - - - - + + + + + + - + - en + en - - + + - pt + pt - - + + - fr + fr - + - - - + + - + Enter keyword - - - - - - - - - - Add - + - + - - - - - - - - - - - 1000 - 80 - - - - - - - - Delete Selected - - - + + + + + Add + + + - + + + + + + + + + + 1000 + 80 + + + + + + + + Delete Selected + + + + + - - + - - - - - - - - links - + + + + - + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -2207,178 +1968,164 @@ } - - - - - - - - - + + links + + + + + + + + + Qt::Vertical - - + + - 20 - 40 + 20 + 40 - + - - - - - - - - - - - Type - - - - - - - text/csv - - - - - - - - Relations - - - - - - - canonical - - - - - - - - URL - - - - - - - - - - - - - - - Title - - - - - - - (optional) - - - - - - - - Language - - - - - - - (optional) e.g. 'en-US' - - - - - - - - Length - - - - - - - (optional) content size - - - - - - - - - - - - Add - + + + + + + + + + Type + - - - - - - - - - - - - - 200 - 0 - - - - - 250 - 300 - - + + + + + text/csv + - - - - - Delete Selected - + + + + + Relations + - + + + + + canonical + + + + + + + URL + + + + + + + + + + + + + + Title + + + + + + + (optional) + + + + + + + Language + + + + + + + (optional) e.g. 'en-US' + + + + + + + Length + + + + + + + (optional) content size + + + + + + + + + Add + + + - + + + + + + + + + + 200 + 0 + + + + + 250 + 300 + + + + + + + + Delete Selected + + + + + - - - - - - - - - - providers* - + + + + + + - + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -2388,132 +2135,112 @@ } - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - - - - - Add - - - - - - - - - - - - - - - - 200 - 300 - - - - - - - - - - - Edit Selected - - - - - - - Delete Selected - - - - - - + + providers* + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + - - + + + + + Add + + + + + - - - - - - - - - - Read-only - - - - - - - - - 1000 - 40 - - - - QAbstractItemView::NoEditTriggers - - - - + + + + + + + + 200 + 300 + + + + + + + + + + Edit Selected + + + + + + + Delete Selected + + + - - - - - - - - - - - - - - - spatial extents* - + + + + + + + + + + + Read-only + + + + + + + + 1000 + 40 + + + + QAbstractItemView::NoEditTriggers + + + + + + + + + + - + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -2523,149 +2250,132 @@ } - - - - - - - bbox* - - - - - - - - - - - - - XMin - - - - - - - -180 - - - - - - - - - - - YMin - - - - - - - -90 - - - - - - - - - - - XMax - - - - - - - 180 - - - - - - - - - - - YMax - - - - - - - 90 - - - - - - + + spatial extents* + + + + + + bbox* + + + + + + + + + + + XMin + + + + + + + -180 + + + - - - - - - crs - - - - - - - - - + + + + + + + YMin + - - - - - - - CRS84 - - - - - - - Validate - - - - - + + + + + -90 + + + + + + + + + + + XMax + + + + + + + 180 + + + + + + + + + + + YMax + + + + + + + 90 + + + + + - - - - + + + + + crs + + + + + + + + + + + + + + CRS84 + + + + + + + Validate + + + + + + + - - - - - - - - - - - temporal extents - + + + + - + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -2675,61 +2385,58 @@ } - - - - - - begin - - - - - - - 1900-10-30T18:25:00Z - - - - - - - end - - - - - - - 1900-10-30T18:25:00Z - - - - - - - trs - - - - - - - - - - - - - - - - - + temporal extents + + + + + + begin + + + + + + + 1900-10-30T18:25:00Z + + + + + + + end + + + + + + + 1900-10-30T18:25:00Z + + + + + + + trs + + + + + + + + + + + + + false - + QGroupBox { background-color: rgba(240, 240, 240, 1); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -2739,51 +2446,43 @@ } - - false - - - - - - - - linked-data - - - false - - - - - - - Qt::ScrollBarAlwaysOff - - - - 1000 - 25 - - - - QAbstractItemView::NoEditTriggers - - - - - - - - - - - - + + + + + + false + + + linked-data + + + + + + + + 1000 + 25 + + + + Qt::ScrollBarAlwaysOff + + + QAbstractItemView::NoEditTriggers + + + + + + + + - + QGroupBox { background-color: rgba(240, 240, 240, 0); /* change to your desired color */ border: 0px solid #ffffffff; /* optional: border styling */ @@ -2793,565 +2492,66 @@ } - - + + + + + - + Save changes - + - - + + - + Cancel changes - + - - - - - - + + + + + + + + + + + + + + + Liberation Serif + + + + Brought to you with ❤️ by ByteRoad + + + Qt::MarkdownText + + + + + + + QDialogButtonBox::Close|QDialogButtonBox::Open|QDialogButtonBox::Save + - - - - - - + + + + + + - - - buttonBox - clicked(QAbstractButton*) - PygeoapiConfigDialogBase - on_button_clicked() - - - 271 - 375 - - - 271 - 198 - - - - - pushButtonBrowse - clicked() - PygeoapiConfigDialogBase - open_logfile_dialog() - - - 822 - 406 - - - 434 - 244 - - - - - - pushButtonBrowseTemplatesPath - clicked() - PygeoapiConfigDialogBase - open_templates_path_dialog() - - - 822 - 406 - - - 434 - 244 - - - - - - addServerLangsButton - clicked() - PygeoapiConfigDialogBase - add_server_lang() - - - 822 - 406 - - - 434 - 244 - - - - - - deleteServerLangsButton - clicked() - PygeoapiConfigDialogBase - delete_server_lang() - - - 822 - 406 - - - 434 - 244 - - - - - - addMetadataIdTitleButton - clicked() - PygeoapiConfigDialogBase - add_metadata_id_title() - - - 822 - 406 - - - 434 - 244 - - - - - - addMetadataIdDescriptionButton - clicked() - PygeoapiConfigDialogBase - add_metadata_id_description() - - - 822 - 406 - - - 434 - 244 - - - - - - addMetadataKeywordButton - clicked() - PygeoapiConfigDialogBase - add_metadata_keyword() - - - 822 - 406 - - - 434 - 244 - - - - - - - addResTitleButton - clicked() - PygeoapiConfigDialogBase - add_res_title() - - - 822 - 406 - - - 434 - 244 - - - - - - - addResDescriptionButton - clicked() - PygeoapiConfigDialogBase - add_res_description() - - - 822 - 406 - - - 434 - 244 - - - - - - - addResKeywordsButton - clicked() - PygeoapiConfigDialogBase - add_res_keyword() - - - 822 - 406 - - - 434 - 244 - - - - - - addResLinksButton - clicked() - PygeoapiConfigDialogBase - add_res_link() - - - 822 - 406 - - - 434 - 244 - - - - - - addResProviderButton - clicked() - PygeoapiConfigDialogBase - try_add_res_provider() - - - 822 - 406 - - - 434 - 244 - - - - - - deleteMetadataIdTitleButton - clicked() - PygeoapiConfigDialogBase - delete_metadata_id_title() - - - 822 - 406 - - - 434 - 244 - - - - - - deleteMetadataIdDescriptionButton - clicked() - PygeoapiConfigDialogBase - delete_metadata_id_description() - - - 822 - 406 - - - 434 - 244 - - - - - - deleteResTitleButton - clicked() - PygeoapiConfigDialogBase - delete_res_title() - - - 822 - 406 - - - 434 - 244 - - - - - - deleteResDescriptionButton - clicked() - PygeoapiConfigDialogBase - delete_res_description() - - - 822 - 406 - - - 434 - 244 - - - - - - deleteResKeywordsButton - clicked() - PygeoapiConfigDialogBase - delete_res_keyword() - - - 822 - 406 - - - 434 - 244 - - - - - - deleteResLinksButton - clicked() - PygeoapiConfigDialogBase - delete_res_link() - - - 822 - 406 - - - 434 - 244 - - - - - - editResProviderButton - clicked() - PygeoapiConfigDialogBase - edit_res_provider() - - - 822 - 406 - - - 434 - 244 - - - - - - deleteResProviderButton - clicked() - PygeoapiConfigDialogBase - delete_res_provider() - - - 822 - 406 - - - 434 - 244 - - - - - - - deleteMetadataKeywordButton - clicked() - PygeoapiConfigDialogBase - delete_metadata_keyword() - - - 822 - 406 - - - 434 - 244 - - - - - - pushButtonBrowseTemplatesStatic - clicked() - PygeoapiConfigDialogBase - open_templates_static_dialog() - - - 822 - 406 - - - 434 - 244 - - - - - - lineEditCollection - textChanged(QString) - PygeoapiConfigDialogBase - filterResources(QString) - - - 434 - 91 - - - 434 - 244 - - - - - listViewCollection - clicked(QModelIndex) - PygeoapiConfigDialogBase - preview_resource(QModelIndex) - - - 434 - 160 - - - 434 - 244 - - - - - pushDeleteCollection - clicked() - PygeoapiConfigDialogBase - delete_resource() - - - 434 - 160 - - - 434 - 244 - - - - - pushNewCollection - clicked() - PygeoapiConfigDialogBase - new_resource() - - - 434 - 160 - - - 434 - 244 - - - - - pushLoadCollection - clicked() - PygeoapiConfigDialogBase - load_resource() - - - 434 - 160 - - - 434 - 244 - - - - - - pushSaveAndPreviewResource - clicked() - PygeoapiConfigDialogBase - save_resource_edit_and_preview() - - - 434 - 160 - - - 434 - 244 - - - - - pushExitResourceEdit - clicked() - PygeoapiConfigDialogBase - exit_resource_edit() - - - 434 - 160 - - - 434 - 244 - - - - - - validateResExtentsCrsButton - clicked() - PygeoapiConfigDialogBase - validate_res_extents_crs() - - - 434 - 160 - - - 434 - 244 - - - - - + open_logfile_dialog() From a12de62f46bd6f3d3e20d2e7d55d49e128cc3ade Mon Sep 17 00:00:00 2001 From: doublebyte Date: Mon, 8 Dec 2025 14:54:09 +0000 Subject: [PATCH 03/10] - put back connections --- pygeoapi_config_dialog_base.ui | 527 ++++++++++++++++++++++++++++++++- 1 file changed, 526 insertions(+), 1 deletion(-) diff --git a/pygeoapi_config_dialog_base.ui b/pygeoapi_config_dialog_base.ui index 7d2856d..111ea1e 100644 --- a/pygeoapi_config_dialog_base.ui +++ b/pygeoapi_config_dialog_base.ui @@ -2551,7 +2551,532 @@ - + + + buttonBox + clicked(QAbstractButton*) + PygeoapiConfigDialogBase + on_button_clicked() + + + 271 + 375 + + + 271 + 198 + + + + + pushButtonBrowse + clicked() + PygeoapiConfigDialogBase + open_logfile_dialog() + + + 822 + 406 + + + 434 + 244 + + + + + + pushButtonBrowseTemplatesPath + clicked() + PygeoapiConfigDialogBase + open_templates_path_dialog() + + + 822 + 406 + + + 434 + 244 + + + + + + addServerLangsButton + clicked() + PygeoapiConfigDialogBase + add_server_lang() + + + 822 + 406 + + + 434 + 244 + + + + + + deleteServerLangsButton + clicked() + PygeoapiConfigDialogBase + delete_server_lang() + + + 822 + 406 + + + 434 + 244 + + + + + + addMetadataIdTitleButton + clicked() + PygeoapiConfigDialogBase + add_metadata_id_title() + + + 822 + 406 + + + 434 + 244 + + + + + + addMetadataIdDescriptionButton + clicked() + PygeoapiConfigDialogBase + add_metadata_id_description() + + + 822 + 406 + + + 434 + 244 + + + + + + addMetadataKeywordButton + clicked() + PygeoapiConfigDialogBase + add_metadata_keyword() + + + 822 + 406 + + + 434 + 244 + + + + + + + addResTitleButton + clicked() + PygeoapiConfigDialogBase + add_res_title() + + + 822 + 406 + + + 434 + 244 + + + + + + + addResDescriptionButton + clicked() + PygeoapiConfigDialogBase + add_res_description() + + + 822 + 406 + + + 434 + 244 + + + + + + + addResKeywordsButton + clicked() + PygeoapiConfigDialogBase + add_res_keyword() + + + 822 + 406 + + + 434 + 244 + + + + + + addResLinksButton + clicked() + PygeoapiConfigDialogBase + add_res_link() + + + 822 + 406 + + + 434 + 244 + + + + + + addResProviderButton + clicked() + PygeoapiConfigDialogBase + try_add_res_provider() + + + 822 + 406 + + + 434 + 244 + + + + + + deleteMetadataIdTitleButton + clicked() + PygeoapiConfigDialogBase + delete_metadata_id_title() + + + 822 + 406 + + + 434 + 244 + + + + + + deleteMetadataIdDescriptionButton + clicked() + PygeoapiConfigDialogBase + delete_metadata_id_description() + + + 822 + 406 + + + 434 + 244 + + + + + + deleteResTitleButton + clicked() + PygeoapiConfigDialogBase + delete_res_title() + + + 822 + 406 + + + 434 + 244 + + + + + + deleteResDescriptionButton + clicked() + PygeoapiConfigDialogBase + delete_res_description() + + + 822 + 406 + + + 434 + 244 + + + + + + deleteResKeywordsButton + clicked() + PygeoapiConfigDialogBase + delete_res_keyword() + + + 822 + 406 + + + 434 + 244 + + + + + + deleteResLinksButton + clicked() + PygeoapiConfigDialogBase + delete_res_link() + + + 822 + 406 + + + 434 + 244 + + + + + + editResProviderButton + clicked() + PygeoapiConfigDialogBase + edit_res_provider() + + + 822 + 406 + + + 434 + 244 + + + + + + deleteResProviderButton + clicked() + PygeoapiConfigDialogBase + delete_res_provider() + + + 822 + 406 + + + 434 + 244 + + + + + + + deleteMetadataKeywordButton + clicked() + PygeoapiConfigDialogBase + delete_metadata_keyword() + + + 822 + 406 + + + 434 + 244 + + + + + + pushButtonBrowseTemplatesStatic + clicked() + PygeoapiConfigDialogBase + open_templates_static_dialog() + + + 822 + 406 + + + 434 + 244 + + + + + + lineEditCollection + textChanged(QString) + PygeoapiConfigDialogBase + filterResources(QString) + + + 434 + 91 + + + 434 + 244 + + + + + listViewCollection + clicked(QModelIndex) + PygeoapiConfigDialogBase + preview_resource(QModelIndex) + + + 434 + 160 + + + 434 + 244 + + + + + pushDeleteCollection + clicked() + PygeoapiConfigDialogBase + delete_resource() + + + 434 + 160 + + + 434 + 244 + + + + + pushNewCollection + clicked() + PygeoapiConfigDialogBase + new_resource() + + + 434 + 160 + + + 434 + 244 + + + + + pushLoadCollection + clicked() + PygeoapiConfigDialogBase + load_resource() + + + 434 + 160 + + + 434 + 244 + + + + + + pushSaveAndPreviewResource + clicked() + PygeoapiConfigDialogBase + save_resource_edit_and_preview() + + + 434 + 160 + + + 434 + 244 + + + + + pushExitResourceEdit + clicked() + PygeoapiConfigDialogBase + exit_resource_edit() + + + 434 + 160 + + + 434 + 244 + + + + + + validateResExtentsCrsButton + clicked() + PygeoapiConfigDialogBase + validate_res_extents_crs() + + + 434 + 160 + + + 434 + 244 + + + + open_logfile_dialog() From a69ed6f46a539da1656d322d332a8d86d544eca6 Mon Sep 17 00:00:00 2001 From: doublebyte Date: Mon, 8 Dec 2025 15:38:49 +0000 Subject: [PATCH 04/10] - introduced server radio --- pygeoapi_config_dialog.py | 37 ++++++++++---- pygeoapi_config_dialog_base.ui | 90 ++++++++++++++-------------------- 2 files changed, 63 insertions(+), 64 deletions(-) diff --git a/pygeoapi_config_dialog.py b/pygeoapi_config_dialog.py index bf975bf..6daa98e 100644 --- a/pygeoapi_config_dialog.py +++ b/pygeoapi_config_dialog.py @@ -144,19 +144,36 @@ def on_button_clicked(self, button): # You can also check the standard button type if button == self.buttonBox.button(QDialogButtonBox.Save): if self._set_validate_ui_data()[0]: - file_path, _ = QFileDialog.getSaveFileName( - self, "Save File", "", "YAML Files (*.yml);;All Files (*)" - ) - # before saving, show diff with "Procced" and "Cancel" options - if file_path and self._diff_original_and_current_data(): - self.save_to_file(file_path) + if self.serverRadio.isChecked(): + QMessageBox.warning( + self, + "Warning", + "Please switch to 'Server' tab before opening a configuration file.", + ) + return + else: + file_path, _ = QFileDialog.getSaveFileName( + self, "Save File", "", "YAML Files (*.yml);;All Files (*)" + ) + + # before saving, show diff with "Procced" and "Cancel" options + if file_path and self._diff_original_and_current_data(): + self.save_to_file(file_path) elif button == self.buttonBox.button(QDialogButtonBox.Open): - file_name, _ = QFileDialog.getOpenFileName( - self, "Open File", "", "YAML Files (*.yml);;All Files (*)" - ) - self.open_file(file_name) + if self.serverRadio.isChecked(): + QMessageBox.warning( + self, + "Warning", + "Please switch to 'Server' tab before opening a configuration file.", + ) + return + else: + file_name, _ = QFileDialog.getOpenFileName( + self, "Open File", "", "YAML Files (*.yml);;All Files (*)" + ) + self.open_file(file_name) elif button == self.buttonBox.button(QDialogButtonBox.Close): self.reject() diff --git a/pygeoapi_config_dialog_base.ui b/pygeoapi_config_dialog_base.ui index 111ea1e..ddbfd48 100644 --- a/pygeoapi_config_dialog_base.ui +++ b/pygeoapi_config_dialog_base.ui @@ -29,9 +29,9 @@ 0 - 0 + -71 834 - 992 + 1021 @@ -2520,6 +2520,23 @@ + + + + Qt::RightToLeft + + + Server Connection + + + + + + + QDialogButtonBox::Close|QDialogButtonBox::Open|QDialogButtonBox::Save + + + @@ -2535,13 +2552,6 @@ - - - - QDialogButtonBox::Close|QDialogButtonBox::Open|QDialogButtonBox::Save - - - @@ -2551,23 +2561,7 @@ - - - buttonBox - clicked(QAbstractButton*) - PygeoapiConfigDialogBase - on_button_clicked() - - - 271 - 375 - - - 271 - 198 - - - + pushButtonBrowse clicked() @@ -2584,7 +2578,6 @@ - pushButtonBrowseTemplatesPath clicked() @@ -2601,7 +2594,6 @@ - addServerLangsButton clicked() @@ -2618,7 +2610,6 @@ - deleteServerLangsButton clicked() @@ -2635,7 +2626,6 @@ - addMetadataIdTitleButton clicked() @@ -2652,7 +2642,6 @@ - addMetadataIdDescriptionButton clicked() @@ -2669,7 +2658,6 @@ - addMetadataKeywordButton clicked() @@ -2686,8 +2674,6 @@ - - addResTitleButton clicked() @@ -2704,8 +2690,6 @@ - - addResDescriptionButton clicked() @@ -2722,8 +2706,6 @@ - - addResKeywordsButton clicked() @@ -2740,7 +2722,6 @@ - addResLinksButton clicked() @@ -2757,7 +2738,6 @@ - addResProviderButton clicked() @@ -2774,7 +2754,6 @@ - deleteMetadataIdTitleButton clicked() @@ -2791,7 +2770,6 @@ - deleteMetadataIdDescriptionButton clicked() @@ -2808,7 +2786,6 @@ - deleteResTitleButton clicked() @@ -2825,7 +2802,6 @@ - deleteResDescriptionButton clicked() @@ -2842,7 +2818,6 @@ - deleteResKeywordsButton clicked() @@ -2859,7 +2834,6 @@ - deleteResLinksButton clicked() @@ -2876,7 +2850,6 @@ - editResProviderButton clicked() @@ -2893,7 +2866,6 @@ - deleteResProviderButton clicked() @@ -2910,8 +2882,6 @@ - - deleteMetadataKeywordButton clicked() @@ -2928,7 +2898,6 @@ - pushButtonBrowseTemplatesStatic clicked() @@ -2945,7 +2914,6 @@ - lineEditCollection textChanged(QString) @@ -3026,7 +2994,6 @@ - pushSaveAndPreviewResource clicked() @@ -3059,7 +3026,6 @@ - validateResExtentsCrsButton clicked() @@ -3076,6 +3042,22 @@ + + buttonBox + clicked(QAbstractButton*) + PygeoapiConfigDialogBase + on_button_clicked() + + + 271 + 375 + + + 271 + 198 + + + open_logfile_dialog() From 49b80e57d211bafdd8e2d4f2b1cba3b171fbc22b Mon Sep 17 00:00:00 2001 From: doublebyte Date: Mon, 8 Dec 2025 16:48:13 +0000 Subject: [PATCH 05/10] - added server config dialog --- pygeoapi_config.py | 1 + pygeoapi_config_dialog.py | 64 ++++++++++++---- pygeoapi_config_dialog_base.ui | 3 + server_config_dialog.py | 71 +++++++++++++++++ server_config_dialog.ui | 135 +++++++++++++++++++++++++++++++++ 5 files changed, 261 insertions(+), 13 deletions(-) create mode 100644 server_config_dialog.py create mode 100644 server_config_dialog.ui diff --git a/pygeoapi_config.py b/pygeoapi_config.py index 825d9a9..528cc51 100644 --- a/pygeoapi_config.py +++ b/pygeoapi_config.py @@ -30,6 +30,7 @@ # Import the code for the dialog from .pygeoapi_config_dialog import PygeoapiConfigDialog + import os.path diff --git a/pygeoapi_config_dialog.py b/pygeoapi_config_dialog.py index 6daa98e..7cb031a 100644 --- a/pygeoapi_config_dialog.py +++ b/pygeoapi_config_dialog.py @@ -31,6 +31,7 @@ from .ui_widgets.utils import get_url_status +from .server_config_dialog import Ui_serverDialog from .models.top_level.providers.records import ProviderTypes from .ui_widgets.providers.NewProviderWindow import NewProviderWindow @@ -72,13 +73,34 @@ except: pass +class ServerConfigDialog(QDialog, Ui_serverDialog): + """ + Logic for the Server Configuration Dialog. + Inherits from QDialog (functionality) and Ui_serverDialog (layout). + """ + def __init__(self, parent=None): + super().__init__(parent) + self.setupUi(self) # Builds the UI defined in Designer + + # Optional: Set default values based on current config if needed + # self.ServerHostlineEdit.setText("localhost") + + def get_server_data(self): + """ + Retrieve the server configuration data entered by the user. + :return: A dictionary with 'host' and 'port' keys. + """ + host = self.ServerHostlineEdit.text() + port = self.ServerSpinBox.value() + return {'host': host, 'port': port} + # This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer FORM_CLASS, _ = uic.loadUiType( os.path.join(os.path.dirname(__file__), "pygeoapi_config_dialog_base.ui") ) - + class PygeoapiConfigDialog(QtWidgets.QDialog, FORM_CLASS): config_data: ConfigData @@ -146,12 +168,7 @@ def on_button_clicked(self, button): if self._set_validate_ui_data()[0]: if self.serverRadio.isChecked(): - QMessageBox.warning( - self, - "Warning", - "Please switch to 'Server' tab before opening a configuration file.", - ) - return + self.server_config(save=True) else: file_path, _ = QFileDialog.getSaveFileName( self, "Save File", "", "YAML Files (*.yml);;All Files (*)" @@ -163,12 +180,7 @@ def on_button_clicked(self, button): elif button == self.buttonBox.button(QDialogButtonBox.Open): if self.serverRadio.isChecked(): - QMessageBox.warning( - self, - "Warning", - "Please switch to 'Server' tab before opening a configuration file.", - ) - return + self.server_config(save=False) else: file_name, _ = QFileDialog.getOpenFileName( self, "Open File", "", "YAML Files (*.yml);;All Files (*)" @@ -177,6 +189,32 @@ def on_button_clicked(self, button): elif button == self.buttonBox.button(QDialogButtonBox.Close): self.reject() + return + + def server_config(self, save): + + dialog = ServerConfigDialog(self) + + if dialog.exec_(): + data = dialog.get_server_data() + if save == True: + self.push_to_server(data) + else: + self.pull_from_server(data) + + def push_to_server(self, data): + QMessageBox.warning( + self, + "Warning", + f"Pushing configuration to Host: {data['host']}, Port: {data['port']}", + ) + + def pull_from_server(self, data): + QMessageBox.warning( + self, + "Warning", + f"Pulling configuration from Host: {data['host']}, Port: {data['port']}", + ) def save_to_file(self, file_path): diff --git a/pygeoapi_config_dialog_base.ui b/pygeoapi_config_dialog_base.ui index ddbfd48..012b938 100644 --- a/pygeoapi_config_dialog_base.ui +++ b/pygeoapi_config_dialog_base.ui @@ -2528,6 +2528,9 @@ Server Connection + + + diff --git a/server_config_dialog.py b/server_config_dialog.py new file mode 100644 index 0000000..15151df --- /dev/null +++ b/server_config_dialog.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'server_config_dialog.ui' +# +# Created by: PyQt5 UI code generator 5.15.11 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_serverDialog(object): + def setupUi(self, serverDialog): + serverDialog.setObjectName("serverDialog") + serverDialog.resize(379, 130) + self.verticalLayout = QtWidgets.QVBoxLayout(serverDialog) + self.verticalLayout.setObjectName("verticalLayout") + self.serverHorizontalLayout = QtWidgets.QHBoxLayout() + self.serverHorizontalLayout.setObjectName("serverHorizontalLayout") + self.labelServerHost = QtWidgets.QLabel(serverDialog) + self.labelServerHost.setObjectName("labelServerHost") + self.serverHorizontalLayout.addWidget(self.labelServerHost) + self.ServerHostlineEdit = QtWidgets.QLineEdit(serverDialog) + self.ServerHostlineEdit.setObjectName("ServerHostlineEdit") + self.serverHorizontalLayout.addWidget(self.ServerHostlineEdit) + self.verticalLayout.addLayout(self.serverHorizontalLayout) + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.serverPortLabel = QtWidgets.QLabel(serverDialog) + self.serverPortLabel.setObjectName("serverPortLabel") + self.horizontalLayout.addWidget(self.serverPortLabel) + self.ServerSpinBox = QtWidgets.QSpinBox(serverDialog) + self.ServerSpinBox.setProperty("showGroupSeparator", True) + self.ServerSpinBox.setMaximum(100000000) + self.ServerSpinBox.setProperty("value", 5000) + self.ServerSpinBox.setObjectName("ServerSpinBox") + self.horizontalLayout.addWidget(self.ServerSpinBox) + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout.addItem(spacerItem) + self.verticalLayout.addLayout(self.horizontalLayout) + spacerItem1 = QtWidgets.QSpacerItem(20, 1, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.MinimumExpanding) + self.verticalLayout.addItem(spacerItem1) + self.serverButtonBox = QtWidgets.QDialogButtonBox(serverDialog) + self.serverButtonBox.setOrientation(QtCore.Qt.Horizontal) + self.serverButtonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) + self.serverButtonBox.setObjectName("serverButtonBox") + self.verticalLayout.addWidget(self.serverButtonBox) + + self.retranslateUi(serverDialog) + self.serverButtonBox.accepted.connect(serverDialog.accept) # type: ignore + self.serverButtonBox.rejected.connect(serverDialog.reject) # type: ignore + QtCore.QMetaObject.connectSlotsByName(serverDialog) + + def retranslateUi(self, serverDialog): + _translate = QtCore.QCoreApplication.translate + serverDialog.setWindowTitle(_translate("serverDialog", "Dialog")) + self.labelServerHost.setText(_translate("serverDialog", "Host")) + self.ServerHostlineEdit.setText(_translate("serverDialog", "localhost")) + self.serverPortLabel.setText(_translate("serverDialog", "Port")) + + +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + serverDialog = QtWidgets.QDialog() + ui = Ui_serverDialog() + ui.setupUi(serverDialog) + serverDialog.show() + sys.exit(app.exec_()) diff --git a/server_config_dialog.ui b/server_config_dialog.ui new file mode 100644 index 0000000..5e52090 --- /dev/null +++ b/server_config_dialog.ui @@ -0,0 +1,135 @@ + + + serverDialog + + + + 0 + 0 + 379 + 130 + + + + Dialog + + + + + + + + Host + + + + + + + localhost + + + + + + + + + + + Port + + + + + + + true + + + 100000000 + + + 5000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 1 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + serverButtonBox + accepted() + serverDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + serverButtonBox + rejected() + serverDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + From fbaf59453821ebf97e3cf47bec08be2428216d92 Mon Sep 17 00:00:00 2001 From: doublebyte Date: Mon, 8 Dec 2025 17:00:40 +0000 Subject: [PATCH 06/10] - added option to specify server protocol --- pygeoapi_config_dialog.py | 15 +++++++------- server_config_dialog.py | 27 +++++++++++++++++++----- server_config_dialog.ui | 43 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/pygeoapi_config_dialog.py b/pygeoapi_config_dialog.py index 7cb031a..a148354 100644 --- a/pygeoapi_config_dialog.py +++ b/pygeoapi_config_dialog.py @@ -92,7 +92,8 @@ def get_server_data(self): """ host = self.ServerHostlineEdit.text() port = self.ServerSpinBox.value() - return {'host': host, 'port': port} + protocol = 'http' if self.radioHttp.isChecked() else 'https' + return {'host': host, 'port': port, 'protocol': protocol} # This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer @@ -203,17 +204,17 @@ def server_config(self, save): self.pull_from_server(data) def push_to_server(self, data): - QMessageBox.warning( + QMessageBox.information( self, - "Warning", - f"Pushing configuration to Host: {data['host']}, Port: {data['port']}", + "Information", + f"Pushing configuration to: {data['protocol']}://{data['host']}:{data['port']}", ) def pull_from_server(self, data): - QMessageBox.warning( + QMessageBox.information( self, - "Warning", - f"Pulling configuration from Host: {data['host']}, Port: {data['port']}", + "Information", + f"Pulling configuration from: {data['protocol']}://{data['host']}:{data['port']}", ) def save_to_file(self, file_path): diff --git a/server_config_dialog.py b/server_config_dialog.py index 15151df..d27ecaa 100644 --- a/server_config_dialog.py +++ b/server_config_dialog.py @@ -14,9 +14,24 @@ class Ui_serverDialog(object): def setupUi(self, serverDialog): serverDialog.setObjectName("serverDialog") - serverDialog.resize(379, 130) + serverDialog.resize(382, 173) self.verticalLayout = QtWidgets.QVBoxLayout(serverDialog) self.verticalLayout.setObjectName("verticalLayout") + self.serverGroupBox = QtWidgets.QGroupBox(serverDialog) + self.serverGroupBox.setTitle("") + self.serverGroupBox.setObjectName("serverGroupBox") + self.gridLayout = QtWidgets.QGridLayout(self.serverGroupBox) + self.gridLayout.setObjectName("gridLayout") + self.radioHttp = QtWidgets.QRadioButton(self.serverGroupBox) + self.radioHttp.setChecked(True) + self.radioHttp.setObjectName("radioHttp") + self.gridLayout.addWidget(self.radioHttp, 0, 0, 1, 1) + self.radioHttps = QtWidgets.QRadioButton(self.serverGroupBox) + self.radioHttps.setObjectName("radioHttps") + self.gridLayout.addWidget(self.radioHttps, 0, 1, 1, 1) + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.gridLayout.addItem(spacerItem, 0, 2, 1, 1) + self.verticalLayout.addWidget(self.serverGroupBox) self.serverHorizontalLayout = QtWidgets.QHBoxLayout() self.serverHorizontalLayout.setObjectName("serverHorizontalLayout") self.labelServerHost = QtWidgets.QLabel(serverDialog) @@ -37,11 +52,11 @@ def setupUi(self, serverDialog): self.ServerSpinBox.setProperty("value", 5000) self.ServerSpinBox.setObjectName("ServerSpinBox") self.horizontalLayout.addWidget(self.ServerSpinBox) - spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout.addItem(spacerItem) + spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout.addItem(spacerItem1) self.verticalLayout.addLayout(self.horizontalLayout) - spacerItem1 = QtWidgets.QSpacerItem(20, 1, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.MinimumExpanding) - self.verticalLayout.addItem(spacerItem1) + spacerItem2 = QtWidgets.QSpacerItem(20, 1, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.MinimumExpanding) + self.verticalLayout.addItem(spacerItem2) self.serverButtonBox = QtWidgets.QDialogButtonBox(serverDialog) self.serverButtonBox.setOrientation(QtCore.Qt.Horizontal) self.serverButtonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) @@ -56,6 +71,8 @@ def setupUi(self, serverDialog): def retranslateUi(self, serverDialog): _translate = QtCore.QCoreApplication.translate serverDialog.setWindowTitle(_translate("serverDialog", "Dialog")) + self.radioHttp.setText(_translate("serverDialog", "http")) + self.radioHttps.setText(_translate("serverDialog", "https")) self.labelServerHost.setText(_translate("serverDialog", "Host")) self.ServerHostlineEdit.setText(_translate("serverDialog", "localhost")) self.serverPortLabel.setText(_translate("serverDialog", "Port")) diff --git a/server_config_dialog.ui b/server_config_dialog.ui index 5e52090..e75c511 100644 --- a/server_config_dialog.ui +++ b/server_config_dialog.ui @@ -6,14 +6,53 @@ 0 0 - 379 - 130 + 382 + 173 Dialog + + + + + + + + + + http + + + true + + + + + + + https + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + From 76e795b93ae88e6682932008ba4eccd5519e430b Mon Sep 17 00:00:00 2001 From: doublebyte Date: Mon, 8 Dec 2025 17:37:11 +0000 Subject: [PATCH 07/10] - added support for pushing and pulling configiration from a pygeoapi instance --- pygeoapi_config_dialog.py | 108 +++++++++++++++++++++++++++++++++----- 1 file changed, 94 insertions(+), 14 deletions(-) diff --git a/pygeoapi_config_dialog.py b/pygeoapi_config_dialog.py index a148354..a20198d 100644 --- a/pygeoapi_config_dialog.py +++ b/pygeoapi_config_dialog.py @@ -23,8 +23,10 @@ """ from copy import deepcopy -from datetime import datetime, timezone +from datetime import date, datetime, timezone import os +from wsgiref import headers +import requests import yaml from .utils.data_diff import diff_yaml_dict @@ -73,6 +75,21 @@ except: pass +headers = { + 'accept': '*/*', + 'Content-Type': 'application/json' +} + +def preprocess_for_json(d): + """Recursively converts datetime/date objects in a dict to ISO strings.""" + if isinstance(d, dict): + return {k: preprocess_for_json(v) for k, v in d.items()} + elif isinstance(d, list): + return [preprocess_for_json(i) for i in d] + elif isinstance(d, (datetime, date)): + return d.isoformat() + return d + class ServerConfigDialog(QDialog, Ui_serverDialog): """ Logic for the Server Configuration Dialog. @@ -196,26 +213,89 @@ def server_config(self, save): dialog = ServerConfigDialog(self) - if dialog.exec_(): + if dialog.exec_(): data = dialog.get_server_data() + url = f"{data['protocol']}://{data['host']}:{data['port']}/admin/config" if save == True: - self.push_to_server(data) + self.push_to_server(url) else: - self.pull_from_server(data) + self.pull_from_server(url) - def push_to_server(self, data): - QMessageBox.information( - self, - "Information", - f"Pushing configuration to: {data['protocol']}://{data['host']}:{data['port']}", + def push_to_server(self, url): + + QMessageBox.information( + self, + "Information", + f"Pushing configuration to: {url}", + ) + + config_dict = self.config_data.asdict_enum_safe(self.config_data) + + # Pre-process the dictionary to handle datetime objects + processed_config_dict = preprocess_for_json(config_dict) + + # TODO: support authentication through the QT framework + try: + # Send the PUT request to Admin API + response = requests.put(url, headers=headers, json=processed_config_dict) + response.raise_for_status() + + QgsMessageLog.logMessage( + f"Success! Status Code: {response.status_code}") + + except requests.exceptions.RequestException as e: + QgsMessageLog.logMessage(f"An error occurred: {e}") + + + def pull_from_server(self, url): + + QMessageBox.information( + self, + "Information", + f"Pulling configuration from: {url}", + ) + + # TODO: support authentication through the QT framework + try: + # Send the GET request to Admin API + response = requests.get(url, headers=headers) + response.raise_for_status() + + QgsMessageLog.logMessage( + f"Success! Status Code: {response.status_code}") + + QgsMessageLog.logMessage( + f"Response: {response.text}") + + data_dict = response.json() + + self.config_data = ConfigData() + self.config_data.set_data_from_yaml(data_dict) + self.ui_setter.set_ui_from_data() + + # log messages about missing or mistyped values during deserialization + QgsMessageLog.logMessage( + f"Errors during deserialization: {self.config_data.error_message}" + ) + QgsMessageLog.logMessage( + f"Default values used for missing YAML fields: {self.config_data.defaults_message}" ) - def pull_from_server(self, data): - QMessageBox.information( - self, - "Information", - f"Pulling configuration from: {data['protocol']}://{data['host']}:{data['port']}", + # summarize all properties missing/overwitten with defaults + # atm, warning with the full list of properties + all_missing_props = self.config_data.all_missing_props + QgsMessageLog.logMessage( + f"All missing or replaced properties: {self.config_data.all_missing_props}" ) + if len(all_missing_props) > 0: + ReadOnlyTextDialog( + self, + "Warning", + f"All missing or replaced properties (check logs for more details): {self.config_data.all_missing_props}", + ).exec_() + + except requests.exceptions.RequestException as e: + QgsMessageLog.logMessage(f"An error occurred: {e}") def save_to_file(self, file_path): From 3bc869a81910c1e964307d45b8ee793fbcdd9133 Mon Sep 17 00:00:00 2001 From: doublebyte Date: Mon, 15 Dec 2025 12:28:50 +0000 Subject: [PATCH 08/10] - added another radio for local file option --- pygeoapi_config_dialog_base.ui | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/pygeoapi_config_dialog_base.ui b/pygeoapi_config_dialog_base.ui index 012b938..8177d28 100644 --- a/pygeoapi_config_dialog_base.ui +++ b/pygeoapi_config_dialog_base.ui @@ -29,9 +29,9 @@ 0 - -71 + -96 834 - 1021 + 1050 @@ -2520,6 +2520,19 @@ + + + + Qt::RightToLeft + + + Local File + + + true + + + @@ -2528,9 +2541,6 @@ Server Connection - - - From 93ba679721bc1e095c8c16f6a3732f53c2786373 Mon Sep 17 00:00:00 2001 From: doublebyte Date: Mon, 15 Dec 2025 12:34:31 +0000 Subject: [PATCH 09/10] - added server_config_dialog.ui to pb_tool configuration --- pb_tool.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pb_tool.cfg b/pb_tool.cfg index f6b59e5..ca0f171 100644 --- a/pb_tool.cfg +++ b/pb_tool.cfg @@ -54,7 +54,7 @@ python_files: __init__.py pygeoapi_config.py pygeoapi_config_dialog.py main_dialog: pygeoapi_config_dialog_base.ui # Other ui files for dialogs you create (these will be compiled) -compiled_ui_files: +compiled_ui_files: server_config_dialog.ui # Resource file(s) that will be compiled resource_files: resources.qrc From b1cc03fd20c334073caf2358389e81c3109c94ee Mon Sep 17 00:00:00 2001 From: doublebyte Date: Mon, 15 Dec 2025 13:17:39 +0000 Subject: [PATCH 10/10] - added more expressive error messages --- pygeoapi_config_dialog.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pygeoapi_config_dialog.py b/pygeoapi_config_dialog.py index a20198d..1a49425 100644 --- a/pygeoapi_config_dialog.py +++ b/pygeoapi_config_dialog.py @@ -243,8 +243,19 @@ def push_to_server(self, url): QgsMessageLog.logMessage( f"Success! Status Code: {response.status_code}") + QMessageBox.information( + self, + "Information", + f"Success! Status Code: {response.status_code}", + ) + except requests.exceptions.RequestException as e: QgsMessageLog.logMessage(f"An error occurred: {e}") + QMessageBox.critical( + self, + "Error", + f"An error occurred pulling the configuration from the server: {e}", + ) def pull_from_server(self, url): @@ -264,6 +275,12 @@ def pull_from_server(self, url): QgsMessageLog.logMessage( f"Success! Status Code: {response.status_code}") + QMessageBox.information( + self, + "Information", + f"Success! Status Code: {response.status_code}", + ) + QgsMessageLog.logMessage( f"Response: {response.text}") @@ -297,6 +314,13 @@ def pull_from_server(self, url): except requests.exceptions.RequestException as e: QgsMessageLog.logMessage(f"An error occurred: {e}") + QMessageBox.critical( + self, + "Error", + f"An error occurred pulling the configuration from the server: {e}", + ) + + def save_to_file(self, file_path): if file_path: