コード例 #1
0
  def update_store(self, store):

    def restore_adjustment(value):

      adj = self._tree.parent.get_vadjustment()
      upper = adj.get_upper() - adj.get_page_size()

      if value > upper:
        value = upper

      adj.set_value(value)


    self._store.destroy()
    self._store = store.copy()
    if __debug__: RT.register(self._store, __name__)

    value = self._tree.parent.get_vadjustment().get_value()
    gobject.idle_add(restore_adjustment, value)

    if self._tree.window:
      self._tree.window.freeze_updates()
      gobject.idle_add(self._tree.window.thaw_updates)

    selection = self._tree.get_selection()
    selection.handler_block_by_func(self._on_selection_changed)

    self._tree.set_model(self._store.model)
    self._load_state()

    selection.handler_unblock_by_func(self._on_selection_changed)
コード例 #2
0
  def _create_options_item(self):

    def on_activate(widget):

      try:
        ids = self.get_selected_torrent_labels()
        dialog = LabelOptionsDialog(self._plugin, ids[0])
        if __debug__: RT.register(dialog, __name__)
        dialog.show()
      except:
        log.exception("Error initializing LabelOptionsDialog")
        pass


    def on_show(widget, item):

      ids = self.get_selected_torrent_labels()
      if ids and len(ids) == 1 and self._store.is_user_label(ids[0]):
        item.show()
      else:
        item.hide()


    item = gtk.MenuItem(_(TITLE_LABEL_OPTIONS))
    item.connect("activate", on_activate)

    self._menu.get_submenu().connect("show", on_show, item)

    if __debug__: RT.register(item, __name__)

    return item
コード例 #3
0
  def __init__(self, plugin):

    self._plugin = plugin
    self._view = deluge.component.get("TorrentView")
    self._menubar = deluge.component.get("MenuBar")

    self._store = None

    self._menu = None
    self._sep = None
    self._submenus = []

    self._alt_menu = None

    self._dnd_src_proxy = None

    self._handlers = []

    try:
      self._store = plugin.store.copy()
      if __debug__: RT.register(self._store, __name__)

      log.debug("Installing widgets...")
      self._add_column()
      self._register_handlers()
      self._enable_dnd()

      log.debug("Creating menu...")
      self._create_menus()
      self._install_context_menu()

      self._plugin.register_update_func(self.update_store)
    except:
      self.unload()
      raise
コード例 #4
0
def menu_add_separator(menu, pos=-1):

  sep = gtk.SeparatorMenuItem()
  menu.insert(sep, pos)

  if __debug__: RT.register(sep, __name__)

  return sep
コード例 #5
0
  def _create_context_menu(self):

    item = gtk.MenuItem(DISPLAY_NAME)
    item.set_submenu(gtk.Menu())

    if __debug__: RT.register(item, __name__)
    if __debug__: RT.register(item.get_submenu(), __name__)

    return item
コード例 #6
0
    def on_add(widget):

      try:
        dialog = AddLabelDialog(self._plugin, ID_NULL)
        if __debug__: RT.register(dialog, __name__)
        dialog.show()
      except:
        log.exception("Error initializing AddLabelDialog")
        pass
コード例 #7
0
    def on_activate(widget):

      try:
        ids = self.get_selected_torrent_labels()
        dialog = LabelOptionsDialog(self._plugin, ids[0])
        if __debug__: RT.register(dialog, __name__)
        dialog.show()
      except:
        log.exception("Error initializing LabelOptionsDialog")
        pass
コード例 #8
0
  def update_store(self, store):

    self._store.destroy()
    self._store = store.copy()
    if __debug__: RT.register(self._store, __name__)

    self._destroy_menu()
    self._create_menu()

    self._refresh_torrent_label()
コード例 #9
0
    def on_option(widget):

      try:
        id = self._menu.get_title()
        dialog = LabelOptionsDialog(self._plugin, id)
        if __debug__: RT.register(dialog, __name__)
        dialog.show()
      except:
        log.exception("Error initializing LabelOptionsDialog")
        pass
コード例 #10
0
  def _setup_autolabel_box(self):

    crbox = AutolabelBox(row_spacing=6, column_spacing=3)
    if __debug__: RT.register(crbox, __name__)

    crbox.set_name("crbox_autolabel_rules")
    self._crbox_autolabel_rules = crbox
    self._blk_criteria_box.add(crbox)
    self._widgets.append(crbox)

    crbox.show_all()
コード例 #11
0
  def _create_alternate_menu(self):

    item = self._create_context_menu()
    item.get_submenu().append(self._create_filter_menu())

    menu = gtk.Menu()
    menu.append(item)
    menu.show_all()

    if __debug__: RT.register(menu, __name__)

    return menu
コード例 #12
0
  def _setup_test_combo_box(self):

    prop_store = labelplus.gtkui.common.gtklib.liststore_create(str,
      [_(x) for x in PROPS])
    if __debug__: RT.register(prop_store, __name__)

    cell = gtk.CellRendererText()
    if __debug__: RT.register(cell, __name__)

    self._cmb_test_criteria.pack_start(cell)
    self._cmb_test_criteria.add_attribute(cell, "text", 0)
    self._cmb_test_criteria.set_model(prop_store)
    self._cmb_test_criteria.set_active(0)
コード例 #13
0
ファイル: gtkui.py プロジェクト: joyrida08/deluge-labelplus
  def _load_extensions(self):

    log.info("Loading extensions...")

    for ext in EXTENSIONS:
      try:
        log.debug("Initializing %s", ext.__name__)
        instance = ext(self)
        self._extensions.append(instance)
        if __debug__: RT.register(instance, ext.__name__)
        log.info("%s initialized", ext.__name__)
      except:
        log.exception("Error initializing %s", ext.__name__)
コード例 #14
0
  def update_store(self, store):

    self._store.destroy()
    self._store = store.copy()
    if __debug__: RT.register(self._store, __name__)

    self._destroy_alternate_menu()
    self._alt_menu = self._create_alternate_menu()

    self._uninstall_submenus()
    self._destroy_submenus()
    self._submenus = self._create_submenus()
    self._install_submenus()
コード例 #15
0
  def _setup_radio_button_groups(self):

    for path_type in PATH_TYPES:
      rgrp = RadioButtonGroup((
        (getattr(self, "_rb_%s_to_parent" % path_type), MOVE_PARENT),
        (getattr(self, "_rb_%s_to_subfolder" % path_type), MOVE_SUBFOLDER),
        (getattr(self, "_rb_%s_to_folder" % path_type), MOVE_FOLDER),
      ))

      rgrp.set_name("rgrp_%s_mode" % path_type)
      self.__dict__["_rgrp_%s_mode" % path_type] = rgrp

      if __debug__: RT.register(rgrp, __name__)
