コード例 #1
0
ファイル: __init__.py プロジェクト: darnyte/deluge-labelplus
  def _create_jump_menu(self):


    def on_select_label(widget, label_id):

      self._do_go_to_label(widget, label_id)


    def hide_unavailable(widget):

      selected_item.hide()
      parent_item.hide()

      id = self.get_selected_torrent_label()
      if id:
        if getattr(selected_item, "handler", None):
          selected_item.disconnect(selected_item.handler)

        handler = selected_item.connect("activate", on_select_label, id)
        selected_item.handler = handler
        selected_item.show()

      elif self.label_sidebar.page_selected():
        id = self.label_sidebar.get_selected_label()

      if id:
        parent = get_parent(id)
        if parent and parent not in RESERVED_IDS:
          if getattr(parent_item, "handler", None):
            parent_item.disconnect(parent_item.handler)

          handler = parent_item.connect("activate", on_select_label, parent)
          parent_item.handler = handler
          parent_item.show()


    items = []

    menu_item = gtk.MenuItem(_(ID_ALL))
    menu_item.connect("activate", on_select_label, ID_ALL)
    items.append(menu_item)

    menu_item = gtk.MenuItem(_(ID_NONE))
    menu_item.connect("activate", on_select_label, ID_NONE)
    items.append(menu_item)

    selected_item = gtk.MenuItem(_("Selected"))
    items.append(selected_item)

    parent_item = gtk.MenuItem(_("Parent"))
    items.append(parent_item)

    menu_item = gtk.SeparatorMenuItem()
    items.append(menu_item)

    menu = LabelSelectionMenu(_("Jump To"), on_select_label, items)
    menu.connect("activate", hide_unavailable)

    return menu
コード例 #2
0
  def __init__(self):

    self.mappings = {}
    self.cur_label = None
    self.lv = component.get("AddTorrentDialog").listview_torrents
    self.handlers = []

    self.blk_ext = None
    self.lbl_name = None
    self.btn_select = None

    self._build_ext_block()
    self.blk_ext.show_all()

    self.menu = LabelSelectionMenu()
    self.menu.on_select_label = self._do_set_mapping

    self.submenu = self.menu.get_submenu()

    self.handlers.append((
      self.lv.get_selection(),
      self.lv.get_selection().connect("changed", self._do_update_label_text),
    ))

    self.btn_select.connect("button-release-event", self._do_show_menu)

    self._install_ext_block()
    self._register_button_handlers()
コード例 #3
0
ファイル: __init__.py プロジェクト: darnyte/deluge-labelplus
  def _create_set_label_menu(self):


    def on_select_label(widget, label_id):

      torrents = component.get("TorrentView").get_selected_torrents()
      client.labelplus.set_torrent_labels(label_id, torrents)


    def hide_unavailable(widget):

      parent_item.hide()

      id = self.get_selected_torrent_label()
      if id:
        parent = get_parent(id)
        if parent and parent not in RESERVED_IDS:
          if getattr(parent_item, "handler", None):
            parent_item.disconnect(parent_item.handler)

          handler = parent_item.connect("activate", on_select_label, parent)
          parent_item.handler = handler
          parent_item.show()


    items = []

    menu_item = gtk.MenuItem(_(ID_NONE))
    menu_item.connect("activate", on_select_label, ID_NONE)
    items.append(menu_item)

    parent_item = gtk.MenuItem(_("Parent"))
    items.append(parent_item)

    menu_item = gtk.SeparatorMenuItem()
    items.append(menu_item)

    menu = LabelSelectionMenu(_("Set Label"), on_select_label, items)
    menu.connect("activate", hide_unavailable)

    return menu
コード例 #4
0
ファイル: __init__.py プロジェクト: vfrc2/deluge-labelplus
  def _create_menu(self):

    menu = gtk.MenuItem(DISPLAY_NAME)
    menu.connect("activate", self._on_activate)
    submenu = gtk.Menu()

    self.label_selection_menu = LabelSelectionMenu(_("Set Label"))
    submenu.append(self.label_selection_menu)

    self.menu_jump_item = gtk.MenuItem(_("Go to Label"))
    self.menu_jump_item.connect("activate", self._do_go_to_label)
    submenu.append(self.menu_jump_item)

    menu.set_submenu(submenu)
    menu.show_all()

    return menu
