예제 #1
0
 def __confirmation_dialog_response(widget, response_id):
     if response_id == Gtk.ResponseType.OK:
         Utility.reset_config()
         self.config = Config()
         # Remove breaks from the container
         self.box_short_breaks.foreach(lambda element: self.box_short_breaks.remove(element))
         self.box_long_breaks.foreach(lambda element: self.box_long_breaks.remove(element))
         # Remove plugins from the container
         self.box_plugins.foreach(lambda element: self.box_plugins.remove(element))
         # Initialize again
         self.__initialize(self.config)
     widget.destroy()
예제 #2
0
def main():
    """
    Start the Safe Eyes.
    """
    system_locale = gettext.translation('safeeyes', localedir=Utility.LOCALE_PATH, languages=[Utility.system_locale(), 'en_US'], fallback=True)
    system_locale.install()
    # locale.bindtextdomain is required for Glade files
    # gettext.bindtextdomain(gettext.textdomain(), Utility.LOCALE_PATH)
    locale.bindtextdomain('safeeyes', Utility.LOCALE_PATH)

    parser = argparse.ArgumentParser(prog='safeeyes', description=_('description'))
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-a', '--about', help=_('show the about dialog'), action='store_true')
    group.add_argument('-d', '--disable', help=_('disable the currently running safeeyes instance'), action='store_true')
    group.add_argument('-e', '--enable', help=_('enable the currently running safeeyes instance'), action='store_true')
    group.add_argument('-q', '--quit', help=_('quit the running safeeyes instance and exit'), action='store_true')
    group.add_argument('-s', '--settings', help=_('show the settings dialog'), action='store_true')
    group.add_argument('-t', '--take-break', help=_('Take a break now').lower(), action='store_true')
    parser.add_argument('--debug', help=_('start safeeyes in debug mode'), action='store_true')
    parser.add_argument('--version', action='version', version='%(prog)s ' + SAFE_EYES_VERSION)
    args = parser.parse_args()

    # Initialize the logging
    Utility.intialize_logging(args.debug)
    config = Config()

    if __running():
        logging.info("Safe Eyes is already running")
        rpc_client = RPCClient(config.get('rpc_port'))
        if args.about:
            rpc_client.show_about()
        elif args.disable:
            rpc_client.disable_safeeyes()
        elif args.enable:
            rpc_client.enable_safeeyes()
        elif args.settings:
            rpc_client.show_settings()
        elif args.take_break:
            rpc_client.take_break()
        elif args.quit:
            rpc_client.quit()
        else:
            # Default behavior is opening settings
            rpc_client.show_settings()
        sys.exit(0)
    elif not args.quit:
        logging.info("Starting Safe Eyes")
        safeeyes = SafeEyes(system_locale, config)
        safeeyes.start()
        Timer(1.0, lambda: __evaluate_arguments(args, safeeyes)).start()
        Gtk.main()