コード例 #16
0
  def _create_menu(self):

    def on_activate(widget, label_id):

      id = self._get_selected_torrent()
      if id:
        self._set_torrent_label(id, label_id)
        self._display_torrent_label(id)


    items = (((Gtk.MenuItem, {'label': _(STR_NONE)}), on_activate, ID_NONE),)

    self._menu = LabelSelectionMenu(self._store.model, on_activate,
      root_items=items)

    if __debug__: RT.register(self._menu, __name__)
コード例 #17
0
  def _create_menu(self):

    def on_activate(widget, label_id):

      id = self._get_selected_torrent()
      if id:
        self._set_torrent_label(id, label_id)
        self._display_torrent_label(id)


    items = (((gtk.MenuItem, _(STR_NONE)), on_activate, ID_NONE),)

    self._menu = LabelSelectionMenu(self._store.model, on_activate,
      root_items=items)

    if __debug__: RT.register(self._menu, __name__)
コード例 #18
0
    def _build_store(self, data):
        def data_sort_asc(model, iter1, iter2):

            id1, data1 = model[iter1]
            id2, data2 = model[iter2]

            is_reserved1 = id1 in RESERVED_IDS
            is_reserved2 = id2 in RESERVED_IDS

            if is_reserved1 and is_reserved2:
                return cmp(id1, id2)
            elif is_reserved1:
                return -1
            elif is_reserved2:
                return 1

            return cmp(data1["name"], data2["name"])

        store = gtk.TreeStore(str, gobject.TYPE_PYOBJECT)
        store_map = {}

        if __debug__:
            RT.register(store, __name__)

        for id_ in sorted(data):
            if id_ in RESERVED_IDS:
                parent_id = ID_NULL
            else:
                parent_id = labelplus.common.label.get_parent_id(id_)

            parent_iter = store_map.get(parent_id)
            iter_ = store.append(parent_iter, [id_, data[id_]])
            store_map[id_] = iter_

        sorted_model = gtk.TreeModelSort(store)
        sorted_model.set_sort_func(self.LABEL_DATA, data_sort_asc)
        sorted_model.set_sort_column_id(self.LABEL_DATA, gtk.SORT_ASCENDING)

        if __debug__:
            RT.register(sorted_model, __name__)

        self._data = data
        self._map = store_map
        self._store = store
        self.model = sorted_model
コード例 #19
0
  def _enable_dnd(self):

    def on_drag_start(widget, context):

      torrent_ids = self._view.get_selected_torrents()
      widget.set_data("dnd_data", torrent_ids)


    def load_ids(widget, path, col, selection, *args):

      torrent_ids = widget.get_data("dnd_data")
      data = cPickle.dumps(torrent_ids)
      selection.set("TEXT", 8, data)

      return True


    def get_drag_icon(widget, x, y):

      if widget.get_selection().count_selected_rows() > 1:
        pixbuf = icon_multiple
      else:
        pixbuf = icon_single

      return (pixbuf, 0, 0)


    icon_single = self._view.treeview.render_icon(gtk.STOCK_DND,
      gtk.ICON_SIZE_DND)
    icon_multiple = self._view.treeview.render_icon(gtk.STOCK_DND_MULTIPLE,
      gtk.ICON_SIZE_DND)

    src_target = DragTarget(
      name="torrent_ids",
      scope=gtk.TARGET_SAME_APP,
      action=gtk.gdk.ACTION_MOVE,
      data_func=load_ids,
    )

    self._dnd_src_proxy = TreeViewDragSourceProxy(self._view.treeview,
      get_drag_icon, on_drag_start)
    self._dnd_src_proxy.add_target(src_target)

    if __debug__: RT.register(src_target, __name__)
    if __debug__: RT.register(self._dnd_src_proxy, __name__)
コード例 #20
0
    def _create_set_label_menu(self):
        def on_activate(widget, label_id):

            torrent_ids = self._view.get_selected_torrents()
            if torrent_ids and label_id in self._store:
                log.info("Setting label %r on %r",
                         self._store[label_id]["fullname"], torrent_ids)
                client.labelplus.set_torrent_labels(torrent_ids, label_id)

        def on_activate_parent(widget):

            ids = self.get_selected_torrent_labels()
            parent_id = labelplus.common.label.get_common_parent(ids)
            on_activate(widget, parent_id)

        def on_show_menu(widget):

            items[0].hide()

            ids = self.get_selected_torrent_labels()
            parent_id = labelplus.common.label.get_common_parent(ids)
            if self._store.is_user_label(parent_id):
                items[0].show()

        root_items = (((Gtk.MenuItem, {
            'label': _(STR_NONE)
        }), on_activate, ID_NONE), )

        menu = LabelSelectionMenu(self._store.model,
                                  on_activate,
                                  root_items=root_items)
        menu.connect("show", on_show_menu)

        items = labelplus.gtkui.common.gtklib.menu_add_items(
            menu, 1, (((Gtk.MenuItem, {
                'label': _(STR_PARENT)
            }), on_activate_parent), ))

        root = Gtk.MenuItem(label=_(TITLE_SET_LABEL))
        root.set_submenu(menu)

        if __debug__: RT.register(menu, __name__)
        if __debug__: RT.register(root, __name__)

        return root
コード例 #21
0
    def _build_store(self, data):
        def data_sort_asc(model, iter1, iter2, *user_data):

            id1, data1 = model[iter1]
            id2, data2 = model[iter2]

            is_reserved1 = id1 in RESERVED_IDS
            is_reserved2 = id2 in RESERVED_IDS

            if is_reserved1 and is_reserved2:
                return cmp(id1, id2)
            elif is_reserved1:
                return -1
            elif is_reserved2:
                return 1

            return cmp(data1["name"], data2["name"])

        store = Gtk.TreeStore(str, GObject.TYPE_PYOBJECT)
        store_map = {}

        if __debug__: RT.register(store, __name__)

        for id_ in sorted(data):
            if id_ in RESERVED_IDS:
                parent_id = ID_NULL
            else:
                parent_id = labelplus.common.label.get_parent_id(id_)

            parent_iter = store_map.get(parent_id)
            iter_ = store.append(parent_iter, [id_, data[id_]])
            store_map[id_] = iter_

        sorted_model = Gtk.TreeModelSort(model=store)
        sorted_model.set_sort_func(self.LABEL_DATA, data_sort_asc)
        sorted_model.set_sort_column_id(self.LABEL_DATA,
                                        Gtk.SortType.ASCENDING)

        if __debug__: RT.register(sorted_model, __name__)

        self._data = data
        self._map = store_map
        self._store = store
        self.model = sorted_model
