Skip to content

Replace custom delete_basket method by a call to Ili2dbUtils in Model Baker lib #974

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
616bba6
Replace custom delete_basket method by a call to Ili2dbUtils in Model…
gacarrillor Oct 31, 2024
93607db
[gui] Homogenize the dataset manager dialog: add/edit/remove buttons …
gacarrillor Aug 26, 2024
4fc7e21
[gui] Convert current Basket manager into Create Basket dialog
gacarrillor Aug 26, 2024
052a3b9
[gui] Introduce brand new new Basket Manager (still partial)
gacarrillor Aug 26, 2024
97987ec
[gui] Adapt BasketManager and CreateBasket dialogs, as well as their …
gacarrillor Sep 20, 2024
22f7bf2
[gui] Introduce EditBasketDialog, load info from the selected basket …
gacarrillor Sep 20, 2024
c3c756a
[gui] Add edit basket support
gacarrillor Sep 22, 2024
73ade58
[gui] Trigger basket edit on basket managet item double click
gacarrillor Sep 24, 2024
cc1a46c
[gui] Allow users to set the attachment key during basket creation
gacarrillor Sep 24, 2024
4498eb3
[git] Add Delete Dataset support
gacarrillor Sep 28, 2024
b437274
[gui] Add Delete Basket support; introduce ili2db_utils module to exe…
gacarrillor Sep 29, 2024
02c448c
Move Ili2DbUtils to lib
gacarrillor Oct 1, 2024
2cfae0f
[datasetmanager] Fix selection changed after closing 'Add dataset' di…
gacarrillor Oct 1, 2024
565be88
[basketmanager] Enable edit/delete basket buttons depending on item s…
gacarrillor Oct 1, 2024
cff3d7a
[ux] Disable read-only controls for edit basket dialog
gacarrillor Oct 1, 2024
83754b9
Replace custom delete_basket method by a call to Ili2dbUtils in Model…
gacarrillor Oct 31, 2024
56b34bb
Merge branch 'modification_baskets_datasets_followup' of github.com:o…
signedav Nov 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 137 additions & 27 deletions QgisModelBaker/gui/basket_manager.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""
/***************************************************************************
-------------------
begin : 10.08.2021
begin : 26.08.2024
git sha : :%H$
copyright : (C) 2021 by Dave Signer
email : david at opengis ch
copyright : (C) 2024 by Germán Carrillo
email : german at opengis ch
***************************************************************************/