コード例 #5
0
ファイル: __init__.py プロジェクト: Lugoues/deluge-labelplus
  def _do_load(self):

    self._config = deluge.configmanager.ConfigManager(
        GTKUI_CONFIG, defaults=GTKUI_DEFAULTS)

    component.get("TorrentView").add_text_column(DISPLAY_NAME,
        status_field=[STATUS_NAME])

    self.label_selection_menu = LabelSelectionMenu()
    self.sep = component.get("MenuBar").add_torrentmenu_separator()
    component.get("MenuBar").torrentmenu.append(self.label_selection_menu)

    self.label_sidebar = LabelSidebar()

    self.preferences = Preferences()

    self.add_torrent_ext = AddTorrentExt()

    self.enable_dnd()

    self.initialized = True
コード例 #6
0
ファイル: __init__.py プロジェクト: Lugoues/deluge-labelplus
class GtkUI(GtkPluginBase):


  def __init__(self, plugin_name):

    super(GtkUI, self).__init__(plugin_name)
    self.initialized = False
    self.retries = 0


  def enable(self):

    self.timestamp = None
    self.label_data = None

    client.labelplus.is_initialized().addCallback(self.cb_check)


  def cb_check(self, result):

    if result == True:
      client.labelplus.get_label_data(self.timestamp).addCallback(
        self.cb_data_init)
    elif self.retries < MAX_RETRIES:
      reactor.callLater(WAIT_TIME, self.enable)
      self.retries += 1


  def cb_data_init(self, data):

    self.timestamp = data[0]
    self.label_data = data[1]

    self.label_data[ID_ALL]["name"] = _(ID_ALL)
    self.label_data[ID_NONE]["name"] = _(ID_NONE)

    self._do_load()


  def _do_load(self):

    self._config = deluge.configmanager.ConfigManager(
        GTKUI_CONFIG, defaults=GTKUI_DEFAULTS)

    component.get("TorrentView").add_text_column(DISPLAY_NAME,
        status_field=[STATUS_NAME])

    self.label_selection_menu = LabelSelectionMenu()
    self.sep = component.get("MenuBar").add_torrentmenu_separator()
    component.get("MenuBar").torrentmenu.append(self.label_selection_menu)

    self.label_sidebar = LabelSidebar()

    self.preferences = Preferences()

    self.add_torrent_ext = AddTorrentExt()

    self.enable_dnd()

    self.initialized = True


  def disable(self):

    self.retries = MAX_RETRIES

    if self.initialized:
      self.initialized = False

      self._config.save()
      deluge.configmanager.close(self._config)

      self.disable_dnd()

      component.get("MenuBar").torrentmenu.remove(self.sep)
      component.get("MenuBar").torrentmenu.remove(self.label_selection_menu)
      self.label_selection_menu.destroy()
      del self.label_selection_menu

      self.label_sidebar.unload()
      del self.label_sidebar

      self.preferences.unload()

      self.add_torrent_ext.unload()

      component.get("TorrentView").remove_column(DISPLAY_NAME)


  def update(self):

    if self.initialized:
      client.labelplus.get_label_data(self.timestamp).addCallback(
        self.cb_update_data)


  def cb_update_data(self, data):

    if data is not None:
      self.timestamp = data[0]
      self.label_data = data[1]

      self.label_data[ID_ALL]["name"] = _(ID_ALL)
      self.label_data[ID_NONE]["name"] = _(ID_NONE)

      self.label_sidebar.update_counts(self.label_data)


  def get_labels(self):

    data = self.label_data
    labels = []
    for id in data:
      if id not in RESERVED_IDS:
        labels.append((id, data[id]["name"]))

    return labels


  def get_label_counts(self):

    return self.label_data


  def enable_dnd(self):


    def get_drag_icon(widget, x, y):

      num = widget.get_selection().count_selected_rows()

      if num > 1:
        pixbuf = self.icon_multiple
      else:
        pixbuf = self.icon_single

      return (pixbuf, 0, 0)


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

      selection.set("TEXT", 8, "OK")

      return True


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

      if selection.data == "OK":
        model = widget.get_model()
        id = model[path][0]

        if id == ID_NONE:
          id = None

        if id not in RESERVED_IDS:
          torrents = component.get("TorrentView").get_selected_torrents()
          client.labelplus.set_torrent_labels(id, torrents)

          return True


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

      if selection.data == "OK":
        model = widget.get_model()
        id = model[path][0]

        if id == ID_NONE:
          id = None

        if id not in RESERVED_IDS:
          return True


    class ModuleFilter(object):


      def filter(self, record):

        record.msg = "[%s] %s" % (PLUGIN_NAME, record.msg)

        return True


    dnd.log.setLevel(logging.INFO)
    dnd.log.addFilter(ModuleFilter())

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

    src_treeview = component.get("TorrentView").treeview

    self.icon_single = \
        src_treeview.render_icon(gtk.STOCK_DND, gtk.ICON_SIZE_DND)
    self.icon_multiple = \
        src_treeview.render_icon(gtk.STOCK_DND_MULTIPLE, gtk.ICON_SIZE_DND)

    self.src_proxy = dnd.TreeViewDragSourceProxy(src_treeview, get_drag_icon)
    self.src_proxy.add_target(src_target)

    dest_target = dnd.DragTarget(
      name="torrent_ids",
      scope=gtk.TARGET_SAME_APP,
      action=gtk.gdk.ACTION_MOVE,
      pos=gtk.TREE_VIEW_DROP_INTO_OR_BEFORE,
      data_func=receive_ids,
      aux_func=peek_ids,
    )

    dest_treeview = self.label_sidebar.label_tree
    self.dest_proxy = dnd.TreeViewDragDestProxy(dest_treeview)
    self.dest_proxy.add_target(dest_target)


  def disable_dnd(self):

    self.dest_proxy.unload()
    self.src_proxy.unload()