コード例 #22
0
  def _create_set_label_menu(self):

    def on_activate(widget, label_id):

      torrent_ids = self._view.get_selected_torrents()
      if torrent_ids and label_id in self._store:
        log.info("Setting label %r on %r", self._store[label_id]["fullname"],
          torrent_ids)
        client.labelplus.set_torrent_labels(torrent_ids, label_id)


    def on_activate_parent(widget):

      ids = self.get_selected_torrent_labels()
      parent_id = labelplus.common.label.get_common_parent(ids)
      on_activate(widget, parent_id)


    def on_show_menu(widget):

      items[0].hide()

      ids = self.get_selected_torrent_labels()
      parent_id = labelplus.common.label.get_common_parent(ids)
      if self._store.is_user_label(parent_id):
        items[0].show()


    root_items = (((gtk.MenuItem, _(STR_NONE)), on_activate, ID_NONE),)

    menu = LabelSelectionMenu(self._store.model, on_activate,
      root_items=root_items)
    menu.connect("show", on_show_menu)

    items = labelplus.gtkui.common.gtklib.menu_add_items(menu, 1,
      (((gtk.MenuItem, _(STR_PARENT)), on_activate_parent),))

    root = gtk.MenuItem(_(TITLE_SET_LABEL))
    root.set_submenu(menu)

    if __debug__: RT.register(menu, __name__)
    if __debug__: RT.register(root, __name__)

    return root
コード例 #23
0
    def _enable_dnd(self):
        def on_drag_start(widget, context):

            torrent_ids = self._view.get_selected_torrents()
            widget._tv_dnd_data = torrent_ids

        def load_ids(widget, path, col, selection, *args):

            #torrent_ids = widget.get_data("dnd_data")
            torrent_ids = widget._tv_dnd_data
            data = pickle.dumps(torrent_ids)
            selection.set(Gdk.Atom.intern("TEXT", False), 8, data)

            return True

        def get_drag_icon(widget, x, y):

            if widget.get_selection().count_selected_rows() > 1:
                pixbuf = icon_multiple
            else:
                pixbuf = icon_single

            return (pixbuf, 0, 0)

        icon_single = Gtk.IconTheme.get_default().load_icon(
            'gtk-dnd', Gtk.IconSize.DND, 0)
        icon_multiple = Gtk.IconTheme.get_default().load_icon(
            'gtk-dnd-multiple', Gtk.IconSize.DND, 0)

        src_target = DragTarget(
            name="torrent_ids",
            scope=Gtk.TargetFlags.SAME_APP,
            action=Gdk.DragAction.MOVE,
            data_func=load_ids,
        )

        self._dnd_src_proxy = TreeViewDragSourceProxy(self._view.treeview,
                                                      get_drag_icon,
                                                      on_drag_start)
        self._dnd_src_proxy.add_target(src_target)

        if __debug__: RT.register(src_target, __name__)
        if __debug__: RT.register(self._dnd_src_proxy, __name__)
コード例 #24
0
    def _create_item(self, model, iter_, menu, on_activate, headers,
                     sub_items):

        id_, data = model[iter_]
        name = data["name"]

        item = Gtk.MenuItem(label=name)
        item.set_name(id_)
        menu.append(item)
        self._items.append(item)
        if __debug__: RT.register(item, __name__)

        children = labelplus.gtkui.common.gtklib.treemodel_get_children(
            model, iter_)

        if not children and not sub_items:
            if on_activate:
                item.connect("activate", on_activate, id_)
        else:
            submenu = Gtk.Menu()
            item.set_submenu(submenu)
            self._menus.append(submenu)
            if __debug__: RT.register(submenu, __name__)

            if headers:
                self._items += labelplus.gtkui.common.gtklib.menu_add_items(
                    submenu, -1, (((Gtk.MenuItem, {
                        'label': name
                    }), on_activate, id_), ))
                self._items.append(
                    labelplus.gtkui.common.gtklib.menu_add_separator(submenu))

            if sub_items:
                self._items += labelplus.gtkui.common.gtklib.menu_add_items(
                    submenu, -1, sub_items, id_)
                if children:
                    self._items.append(
                        labelplus.gtkui.common.gtklib.menu_add_separator(
                            submenu))

            for child in children:
                self._create_item(model, child, submenu, on_activate, headers,
                                  sub_items)
コード例 #25
0
ファイル: gtkui.py プロジェクト: joyrida08/deluge-labelplus
  def __init__(self, plugin_name):

    RT.logger.setLevel(logging.INFO)
    if __debug__: RT.register(self)

    super(GtkUI, self).__init__(plugin_name)

    self.initialized = False

    self.config = None

    self.store = LabelStore()
    self.last_updated = None
    self._tries = 0
    self._calls = []

    self._extensions = []

    self._update_funcs = []
    self._cleanup_funcs = []
コード例 #26
0
    def __init__(self, filename, root, attr_prefix=""):

        self._model = None
        self._root_widget = None
        self._widgets = []

        self._attr_prefix = attr_prefix

        self._model = gtk.glade.XML(filename, root)
        if __debug__: RT.register(self._model, __name__)

        self._root_widget = self._model.get_widget(root)

        self._widgets = self._model.get_widget_prefix("")
        for widget in self._widgets:
            if __debug__: RT.register(widget, __name__)

            name = self._attr_prefix + widget.get_name()
            if not hasattr(self, name):
                setattr(self, name, widget)
コード例 #27
0
  def __init__(self, filename, root, attr_prefix=""):

    self._model = None
    self._root_widget = None
    self._widgets = []

    self._attr_prefix = attr_prefix

    self._model = gtk.glade.XML(filename, root)
    if __debug__: RT.register(self._model, __name__)

    self._root_widget = self._model.get_widget(root)

    self._widgets = self._model.get_widget_prefix("")
    for widget in self._widgets:
      if __debug__: RT.register(widget, __name__)

      name = self._attr_prefix + widget.get_name()
      if not hasattr(self, name):
        setattr(self, name, widget)
コード例 #28
0
    def __init__(self, plugin_name):

        RT.logger.setLevel(logging.INFO)
        if __debug__: RT.register(self)

        super(GtkUI, self).__init__(plugin_name)

        self.initialized = False

        self.config = None

        self.store = LabelStore()
        self.last_updated = None
        self._tries = 0
        self._calls = []

        self._extensions = []

        self._update_funcs = []
        self._cleanup_funcs = []
