예제 #1
0
class BackendsDialog(object):
    '''
    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
        self.icon_theme = None
        self._configure_icon_theme()
        # 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(_("Synchronization Services - %s" % 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)
        '''
        icon_info = self.icon_theme.lookup_icon(name, height, 0)
        if icon_info is None:
            return None
        else:
            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 not panel_to_add 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_dialog',
            '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_BackendsDialog_delete_event': self.on_close,
            'on_close_button_clicked': self.on_close,
            'on_remove_button_clicked': self.on_remove_button,
            'on_help_button_clicked': lambda w:
            openurl("help:gtg/gtg-add-sync"),
        }
        builder.connect_signals(signals)

    def _configure_icon_theme(self):
        '''
        Inform gtk on the location of the backends icons (which is in
        the GTG directory tree, and not in the default location for icons
        '''
        self.icon_theme = Gtk.IconTheme.get_default()
        for directory in CoreConfig().get_icons_directories():
            self.icon_theme.prepend_search_path(directory)

    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)
예제 #2
0
class BackendsDialog(object):
    '''
    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(_("Synchronization Services - %s" % info.NAME))
        self._create_widgets_for_add_panel()
        self._create_widgets_for_conf_panel()
        self._setup_signal_connections(builder)
        self._create_widgets_for_treeview()
        help.add_help_shortcut(self.dialog, "sync")

########################################
# 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_dialog',
            '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_BackendsDialog_delete_event': self.on_close,
            'on_close_button_clicked': self.on_close,
            'on_remove_button_clicked': self.on_remove_button,
            'on_help_button_clicked': self.on_help,
        }
        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 #######################
########################################

    @classmethod
    def on_help(cls, widget):
        """ Open help for syncronization services """
        help.show_help("sync")
        return True

    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)
예제 #3
0
 def _create_widgets_for_conf_panel(self):
     '''simply creates the panel to configure backends'''
     self.config_panel = ConfigurePanel(self)
예제 #4
0
 def _create_widgets_for_conf_panel(self):
     '''simply creates the panel to configure backends'''
     self.config_panel = ConfigurePanel(self)