diff --git a/deluge/common.py b/deluge/common.py index 50a94177a..d24de40d3 100644 --- a/deluge/common.py +++ b/deluge/common.py @@ -165,6 +165,18 @@ def get_default_download_dir(): if windows_check(): return os.path.expanduser("~") else: + from xdg.BaseDirectory import xdg_config_home + userdir_file = os.path.join(xdg_config_home, 'user-dirs.dirs') + try: + for line in open(userdir_file, 'r'): + if not line.startswith('#') and 'XDG_DOWNLOAD_DIR' in line: + download_dir = os.path.expandvars(\ + line.partition("=")[2].rstrip().strip('"')) + if os.path.isdir(download_dir): + return download_dir + except IOError: + pass + return os.environ.get("HOME") def windows_check(): @@ -527,7 +539,7 @@ def path_join(*parts): path += '/' + part return path -XML_ESCAPES = ( +XML_ESCAPES = ( ('&', '&'), ('<', '<'), ('>', '>'), @@ -536,9 +548,9 @@ XML_ESCAPES = ( ) def xml_decode(string): - """ + """ Unescape a string that was previously encoded for use within xml. - + :param string: The string to escape :type string: string :returns: The unescaped version of the string. @@ -549,9 +561,9 @@ def xml_decode(string): return string def xml_encode(string): - """ + """ Escape a string for use within an xml element or attribute. - + :param string: The string to escape :type string: string :returns: An escaped version of the string. diff --git a/deluge/plugins/autoadd/autoadd/gtkui.py b/deluge/plugins/autoadd/autoadd/gtkui.py index 3fe74ca29..7b069f3cd 100644 --- a/deluge/plugins/autoadd/autoadd/gtkui.py +++ b/deluge/plugins/autoadd/autoadd/gtkui.py @@ -113,22 +113,22 @@ class OptionsDialog(): self.glade.get_widget(field+"_entry").show() self.glade.get_widget(field+"_chooser").hide() self.set_sensitive() - + def on_get_enabled_plugins(result): - if 'Label' in result: + if 'Label' in result: self.glade.get_widget('label_frame').show() else: self.glade.get_widget('label_frame').hide() self.glade.get_widget('label_toggle').set_active(False) - + client.core.get_enabled_plugins().addCallback(on_get_enabled_plugins) - + def set_sensitive(self): maintoggles = ['download_location', 'append_extension', 'move_completed', 'label', \ 'max_download_speed', 'max_upload_speed', 'max_connections', \ 'max_upload_slots', 'add_paused', 'auto_managed', 'stop_at_ratio', 'queue_to_top'] [self.on_toggle_toggled(self.glade.get_widget(x+'_toggle')) for x in maintoggles] - + def on_toggle_toggled(self, tb): toggle = str(tb.name).replace("_toggle", "") isactive = tb.get_active() @@ -166,29 +166,29 @@ class OptionsDialog(): self.glade.get_widget('stop_at_ratio').set_active(isactive) self.glade.get_widget('stop_ratio').set_sensitive(isactive) self.glade.get_widget('remove_at_ratio').set_sensitive(isactive) - + def on_apply(self, Event=None): client.autoadd.set_options(str(self.watchdir_id), self.generate_opts()).addCallbacks(self.on_added, self.on_error_show) - + def on_error_show(self, result): self.glade.get_widget('error_label').set_text(result.value.exception_msg) self.err_dialog = self.glade.get_widget('error_dialog') self.err_dialog.set_transient_for(self.dialog) result.cleanFailure() self.err_dialog.show() - + def on_added(self, result): self.dialog.destroy() - + def on_error_ok(self, Event=None): self.err_dialog.hide() - + def on_add(self, Event=None): client.autoadd.add(self.generate_opts()).addCallbacks(self.on_added, self.on_error_show) - + def on_cancel(self, Event=None): self.dialog.destroy() - + def generate_opts(self): # generate options dict based on gtk objects options = {} @@ -217,11 +217,11 @@ class OptionsDialog(): options[id] = self.glade.get_widget(id).get_active() options[id+'_toggle'] = self.glade.get_widget(id+'_toggle').get_active() return options - + class GtkUI(GtkPluginBase): def enable(self): - + self.glade = gtk.glade.XML(get_resource("config.glade")) self.glade.signal_autoconnect({ "on_add_button_clicked": self.on_add_button_clicked, @@ -229,18 +229,18 @@ class GtkUI(GtkPluginBase): "on_remove_button_clicked": self.on_remove_button_clicked }) self.opts_dialog = OptionsDialog() - + component.get("PluginManager").register_hook("on_apply_prefs", self.on_apply_prefs) component.get("PluginManager").register_hook("on_show_prefs", self.on_show_prefs) client.register_event_handler("AutoaddOptionsChangedEvent", self.on_options_changed_event) - + self.watchdirs = {} - + vbox = self.glade.get_widget("watchdirs_vbox") sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - + vbox.pack_start(sw, True, True, 0) self.store = self.create_model() @@ -256,28 +256,28 @@ class GtkUI(GtkPluginBase): component.get("Preferences").add_page("AutoAdd", self.glade.get_widget("prefs_box")) self.on_show_prefs() - + def disable(self): component.get("Preferences").remove_page("AutoAdd") component.get("PluginManager").deregister_hook("on_apply_prefs", self.on_apply_prefs) component.get("PluginManager").deregister_hook("on_show_prefs", self.on_show_prefs) - + def create_model(self): - + store = gtk.ListStore(str, bool, str) for watchdir_id, watchdir in self.watchdirs.iteritems(): store.append([watchdir_id, watchdir['enabled'], watchdir['path']]) return store - + def create_columns(self, treeView): rendererToggle = gtk.CellRendererToggle() - column = gtk.TreeViewColumn("On", rendererToggle, activatable=True, active=1) - column.set_sort_column_id(1) + column = gtk.TreeViewColumn("On", rendererToggle, activatable=1, active=1) + column.set_sort_column_id(1) treeView.append_column(column) tt = gtk.Tooltip() tt.set_text('Double-click to toggle') treeView.set_tooltip_cell(tt, None, None, rendererToggle) - + rendererText = gtk.CellRendererText() column = gtk.TreeViewColumn("Path", rendererText, text=2) column.set_sort_column_id(2) @@ -289,20 +289,20 @@ class GtkUI(GtkPluginBase): def load_watchdir_list(self): pass - + def add_watchdir_entry(self): pass - + def on_add_button_clicked(self, Event=None): #display options_window self.opts_dialog.show() - + def on_remove_button_clicked(self, Event=None): tree, tree_id = self.treeView.get_selection().get_selected() watchdir_id = str(self.store.get_value(tree_id, 0)) if watchdir_id: client.autoadd.remove(watchdir_id) - + def on_edit_button_clicked(self, Event=None, a=None, col=None): tree, tree_id = self.treeView.get_selection().get_selected() watchdir_id = str(self.store.get_value(tree_id, 0)) @@ -314,7 +314,7 @@ class GtkUI(GtkPluginBase): client.autoadd.enable_watchdir(watchdir_id) else: self.opts_dialog.show(self.watchdirs[watchdir_id], watchdir_id) - + def on_listitem_activated(self, treeview): tree, tree_id = self.treeView.get_selection().get_selected() if tree_id: @@ -323,7 +323,7 @@ class GtkUI(GtkPluginBase): else: self.glade.get_widget('edit_button').set_sensitive(False) self.glade.get_widget('remove_button').set_sensitive(False) - + def on_apply_prefs(self): log.debug("applying prefs for AutoAdd") for watchdir_id, watchdir in self.watchdirs.iteritems(): @@ -331,7 +331,7 @@ class GtkUI(GtkPluginBase): def on_show_prefs(self): client.autoadd.get_config().addCallback(self.cb_get_config) - + def on_options_changed_event(self): client.autoadd.get_config().addCallback(self.cb_get_config) @@ -344,4 +344,4 @@ class GtkUI(GtkPluginBase): # Disable the remove and edit buttons, because nothing in the store is selected self.glade.get_widget('remove_button').set_sensitive(False) self.glade.get_widget('edit_button').set_sensitive(False) - + diff --git a/deluge/plugins/autoadd/setup.py b/deluge/plugins/autoadd/setup.py index 156493167..fe0d7df43 100644 --- a/deluge/plugins/autoadd/setup.py +++ b/deluge/plugins/autoadd/setup.py @@ -42,7 +42,7 @@ from setuptools import setup __plugin_name__ = "AutoAdd" __author__ = "Chase Sterling" __author_email__ = "chase.sterling@gmail.com" -__version__ = "1.02" +__version__ = "1.03" __url__ = "http://dev.deluge-torrent.org/wiki/Plugins/AutoAdd" __license__ = "GPLv3" __description__ = "Monitors folders for .torrent files." diff --git a/deluge/ui/gtkui/files_tab.py b/deluge/ui/gtkui/files_tab.py index 8442331bc..53db593b2 100644 --- a/deluge/ui/gtkui/files_tab.py +++ b/deluge/ui/gtkui/files_tab.py @@ -119,7 +119,8 @@ class FilesTab(Tab): self._editing_index = None # Filename column - column = gtk.TreeViewColumn(_("Filename")) + self.filename_column_name = _("Filename") + column = gtk.TreeViewColumn(self.filename_column_name) render = gtk.CellRendererPixbuf() column.pack_start(render, False) column.add_attribute(render, "stock-id", 6) @@ -437,9 +438,8 @@ class FilesTab(Tab): """ Go through the tree and update the folder complete percentages. """ - root = self.treestore.get_iter_root() - if self.treestore[root][5] != -1: + if root is None or self.treestore[root][5] != -1: return def get_completed_bytes(row): @@ -482,7 +482,10 @@ class FilesTab(Tab): if self._editing_index == row[5]: continue - progress_string = "%.2f%%" % (status["file_progress"][index] * 100) + try: + progress_string = "%.2f%%" % (status["file_progress"][index] * 100) + except IndexError: + continue if row[2] != progress_string: row[2] = progress_string progress_value = status["file_progress"][index] * 100 @@ -501,17 +504,15 @@ class FilesTab(Tab): # We only care about right-clicks if event.button == 3: x, y = event.get_coords() - path = self.listview.get_path_at_pos(int(x), int(y)) - if not path: + cursor_path = self.listview.get_path_at_pos(int(x), int(y)) + if not cursor_path: return - row = self.treestore.get_iter(path[0]) - if self.get_selected_files(): - if self.treestore.get_value(row, 5) not in self.get_selected_files(): + paths = self.listview.get_selection().get_selected_rows()[1] + if cursor_path[0] not in paths: + row = self.treestore.get_iter(cursor_path[0]) self.listview.get_selection().unselect_all() self.listview.get_selection().select_iter(row) - else: - self.listview.get_selection().select_iter(row) for widget in self.file_menu_priority_items: widget.set_sensitive(not self.__compact) @@ -520,16 +521,25 @@ class FilesTab(Tab): return True def _on_key_press_event(self, widget, event): - # Menu key - if gtk.gdk.keyval_name(event.keyval) != "Menu": - return - - if not self.get_selected_files(): + keyname = gtk.gdk.keyval_name(event.keyval) + func = getattr(self, 'keypress_' + keyname, None) + selected_rows = self.listview.get_selection().get_selected_rows()[1] + if func and selected_rows: + return func(event) + else: return + def keypress_Menu(self, event): self.file_menu.popup(None, None, None, 3, event.time) return True + def keypress_F2(self, event): + path, col = self.listview.get_cursor() + for column in self.listview.get_columns(): + if column.get_title() == self.filename_column_name: + self.listview.set_cursor(path, column, True) + return True + def _on_menuitem_open_file_activate(self, menuitem): self._on_row_activated(None, None, None)