コード例 #29
0
    def __init__(self, homogeneous=False, row_spacing=0, column_spacing=0):

        super(AutolabelBox, self).__init__(homogeneous, row_spacing,
                                           column_spacing)

        prop_store = labelplus.gtkui.common.gtklib.liststore_create(
            str, [_(x) for x in PROPS])
        op_store = labelplus.gtkui.common.gtklib.liststore_create(
            str, [_(x) for x in OPS])
        case_store = labelplus.gtkui.common.gtklib.liststore_create(
            str, [_(x) for x in CASES])

        if __debug__: RT.register(prop_store, __name__)
        if __debug__: RT.register(op_store, __name__)
        if __debug__: RT.register(case_store, __name__)

        self.add_combobox_column(prop_store)
        self.add_combobox_column(op_store)
        self.add_combobox_column(case_store)
        self.add_entry_column(expand=True)

        # Determine minimum width
        row = self.add_row()
        self.show()
        size = self.size_request()
        self.remove(row)
        self.set_size_request(size[0], -1)
コード例 #30
0
  def __init__(self, homogeneous=False, row_spacing=0, column_spacing=0):

    super(AutolabelBox, self).__init__(homogeneous, row_spacing,
      column_spacing)

    prop_store = labelplus.gtkui.common.gtklib.liststore_create(str,
      [_(x) for x in PROPS])
    op_store = labelplus.gtkui.common.gtklib.liststore_create(str,
      [_(x) for x in OPS])
    case_store = labelplus.gtkui.common.gtklib.liststore_create(str,
      [_(x) for x in CASES])

    if __debug__: RT.register(prop_store, __name__)
    if __debug__: RT.register(op_store, __name__)
    if __debug__: RT.register(case_store, __name__)

    self.add_combobox_column(prop_store)
    self.add_combobox_column(op_store)
    self.add_combobox_column(case_store)
    self.add_entry_column(expand=True)

    # Determine minimum width
    row = self.add_row()
    self.show()
    size = self.size_request()
    self.remove(row)
    self.set_size_request(size[0], -1)
コード例 #31
0
  def _create_menu(self):

    def on_show_menu(widget):

      parent_id = labelplus.common.label.get_parent_id(self._label_id)
      if parent_id in self._store:
        items[0].show()
        items[1].show()
      else:
        items[0].hide()
        items[1].hide()


    def on_activate(widget, label_id):

      self._request_options(label_id)


    def on_activate_parent(widget):

      parent_id = labelplus.common.label.get_parent_id(self._label_id)
      self._request_options(parent_id)


    self._menu = LabelSelectionMenu(self._store.model, on_activate)
    if __debug__: RT.register(self._menu, __name__)

    items = labelplus.gtkui.common.gtklib.menu_add_items(self._menu, 0,
      (
        ((gtk.MenuItem, _(STR_PARENT)), on_activate_parent),
        ((gtk.SeparatorMenuItem,),),
      )
    )

    if __debug__:
      for item in items:
        RT.register(item, __name__)

    self._menu.connect("show", on_show_menu)
    self._menu.show_all()
コード例 #32
0
  def __init__(self, plugin):

    self._plugin = plugin
    self._filterview = deluge.component.get("FilterTreeView")

    self._state = \
      self._plugin.config["daemon"][self._plugin.daemon]["sidebar_state"]

    self._store = None
    self._tree = None
    self._menu = None

    self._dnd_src_proxy = None
    self._dnd_dest_proxy = None

    self._handlers = []

    try:
      self._store = plugin.store.copy()
      if __debug__: RT.register(self._store, __name__)

      log.debug("Setting up widgets...")
      self._create_label_tree()

      log.debug("Installing widgets...")
      self._install_label_tree()
      self._register_handlers()
      self._enable_dnd()

      log.debug("Loading state...")
      self._load_state()
      self._scroll_to_nearest_id(self._state["selected"])

      log.debug("Creating menu...")
      self._create_menu()

      self._plugin.register_update_func(self.update_store)
    except:
      self.unload()
      raise
コード例 #33
0
    def __init__(self, plugin):

        self._plugin = plugin
        self._filterview = deluge.component.get("FilterTreeView")

        self._state = \
          self._plugin.config["daemon"][self._plugin.daemon]["sidebar_state"]

        self._store = None
        self._tree = None
        self._menu = None

        self._dnd_src_proxy = None
        self._dnd_dest_proxy = None

        self._handlers = []

        try:
            self._store = plugin.store.copy()
            if __debug__: RT.register(self._store, __name__)

            log.debug("Setting up widgets...")
            self._create_label_tree()

            log.debug("Installing widgets...")
            self._install_label_tree()
            self._register_handlers()
            self._enable_dnd()

            log.debug("Loading state...")
            self._load_state()
            self._scroll_to_nearest_id(self._state["selected"])

            log.debug("Creating menu...")
            self._create_menu()

            self._plugin.register_update_func(self.update_store)
        except:
            self.unload()
            raise
コード例 #34
0
  def _create_item(self, model, iter_, menu, on_activate, headers, sub_items):

    id_, data = model[iter_]
    name = data["name"]

    item = gtk.MenuItem(name)
    item.set_name(id_)
    menu.append(item)
    self._items.append(item)
    if __debug__: RT.register(item, __name__)

    children = labelplus.gtkui.common.gtklib.treemodel_get_children(model,
      iter_)

    if not children and not sub_items:
      if on_activate:
        item.connect("activate", on_activate, id_)
    else:
      submenu = gtk.Menu()
      item.set_submenu(submenu)
      self._menus.append(submenu)
      if __debug__: RT.register(submenu, __name__)

      if headers:
        self._items += labelplus.gtkui.common.gtklib.menu_add_items(submenu,
          -1, (((gtk.MenuItem, name), on_activate, id_),))
        self._items.append(labelplus.gtkui.common.gtklib.menu_add_separator(
          submenu))

      if sub_items:
        self._items += labelplus.gtkui.common.gtklib.menu_add_items(submenu,
          -1, sub_items, id_)
        if children:
          self._items.append(labelplus.gtkui.common.gtklib.menu_add_separator(
            submenu))

      for child in children:
        self._create_item(model, child, submenu, on_activate, headers,
          sub_items)
