diff --git a/README.md b/README.md index a3b99f63..7099bbbe 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Download the latest release](docs/img/download-button.png)](https://github.com/peter88213/novelibre/raw/main/dist/novelibre_v4.15.2.pyzw) +[![Download the latest release](docs/img/download-button.png)](https://github.com/peter88213/novelibre/raw/main/dist/novelibre_v4.15.3.pyzw) [![Changelog](docs/img/changelog-button.png)](docs/changelog.md) [![News](docs/img/news-button.png)](https://github.com/peter88213/novelibre/discussions/1) [![Online help](docs/img/help-button.png)](https://peter88213.github.io/nvhelp-en/) @@ -82,10 +82,10 @@ I use the program myself and fix bugs immediately if I notice any. As far as I c ### Default: Executable Python zip archive -Download the latest release [novelibre_v4.15.2.pyzw](https://github.com/peter88213/novelibre/raw/main/dist/novelibre_v4.15.2.pyzw) +Download the latest release [novelibre_v4.15.3.pyzw](https://github.com/peter88213/novelibre/raw/main/dist/novelibre_v4.15.3.pyzw) -- Launch *novelibre_v4.15.2.pyzw* by double-clicking (Windows/Linux desktop), -- or execute `python novelibre_v4.15.2.pyzw` (Windows), resp. `python3 novelibre_v4.15.2.pyzw` (Linux) on the command line. +- Launch *novelibre_v4.15.3.pyzw* by double-clicking (Windows/Linux desktop), +- or execute `python novelibre_v4.15.3.pyzw` (Windows), resp. `python3 novelibre_v4.15.3.pyzw` (Linux) on the command line. #### Important @@ -101,9 +101,9 @@ the zip file. ### Alternative: Zip file -The package is also available in zip format: [novelibre_v4.15.2.zip](https://github.com/peter88213/novelibre/raw/main/dist/novelibre_v4.15.2.zip) +The package is also available in zip format: [novelibre_v4.15.3.zip](https://github.com/peter88213/novelibre/raw/main/dist/novelibre_v4.15.3.zip) -- Extract the *novelibre_v4.15.2* folder from the downloaded zipfile "novelibre_v4.15.2.zip". +- Extract the *novelibre_v4.15.3* folder from the downloaded zipfile "novelibre_v4.15.3.zip". - Move into this new folder and launch *setup.pyw* by double-clicking (Windows/Linux desktop), - or execute `python setup.pyw` (Windows), resp. `python3 setup.pyw` (Linux) on the command line. diff --git a/VERSION b/VERSION index f0a8efdb..2bfad2a9 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ [LATEST] -version = 4.15.2 -download_link = https://github.com/peter88213/novelibre/raw/main/dist/novelibre_v4.15.2.pyzw +version = 4.15.3 +download_link = https://github.com/peter88213/novelibre/raw/main/dist/novelibre_v4.15.3.pyzw diff --git a/dist/novelibre_v4.15.2.pyzw b/dist/novelibre_v4.15.3.pyzw similarity index 63% rename from dist/novelibre_v4.15.2.pyzw rename to dist/novelibre_v4.15.3.pyzw index 80027d09..bac8302a 100644 Binary files a/dist/novelibre_v4.15.2.pyzw and b/dist/novelibre_v4.15.3.pyzw differ diff --git a/dist/novelibre_v4.15.2.zip b/dist/novelibre_v4.15.3.zip similarity index 63% rename from dist/novelibre_v4.15.2.zip rename to dist/novelibre_v4.15.3.zip index 645b2c44..c3e3928a 100644 Binary files a/dist/novelibre_v4.15.2.zip and b/dist/novelibre_v4.15.3.zip differ diff --git a/docs/changelog.md b/docs/changelog.md index 425a929a..7b8ebb74 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -8,6 +8,17 @@ See the [GitHub "Features" project](https://github.com/users/peter88213/projects/14). + +### Version 4.15.3 + +Refactor the code for better maintainability + +- PropertiesViewer now using the new ViewComponentBase methods of apptk 2.1.0. +- Update docstrings and code comments. + +Based on novxlib 4.8.0 +Based on apptk 2.1.0 + ### Version 4.15.2 - Restore the plugin_manager module from version 4.14.1. diff --git a/i18n/de.po b/i18n/de.po index 4683bac2..2477eff5 100644 --- a/i18n/de.po +++ b/i18n/de.po @@ -3,9 +3,9 @@ # msgid "" msgstr "" -"Project-Id-Version: 4.15.2\n" -"POT-Creation-Date: 2024-10-30 08:48:35\n" -"PO-Revision-Date: 2024-10-30 08:48:35\n" +"Project-Id-Version: 4.15.3\n" +"POT-Creation-Date: 2024-10-31 08:04:10\n" +"PO-Revision-Date: 2024-10-31 08:04:10\n" "Last-Translator: Peter Triesberger\n" "Language: de\n" "MIME-Version: 1.0\n" diff --git a/i18n/locale/de/LC_MESSAGES/novelibre.mo b/i18n/locale/de/LC_MESSAGES/novelibre.mo index 82b57f16..334ab668 100644 Binary files a/i18n/locale/de/LC_MESSAGES/novelibre.mo and b/i18n/locale/de/LC_MESSAGES/novelibre.mo differ diff --git a/i18n/messages.pot b/i18n/messages.pot index 422569b1..33c6d0e3 100644 --- a/i18n/messages.pot +++ b/i18n/messages.pot @@ -3,8 +3,8 @@ # msgid "" msgstr "" -"Project-Id-Version: 4.15.2\n" -"POT-Creation-Date: 2024-10-30 08:48:35\n" +"Project-Id-Version: 4.15.3\n" +"POT-Creation-Date: 2024-10-31 08:04:10\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: LANGUAGE\n" diff --git a/src/nvlib/plugin/plugin_base.py b/src/nvlib/plugin/plugin_base.py index a35cf342..b9141e6d 100644 --- a/src/nvlib/plugin/plugin_base.py +++ b/src/nvlib/plugin/plugin_base.py @@ -10,6 +10,12 @@ class PluginBase(ABC): """Abstract Plugin base class. + Accepts commands from the plugin collection: + - close + - quit + - enable/disable menu + - lock + Public class constants: VERSION: str -- Version string. NOVELYST_API: str -- API compatibility indicator. diff --git a/src/nvlib/plugin/plugin_collection.py b/src/nvlib/plugin/plugin_collection.py index f1b55330..3f49a205 100644 --- a/src/nvlib/plugin/plugin_collection.py +++ b/src/nvlib/plugin/plugin_collection.py @@ -15,11 +15,17 @@ class PluginCollection(dict): - """A plugin registry class. - + """A collection of plugin modules. + Represents a dictionary with key: str -- The module name. - value: object -- The module's Plugin() instance. + value: object -- The module's Plugin instance. + + Passes down the following commands to the plugins: + - close + - quit + - enable/disable menu + - lock Public instance variables: majorVersion: int -- The application's major version number. @@ -78,6 +84,24 @@ def delete_file(self, moduleName): print(str(ex)) return False + def disable_menu(self): + """Disable menu entries when no project is open.""" + for moduleName in self: + if self[moduleName].isActive: + try: + self[moduleName].disable_menu() + except: + pass + + def enable_menu(self): + """Enable menu entries when a project is open.""" + for moduleName in self: + if self[moduleName].isActive: + try: + self[moduleName].enable_menu() + except: + pass + def load_file(self, filePath): """Load and register a single plugin. @@ -153,24 +177,6 @@ def load_plugins(self, pluginPath): return True - def disable_menu(self): - """Disable menu entries when no project is open.""" - for moduleName in self: - if self[moduleName].isActive: - try: - self[moduleName].disable_menu() - except: - pass - - def enable_menu(self): - """Enable menu entries when a project is open.""" - for moduleName in self: - if self[moduleName].isActive: - try: - self[moduleName].enable_menu() - except: - pass - def lock(self): """Prevent the plugins from changing the model.""" for moduleName in self: @@ -180,12 +186,12 @@ def lock(self): except: pass - def unlock(self): - """Allow the plugins changing the model.""" + def on_close(self): + """Perform actions before a project is closed.""" for moduleName in self: if self[moduleName].isActive: try: - self[moduleName].unlock() + self[moduleName].on_close() except: pass @@ -198,23 +204,23 @@ def on_quit(self): except: pass - def on_close(self): - """Perform actions before a project is closed.""" + def open_node(self, event=None): + """Actions on double-clicking on a node or pressing the Return key.""" + # Deprecated! + # Plugins are expected to configure their open_node() method locally, if any. for moduleName in self: if self[moduleName].isActive: try: - self[moduleName].on_close() + self[moduleName].open_node() except: pass - def open_node(self, event=None): - """Actions on double-clicking on a node or pressing the Return key.""" - # Deprecated! - # Plugins are expected to configure their open_node() method locally, if any. + def unlock(self): + """Allow the plugins changing the model.""" for moduleName in self: if self[moduleName].isActive: try: - self[moduleName].open_node() + self[moduleName].unlock() except: pass diff --git a/src/nvlib/view/properties_window/properties_viewer.py b/src/nvlib/view/properties_window/properties_viewer.py index 42c36a12..31a7feee 100644 --- a/src/nvlib/view/properties_window/properties_viewer.py +++ b/src/nvlib/view/properties_window/properties_viewer.py @@ -36,9 +36,6 @@ def __init__(self, parent, model, view, controller, **kw): ViewComponentBase.__init__(self, model, view, controller) ttk.Frame.__init__(self, parent, **kw) - self._viewComponents = [] - # applying the Composite design pattern - # Call a factory method to instantiate and register one view component per element type. self._noView = self._make_view(NoView) self._projectView = self._make_view(ProjectView) @@ -68,12 +65,6 @@ def focus_title(self): """Prepare the current element's title entry for manual input.""" self._activeView.focus_title() - def lock(self): - """Inhibit element change.""" - for view in self._viewComponents: - view.lock() - # applying the Composite design pattern - def show_properties(self, nodeId): """Show the properties of the selected element.""" if self._mdl is None: @@ -110,12 +101,6 @@ def refresh(self): except: pass - def unlock(self): - """enable element change.""" - for view in self._viewComponents: - view.unlock() - # applying the Composite design pattern - def _make_view(self, viewClass): """Return a viewClass instance that is registered as a local view.. @@ -123,8 +108,7 @@ def _make_view(self, viewClass): viewClass: BasicView subclass. """ newView = viewClass(self, self._mdl, self._ui, self._ctrl) - self._viewComponents.append(newView) - # registering the view component locally + self.register_view(newView) # NOTE: the new view component must not be registered by the main view, # because the PropertiesViewer instance may be deleted and recreated # due to re-parenting when docking the properties window. diff --git a/tools/build.py b/tools/build.py index cc691f22..6092581a 100644 --- a/tools/build.py +++ b/tools/build.py @@ -12,7 +12,7 @@ sys.path.insert(0, f'{os.getcwd()}/../../novelibre/tools') from package_builder import PackageBuilder -VERSION = '4.15.2' +VERSION = '4.15.3' class ApplicationBuilder(PackageBuilder):