diff --git a/MiAZ/backend/repository.py b/MiAZ/backend/repository.py index 850f6696..d5534821 100644 --- a/MiAZ/backend/repository.py +++ b/MiAZ/backend/repository.py @@ -104,7 +104,7 @@ def load(self, path): self.config['Project'] = MiAZConfigProjects(self.backend, repo_dir_conf) self.config['Plugin'] = MiAZConfigUserPlugins(self.backend, repo_dir_conf) self.backend.add_service('Projects', MiAZProject(self.backend)) - watcher = MiAZWatcher('source', path) + watcher = MiAZWatcher(path) watcher.set_active(active=True) self.backend.add_service('watcher', watcher) self.log.debug("Config repo loaded from: %s", repo_dir_conf) diff --git a/MiAZ/backend/watcher.py b/MiAZ/backend/watcher.py index 9cf8ebd1..ece65b30 100644 --- a/MiAZ/backend/watcher.py +++ b/MiAZ/backend/watcher.py @@ -26,10 +26,9 @@ class MiAZWatcher(GObject.GObject): before = {} active = False - def __init__(self, name: str, dirpath: str): + def __init__(self, dirpath: str): super(MiAZWatcher, self).__init__() self.log = get_logger('MiAZ.Watcher') - self.name = name.lower() self.dirpath = dirpath sid = GObject.signal_lookup('repository-updated', MiAZWatcher) if sid == 0: @@ -67,7 +66,7 @@ def __files_with_timestamp(self, rootdir): def set_path(self, dirpath: str): self.dirpath = dirpath - self.log.debug("Monitoring '%s'", self.dirpath) + self.log.debug("Watcher monitoring '%s'", self.dirpath) def set_active(self, active: bool = True) -> None: self.active = active @@ -95,18 +94,17 @@ def watch(self): modified.append(f) if added: - self.log.debug("Watcher[%s] > %d files added", self.name, len(added)) + self.log.debug("Watcher > %d files added", len(added)) updated |= True if removed: - self.log.debug("Watcher[%s] > %d files removed", self.name, len(removed)) + self.log.debug("Watcher > %d files removed", len(removed)) updated |= True if modified: - self.log.debug("Watcher[%s] > %d files modified", self.name, len(modified)) + self.log.debug("Watcher > %d files modified", len(modified)) updated |= True if updated: self.emit('repository-updated') - # ~ self.log.debug("Signal 'repository-updated' emitted", self.name) self.before = after return True diff --git a/MiAZ/frontend/desktop/app.py b/MiAZ/frontend/desktop/app.py index 207bfb03..b9b1b4a8 100644 --- a/MiAZ/frontend/desktop/app.py +++ b/MiAZ/frontend/desktop/app.py @@ -87,7 +87,7 @@ def _on_window_close_request(self, window): def _update_repo_settings(self, *args): repo_active = self.conf['App'].get('current') - self.actions.statusbar_message("Switched to repository '%s'" % repo_active) + # ~ self.actions.statusbar_message("Switched to repository '%s'" % repo_active) def _finish_configuration(self, *args): self.log.debug("Finish loading app") @@ -167,10 +167,6 @@ def check_repository(self, repo_id: str = None): self._setup_page_rename() self.actions.show_stack_page_by_name('workspace') valid = True - statusbar = self.get_widget('statusbar') - name = self.conf['App'].get('current') - statusbar.repo(name) - statusbar.message("Repository loaded") self.emit('start-application-completed') else: valid = False @@ -243,6 +239,7 @@ def set_widget(self, name: str, widget): return widget else: self.log.error("A widget with name '%s' doesn't exists", name) + return None def get_widget(self, name): try: diff --git a/MiAZ/frontend/desktop/services/actions.py b/MiAZ/frontend/desktop/services/actions.py index 3b73af1a..dd83c363 100644 --- a/MiAZ/frontend/desktop/services/actions.py +++ b/MiAZ/frontend/desktop/services/actions.py @@ -260,10 +260,10 @@ def show_stack_page_by_name(self, name: str = 'workspace'): def noop(self, *args): pass - def statusbar_message(self, message: str): - """Statusbar message""" - statusbar = self.app.get_widget('statusbar') - statusbar.message(message) + def toggle_workspace_filters(self, *args): + btnShowFilters = self.app.get_widget('workspace-togglebutton-filters') + active = btnShowFilters.get_active() + btnShowFilters.set_active(not active) def exit_app(self, *args): self.log.debug('Closing MiAZ') diff --git a/MiAZ/frontend/desktop/services/factory.py b/MiAZ/frontend/desktop/services/factory.py index 329ee419..4476236a 100644 --- a/MiAZ/frontend/desktop/services/factory.py +++ b/MiAZ/frontend/desktop/services/factory.py @@ -8,23 +8,11 @@ # Description: Custom widgets widely used """ -import os - -import gi -gi.require_version('GdkPixbuf', '2.0') -gi.require_version('Gtk', '4.0') - from gi.repository import Gtk -from gi.repository import Gdk from gi.repository import Gio -from gi.repository import GLib -from gi.repository import GObject from gi.repository import Pango -from gi.repository.GdkPixbuf import Pixbuf from MiAZ.backend.log import get_logger -from MiAZ.backend.models import Country -from MiAZ.frontend.desktop.services.icm import MiAZIconManager from MiAZ.frontend.desktop.widgets.button import MiAZPopoverButton from MiAZ.frontend.desktop.widgets.filechooser import MiAZFileChooserDialog @@ -74,7 +62,7 @@ def create_actionrow(self, title:str = '', subtitle:str = '', prefix: Gtk.Widget def create_box_filter(self, title, widget: Gtk.Widget) -> Gtk.Box: box = Gtk.Box.new(orientation=Gtk.Orientation.VERTICAL, spacing=3) box.set_margin_bottom(margin=12) - lblTitle = self.create_label('%s' % title) + lblTitle = self.create_label('%s' % title) lblTitle.set_xalign(0.0) box.append(lblTitle) box.append(widget) @@ -225,10 +213,9 @@ def _on_factory_bind(factory, list_item): box = list_item.get_child() label = box.get_last_child() item = list_item.get_item() - label.set_markup('%s' % item.title) + label.set_markup('%s' % item.title) def _on_search_changed(search_entry, item_filter): - text = search_entry.get_text() item_filter.changed(Gtk.FilterChange.DIFFERENT) def _do_filter(item, filter_list_model, search_entry): diff --git a/MiAZ/frontend/desktop/widgets/mainwindow.py b/MiAZ/frontend/desktop/widgets/mainwindow.py index 48f1c946..2964938b 100644 --- a/MiAZ/frontend/desktop/widgets/mainwindow.py +++ b/MiAZ/frontend/desktop/widgets/mainwindow.py @@ -12,6 +12,7 @@ from MiAZ.backend.log import get_logger from MiAZ.frontend.desktop.widgets.statusbar import MiAZStatusbar +from MiAZ.frontend.desktop.widgets.searchbar import SearchBar class MiAZMainWindow(Gtk.Box): @@ -47,9 +48,9 @@ def _setup_ui(self): self._setup_headerbar_center() self._setup_headerbar_right() - # Statusbar - statusbar = self.app.add_widget('statusbar', MiAZStatusbar(self.app)) - self.append(statusbar) + # On-Demand SearchBar + search = self.app.add_widget('searchbar', SearchBar(self.app)) + self.append(search) def _setup_event_listener(self): evk = Gtk.EventControllerKey.new() @@ -116,6 +117,9 @@ def show_workspace(self, *args): def _on_key_press(self, event, keyval, keycode, state): keyname = Gdk.keyval_name(keyval) - self.log.debug(keyname) + # ~ self.log.debug(keyname) if keyname == 'Escape': self.actions.show_stack_page_by_name('workspace') + elif keyname == 'F3': + self.actions.toggle_workspace_filters() + diff --git a/MiAZ/frontend/desktop/widgets/rename.py b/MiAZ/frontend/desktop/widgets/rename.py index 34eba252..a734b8e1 100644 --- a/MiAZ/frontend/desktop/widgets/rename.py +++ b/MiAZ/frontend/desktop/widgets/rename.py @@ -9,22 +9,15 @@ """ import os -import sys from datetime import datetime -from abc import abstractmethod from gettext import gettext as _ -import gi -gi.require_version('Gtk', '4.0') from gi.repository import Gtk -from gi.repository import Gio from gi.repository import GLib -from gi.repository.GdkPixbuf import Pixbuf from MiAZ.backend.log import get_logger -from MiAZ.frontend.desktop.widgets.dialogs import MiAZDialogAdd from MiAZ.backend.models import Group, Person, Country, Purpose, Concept, SentBy, SentTo -from MiAZ.frontend.desktop.widgets.configview import MiAZCountries, MiAZGroups, MiAZPeople, MiAZPurposes, MiAZPeopleSentBy, MiAZPeopleSentTo +from MiAZ.frontend.desktop.widgets.configview import MiAZCountries, MiAZGroups, MiAZPurposes, MiAZPeopleSentBy, MiAZPeopleSentTo class MiAZRenameDialog(Gtk.Box): @@ -100,7 +93,6 @@ def __init__(self, app) -> Gtk.Widget: def _update_dropdowns(self, *args): for item_type in [Country, Group, SentBy, Purpose, SentTo]: i_type = item_type.__gtype_name__ - i_title = _(item_type.__title__) config = self.config[i_type] self.actions.dropdown_populate(config, self.dropdown[i_type], item_type, False, False) @@ -174,7 +166,6 @@ def __create_field_0_date(self): """Field 0. Date""" title = _('Date') icon_name = 'miaz-res-date' - icon = self.icons.get_image_by_name(name=icon_name) boxValue = self.__create_box_value() boxValue.set_hexpand(False) boxValue.set_valign(Gtk.Align.CENTER) @@ -278,7 +269,6 @@ def __create_field_9_result(self, *args): """Field 7. extension""" # Current filename title = _('Current filename') - boxValueCur = self.__create_box_value() self.lblFilenameCur = Gtk.Label() self.lblFilenameCur.get_style_context().add_class(class_name='monospace') self.row_cur_filename = self.factory.create_actionrow(title=title, suffix=self.lblFilenameCur) @@ -286,7 +276,6 @@ def __create_field_9_result(self, *args): # New filename title = _('New filename') - boxValueNew = self.__create_box_value() self.lblFilenameNew = Gtk.Label() self.lblFilenameNew.get_style_context().add_class(class_name='monospace') self.row_new_filename = self.factory.create_actionrow(title=title, suffix=self.lblFilenameNew) @@ -380,7 +369,7 @@ def validate_date(self, sdate: str) -> bool: self.calendar.select_day(GLib.DateTime.new_from_iso8601(iso8601)) self.label_date.set_markup(adate.strftime("%A, %B %d %Y")) return True - except Exception as error: + except Exception: return False def get_filepath_source(self) -> str: @@ -410,7 +399,7 @@ def on_answer_question_rename(self, dialog, response): dialog.destroy() def on_rename_cancel(self, *args): - self.app.show_stack_page_by_name('workspace') + self.actions.show_stack_page_by_name('workspace') def _on_document_display(self, *args): doc = self.get_filepath_source() @@ -436,4 +425,4 @@ def on_answer_question_delete(self, dialog, response): self.log.error("Something went wrong: %s", error) self.log.error("Doesn't it exist? Really?") else: - self.app.show_stack_page_by_name('workspace') + self.actions.show_stack_page_by_name('workspace') diff --git a/MiAZ/frontend/desktop/widgets/searchbar.py b/MiAZ/frontend/desktop/widgets/searchbar.py new file mode 100644 index 00000000..9645e639 --- /dev/null +++ b/MiAZ/frontend/desktop/widgets/searchbar.py @@ -0,0 +1,46 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- + +""" +# File: searchbar.py +# Author: Tomás Vírseda +# License: GPL v3 +# Description: Custom SearchBar widget +# Borrowed from: https://github.com/timlau/gtk4-python +""" + +from gi.repository import Gtk + +class SearchBar(Gtk.SearchBar): + """ Wrapper for Gtk.Searchbar Gtk.SearchEntry""" + + def __init__(self, app): + super(SearchBar, self).__init__() + self.app = app + window = self.app.get_widget('window') + box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + box.set_spacing(24) + + # Add SearchEntry + entry = self.app.add_widget('searchbar_entry', Gtk.SearchEntry()) + entry.set_hexpand(True) + box.append(entry) + self.set_child(box) + + # connect search entry to seach bar + self.connect_entry(entry) + + # set key capture from main window, it will show searchbar, when you start typing + if window: + self.set_key_capture_widget(window) + + # show close button in search bar + self.set_show_close_button(True) + + # Set search mode to off by default + self.set_search_mode(False) + + def set_callback(self, callback): + """ Connect the search entry activate to an callback handler""" + entry = self.app.get_widget('searchbar_entry') + entry.connect('changed', callback) diff --git a/MiAZ/frontend/desktop/widgets/selector.py b/MiAZ/frontend/desktop/widgets/selector.py index 36286756..0bbb8158 100644 --- a/MiAZ/frontend/desktop/widgets/selector.py +++ b/MiAZ/frontend/desktop/widgets/selector.py @@ -79,16 +79,6 @@ def __init__(self, app, edit=True): boxViews.append(boxRight) self.append(boxViews) - # Status bar... - statusbar = self.factory.create_box_horizontal(hexpand=True) - self.sbicon = Gtk.Image() #.new_from_icon_name('info') - self.sbicon.set_pixel_size(32) - self.sbtext = Gtk.Label() - statusbar.append(self.sbicon) - statusbar.append(self.sbtext) - # ~ self.append(statusbar) - # ~ self.actions.statusbar_message('', '') - # Available self.frmViewAv = Gtk.Frame() title = Gtk.Label() @@ -112,16 +102,6 @@ def __init__(self, app, edit=True): boxRight.append(self.frmViewSl) self._setup_view_finish() - # ~ def statusbar_message(self, dtype: str = 'warning', message: str = ''): - # ~ icon_name = {} - # ~ icon_name["info"] = "dialog-information-symbolic" - # ~ icon_name["warning"] = "dialog-warning-symbolic" - # ~ icon_name["error"] = "dialog-error-symbolic" - # ~ icon_name["question"] = "dialog-question-symbolic" - # ~ icon_name[""] = None - # ~ self.sbicon.set_from_icon_name(icon_name[dtype]) - # ~ self.sbtext.set_markup(message) - def add_columnview_available(self, columnview): columnview.set_filter(self._do_filter_view) columnview.column_title.set_expand(True) @@ -143,7 +123,6 @@ def _setup_view_finish(self, *args): def update(self, *args): self._update_view_available() self._update_view_used() - # ~ self.statusbar_message('', '') def _on_item_used_add(self, *args): changed = False @@ -178,12 +157,9 @@ def _on_item_used_remove(self, *args): changed = True text = _('Removed %s (%s) from used') % (item_used.id, item_used.title) self.log.debug(text) - # ~ self.statusbar_message('info', text) else: - # ~ title = "%s %s not removed" % (self.config.model.__title__, item_used.id) dtype = "warning" text = _('%s %s is still being used by some docs') % (self.config.model.__title__, item_used.id) - # ~ self.statusbar_message(dtype, text) window = self.app.get_widget('window') dtype = 'error' title = "Item can't be removed" diff --git a/MiAZ/frontend/desktop/widgets/settings.py b/MiAZ/frontend/desktop/widgets/settings.py index 6c61a0d7..04a2cc96 100644 --- a/MiAZ/frontend/desktop/widgets/settings.py +++ b/MiAZ/frontend/desktop/widgets/settings.py @@ -264,7 +264,7 @@ def _on_plugin_remove(self, *args): deleted = plugin_manager.remove_plugin(plugin) if deleted: self.log.debug("Plugin '%s' deleted", module.id) - self.actions.statusbar_message("Plugin '%s' deleted" % module.id) + # ~ self.actions.statusbar_message("Plugin '%s' deleted" % module.id) self.update_user_plugins() def get_plugin_status(self, name: str) -> bool: diff --git a/MiAZ/frontend/desktop/widgets/workspace.py b/MiAZ/frontend/desktop/widgets/workspace.py index b8a03216..c1b3d1b9 100644 --- a/MiAZ/frontend/desktop/widgets/workspace.py +++ b/MiAZ/frontend/desktop/widgets/workspace.py @@ -144,6 +144,8 @@ def _setup_toolbar_filters(self): body = self.factory.create_box_horizontal(margin=3, spacing=6, hexpand=True, vexpand=True) body.set_homogeneous(True) body.set_margin_top(margin=6) + body.set_margin_start(margin=12) + body.set_margin_end(margin=12) widget.append(body) widget.append(Gtk.Separator.new(orientation=Gtk.Orientation.HORIZONTAL)) @@ -199,8 +201,9 @@ def update_dropdown_filter(self, config, item_type): self.actions.dropdown_populate(config, dropdowns[i_type], item_type) # ~ self.log.debug("Dropdown %s updated", i_type) - def _on_filters_toggled(self, button, data=None): - active = button.get_active() + def _on_filters_toggled(self, *args): + toggleButtonFilters = self.app.get_widget('workspace-togglebutton-filters') + active = toggleButtonFilters.get_active() self.toolbar_filters.set_visible(active) def _on_selection_changed(self, selection, position, n_items): @@ -213,15 +216,7 @@ def _on_selection_changed(self, selection, position, n_items): self.selected_items.append(item) label = self.btnDocsSel.get_child() docs = self.util.get_files(self.repository.docs) - # ~ self.log.debug(', '.join([item.id for item in self.selected_items])) label.set_markup("%d / %d / %d" % (len(self.selected_items), len(model), len(docs))) - # ~ self.app.statusbar_message("Selected %d of %d documents in current view (total documents: %d)" % (len(self.selected_items), len(model), len(docs))) - # ~ if len(self.selected_items) == 1: - # ~ menu = self.app.get_widget('workspace-menu-single') - # ~ self.popDocsSel.set_menu_model(menu) - # ~ else: - # ~ menu = self.app.get_widget('workspace-menu-selection') - # ~ self.popDocsSel.set_menu_model(menu) def _setup_toolbar_top(self): hdb_left = self.app.get_widget('headerbar-left-box') @@ -229,18 +224,13 @@ def _setup_toolbar_top(self): hdb_right.get_style_context().add_class(class_name='linked') ## Show/Hide Filters - self.tgbFilters = self.factory.create_button_toggle('miaz-filters2', callback=self._on_filters_toggled) - self.tgbFilters.set_active(False) - self.tgbFilters.set_hexpand(False) - self.tgbFilters.get_style_context().remove_class(class_name='flat') - self.tgbFilters.set_valign(Gtk.Align.CENTER) - hdb_left.append(self.tgbFilters) - - ## Searchbox - self.ent_sb = Gtk.SearchEntry(placeholder_text=_('Type here')) - self.ent_sb.set_hexpand(False) - self.ent_sb.get_style_context().add_class(class_name='caption') - hdb_left.append(self.ent_sb) + tgbFilters = self.factory.create_button_toggle('miaz-filters2', callback=self._on_filters_toggled) + self.app.add_widget('workspace-togglebutton-filters', tgbFilters) + tgbFilters.set_active(False) + tgbFilters.set_hexpand(False) + tgbFilters.get_style_context().remove_class(class_name='flat') + tgbFilters.set_valign(Gtk.Align.CENTER) + hdb_left.append(tgbFilters) ## Dropdowns dropdowns = self.app.get_widget('ws-dropdowns') @@ -355,12 +345,8 @@ def _setup_workspace(self): self.toolbar_filters = self._setup_toolbar_filters() self.app.add_widget('workspace-toolbar-filters', self.toolbar_filters) - # ~ toolbar_top = self.app.add_widget('workspace-toolbar-top', self._setup_toolbar_top()) self._setup_toolbar_top() - # ~ headerbar = self.app.get_widget('headerbar') - # ~ headerbar.set_title_widget(toolbar_top) frmView = self._setup_columnview() - # ~ head.append(toolbar_top) head.append(self.toolbar_filters) body.append(frmView) @@ -369,7 +355,6 @@ def _setup_workspace(self): self.view.column_subtitle.set_expand(True) self.view.column_group.set_visible(True) self.view.column_purpose.set_visible(True) - # ~ self.view.column_flag.set_visible(True) self.view.column_sentby.set_visible(True) self.view.column_sentto.set_visible(True) self.view.column_sentto.set_expand(False) @@ -381,7 +366,7 @@ def _setup_workspace(self): # Trigger events self._do_connect_filter_signals() - self._on_filters_toggled(self.tgbFilters) + self._on_filters_toggled() return widget @@ -573,7 +558,8 @@ def update(self, *args): self.selected_items = [] def _do_eval_cond_matches_freetext(self, item): - left = self.ent_sb.get_text() + entry = self.app.get_widget('searchbar_entry') + left = entry.get_text() right = item.id if left.upper() in right.upper(): return True @@ -685,7 +671,8 @@ def _do_filter_view(self, item, filter_list_model): return show_item def _do_connect_filter_signals(self): - self.ent_sb.connect('changed', self._on_filter_selected) + searchbar = self.app.get_widget('searchbar') + searchbar.set_callback(self._on_filter_selected) dropdowns = self.app.get_widget('ws-dropdowns') for dropdown in dropdowns: dropdowns[dropdown].connect("notify::selected-item", self._on_filter_selected) @@ -721,10 +708,3 @@ def _on_select_none(self, *args): selection = self.view.get_selection() selection.unselect_all() - def display_dashboard(self, *args): - self.view.column_subtitle.set_title(_('Concept')) - self.view.column_subtitle.set_expand(True) - self.column_sentto.set_expand(False) - self.column_sentby.set_expand(False) - self.view.refilter() - self.tgbFilters.set_visible(True) diff --git a/data/resources/icons/scalable/com.github.t00m.MiAZ-view-document.png b/data/resources/icons/scalable/com.github.t00m.MiAZ-view-document.png new file mode 100644 index 00000000..c1423166 Binary files /dev/null and b/data/resources/icons/scalable/com.github.t00m.MiAZ-view-document.png differ diff --git a/data/resources/plugins/renameitem.py b/data/resources/plugins/renameitem.py index 0ae9fbf4..b6fed07c 100644 --- a/data/resources/plugins/renameitem.py +++ b/data/resources/plugins/renameitem.py @@ -47,7 +47,7 @@ def _on_selection_changed(self, *args): def add_toolbar_button(self, *args): if self.app.get_widget('toolbar-top-button-rename') is None: toolbar_top_right = self.app.get_widget('headerbar-right-box') - button = self.factory.create_button(icon_name='miaz-res-manage', callback=self.callback) + button = self.factory.create_button(icon_name='com.github.t00m.MiAZ-text-editor-symbolic', callback=self.callback) # ~ button.get_style_context().add_class(class_name='flat') button.set_visible(False) self.app.add_widget('toolbar-top-button-rename', button) diff --git a/data/resources/plugins/viewitem.py b/data/resources/plugins/viewitem.py index 4b76189c..6af31ed3 100644 --- a/data/resources/plugins/viewitem.py +++ b/data/resources/plugins/viewitem.py @@ -51,7 +51,7 @@ def _on_selection_changed(self, *args): def add_toolbar_button(self, *args): if self.app.get_widget('toolbar-top-button-view') is None: toolbar_top_right = self.app.get_widget('headerbar-right-box') - button = self.factory.create_button(icon_name='miaz-display', callback=self.callback) + button = self.factory.create_button(icon_name='com.github.t00m.MiAZ-view-document', callback=self.callback) # ~ button.get_style_context().add_class(class_name='flat') button.set_visible(False) self.app.add_widget('toolbar-top-button-view', button) diff --git a/meson.build b/meson.build index 8d20069c..3e30c7eb 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('MiAZ', - version: '0.0.30', + version: '0.0.31', meson_version: '>= 0.61.2', default_options: [ 'warning_level=2', ],