コード例 #35
0
  def _create_menu(self):

    def on_show_menu(menu):

      parent_id = labelplus.common.label.get_parent_id(self._parent_id)
      if parent_id in self._store:
        items[0].show()
      else:
        items[0].hide()


    def on_activate(widget, parent_id):

      self._select_parent_label(parent_id)


    def on_activate_parent(widget):

      parent_id = labelplus.common.label.get_parent_id(self._parent_id)
      self._select_parent_label(parent_id)


    root_items = (((Gtk.MenuItem, {'label': _(STR_NONE)}), on_activate, ID_NULL),)

    self._menu = LabelSelectionMenu(self._store.model, on_activate,
      root_items=root_items)
    if __debug__: RT.register(self._menu, __name__)

    items = labelplus.gtkui.common.gtklib.menu_add_items(self._menu, 1,
            (((Gtk.MenuItem, {'label': _(STR_PARENT)}), on_activate_parent),))
    if __debug__: RT.register(items[0], __name__)

    self._menu.connect("show", on_show_menu)
    self._menu.show_all()

    if self._type == self.TYPE_RENAME:
      item = self._menu.get_label_item(self._label_id)
      if item:
        item.set_sensitive(False)
コード例 #36
0
  def _create_menu(self):

    def on_show_menu(menu):

      parent_id = labelplus.common.label.get_parent_id(self._parent_id)
      if parent_id in self._store:
        items[0].show()
      else:
        items[0].hide()


    def on_activate(widget, parent_id):

      self._select_parent_label(parent_id)


    def on_activate_parent(widget):

      parent_id = labelplus.common.label.get_parent_id(self._parent_id)
      self._select_parent_label(parent_id)


    root_items = (((gtk.MenuItem, _(STR_NONE)), on_activate, ID_NULL),)

    self._menu = LabelSelectionMenu(self._store.model, on_activate,
      root_items=root_items)
    if __debug__: RT.register(self._menu, __name__)

    items = labelplus.gtkui.common.gtklib.menu_add_items(self._menu, 1,
      (((gtk.MenuItem, _(STR_PARENT)), on_activate_parent),))
    if __debug__: RT.register(items[0], __name__)

    self._menu.connect("show", on_show_menu)
    self._menu.show_all()

    if self._type == self.TYPE_RENAME:
      item = self._menu.get_label_item(self._label_id)
      if item:
        item.set_sensitive(False)
コード例 #37
0
  def _do_open_file_dialog(self, widget):

    def on_response(widget, response):

      if self.valid and response == gtk.RESPONSE_OK:
        txt_widget.set_text(widget.get_filename())

      widget.destroy()


    path_type = widget.name[widget.name.index("_")+1:widget.name.rindex("_")]
    txt_widget = self.__dict__["_txt_%s_path" % path_type]

    dialog = gtk.FileChooserDialog(_(TITLE_SELECT_FOLDER),
      self._blk_preferences.get_toplevel(),
      gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
      (
        gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
        gtk.STOCK_OK, gtk.RESPONSE_OK,
      )
    )
    if __debug__: RT.register(dialog, __name__)

    dialog.set_destroy_with_parent(True)
    dialog.connect("response", on_response)

    path = txt_widget.get_text()
    if not os.path.exists(path):
      path = ""

    dialog.set_filename(path)
    dialog.show_all()

    widgets = labelplus.gtkui.common.gtklib.widget_get_descendents(dialog,
      (gtk.ToggleButton,), 1)
    if widgets:
      location_toggle = widgets[0]
      location_toggle.set_active(False)
コード例 #38
0
    def _on_button_pressed(self, widget, event):

        x, y = event.get_coords()
        path_info = widget.get_path_at_pos(int(x), int(y))
        if not path_info:
            return

        path, column, cell_x, cell_y = path_info
        id, data = widget.get_model()[path]

        if event.button == 1 and event.type == Gdk.EventType._2BUTTON_PRESS:
            if self._store.is_user_label(id):
                try:
                    dialog = LabelOptionsDialog(self._plugin, id)
                    if __debug__: RT.register(dialog, __name__)
                    dialog.show()
                except:
                    log.exception("Error initializing LabelOptionsDialog")
                    pass
        elif event.button == 3:
            self._menu.set_title(id)
            self._menu.popup(None, None, None, None, event.button, event.time)
            return True
コード例 #39
0
  def _on_view_button_press(self, widget, event):

    x, y = event.get_coords()
    path_info = widget.get_path_at_pos(int(x), int(y))
    if not path_info:
      self._view.treeview.get_selection().unselect_all()
      if event.button == 3:
        self._alt_menu.popup(None, None, None, event.button, event.time)
      return

    if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
      if path_info[1] == self._get_view_column():
        ids = self.get_selected_torrent_labels()
        if self.is_filter(ids):
          try:
            dialog = LabelOptionsDialog(self._plugin, ids[0])
            if __debug__: RT.register(dialog, __name__)
            dialog.show()
          except:
            log.exception("Error initializing LabelOptionsDialog")
            pass
        else:
          self._set_filter_sync_sidebar(ids)
コード例 #40
0
  def _on_button_pressed(self, widget, event):

    x, y = event.get_coords()
    path_info = widget.get_path_at_pos(int(x), int(y))
    if not path_info:
      return

    path, column, cell_x, cell_y = path_info
    id, data = widget.get_model()[path]

    if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
      if self._store.is_user_label(id):
        try:
          dialog = LabelOptionsDialog(self._plugin, id)
          if __debug__: RT.register(dialog, __name__)
          dialog.show()
        except:
          log.exception("Error initializing LabelOptionsDialog")
          pass
    elif event.button == 3:
      self._menu.set_title(id)
      self._menu.popup(None, None, None, event.button, event.time)
      return True
コード例 #41
0
    def _create_menu(self):
        def on_show_menu(widget):

            parent_id = labelplus.common.label.get_parent_id(self._label_id)
            if parent_id in self._store:
                items[0].show()
                items[1].show()
            else:
                items[0].hide()
                items[1].hide()

        def on_activate(widget, label_id):

            self._request_options(label_id)

        def on_activate_parent(widget):

            parent_id = labelplus.common.label.get_parent_id(self._label_id)
            self._request_options(parent_id)

        self._menu = LabelSelectionMenu(self._store.model, on_activate)
        if __debug__: RT.register(self._menu, __name__)

        items = labelplus.gtkui.common.gtklib.menu_add_items(
            self._menu, 0, (
                ((Gtk.MenuItem, {
                    'label': _(STR_PARENT)
                }), on_activate_parent),
                ((Gtk.SeparatorMenuItem, ), ),
            ))

        if __debug__:
            for item in items:
                RT.register(item, __name__)

        self._menu.connect("show", on_show_menu)
        self._menu.show_all()
