class BackendsDialog(): """ BackendsDialog manages a window that lets you manage and configure synchronization service. It can display two "views", or "panels": - the backend configuration view - the backend adding view """ def __init__(self, req): """ Initializes the gtk objects and signals. @param req: a Requester object """ self.req = req # Declare subsequently loaded widget self.dialog = None self.treeview_window = None self.central_pane = None self.add_button = None self.remove_button = None self.backends_tv = None self.config_panel = None self.add_panel = None builder = Gtk.Builder() self._load_widgets_from_builder(builder) # Load and setup other widgets self.dialog.set_title(_(f"Synchronization Services - {info.NAME}")) self._create_widgets_for_add_panel() self._create_widgets_for_conf_panel() self._setup_signal_connections(builder) self._create_widgets_for_treeview() ######################################## # INTERFACE WITH THE VIEWMANAGER ####### ######################################## def activate(self): """Shows this window, refreshing the current view""" self.dialog.show_all() self.backends_tv.refresh() self.backends_tv.select_backend() self.dialog.present() def on_close(self, widget, data=None): """ Hides this window, saving the backends configuration. @param widget: not used, here only for using this as signal callback @param data: same as widget, disregard the content """ self.dialog.hide() self.req.save_datastore() return True ######################################## # HELPER FUNCTIONS ##################### ######################################## def get_requester(self): """ Helper function: returns the requester. It's used by the "views" displayed by this class (backend editing and adding views) to access the requester """ return self.req def get_pixbuf_from_icon_name(self, name, height): """ Helper function: returns a pixbuf of an icon given its name in the loaded icon theme @param name: the name of the icon @param height: the height of the returned pixbuf @param width: the width of the returned pixbuf @returns GdkPixbuf: a pixbuf containing the wanted icon, or None (if the icon is not present) """ return Gtk.IconTheme.get_default().load_icon(name, height, 0) def _show_panel(self, panel_name): """ Helper function to switch between panels. @param panel_name: the name of the wanted panel. Choose between "configuration" or "add" """ if panel_name == "configuration": panel_to_remove = self.add_panel panel_to_add = self.config_panel side_is_enabled = True elif panel_name == "add": panel_to_remove = self.config_panel panel_to_add = self.add_panel side_is_enabled = False else: log.error("panel name unknown") return # Central pane # NOTE: self.central_pane is the Gtk.Container in which we load panels if panel_to_remove in self.central_pane: self.central_pane.remove(panel_to_remove) if panel_to_add not in self.central_pane: self.central_pane.add(panel_to_add) self.central_pane.show_all() # Side treeview # disabled if we're adding a new backend try: # when this is called upon initialization of this class, the # backends_tv object has not been created yet. self.add_button.set_sensitive(side_is_enabled) self.remove_button.set_sensitive(side_is_enabled) self.backends_tv.set_sensitive(side_is_enabled) except AttributeError: pass ######################################## # WIDGETS AND SIGNALS ################## ######################################## def _load_widgets_from_builder(self, builder): """ Loads widgets from the builder .ui file @param builder: a Gtk.Builder """ builder.add_from_file(ViewConfig.BACKENDS_UI_FILE) widgets = { 'dialog': 'backends', 'treeview_window': 'treeview_window', 'central_pane': 'central_pane', 'add_button': 'add_button', 'remove_button': 'remove_button', } for attr, widget in widgets.items(): setattr(self, attr, builder.get_object(widget)) def _setup_signal_connections(self, builder): """ Creates some GTK signals connections @param builder: a Gtk.Builder """ signals = { 'on_add_button_clicked': self.on_add_button, 'on_remove_button_clicked': self.on_remove_button, } builder.connect_signals(signals) def _create_widgets_for_treeview(self): """ Creates the widgets for the lateral treeview displaying the backends the user has added """ self.backends_tv = BackendsTree(self) self.treeview_window.add(self.backends_tv) def _create_widgets_for_conf_panel(self): """simply creates the panel to configure backends""" self.config_panel = ConfigurePanel(self) def _create_widgets_for_add_panel(self): """simply creates the panel to add backends""" self.add_panel = AddPanel(self) ######################################## # EVENT HANDLING ####################### ######################################## def on_backend_selected(self, backend_id): """ When a backend in the treeview gets selected, show its configuration pane @param backend_id: the id of the selected backend """ if backend_id: self._show_panel("configuration") self.config_panel.set_backend(backend_id) backend = self.req.get_backend(backend_id) self.remove_button.set_sensitive(not backend.is_default()) def on_add_button(self, widget=None, data=None): """ When the add button is pressed, the add panel is shown @param widget: not used, here only for using this as signal callback @param data: same as widget, disregard the content """ self._show_panel("add") self.add_panel.refresh_backends() def on_backend_added(self, backend_name): """ When a backend is added, it is created and registered in the Datastore. Also, the configuration panel is shown. @param backend_name: the name of the type of the backend to add (identified as BACKEND_NAME in the Backend class) """ # Create Backend backend_dic = BackendFactory().get_new_backend_dict(backend_name) if backend_dic: backend_dic[GenericBackend.KEY_ENABLED] = False self.req.register_backend(backend_dic) # Restore UI self._show_panel("configuration") def show_config_for_backend(self, backend_id): """ Selects a backend in the lateral treeview @param backend_id: the id of the backend that must be selected """ self.backends_tv.select_backend(backend_id) def on_remove_button(self, widget=None, data=None): """ When the remove button is pressed, a confirmation dialog is shown, and if the answer is positive, the backend is deleted. """ backend_id = self.backends_tv.get_selected_backend_id() if backend_id is None: # no backend selected return backend = self.req.get_backend(backend_id) dialog = Gtk.MessageDialog( parent=self.dialog, flags=Gtk.DialogFlags.DESTROY_WITH_PARENT, type=Gtk.MessageType.QUESTION, buttons=Gtk.ButtonsType.YES_NO, message_format=_("Do you really want to remove the '%s' " "synchronization service?") % backend.get_human_name()) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.YES: # delete the backend and remove it from the lateral treeview self.req.remove_backend(backend_id) self.backends_tv.remove_backend(backend_id)
def _create_widgets_for_conf_panel(self): """simply creates the panel to configure backends""" self.config_panel = ConfigurePanel(self)