diff options
author | bendikro <bendikro@gmail.com> | 2013-05-17 19:06:00 +0100 |
---|---|---|
committer | Calum Lind <calumlind+deluge@gmail.com> | 2013-05-18 17:55:25 +0100 |
commit | 1596475db23e66d0d54fb927113a4850b95efc9d (patch) | |
tree | 52d84c36334b637b9670248d53ac14232ca5b154 /deluge/ui/gtkui/path_chooser.py | |
parent | 42f5cc382dad06cbf584d6bd41303e2f0e3a0167 (diff) | |
download | deluge-1596475d.tar.gz deluge-1596475d.tar.bz2 deluge-1596475d.zip |
GTKUI: New path chooser to handle remote paths and store favorite paths
Diffstat (limited to 'deluge/ui/gtkui/path_chooser.py')
-rw-r--r-- | deluge/ui/gtkui/path_chooser.py | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/deluge/ui/gtkui/path_chooser.py b/deluge/ui/gtkui/path_chooser.py new file mode 100644 index 000000000..533839c66 --- /dev/null +++ b/deluge/ui/gtkui/path_chooser.py @@ -0,0 +1,191 @@ +# +# path_chooser.py +# +# Copyright (C) 2013 Bro <bro.development@gmail.com> +# +# Deluge is free software. +# +# You may redistribute it and/or modify it under the terms of the +# GNU General Public License, as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) +# any later version. +# +# deluge is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with deluge. If not, write to: +# The Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor +# Boston, MA 02110-1301, USA. +# +# In addition, as a special exception, the copyright holders give +# permission to link the code of portions of this program with the OpenSSL +# library. +# You must obey the GNU General Public License in all respects for all of +# the code used other than OpenSSL. If you modify file(s) with this +# exception, you may extend this exception to your version of the file(s), +# but you are not obligated to do so. If you do not wish to do so, delete +# this exception statement from your version. If you delete this exception +# statement from all source files in the program, then also delete it here. +# + +import logging + +from deluge.ui.client import client +from deluge.ui.gtkui.path_combo_chooser import PathChooserComboBox +import deluge.component as component + +log = logging.getLogger(__name__) + +def singleton(cls): + instances = {} + def getinstance(): + if cls not in instances: + instances[cls] = cls() + return instances[cls] + return getinstance + +@singleton +class PathChoosersHandler(component.Component): + + def __init__(self, paths_config_key=None): + #self.chooser_name = "PathChooser_%d" % (len(PathChooser.path_choosers) +1) + component.Component.__init__(self, "PathChoosersHandler") + self.path_choosers = [] + self.paths_list_keys = [] + self.config_properties = {} + self.started = False + self.config_keys_to_funcs_mapping = {"path_chooser_show_chooser_button_on_localhost": "filechooser_button_visible", + "path_chooser_show_path_entry": "path_entry_visible", + "path_chooser_auto_complete_enabled": "auto_complete_enabled", + "path_chooser_show_folder_name": "show_folder_name_on_button", + "path_chooser_accelerator_string": "accelerator_string", + "path_chooser_show_hidden_files": "show_hidden_files", + "path_chooser_max_popup_rows": "max_popup_rows", + } + def start(self): + self.started = True + self.update_config_from_core() + + def stop(self): + self.started = False + + def update_config_from_core(self): + def _on_config_values(config): + self.config_properties.update(config) + for chooser in self.path_choosers: + chooser.set_config(config) + keys = self.config_keys_to_funcs_mapping.keys() + keys += self.paths_list_keys + client.core.get_config_values(keys).addCallback(_on_config_values) + + def register_chooser(self, chooser): + chooser.config_key_funcs = {} + for key in self.config_keys_to_funcs_mapping: + chooser.config_key_funcs[key] = [None, None] + chooser.config_key_funcs[key][0] = getattr(chooser, "get_%s" % self.config_keys_to_funcs_mapping[key]) + chooser.config_key_funcs[key][1] = getattr(chooser, "set_%s" % self.config_keys_to_funcs_mapping[key]) + + self.path_choosers.append(chooser) + if not chooser.paths_config_key in self.paths_list_keys: + self.paths_list_keys.append(chooser.paths_config_key) + if self.started: + self.update_config_from_core() + else: + chooser.set_config(self.config_properties) + + def set_value_for_path_choosers(self, value, key): + for chooser in self.path_choosers: + chooser.config_key_funcs[key][1](value) + + # Save to core + if not key is "path_chooser_max_popup_rows": + client.core.set_config({key: value}) + else: + # Since the max rows value can be changed fast with a spinbutton, we + # delay saving to core until the values hasn't been changed in 1 second. + self.max_rows_value_set = value + def update(value_): + # The value hasn't been changed in one second, so save to core + if self.max_rows_value_set == value_: + client.core.set_config({"path_chooser_max_popup_rows": value}) + from twisted.internet import reactor + reactor.callLater(1, update, value) + + def on_list_values_changed(self, values, key, caller): + # Save to core + config = { key : values } + client.core.set_config(config) + # Set the values on all path choosers with that key + for chooser in self.path_choosers: + # Found chooser with values from 'key' + if chooser.paths_config_key == key: + chooser.set_values(values) + + def get_config_keys(self): + keys = self.config_keys_to_funcs_mapping.keys() + keys += self.paths_list_keys + return keys + +class PathChooser(PathChooserComboBox): + + def __init__(self, paths_config_key=None): + self.paths_config_key = paths_config_key + PathChooserComboBox.__init__(self) + self.chooser_handler = PathChoosersHandler() + self.chooser_handler.register_chooser(self) + self.set_auto_completer_func(self.on_completion) + self.connect("list-values-changed", self.on_list_values_changed_event) + self.connect("auto-complete-enabled-toggled", self.on_auto_complete_enabled_toggled) + self.connect("show-filechooser-toggled", self.on_show_filechooser_toggled) + self.connect("show-folder-name-on-button", self.on_show_folder_on_button_toggled) + self.connect("show-path-entry-toggled", self.on_show_path_entry_toggled) + self.connect("accelerator-set", self.on_accelerator_set) + self.connect("max-rows-changed", self.on_max_rows_changed) + self.connect("show-hidden-files-toggled", self.on_show_hidden_files_toggled) + + def on_auto_complete_enabled_toggled(self, widget, value): + self.chooser_handler.set_value_for_path_choosers(value, "path_chooser_auto_complete_enabled") + + def on_show_filechooser_toggled(self, widget, value): + self.chooser_handler.set_value_for_path_choosers(value, "path_chooser_show_chooser_button_on_localhost") + + def on_show_folder_on_button_toggled(self, widget, value): + self.chooser_handler.set_value_for_path_choosers(value, "path_chooser_show_folder_name") + + def on_show_path_entry_toggled(self, widget, value): + self.chooser_handler.set_value_for_path_choosers(value, "path_chooser_show_path_entry") + + def on_accelerator_set(self, widget, value): + self.chooser_handler.set_value_for_path_choosers(value, "path_chooser_accelerator_string") + + def on_show_hidden_files_toggled(self, widget, value): + self.chooser_handler.set_value_for_path_choosers(value, "path_chooser_show_hidden_files") + + def on_max_rows_changed(self, widget, value): + self.chooser_handler.set_value_for_path_choosers(value, "path_chooser_max_popup_rows") + + def on_list_values_changed_event(self, widget, values): + self.chooser_handler.on_list_values_changed(values, self.paths_config_key, self) + + def set_config(self, config): + self.config = config + for key in self.config_key_funcs: + if key in config: + try: + self.config_key_funcs[key][1](config[key]) + except TypeError, e: + log.warn("TypeError: %s" % str(e)) + + # Set the saved paths + if self.paths_config_key and self.paths_config_key in config: + self.set_values(config[self.paths_config_key]) + + def on_completion(self, value, hidden_files): + def on_paths_cb(paths): + self.complete(value, paths) + d = client.core.get_completion_paths(value, hidden_files=hidden_files) + d.addCallback(on_paths_cb) |