コード例 #42
0
    def __init__(self, plugin):

        self._plugin = plugin
        self._dialog = deluge.component.get("AddTorrentDialog")
        self._view = self._dialog.listview_torrents

        self._store = None
        self._menu = None

        self._mappings = {}
        self._handlers = []

        super(AddTorrentExt, self).__init__(self.GLADE_FILE, self.ROOT_WIDGET,
                                            "_")

        try:
            self._store = plugin.store.copy()
            if __debug__: RT.register(self._store, __name__)

            log.debug("Setting up widgets...")
            self._setup_widgets()

            log.debug("Installing widgets...")
            self._install_widgets()
            self._register_handlers()

            log.debug("Loading state...")
            self._display_torrent_label(None)
            self._update_sensitivity()

            log.debug("Creating menu...")
            self._create_menu()

            self._plugin.register_update_func(self.update_store)
        except:
            self.unload()
            raise
コード例 #43
0
    def _do_open_file_dialog(self, widget):
        def on_response(widget, response):

            if self.valid and response == gtk.RESPONSE_OK:
                txt_widget.set_text(widget.get_filename())

            widget.destroy()

        path_type = widget.name[widget.name.index("_") +
                                1:widget.name.rindex("_")]
        txt_widget = self.__dict__["_txt_%s_path" % path_type]

        dialog = gtk.FileChooserDialog(_(TITLE_SELECT_FOLDER),
                                       self._blk_preferences.get_toplevel(),
                                       gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (
                                           gtk.STOCK_CANCEL,
                                           gtk.RESPONSE_CANCEL,
                                           gtk.STOCK_OK,
                                           gtk.RESPONSE_OK,
                                       ))
        if __debug__: RT.register(dialog, __name__)

        dialog.set_destroy_with_parent(True)
        dialog.connect("response", on_response)

        path = txt_widget.get_text()
        if not os.path.exists(path):
            path = ""

        dialog.set_filename(path)
        dialog.show_all()

        widgets = labelplus.gtkui.common.gtklib.widget_get_descendents(
            dialog, (gtk.ToggleButton, ), 1)
        if widgets:
            location_toggle = widgets[0]
            location_toggle.set_active(False)
コード例 #44
0
    def _on_view_button_press(self, widget, event):

        x, y = event.get_coords()
        path_info = widget.get_path_at_pos(int(x), int(y))
        if not path_info:
            self._view.treeview.get_selection().unselect_all()
            if event.button == 3:
                self._alt_menu.popup(None, None, None, None, event.button,
                                     event.time)
            return

        if event.button == 1 and event.type == Gdk.EventType._2BUTTON_PRESS:
            if path_info[1] == self._get_view_column():
                ids = self.get_selected_torrent_labels()
                if self.is_filter(ids):
                    try:
                        dialog = LabelOptionsDialog(self._plugin, ids[0])
                        if __debug__: RT.register(dialog, __name__)
                        dialog.show()
                    except:
                        log.exception("Error initializing LabelOptionsDialog")
                        pass
                else:
                    self._set_filter_sync_sidebar(ids)
コード例 #45
0
    def _do_open_file_dialog(self, widget):
        def on_response(widget, response):

            if self.valid and response == Gtk.ResponseType.OK:
                txt_widget.set_text(widget.get_filename())

            widget.destroy()

        name = safe_get_name(widget)
        path_type = name[name.index("_") + 1:name.rindex("_")]
        txt_widget = self.__dict__["_txt_%s_path" % path_type]

        dialog = Gtk.FileChooserDialog(_(TITLE_SELECT_FOLDER),
                                       self._blk_preferences.get_toplevel(),
                                       Gtk.FileChooserAction.SELECT_FOLDER,
                                       (_("_Cancel"), Gtk.ResponseType.CANCEL,
                                        _("_OK"), Gtk.ResponseType.OK))

        if __debug__: RT.register(dialog, __name__)

        dialog.set_destroy_with_parent(True)

        path = txt_widget.get_text()
        if not os.path.exists(path):
            path = ""

        dialog.set_filename(path)

        response = dialog.run()
        on_response(dialog, response)

        widgets = labelplus.gtkui.common.gtklib.widget_get_descendents(
            dialog, (Gtk.ToggleButton, ), 1)
        if widgets:
            location_toggle = widgets[0]
            location_toggle.set_active(False)
コード例 #46
0
    def __init__(self, filename, root, attr_prefix=""):

        self._model = None
        self._root_widget = None
        self._widgets = []

        self._attr_prefix = attr_prefix

        self._model = Gtk.Builder.new_from_file(filename)
        if __debug__: RT.register(self._model, __name__)

        self._root_widget = self._model.get_object(root)

        self._widgets = [
            w for w in self._model.get_objects()
            if isinstance(w, Gtk.Buildable)
        ]
        for widget in self._widgets:
            if __debug__: RT.register(widget, __name__)

            name = self._attr_prefix + safe_get_name(widget)

            if not hasattr(self, name):
                setattr(self, name, widget)
コード例 #47
0
  def __init__(self, plugin):

    self._plugin = plugin
    self._status_bar = deluge.component.get("StatusBar")

    self._store = None
    self._status_item = None

    self._tries = 0
    self._calls = []

    try:
      self._store = plugin.store.copy()
      if __debug__: RT.register(self._store, __name__)

      log.debug("Installing widgets...")
      self._install_status_item()

      self._plugin.register_update_func(self.update_store)
    except:
      self.unload()
      raise

    twisted.internet.reactor.callLater(0, self._update_loop)
コード例 #48
0
  def __init__(self, plugin):

    self._plugin = plugin
    self._dialog = deluge.component.get("AddTorrentDialog")
    self._view = self._dialog.listview_torrents

    self._store = None
    self._menu = None

    self._mappings = {}
    self._handlers = []

    super(AddTorrentExt, self).__init__(self.GLADE_FILE, self.ROOT_WIDGET, "_")

    try:
      self._store = plugin.store.copy()
      if __debug__: RT.register(self._store, __name__)

      log.debug("Setting up widgets...")
      self._setup_widgets()

      log.debug("Installing widgets...")
      self._install_widgets()
      self._register_handlers()

      log.debug("Loading state...")
      self._display_torrent_label(None)
      self._update_sensitivity()

      log.debug("Creating menu...")
      self._create_menu()

      self._plugin.register_update_func(self.update_store)
    except:
      self.unload()
      raise
コード例 #49
0
def menu_add_items(menu, pos, specs, *args):

    menu_items = []

    if pos < 0:
        pos = -len(specs)

    for spec in specs:
        schematic = spec[0]
        if len(schematic) > 1:
            item = schematic[0](**schematic[1])
        else:
            item = schematic[0]()

        if __debug__: RT.register(item, __name__)

        if len(spec) > 1 and spec[1]:
            item.connect("activate", *(tuple(spec[1:]) + args))

        menu_items.append(item)
        menu.insert(item, pos)
        pos += 1

    return menu_items