コード例 #7
0
class AddTorrentExt(object):


  def __init__(self):

    self.mappings = {}
    self.cur_label = None
    self.lv = component.get("AddTorrentDialog").listview_torrents
    self.handlers = []

    self.blk_ext = None
    self.lbl_name = None
    self.btn_select = None

    self._build_ext_block()
    self.blk_ext.show_all()

    self.menu = LabelSelectionMenu()
    self.menu.on_select_label = self._do_set_mapping

    self.submenu = self.menu.get_submenu()

    self.handlers.append((
      self.lv.get_selection(),
      self.lv.get_selection().connect("changed", self._do_update_label_text),
    ))

    self.btn_select.connect("button-release-event", self._do_show_menu)

    self._install_ext_block()
    self._register_button_handlers()


  def unload(self):

    self._deregister_handlers()
    self.menu.destroy()
    self._uninstall_ext_block()
    self.blk_ext.destroy()


  def _build_ext_block(self):

    self.blk_ext = gtk.Frame()
    self.blk_ext.set_shadow_type(gtk.SHADOW_NONE)
    self.blk_ext.set_label_widget(gtk.Label())
    self.blk_ext.get_label_widget().set_markup("<b>%s</b>" % DISPLAY_NAME)

    blk_align = gtk.Alignment(0.5, 0.5, 1.0, 1.0)
    blk_align.set_padding(5, 0, 5, 5)

    box = gtk.HBox()
    box.set_spacing(3)

    frame = gtk.Frame()
    frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)

    align = gtk.Alignment(0.5, 0.5, 1.0, 1.0)
    align.set_padding(0, 0, 3, 3)

    self.lbl_name = gtk.Label()
    self.lbl_name.set_alignment(0.0, 0.5)
    self.lbl_name.set_ellipsize(pango.ELLIPSIZE_END)
    self.lbl_name.set_text(_(ID_NONE))

    self.btn_select = gtk.Button()
    self.btn_select.set_label(_("Select"))

    self.blk_ext.add(blk_align)
    blk_align.add(box)
    box.pack_start(frame, expand=True)
    frame.add(align)
    align.add(self.lbl_name)
    box.pack_start(self.btn_select, expand=False)


  @debug()
  def _install_ext_block(self):

    dialog = component.get("AddTorrentDialog")
    widget = dialog.glade.get_widget("button_revert")
    vbox = widget.get_ancestor(gtk.VBox())

    vbox.pack_start(self.blk_ext, expand=False)
    pos = vbox.child_get(self.blk_ext, "position")[0] - 1
    vbox.child_set(self.blk_ext, "position", pos)


  @debug()
  def _uninstall_ext_block(self):

    dialog = component.get("AddTorrentDialog")
    widget = dialog.glade.get_widget("button_revert")
    vbox = widget.get_ancestor(gtk.VBox())

    vbox.remove(self.blk_ext)
    dialog.dialog.resize(1, 1)


  @debug(show_args=True)
  def _do_set_mapping(self, widget, label_id):

    self.cur_label = None

    model, row = self.lv.get_selection().get_selected()
    if row:
      id = model.get_value(row, 0)
      if label_id is None:
        if id in self.mappings:
          del self.mappings[id]
      else:
        name = [widget.get_label()]

        parent = widget.get_parent()
        while parent is not self.submenu:
          item = parent.get_attach_widget()
          name.append(item.get_label())
          parent = item.get_parent()

        if len(name) > len(label_id.split(":"))-1:
          name.pop(0)

        self.mappings[id] = (label_id, "/".join(reversed(name)))
        self.cur_label = self.mappings[id]

    self._do_update_label_text(self.lv.get_selection())


  def _do_update_label_text(self, selection):

    self.cur_label = None

    model, row = selection.get_selected()
    if row:
      id = model.get_value(row, 0)
      if id in self.mappings:
        self.lbl_name.set_text(self.mappings[id][1])
        self.lbl_name.set_tooltip_text(self.mappings[id][1])

        self.cur_label = self.mappings[id]
        return

    self.lbl_name.set_text(_(ID_NONE))
    self.lbl_name.set_tooltip_text(None)


  def _do_show_menu(self, widget, event):

    self._do_set_mapping(None, None)
    self.menu.on_activate(self.menu)
    self.submenu.popup(None, None, None, event.button, event.time)


  def _register_button_handlers(self):

    dialog = component.get("AddTorrentDialog")

    btn = dialog.glade.get_widget("button_revert")
    self.handlers.append((btn, btn.connect("clicked", self._do_revert)))

    btn = dialog.glade.get_widget("button_apply")
    self.handlers.append((btn, btn.connect("clicked", self._do_apply_to_all)))

    btn = dialog.glade.get_widget("button_cancel")
    self.handlers.append((btn, btn.connect("clicked", self._do_clear)))

    btn = dialog.glade.get_widget("button_remove")
    self.handlers.append((btn, btn.connect("clicked", self._do_remove)))

    btn = dialog.glade.get_widget("button_add")
    self.handlers.append((btn, btn.connect("clicked", self._do_add)))


  def _deregister_handlers(self):

    for widget, handler in self.handlers:
      widget.disconnect(handler)


  @debug()
  def _do_revert(self, widget):

    self._do_set_mapping(None, None)


  @debug()
  def _do_apply_to_all(self, widget):


    def set_mapping(model, path, row):

      id = model.get_value(row, 0)
      self.mappings[id] = self.cur_label


    if self.cur_label is None:
      self.mappings.clear()
    else:
      self.lv.get_model().foreach(set_mapping)

    self._do_update_label_text(self.lv.get_selection())


  @debug()
  def _do_clear(self, widget):

    self.mappings.clear()
    self._do_update_label_text(self.lv.get_selection())


  @debug()
  def _do_remove(self, widget):

    dialog = component.get("AddTorrentDialog")

    ids = dialog.files.keys()
    for key in self.mappings.keys():
      if key not in ids:
        del self.mappings[key]

    self._do_update_label_text(self.lv.get_selection())


  @debug()
  def _do_add(self, widget):

    reverse_map = {}
    for torrent_id, label_tup in self.mappings.iteritems():
      label_id = label_tup[0]
      if label_id not in reverse_map:
        reverse_map[label_id] = []

      reverse_map[label_id].append(torrent_id)

    for label_id, torrent_ids in reverse_map.iteritems():
      client.labelplus.set_torrent_labels(label_id, torrent_ids)

    self._do_clear(widget)