diff --git a/metadata.txt b/metadata.txt index 7e8bca4e..358bf1fd 100644 --- a/metadata.txt +++ b/metadata.txt @@ -18,6 +18,8 @@ deprecated=False icon=resources/icon.png changelog= 0.15.2 - GUI improvements (#138, #139, #140, #141) + - Add button for reloading the QGIS directory of approved resources (#145) + - Fix bug in the handling of QGIS directory updates (#146) 0.15.1 - Fix incorrect handling of searchPathsForSVG setting (#135) - Handle XML parsing exceptions for QML files 0.15.0 - Support expressions (#130). Switch to Python pathlib. diff --git a/resource_sharing/collection_manager.py b/resource_sharing/collection_manager.py index 76ef3215..07b6bde1 100644 --- a/resource_sharing/collection_manager.py +++ b/resource_sharing/collection_manager.py @@ -1,6 +1,5 @@ # coding=utf-8 import hashlib -# Use pathlib instead of os.path from pathlib import Path import shutil import logging @@ -95,57 +94,57 @@ def get_html(self, collection_id): html = '' resource_types = 0 if 'svg' in config.COLLECTIONS[collection_id].keys(): - html = html + str(config.COLLECTIONS[collection_id]['svg']) + ' SVG' - if config.COLLECTIONS[collection_id]['svg'] > 1: - html = html + 's' - resource_types = resource_types + 1 + html = html + str(config.COLLECTIONS[collection_id]['svg']) + ' SVG' + if config.COLLECTIONS[collection_id]['svg'] > 1: + html = html + 's' + resource_types = resource_types + 1 if 'style' in config.COLLECTIONS[collection_id].keys(): - if resource_types > 0: - html = html + ', ' - html = html + str(config.COLLECTIONS[collection_id]['style']) + ' Layer style (QML) file' - if config.COLLECTIONS[collection_id]['style'] > 1: - html = html + 's' - resource_types = resource_types + 1 + if resource_types > 0: + html = html + ', ' + html = html + str(config.COLLECTIONS[collection_id]['style']) + ' Layer style (QML) file' + if config.COLLECTIONS[collection_id]['style'] > 1: + html = html + 's' + resource_types = resource_types + 1 if 'symbol' in config.COLLECTIONS[collection_id].keys(): - if resource_types > 0: - html = html + ', ' - html = html + str(config.COLLECTIONS[collection_id]['symbol']) + ' Symbol (XML) file' - if config.COLLECTIONS[collection_id]['symbol'] > 1: - html = html + 's' - resource_types = resource_types + 1 + if resource_types > 0: + html = html + ', ' + html = html + str(config.COLLECTIONS[collection_id]['symbol']) + ' Symbol (XML) file' + if config.COLLECTIONS[collection_id]['symbol'] > 1: + html = html + 's' + resource_types = resource_types + 1 if 'models' in config.COLLECTIONS[collection_id].keys(): - if resource_types > 0: - html = html + ', ' - html = html + str(config.COLLECTIONS[collection_id]['models']) + ' Processing model' - if config.COLLECTIONS[collection_id]['models'] > 1: - html = html + 's' - resource_types = resource_types + 1 + if resource_types > 0: + html = html + ', ' + html = html + str(config.COLLECTIONS[collection_id]['models']) + ' Processing model' + if config.COLLECTIONS[collection_id]['models'] > 1: + html = html + 's' + resource_types = resource_types + 1 if 'expressions' in config.COLLECTIONS[collection_id].keys(): - if resource_types > 0: - html = html + ', ' - html = html + str(config.COLLECTIONS[collection_id]['expressions']) + ' Expression (JSON) file' - if config.COLLECTIONS[collection_id]['expressions'] > 1: - html = html + 's' - resource_types = resource_types + 1 + if resource_types > 0: + html = html + ', ' + html = html + str(config.COLLECTIONS[collection_id]['expressions']) + ' Expression (JSON) file' + if config.COLLECTIONS[collection_id]['expressions'] > 1: + html = html + 's' + resource_types = resource_types + 1 if 'processing' in config.COLLECTIONS[collection_id].keys(): - if resource_types > 0: - html = html + ', ' - html = html + str(config.COLLECTIONS[collection_id]['processing']) + ' Processing script' - if config.COLLECTIONS[collection_id]['processing'] > 1: - html = html + 's' - resource_types = resource_types + 1 + if resource_types > 0: + html = html + ', ' + html = html + str(config.COLLECTIONS[collection_id]['processing']) + ' Processing script' + if config.COLLECTIONS[collection_id]['processing'] > 1: + html = html + 's' + resource_types = resource_types + 1 if 'rscripts' in config.COLLECTIONS[collection_id].keys(): - if resource_types > 0: - html = html + ', ' - html = html + str(config.COLLECTIONS[collection_id]['rscripts']) + ' R script' - if config.COLLECTIONS[collection_id]['rscripts'] > 1: - html = html + 's' - resource_types = resource_types + 1 + if resource_types > 0: + html = html + ', ' + html = html + str(config.COLLECTIONS[collection_id]['rscripts']) + ' R script' + if config.COLLECTIONS[collection_id]['rscripts'] > 1: + html = html + 's' + resource_types = resource_types + 1 html = html + '.
Reinstall to update' if resource_types == 0: - html = 'No standard resources found.' + html = 'No standard resources found.' if config.COLLECTIONS[collection_id]['status'] != COLLECTION_INSTALLED_STATUS: - html = 'Unknown before installation' + html = 'Unknown before installation' config.COLLECTIONS[collection_id]['resources_html'] = html context = { diff --git a/resource_sharing/gui/resource_sharing_dialog.py b/resource_sharing/gui/resource_sharing_dialog.py index 84e4f52c..f505702e 100644 --- a/resource_sharing/gui/resource_sharing_dialog.py +++ b/resource_sharing/gui/resource_sharing_dialog.py @@ -51,11 +51,9 @@ QProgressDialog, QDialogButtonBox) - from qgis.gui import QgsMessageBar from qgis.core import Qgis from qgis.core import QgsSettings - from resource_sharing.gui.manage_dialog import ManageRepositoryDialog from resource_sharing.repository_manager import RepositoryManager from resource_sharing.collection_manager import ( @@ -79,12 +77,12 @@ COLLECTION_ALL_STATUS, COLLECTION_INSTALLED_STATUS) from resource_sharing import config - FORM_CLASS, _ = uic.loadUiType(str(ui_path('resource_sharing_dialog_base.ui'))) LOGGER = logging.getLogger('QGIS Resource Sharing') REPOSITORY_ITEM = 1000 COLLECTION_ITEM = 2000 + class ResourceSharingDialog(QDialog, FORM_CLASS): TAB_ALL = 0 TAB_INSTALLED = 1 @@ -102,7 +100,6 @@ def __init__(self, parent=None, iface=None): super(ResourceSharingDialog, self).__init__(parent) self.setupUi(self) self.iface = iface - # Reconfigure UI self.setModal(True) self.button_edit.setEnabled(False) @@ -110,7 +107,6 @@ def __init__(self, parent=None, iface=None): self.button_install.setEnabled(False) self.button_open.setEnabled(False) self.button_uninstall.setEnabled(False) - # Set up the "main menu" - QListWidgetItem # All collections icon_all = QIcon() @@ -144,20 +140,16 @@ def __init__(self, parent=None, iface=None): item_settings.setIcon(icon_settings) item_settings.setText(self.tr('Settings')) item_all.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) - # Add the items to the list widget self.menu_list_widget.addItem(item_all) self.menu_list_widget.addItem(item_installed) self.menu_list_widget.addItem(item_settings) - # Init the message bar self.message_bar = QgsMessageBar(self) self.message_bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.vlayoutRightColumn.insertWidget(0, self.message_bar) - # Progress dialog for long running processes self.progress_dialog = None - # Init the repository manager dialog self.repository_manager = RepositoryManager() self.collection_manager = CollectionManager() @@ -168,13 +160,13 @@ def __init__(self, parent=None, iface=None): self.collection_proxy.setSourceModel(self.collections_model) self.list_view_collections.setModel(self.collection_proxy) # Active selected collection - self._selected_collection_id = None - + self._sel_coll_id = None # Slots self.button_add.clicked.connect(self.add_repository) self.button_edit.clicked.connect(self.edit_repository) self.button_delete.clicked.connect(self.delete_repository) self.button_reload.clicked.connect(self.reload_repositories) + self.button_reload_dir.clicked.connect(self.reload_off_res_directory) self.menu_list_widget.currentRowChanged.connect(self.set_current_tab) self.list_view_collections.selectionModel().currentChanged.connect( self.on_list_view_collections_clicked) @@ -184,7 +176,6 @@ def __init__(self, parent=None, iface=None): self.button_uninstall.clicked.connect(self.uninstall_collection) self.button_box.button(QDialogButtonBox.Help).clicked.connect( self.open_help) - # Populate the repositories widget and collections list view self.populate_repositories_widget() self.reload_collections_model() @@ -235,7 +226,6 @@ def add_repository(self): dlg = ManageRepositoryDialog(self) if not dlg.exec_(): return - for repoName, repo in self.repository_manager.directories.items(): if dlg.line_edit_url.text().strip() == repo['url']: self.message_bar.pushMessage( @@ -249,16 +239,13 @@ def add_repository(self): 'Repositories must have unique names!'), Qgis.Warning, 5) return - repo_name = dlg.line_edit_name.text() repo_url = dlg.line_edit_url.text().strip() repo_auth_cfg = dlg.line_edit_auth_id.text().strip() if repo_name in self.repository_manager.directories: repo_name += '(2)' - # Show progress dialog self.show_progress_dialog("Fetching repository's metadata") - # Add repository try: status, adderror = self.repository_manager.add_directory( @@ -279,10 +266,8 @@ def add_repository(self): Qgis.Warning, 5) finally: self.progress_dialog.hide() - # Reload data and widget self.reload_data_and_widget() - # Deactivate edit and delete button self.button_edit.setEnabled(False) self.button_delete.setEnabled(False) @@ -292,10 +277,8 @@ def edit_repository(self): selected_item = self.tree_repositories.currentItem() if selected_item: repo_name = selected_item.text(0) - if not repo_name: return - # Check if it is among the officially approved QGIS repositories settings = QgsSettings() settings.beginGroup(repo_settings_group()) @@ -306,17 +289,14 @@ def edit_repository(self): 'You can not edit the official repositories!'), Qgis.Warning, 5) return - dlg = ManageRepositoryDialog(self) dlg.line_edit_name.setText(repo_name) dlg.line_edit_url.setText( self.repository_manager.directories[repo_name]['url']) dlg.line_edit_auth_id.setText( self.repository_manager.directories[repo_name]['auth_cfg']) - if not dlg.exec_(): return - # Check if the changed URL is already present and that # the new repository name is unique new_url = dlg.line_edit_url.text().strip() @@ -335,17 +315,13 @@ def edit_repository(self): 'Repositories must have unique names!'), Qgis.Warning, 5) return - # Redundant if (new_name in self.repository_manager.directories) and ( new_name != repo_name): new_name += '(2)' - new_auth_cfg = dlg.line_edit_auth_id.text() - # Show progress dialog self.show_progress_dialog("Fetching repository's metadata") - # Edit repository try: status, editerror = self.repository_manager.edit_directory( @@ -368,10 +344,8 @@ def edit_repository(self): self.tr('%s') % e, Qgis.Warning, 5) finally: self.progress_dialog.hide() - # Reload data and widget self.reload_data_and_widget() - # Deactivate the edit and delete buttons self.button_edit.setEnabled(False) self.button_delete.setEnabled(False) @@ -381,7 +355,6 @@ def delete_repository(self): selected_item = self.tree_repositories.currentItem() if selected_item: repo_name = selected_item.text(0) - if not repo_name: return # Check if it is among the offical repositories @@ -392,7 +365,6 @@ def delete_repository(self): 'You can not remove official repositories!'), Qgis.Warning, 5) return - warning = self.tr('Are you sure you want to remove the following ' 'repository?') + '\n' + repo_name if QMessageBox.warning( @@ -418,11 +390,29 @@ def delete_repository(self): self.button_edit.setEnabled(False) self.button_delete.setEnabled(False) + def reload_off_res_directory(self): + """Slot called when the user clicks the 'Reload directory' + button.""" + # Show progress dialog + self.show_progress_dialog('Reloading the official QGIS resource' + ' directory') + self.repository_manager._online_directories = {} + # Registered directories + self.repository_manager._directories = {} + self.repository_manager.fetch_online_directories() + # Load directory of repositories from settings + self.repository_manager.load_directories() + self.message_bar.pushMessage('On-line directory reloaded', + Qgis.Info, 5) + self.progress_dialog.hide() + # Reload data and widget + self.reload_data_and_widget() + def reload_repositories(self): - """Slot for when user clicks reload repositories button.""" + """Slot called when the user clicks the 'Reload repositories' + button.""" # Show progress dialog self.show_progress_dialog('Reloading all repositories') - for repo_name in self.repository_manager.directories: directory = self.repository_manager.directories[repo_name] url = directory['url'] @@ -445,21 +435,19 @@ def reload_repositories(self): self.message_bar.pushMessage( self.tr('%s') % e, Qgis.Warning, 5) - self.progress_dialog.hide() # Reload data and widget self.reload_data_and_widget() def install_collection(self): - """Slot for when the user clicks the install/reinstall button.""" + """Slot called when the user clicks the Install/Reinstall button.""" # Save the current index to enable selection after installation self.current_index = self.list_view_collections.currentIndex() self.show_progress_dialog('Starting installation...') self.progress_dialog.canceled.connect(self.install_canceled) - self.installer_thread = QThread() self.installer_worker = CollectionInstaller( - self.collection_manager, self._selected_collection_id) + self.collection_manager, self._sel_coll_id) self.installer_worker.moveToThread(self.installer_thread) self.installer_worker.finished.connect(self.install_finished) self.installer_worker.aborted.connect(self.install_aborted) @@ -478,45 +466,48 @@ def install_finished(self): self.installer_thread.quit() self.installer_thread.wait() self.installer_thread.deleteLater() - if installStatus: self.reload_collections_model() # Report what has been installed - message = '%s was successfully installed, containing:\n