コード例 #50
0
    def _create_label_tree(self):
        def render_cell_data(column, cell, model, iter, *data):

            id, data = model[iter]

            count = data["count"]

            if self._plugin.config["common"]["filter_include_sublabels"]:
                count += data["descendents"]["count"]

            label_str = "%s (%s)" % (data["name"], count)
            cell.set_property("text", label_str)

        def search_func(model, column, key, iter):

            id, data = model[iter]

            if data["fullname"].lower().startswith(key.lower()):
                return False

            if key.endswith("/"):
                if data["fullname"].lower() == key[:-1].lower():
                    self._tree.expand_to_path(model.get_path(iter))

            return True

        tree = Gtk.TreeView()
        column = Gtk.TreeViewColumn(DISPLAY_NAME)
        renderer = Gtk.CellRendererText()

        column.pack_start(renderer, False)
        column.set_cell_data_func(renderer, render_cell_data)
        tree.append_column(column)

        tree.set_name("%s_tree_view" % MODULE_NAME)
        tree.set_headers_visible(False)
        tree.set_enable_tree_lines(True)
        tree.set_search_equal_func(search_func)
        tree.set_model(self._store.model)
        tree.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)

        tree.connect("button-press-event", self._on_button_pressed)
        tree.connect("row-collapsed", self._on_row_collapsed)
        tree.connect("row-expanded", self._on_row_expanded)
        tree.get_selection().connect("changed", self._on_selection_changed)

        self._tree = tree

        if __debug__: RT.register(tree, __name__)
        if __debug__: RT.register(column, __name__)
        if __debug__: RT.register(renderer, __name__)
コード例 #51
0
  def update_store(self, store):

    self._store.destroy()
    self._store = store.copy()
    if __debug__: RT.register(self._store, __name__)
コード例 #52
0
    def _install_context_menu(self):

        self._sep = self._menubar.add_torrentmenu_separator()
        self._menubar.torrentmenu.append(self._menu)

        if __debug__: RT.register(self._sep, __name__)
コード例 #53
0
    def _create_menu(self):
        def on_add(widget):

            try:
                dialog = AddLabelDialog(self._plugin, ID_NULL)
                if __debug__: RT.register(dialog, __name__)
                dialog.show()
            except:
                log.exception("Error initializing AddLabelDialog")
                pass

        def on_sublabel(widget):

            try:
                id = self._menu.get_title()
                dialog = AddLabelDialog(self._plugin, id)
                if __debug__: RT.register(dialog, __name__)
                dialog.show()
            except:
                log.exception("Error initializing AddLabelDialog")
                pass

        def on_rename(widget):

            try:
                id = self._menu.get_title()
                dialog = RenameLabelDialog(self._plugin, id)
                if __debug__: RT.register(dialog, __name__)
                dialog.show()
            except:
                log.exception("Error initializing RenameLabelDialog")
                pass

        def on_remove(widget):

            id = self._menu.get_title()
            client.labelplus.remove_label(id)

        def on_option(widget):

            try:
                id = self._menu.get_title()
                dialog = LabelOptionsDialog(self._plugin, id)
                if __debug__: RT.register(dialog, __name__)
                dialog.show()
            except:
                log.exception("Error initializing LabelOptionsDialog")
                pass

        def on_show_menu(widget):

            self._menu.show_all()

            id = self._menu.get_title()
            if id in RESERVED_IDS:
                for i in range(1, 7):
                    items[i].hide()

        menu = Gtk.Menu()
        menu.connect("show", on_show_menu)

        items = labelplus.gtkui.common.gtklib.menu_add_items(
            menu, 0, (
                ((ImageMenuItem, {
                    'stock_id': 'list-add',
                    'label': _("_Add Label")
                }), on_add),
                ((Gtk.SeparatorMenuItem, ), ),
                ((ImageMenuItem, {
                    'stock_id': 'list-add',
                    'label': _("Add Sub_label")
                }), on_sublabel),
                ((ImageMenuItem, {
                    'stock_id': 'gtk-edit',
                    'label': _("Re_name Label")
                }), on_rename),
                ((ImageMenuItem, {
                    'stock_id': 'list-remove',
                    'label': _("_Remove Label")
                }), on_remove),
                ((Gtk.SeparatorMenuItem, ), ),
                ((ImageMenuItem, {
                    'stock_id': 'preferences-system',
                    'label': _("Label _Options")
                }), on_option),
            ))

        menu.set_reserve_toggle_size(False)
        self._menu = menu

        if __debug__: RT.register(self._menu, __name__)
コード例 #54
0
    def _create_filter_menu(self):
        def on_activate(widget, ids):

            if not isinstance(ids, list):
                ids = [ids]

            self._set_filter_sync_sidebar(ids)

        def on_activate_parent(widget):

            ids = self.get_any_selected_labels()
            parent_id = labelplus.common.label.get_common_parent(ids)
            on_activate(widget, parent_id)

        def on_activate_selected(widget):

            ids = self.get_selected_torrent_labels()
            on_activate(widget, ids)

        def on_show_menu(widget):

            items[0].hide()
            items[1].hide()

            ids = self.get_any_selected_labels()
            parent_id = labelplus.common.label.get_common_parent(ids)
            if self._store.is_user_label(parent_id):
                items[0].show()

            ids = self.get_selected_torrent_labels()
            if self._store.user_labels(ids):
                items[1].show()

        root_items = (
            ((Gtk.MenuItem, {
                'label': _(STR_ALL)
            }), on_activate, ID_ALL),
            ((Gtk.MenuItem, {
                'label': _(STR_NONE)
            }), on_activate, ID_NONE),
        )

        menu = LabelSelectionMenu(self._store.model,
                                  on_activate,
                                  root_items=root_items)
        menu.connect("show", on_show_menu)

        items = labelplus.gtkui.common.gtklib.menu_add_items(
            menu, 2, (
                ((Gtk.MenuItem, {
                    'label': _(STR_PARENT)
                }), on_activate_parent),
                ((Gtk.MenuItem, {
                    'label': _(STR_SELECTED)
                }), on_activate_selected),
            ))

        root = Gtk.MenuItem(label=_(TITLE_SET_FILTER))
        root.set_submenu(menu)

        if __debug__: RT.register(menu, __name__)
        if __debug__: RT.register(root, __name__)

        return root