예제 #3
0
class SettingsDialog(object):
    """
        Create and initialize SettingsDialog instance.
    """

    def __init__(self, config, on_save_settings):
        self.config = config
        self.on_save_settings = on_save_settings
        self.plugin_switches = {}
        self.plugin_map = {}
        self.last_short_break_interval = config.get('short_break_interval')
        self.initializing = True
        self.infobar_long_break_shown = False

        builder = Utility.create_gtk_builder(SETTINGS_DIALOG_GLADE)
        builder.connect_signals(self)

        self.window = builder.get_object('window_settings')
        self.box_short_breaks = builder.get_object('box_short_breaks')
        self.box_long_breaks = builder.get_object('box_long_breaks')
        self.box_plugins = builder.get_object('box_plugins')
        self.popover = builder.get_object('popover')

        self.spin_short_break_duration = builder.get_object('spin_short_break_duration')
        self.spin_long_break_duration = builder.get_object('spin_long_break_duration')
        self.spin_short_break_interval = builder.get_object('spin_short_break_interval')
        self.spin_long_break_interval = builder.get_object('spin_long_break_interval')
        self.spin_time_to_prepare = builder.get_object('spin_time_to_prepare')
        self.spin_postpone_duration = builder.get_object('spin_postpone_duration')
        self.spin_disable_keyboard_shortcut = builder.get_object('spin_disable_keyboard_shortcut')
        self.switch_strict_break = builder.get_object('switch_strict_break')
        self.switch_postpone = builder.get_object('switch_postpone')
        self.switch_persist = builder.get_object('switch_persist')
        self.info_bar_long_break = builder.get_object("info_bar_long_break")
        self.info_bar_long_break.hide()

        # Set the current values of input fields
        self.__initialize(config)

        # Update relative states
        # GtkSwitch state-set signal is available only from 3.14
        if Gtk.get_minor_version() >= 14:
            self.switch_strict_break.connect('state-set', self.on_switch_strict_break_activate)
            self.switch_postpone.connect('state-set', self.on_switch_postpone_activate)
            self.on_switch_strict_break_activate(self.switch_strict_break, self.switch_strict_break.get_active())
            self.on_switch_postpone_activate(self.switch_postpone, self.switch_postpone.get_active())
        self.initializing = False

    def __initialize(self, config):
        # Don't show infobar for changes made internally
        self.infobar_long_break_shown = True
        for short_break in config.get('short_breaks'):
            self.__create_break_item(short_break, True)
        for long_break in config.get('long_breaks'):
            self.__create_break_item(long_break, False)

        for plugin_config in Utility.load_plugins_config(config):
            self.box_plugins.pack_start(self.__create_plugin_item(plugin_config), False, False, 0)
            
        self.spin_short_break_duration.set_value(config.get('short_break_duration'))
        self.spin_long_break_duration.set_value(config.get('long_break_duration'))
        self.spin_short_break_interval.set_value(config.get('short_break_interval'))
        self.spin_long_break_interval.set_value(config.get('long_break_interval'))
        self.spin_time_to_prepare.set_value(config.get('pre_break_warning_time'))
        self.spin_postpone_duration.set_value(config.get('postpone_duration'))
        self.spin_disable_keyboard_shortcut.set_value(config.get('shortcut_disable_time'))
        self.switch_strict_break.set_active(config.get('strict_break'))
        self.switch_postpone.set_active(config.get('allow_postpone'))
        self.switch_persist.set_active(config.get('persist_state'))
        self.infobar_long_break_shown = False

    def __create_break_item(self, break_config, is_short):
        """
        Create an entry for break to be listed in the break tab.
        """
        parent_box = self.box_long_breaks
        if is_short:
            parent_box = self.box_short_breaks
        builder = Utility.create_gtk_builder(SETTINGS_BREAK_ITEM_GLADE)
        box = builder.get_object('box')
        lbl_name = builder.get_object('lbl_name')
        lbl_name.set_label(_(break_config['name']))
        btn_properties = builder.get_object('btn_properties')
        btn_properties.connect(
            'clicked',
            lambda button: self.__show_break_properties_dialog(
                break_config,
                is_short,
                self.config,
                lambda cfg: lbl_name.set_label(_(cfg['name'])),
                lambda is_short, break_config: self.__create_break_item(break_config, is_short),
                lambda: parent_box.remove(box)
            )
        )
        btn_delete = builder.get_object('btn_delete')
        btn_delete.connect(
            'clicked',
            lambda button: self.__delete_break(
                break_config,
                is_short,
                lambda: parent_box.remove(box),
            )
        )
        box.set_visible(True)
        parent_box.pack_start(box, False, False, 0)
        return box

    def on_reset_menu_clicked(self, button):
        self.popover.hide()
        def __confirmation_dialog_response(widget, response_id):
            if response_id == Gtk.ResponseType.OK:
                Utility.reset_config()
                self.config = Config()
                # Remove breaks from the container
                self.box_short_breaks.foreach(lambda element: self.box_short_breaks.remove(element))
                self.box_long_breaks.foreach(lambda element: self.box_long_breaks.remove(element))
                # Remove plugins from the container
                self.box_plugins.foreach(lambda element: self.box_plugins.remove(element))
                # Initialize again
                self.__initialize(self.config)
            widget.destroy()

        messagedialog = Gtk.MessageDialog(parent=self.window,
                                          flags=Gtk.DialogFlags.MODAL,
                                          type=Gtk.MessageType.WARNING,
                                          buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                                   _("Reset"), Gtk.ResponseType.OK),
                                          message_format=_("Are you sure you want to reset all settings to default?"))
        messagedialog.connect("response", __confirmation_dialog_response)
        messagedialog.format_secondary_text(_("You can't undo this action."))
        messagedialog.show()

    def __delete_break(self, break_config, is_short, on_remove):
        """
        Remove the break after a confirmation.
        """

        def __confirmation_dialog_response(widget, response_id):
            if response_id == Gtk.ResponseType.OK:
                if is_short:
                    self.config.get('short_breaks').remove(break_config)
                else:
                    self.config.get('long_breaks').remove(break_config)
                on_remove()
            widget.destroy()

        messagedialog = Gtk.MessageDialog(parent=self.window,
                                          flags=Gtk.DialogFlags.MODAL,
                                          type=Gtk.MessageType.WARNING,
                                          buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                                   _("Delete"), Gtk.ResponseType.OK),
                                          message_format=_("Are you sure you want to delete this break?"))
        messagedialog.connect("response", __confirmation_dialog_response)
        messagedialog.format_secondary_text(_("You can't undo this action."))
        messagedialog.show()

    def __create_plugin_item(self, plugin_config):
        """
        Create an entry for plugin to be listed in the plugin tab.
        """
        builder = Utility.create_gtk_builder(SETTINGS_PLUGIN_ITEM_GLADE)
        lbl_plugin_name = builder.get_object('lbl_plugin_name')
        lbl_plugin_description = builder.get_object('lbl_plugin_description')
        switch_enable = builder.get_object('switch_enable')
        btn_properties = builder.get_object('btn_properties')
        lbl_plugin_name.set_label(_(plugin_config['meta']['name']))
        switch_enable.set_active(plugin_config['enabled'])
        if plugin_config['error']:
            lbl_plugin_description.set_label(_(plugin_config['meta']['description']))
            lbl_plugin_name.set_sensitive(False)
            lbl_plugin_description.set_sensitive(False)
            switch_enable.set_sensitive(False)
        else:
            lbl_plugin_description.set_label(_(plugin_config['meta']['description']))
        self.plugin_switches[plugin_config['id']] = switch_enable
        if plugin_config.get('break_override_allowed', False):
            self.plugin_map[plugin_config['id']] = plugin_config['meta']['name']
        if plugin_config['icon']:
            builder.get_object('img_plugin_icon').set_from_file(plugin_config['icon'])
        if plugin_config['settings']:
            btn_properties.set_sensitive(True)
            btn_properties.connect('clicked', lambda button: self.__show_plugins_properties_dialog(plugin_config))
        else:
            btn_properties.set_sensitive(False)
        box = builder.get_object('box')
        box.set_visible(True)
        return box

    def __show_plugins_properties_dialog(self, plugin_config):
        """
        Show the PluginProperties dialog
        """
        dialog = PluginSettingsDialog(plugin_config)
        dialog.show()

    def __show_break_properties_dialog(self, break_config, is_short, parent, on_close, on_add, on_remove):
        """
        Show the BreakProperties dialog
        """
        dialog = BreakSettingsDialog(break_config, is_short, parent, self.plugin_map, on_close, on_add, on_remove)
        dialog.show()

    def show(self):
        """
        Show the SettingsDialog.
        """
        self.window.show_all()

    def on_switch_strict_break_activate(self, switch, state):
        """
        Event handler to the state change of the postpone switch.
        Enable or disable the self.spin_postpone_duration based on the state of the postpone switch.
        """
        strict_break_enable = state
        self.switch_postpone.set_sensitive(not strict_break_enable)
        self.spin_disable_keyboard_shortcut.set_sensitive(not strict_break_enable)

    def on_switch_postpone_activate(self, switch, state):
        """
        Event handler to the state change of the postpone switch.
        Enable or disable the self.spin_postpone_duration based on the state of the postpone switch.
        """
        self.spin_postpone_duration.set_sensitive(self.switch_postpone.get_active())

    def on_spin_short_break_interval_change(self, spin_button, *value):
        """
        Event handler for value change of short break interval.
        """
        short_break_interval = self.spin_short_break_interval.get_value_as_int()
        long_break_interval = self.spin_long_break_interval.get_value_as_int()
        self.spin_long_break_interval.set_range(short_break_interval, 120)
        self.spin_long_break_interval.set_increments(short_break_interval, short_break_interval * 2)
        self.spin_long_break_interval.set_value(short_break_interval * math.ceil(long_break_interval / self.last_short_break_interval))
        self.last_short_break_interval = short_break_interval
        if not self.initializing and not self.infobar_long_break_shown:
            self.infobar_long_break_shown = True
            self.info_bar_long_break.show()

    def on_spin_long_break_interval_change(self, spin_button, *value):
        """
        Event handler for value change of long break interval.
        """
        if not self.initializing and not self.infobar_long_break_shown:
            self.infobar_long_break_shown = True
            self.info_bar_long_break.show()

    def on_info_bar_long_break_close(self, infobar, *user_data):
        """
        Event handler for info bar close action.
        """
        self.info_bar_long_break.hide()

    def add_break(self, button):
        """
        Event handler for add break button.
        """
        dialog = NewBreakDialog(self.config, lambda is_short, break_config: self.__create_break_item(break_config, is_short))
        dialog.show()

    def on_window_delete(self, *args):
        """
        Event handler for Settings dialog close action.
        """
        self.config.set('short_break_duration', self.spin_short_break_duration.get_value_as_int())
        self.config.set('long_break_duration', self.spin_long_break_duration.get_value_as_int())
        self.config.set('short_break_interval', self.spin_short_break_interval.get_value_as_int())
        self.config.set('long_break_interval', self.spin_long_break_interval.get_value_as_int())
        self.config.set('pre_break_warning_time', self.spin_time_to_prepare.get_value_as_int())
        self.config.set('postpone_duration', self.spin_postpone_duration.get_value_as_int())
        self.config.set('shortcut_disable_time', self.spin_disable_keyboard_shortcut.get_value_as_int())
        self.config.set('strict_break', self.switch_strict_break.get_active())
        self.config.set('allow_postpone', self.switch_postpone.get_active())
        self.config.set('persist_state', self.switch_persist.get_active())
        for plugin in self.config.get('plugins'):
            if plugin['id'] in self.plugin_switches:
                plugin['enabled'] = self.plugin_switches[plugin['id']].get_active()

        self.on_save_settings(self.config)    # Call the provided save method
        self.window.destroy()