/***************************************************************************
Expand All @@ -17,51 +17,161 @@
***************************************************************************/
"""

from qgis.core import Qgis, QgsApplication, QgsMessageLog, QgsProject
from qgis.PyQt.QtWidgets import QDialog, QMessageBox

from QgisModelBaker.gui.panel.basket_panel import BasketPanel
from QgisModelBaker.gui.create_baskets import CreateBasketDialog
from QgisModelBaker.gui.edit_basket import EditBasketDialog
from QgisModelBaker.gui.panel.summary_basket_panel import SummaryBasketPanel
from QgisModelBaker.libs.modelbaker.iliwrapper.ili2dbconfig import (
Ili2DbCommandConfiguration,
)
from QgisModelBaker.libs.modelbaker.utils.ili2db_utils import Ili2DbUtils
from QgisModelBaker.utils import gui_utils

DIALOG_UI = gui_utils.get_ui_class("basket_manager.ui")


class BasketManagerDialog(QDialog, DIALOG_UI):
def __init__(self, parent=None, db_connector=None, datasetname=None):
def __init__(
self,
iface,
parent=None,
db_connector=None,
datasetname=None,
configuration: Ili2DbCommandConfiguration = None,
):
QDialog.__init__(self, parent)
self.setupUi(self)

self.iface = iface
self.datasetname = datasetname
self.db_connector = db_connector
self.configuration = configuration

self.buttonBox.accepted.connect(self._accepted)
self.buttonBox.rejected.connect(self._rejected)
self.buttonBox.accepted.connect(self.accept)

# baskets part
self.baskets_panel = BasketPanel(self)
self.baskets_panel = SummaryBasketPanel(self)
self.baskets_layout.addWidget(self.baskets_panel)
self.baskets_panel.basket_view.doubleClicked.connect(self._edit_basket)

self.baskets_panel.load_basket_config(self.db_connector, self.datasetname)

def _accepted(self):
feedbacks = self.baskets_panel.save_basket_config(
self.add_button.clicked.connect(self._add_basket)
self.edit_button.clicked.connect(self._edit_basket)
self.delete_button.clicked.connect(self._delete_basket)
self.baskets_panel.basket_view.selectionModel().selectionChanged.connect(
lambda: self._enable_basket_handling(True)
)

self.add_button.setIcon(QgsApplication.getThemeIcon("/symbologyAdd.svg"))
self.edit_button.setIcon(QgsApplication.getThemeIcon("/symbologyEdit.svg"))
self.delete_button.setIcon(QgsApplication.getThemeIcon("/symbologyRemove.svg"))

self._enable_basket_handling(True) # Initial widget status

def _enable_basket_handling(self, enable):
self.add_button.setEnabled(enable)
self.edit_button.setEnabled(self._valid_selection())
self.delete_button.setEnabled(self._valid_selection())

def _valid_selection(self):
"""
Returns if at least one dataset is selected
"""
return bool(self.baskets_panel.basket_view.selectedIndexes())

def _refresh_baskets(self):
self.baskets_panel.bid_model.load_basket_config(
self.db_connector, self.datasetname
)
negative_feedbacks = [
feedback for feedback in feedbacks if feedback[0] is False
]
if negative_feedbacks:
warning_box = QMessageBox(self)
warning_box.setIcon(QMessageBox.Critical)
warning_title = self.tr("Creating baskets failed")
warning_box.setWindowTitle(warning_title)
warning_box.setText(
"{}{}".format(
"\n".join([feedback[1] for feedback in negative_feedbacks]),
"\n(The problem is often an incorrectly formatted BID)",
)
self._enable_basket_handling(True)

def _add_basket(self):
create_basket_dialog = CreateBasketDialog(
self, self.db_connector, self.datasetname
)
if create_basket_dialog.baskets_can_be_created():
create_basket_dialog.exec_()

# Refresh existing baskets in basket manager after creation
self._refresh_baskets()
else:
QMessageBox.information(
self,
self.tr("Create Baskets"),
self.tr(
f"The dataset '{self.datasetname}' already contains one basket for each topic.\n\n"
f"No additional baskets can be created."
),
QMessageBox.Close,
)

def _edit_basket(self) -> None:
if self._valid_selection():
selected_basket_settings = self.baskets_panel.selected_basket_settings()
edit_basket_dialog = EditBasketDialog(
self, self.db_connector, selected_basket_settings
)
warning_box.exec_()
self.close()
edit_basket_dialog.exec_()

# Refresh existing baskets in basket manager after edition
self._refresh_baskets()

def _delete_basket(self) -> None:
if self._valid_selection():
if not self.db_connector.get_basket_handling():
QMessageBox.warning(
self,
self.tr("Delete Basket"),
self.tr(
"Delete baskets is only available for database schemas created with --createBasketCol parameter."
),
QMessageBox.Close,
)
return

if (
QMessageBox.warning(
self,
self.tr("Delete Basket"),
self.tr(
"Deleting a Basket will also delete all the data it contains. This operation cannot be reverted.\n\nAre you sure you want to proceed?"
),
QMessageBox.No | QMessageBox.Yes,
)
== QMessageBox.Yes
):
basket_config = self.baskets_panel.selected_basket_settings()
ili2db_utils = Ili2DbUtils()
ili2db_utils.log_on_error.connect(self._log_on_delete_baskets_error)
res, msg = ili2db_utils.delete_baskets(
basket_config["bid_value"], self.configuration
)

if res:
# After deletion, make sure canvas is refreshed
self._refresh_map_layers()

# Refresh existing baskets in basket manager after deletion
self._refresh_baskets()

warning_box = QMessageBox(self)
warning_box.setIcon(
QMessageBox.Information if res else QMessageBox.Warning
)
warning_box.setWindowTitle(self.tr("Delete Basket"))
warning_box.setText(msg)
warning_box.exec_()

def _refresh_map_layers(self):
# Refresh layer data sources and also their symbology (including feature count)
layer_tree_view = self.iface.layerTreeView()
for tree_layer in QgsProject.instance().layerTreeRoot().findLayers():
layer = tree_layer.layer()
layer.dataProvider().reloadData()
layer_tree_view.refreshLayerSymbology(layer.id())

def _rejected(self):
self.close()
def _log_on_delete_baskets_error(self, log):
QgsMessageLog.logMessage(log, self.tr("Delete basket from DB"), Qgis.Critical)
72 changes: 72 additions & 0 deletions QgisModelBaker/gui/create_baskets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""
/***************************************************************************
-------------------
begin : 10.08.2021
git sha : :%H$
copyright : (C) 2021 by Dave Signer
email : david at opengis ch
***************************************************************************/

/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
"""

from qgis.PyQt.QtWidgets import QDialog, QMessageBox

from QgisModelBaker.gui.panel.create_basket_panel import CreateBasketPanel
from QgisModelBaker.utils import gui_utils

DIALOG_UI = gui_utils.get_ui_class("create_baskets.ui")


class CreateBasketDialog(QDialog, DIALOG_UI):
def __init__(self, parent=None, db_connector=None, datasetname=None):
QDialog.__init__(self, parent)
self.setupUi(self)

self.datasetname = datasetname
self.db_connector = db_connector

self.buttonBox.accepted.connect(self._accepted)
self.buttonBox.rejected.connect(self._rejected)

# baskets part
self.baskets_panel = CreateBasketPanel(self)
self.baskets_layout.addWidget(self.baskets_panel)

self.baskets_panel.load_basket_config(self.db_connector, self.datasetname)

def baskets_can_be_created(self):
# Check if any (non-existing) basket was added, otherwise
# inform that no other baskets can be created for this dataset
return len(self.baskets_panel.bid_model.basket_settings)

def _accepted(self):
feedbacks = self.baskets_panel.save_basket_config(
self.db_connector, self.datasetname
)
negative_feedbacks = [
feedback for feedback in feedbacks if feedback[0] is False
]
if negative_feedbacks:
warning_box = QMessageBox(self)
warning_box.setIcon(QMessageBox.Critical)
warning_title = self.tr("Creating baskets failed")
warning_box.setWindowTitle(warning_title)
warning_box.setText(
"{}{}".format(
"\n".join([feedback[1] for feedback in negative_feedbacks]),
"\n(The problem is often an incorrectly formatted BID)",
)
)
warning_box.exec_()
self.close()

def _rejected(self):
self.close()
Loading