コード例 #55
0
    def _create_menu(self):
        def on_add(widget):

            try:
                dialog = AddLabelDialog(self._plugin, ID_NULL)
                if __debug__: RT.register(dialog, __name__)
                dialog.show()
            except:
                log.exception("Error initializing AddLabelDialog")
                pass

        def on_sublabel(widget):

            try:
                id = self._menu.get_title()
                dialog = AddLabelDialog(self._plugin, id)
                if __debug__: RT.register(dialog, __name__)
                dialog.show()
            except:
                log.exception("Error initializing AddLabelDialog")
                pass

        def on_rename(widget):

            try:
                id = self._menu.get_title()
                dialog = RenameLabelDialog(self._plugin, id)
                if __debug__: RT.register(dialog, __name__)
                dialog.show()
            except:
                log.exception("Error initializing RenameLabelDialog")
                pass

        def on_remove(widget):

            id = self._menu.get_title()
            client.labelplus.remove_label(id)

        def on_option(widget):

            try:
                id = self._menu.get_title()
                dialog = LabelOptionsDialog(self._plugin, id)
                if __debug__: RT.register(dialog, __name__)
                dialog.show()
            except:
                log.exception("Error initializing LabelOptionsDialog")
                pass

        def on_show_menu(widget):

            self._menu.show_all()

            id = self._menu.get_title()
            if id in RESERVED_IDS:
                for i in range(1, 7):
                    items[i].hide()

        menu = gtk.Menu()
        menu.connect("show", on_show_menu)

        items = labelplus.gtkui.common.gtklib.menu_add_items(
            menu, 0, (
                ((ImageMenuItem, gtk.STOCK_ADD, _("_Add Label")), on_add),
                ((gtk.SeparatorMenuItem, ), ),
                ((ImageMenuItem, gtk.STOCK_ADD, _("Add Sub_label")),
                 on_sublabel),
                ((ImageMenuItem, gtk.STOCK_EDIT, _("Re_name Label")),
                 on_rename),
                ((ImageMenuItem, gtk.STOCK_REMOVE, _("_Remove Label")),
                 on_remove),
                ((gtk.SeparatorMenuItem, ), ),
                ((ImageMenuItem, gtk.STOCK_PREFERENCES, _("Label _Options")),
                 on_option),
            ))

        self._menu = menu

        if __debug__: RT.register(self._menu, __name__)
コード例 #56
0
    def _enable_dnd(self):

        # Source Proxy

        def load_row(widget, path, col, selection, *args):

            model = widget.get_model()
            iter_ = model.get_iter(path)
            path_str = bytes(model.get_string_from_iter(iter_),
                             encoding='utf8')
            selection.set(Gdk.Atom.intern("TEXT", False), 8, path_str)

            return True

        def get_drag_icon(widget, x, y):

            return (icon_single, 0, 0)

        # Destination Proxy

        def check_dest_id(widget, path, col, pos, selection, *args):

            model = widget.get_model()
            id = model[path][LABEL_ID]

            if id == ID_NONE or self._store.is_user_label(id):
                return True

        def receive_ids(widget, path, col, pos, selection, *args):

            try:
                torrent_ids = pickle.loads(selection.get_data())
            except:
                return False

            model = widget.get_model()
            id = model[path][LABEL_ID]

            if id == ID_NONE or self._store.is_user_label(id):
                log.info("Setting label %r on %r", self._store[id]["fullname"],
                         torrent_ids)
                client.labelplus.set_torrent_labels(torrent_ids, id)
                return True

        def check_dest_row(widget, path, col, pos, selection, *args):

            model = widget.get_model()
            id = model[path][LABEL_ID]

            try:
                src_path = str(selection.get_data(), encoding='utf8')
                src_id = model[src_path][LABEL_ID]
            except IndexError:
                return False

            if (id == src_id or labelplus.common.label.is_ancestor(src_id, id)
                    or not self._store.is_user_label(src_id)):
                return False

            if id == ID_NONE:
                children = self._store.get_descendent_ids(ID_NULL, 1)
            elif self._store.is_user_label(id):
                children = self._store[id]["children"]
            else:
                return False

            src_name = self._store[src_id]["name"]

            for child in children:
                if child in self._store and self._store[child][
                        "name"] == src_name:
                    return False

            return True

        def receive_row(widget, path, col, pos, selection, *args):

            if not check_dest_row(widget, path, col, pos, selection, *args):
                return False

            model = widget.get_model()
            dest_id = model[path][LABEL_ID]

            src_path = str(selection.get_data(), encoding='utf8')
            src_id = model[src_path][LABEL_ID]
            src_name = self._store[src_id]["name"]

            if dest_id != ID_NONE:
                dest_name = "%s/%s" % (self._store[dest_id]["fullname"],
                                       src_name)
            else:
                dest_id = ID_NULL
                dest_name = src_name

            log.info("Renaming label: %r -> %r",
                     self._store[src_id]["fullname"], dest_name)
            client.labelplus.move_label(src_id, dest_id, src_name)

            # Default drag source will delete row on success, so return failure
            return False

        icon_single = Gtk.IconTheme.get_default().load_icon(
            'gtk-dnd', Gtk.IconSize.DND, 0)

        src_target = DragTarget(
            name="label_row",
            scope=Gtk.TargetFlags.SAME_APP,
            action=Gdk.DragAction.MOVE,
            data_func=load_row,
        )

        self._dnd_src_proxy = TreeViewDragSourceProxy(self._tree,
                                                      get_drag_icon)
        self._dnd_src_proxy.add_target(src_target)

        if __debug__: RT.register(src_target, __name__)
        if __debug__: RT.register(self._dnd_src_proxy, __name__)

        ids_target = DragTarget(
            name="torrent_ids",
            scope=Gtk.TargetFlags.SAME_APP,
            action=Gdk.DragAction.MOVE,
            pos=Gtk.TreeViewDropPosition.INTO_OR_BEFORE,
            data_func=receive_ids,
            aux_func=check_dest_id,
        )

        row_target = DragTarget(
            name="label_row",
            scope=Gtk.TargetFlags.SAME_APP,
            action=Gdk.DragAction.MOVE,
            pos=Gtk.TreeViewDropPosition.INTO_OR_BEFORE,
            data_func=receive_row,
            aux_func=check_dest_row,
        )

        self._dnd_dest_proxy = TreeViewDragDestProxy(self._tree)
        self._dnd_dest_proxy.add_target(ids_target)
        self._dnd_dest_proxy.add_target(row_target)

        if __debug__: RT.register(ids_target, __name__)
        if __debug__: RT.register(row_target, __name__)
        if __debug__: RT.register(self._dnd_dest_proxy, __name__)