# # path_chooser.py # # Copyright (C) 2013 Bro # # 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)