sidebar
This commit is contained in:
parent
7eedaeedf3
commit
9d24f551fc
|
@ -0,0 +1,162 @@
|
||||||
|
#
|
||||||
|
# gtk_sidebar.py
|
||||||
|
#
|
||||||
|
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
||||||
|
# Copyright (C) 2007 Andrew Resch ('andar') <andrewresch@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 2 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 gtk
|
||||||
|
import gtk.glade
|
||||||
|
|
||||||
|
import deluge.component as component
|
||||||
|
import deluge.common
|
||||||
|
from deluge.log import LOG as log
|
||||||
|
from deluge.ui.client import aclient
|
||||||
|
|
||||||
|
STATE_PIX = {
|
||||||
|
"Downloading":"downloading",
|
||||||
|
"Seeding":"seeding",
|
||||||
|
"Paused":"inactive",
|
||||||
|
"Checking":"checking",
|
||||||
|
"Queued":"queued",
|
||||||
|
"Error":"alert"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class LabelSideBar(component.Component):
|
||||||
|
def __init__(self):
|
||||||
|
component.Component.__init__(self, "LabelSideBar", interval=2000)
|
||||||
|
self.window = component.get("MainWindow")
|
||||||
|
glade = self.window.main_glade
|
||||||
|
self.label_view = glade.get_widget("label_view")
|
||||||
|
self.hpaned = glade.get_widget("hpaned")
|
||||||
|
self.scrolled = glade.get_widget("scrolledwindow_sidebar")
|
||||||
|
self.is_visible = True
|
||||||
|
self.filters = {}
|
||||||
|
|
||||||
|
# Create the liststore
|
||||||
|
#cat,value,count , pixmap.
|
||||||
|
self.liststore = gtk.ListStore(str, str, int, gtk.gdk.Pixbuf)
|
||||||
|
self.filters[("state", "All")] = self.liststore.append(["state","All",0,gtk.gdk.pixbuf_new_from_file(
|
||||||
|
deluge.common.get_pixmap("dht16.png"))])
|
||||||
|
|
||||||
|
|
||||||
|
# Create the column
|
||||||
|
column = gtk.TreeViewColumn(_("Filters"))
|
||||||
|
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
|
||||||
|
render = gtk.CellRendererPixbuf()
|
||||||
|
column.pack_start(render, expand=False)
|
||||||
|
column.add_attribute(render, 'pixbuf', 3)
|
||||||
|
render = gtk.CellRendererText()
|
||||||
|
column.pack_start(render, expand=True)
|
||||||
|
column.set_cell_data_func(render, self.render_cell_data,None)
|
||||||
|
|
||||||
|
self.label_view.append_column(column)
|
||||||
|
|
||||||
|
self.label_view.set_model(self.liststore)
|
||||||
|
|
||||||
|
self.label_view.get_selection().connect("changed",
|
||||||
|
self.on_selection_changed)
|
||||||
|
|
||||||
|
# Select the 'All' label on init
|
||||||
|
self.label_view.get_selection().select_iter(
|
||||||
|
self.liststore.get_iter_first())
|
||||||
|
|
||||||
|
#init.....
|
||||||
|
self._start()
|
||||||
|
|
||||||
|
|
||||||
|
def cb_update_filter_items(self, filter_items):
|
||||||
|
for cat,filters in filter_items.iteritems():
|
||||||
|
for value, count in filters:
|
||||||
|
self.update_row(cat, value , count)
|
||||||
|
|
||||||
|
def update_row(self, cat, value , count ):
|
||||||
|
if (cat, value) in self.filters:
|
||||||
|
row = self.filters[(cat, value)]
|
||||||
|
self.liststore.set_value(row, 2, count)
|
||||||
|
else:
|
||||||
|
pix = self.get_pixmap(cat, value)
|
||||||
|
row = self.liststore.append([cat, value, count , pix])
|
||||||
|
self.filters[(cat, value)] = row
|
||||||
|
|
||||||
|
def render_cell_data(self, column, cell, model, row, data):
|
||||||
|
"cell renderer"
|
||||||
|
value = model.get_value(row, 1)
|
||||||
|
count = model.get_value(row, 2)
|
||||||
|
txt = "%s (%s)" % (value, count)
|
||||||
|
cell.set_property('text', txt)
|
||||||
|
|
||||||
|
def get_pixmap(self, cat, value):
|
||||||
|
if cat == "state":
|
||||||
|
pix = STATE_PIX.get(value, "dht")
|
||||||
|
return gtk.gdk.pixbuf_new_from_file(deluge.common.get_pixmap("%s16.png" % pix))
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def visible(self, visible):
|
||||||
|
if visible:
|
||||||
|
self.scrolled.show()
|
||||||
|
else:
|
||||||
|
self.scrolled.hide()
|
||||||
|
self.hpaned.set_position(-1)
|
||||||
|
|
||||||
|
self.is_visible = visible
|
||||||
|
|
||||||
|
def on_selection_changed(self, selection):
|
||||||
|
try:
|
||||||
|
(model, row) = self.label_view.get_selection().get_selected()
|
||||||
|
|
||||||
|
cat = model.get_value(row, 0)
|
||||||
|
value = model.get_value(row, 1)
|
||||||
|
|
||||||
|
#gtk-ui has it's own filtering logic on status-fields.
|
||||||
|
#not using the label-backend for filtering. (for now)
|
||||||
|
#just a few simple hacks to translate label-filters to gtk-filters.
|
||||||
|
if cat == "tracker":
|
||||||
|
cat = "tracker_host"
|
||||||
|
|
||||||
|
filter = (cat, value)
|
||||||
|
if value == "All":
|
||||||
|
filter = (None, None)
|
||||||
|
elif (cat == "label" and value == "No Label"):
|
||||||
|
filter = ("label","")
|
||||||
|
|
||||||
|
component.get("TorrentView").set_filter(*filter)
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
log.debug(e)
|
||||||
|
# paths is likely None .. so lets return None
|
||||||
|
return None
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
aclient.label_filter_items(self.cb_update_filter_items)
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ from deluge import component # for systray
|
||||||
import ui
|
import ui
|
||||||
import gtk, gobject
|
import gtk, gobject
|
||||||
from deluge.ui.client import aclient
|
from deluge.ui.client import aclient
|
||||||
|
import gtk_sidebar
|
||||||
|
|
||||||
from deluge.configmanager import ConfigManager
|
from deluge.configmanager import ConfigManager
|
||||||
config = ConfigManager("label.conf")
|
config = ConfigManager("label.conf")
|
||||||
|
@ -82,6 +83,14 @@ class GtkUI(ui.UI):
|
||||||
"Sorry, the Gtk UI for the Label-plugin is still in development."))
|
"Sorry, the Gtk UI for the Label-plugin is still in development."))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
log.debug("replace sidebar")
|
||||||
|
|
||||||
|
try :
|
||||||
|
labelsidebar = gtk_sidebar.LabelSideBar()
|
||||||
|
#sidebar.hpaned.remove(sidebar.scrolled)
|
||||||
|
except Exception, e:
|
||||||
|
log.debug(e)
|
||||||
|
|
||||||
log.debug("add items to torrentview-popup menu.")
|
log.debug("add items to torrentview-popup menu.")
|
||||||
|
|
||||||
torrentmenu = component.get("MenuBar").torrentmenu
|
torrentmenu = component.get("MenuBar").torrentmenu
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
#
|
||||||
|
# sidebar.py
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 Andrew Resch ('andar') <andrewresch@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 2 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 gtk
|
||||||
|
import gtk.glade
|
||||||
|
|
||||||
|
import deluge.component as component
|
||||||
|
import deluge.common
|
||||||
|
from deluge.log import LOG as log
|
||||||
|
|
||||||
|
class LabelSideBar(component.Component):
|
||||||
|
def __init__(self):
|
||||||
|
component.Component.__init__(self, "SideBar")
|
||||||
|
self.window = component.get("MainWindow")
|
||||||
|
glade = self.window.main_glade
|
||||||
|
self.label_view = glade.get_widget("label_view")
|
||||||
|
self.hpaned = glade.get_widget("hpaned")
|
||||||
|
self.scrolled = glade.get_widget("scrolledwindow_sidebar")
|
||||||
|
self.is_visible = True
|
||||||
|
|
||||||
|
# Create the liststore
|
||||||
|
self.liststore = gtk.ListStore(str, gtk.gdk.Pixbuf)
|
||||||
|
self.liststore.append([_("All"), None])
|
||||||
|
self.liststore.append([_("Downloading"),
|
||||||
|
gtk.gdk.pixbuf_new_from_file(
|
||||||
|
deluge.common.get_pixmap("downloading16.png"))])
|
||||||
|
self.liststore.append([_("Seeding"),
|
||||||
|
gtk.gdk.pixbuf_new_from_file(
|
||||||
|
deluge.common.get_pixmap("seeding16.png"))])
|
||||||
|
self.liststore.append([_("Queued"),
|
||||||
|
gtk.gdk.pixbuf_new_from_file(
|
||||||
|
deluge.common.get_pixmap("queued16.png"))])
|
||||||
|
self.liststore.append([_("Paused"),
|
||||||
|
gtk.gdk.pixbuf_new_from_file(
|
||||||
|
deluge.common.get_pixmap("inactive16.png"))])
|
||||||
|
self.liststore.append([_("Error"),
|
||||||
|
gtk.gdk.pixbuf_new_from_file(
|
||||||
|
deluge.common.get_pixmap("alert16.png"))])
|
||||||
|
self.liststore.append([_("Checking"),
|
||||||
|
gtk.gdk.pixbuf_new_from_file(
|
||||||
|
deluge.common.get_pixmap("checking16.png"))])
|
||||||
|
# Create the column
|
||||||
|
column = gtk.TreeViewColumn(_("LABEL-plugin"))
|
||||||
|
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
|
||||||
|
render = gtk.CellRendererPixbuf()
|
||||||
|
column.pack_start(render, expand=False)
|
||||||
|
column.add_attribute(render, 'pixbuf', 1)
|
||||||
|
render = gtk.CellRendererText()
|
||||||
|
column.pack_start(render, expand=True)
|
||||||
|
column.add_attribute(render, 'text', 0)
|
||||||
|
self.label_view.append_column(column)
|
||||||
|
|
||||||
|
self.label_view.set_model(self.liststore)
|
||||||
|
|
||||||
|
self.label_view.get_selection().connect("changed",
|
||||||
|
self.on_selection_changed)
|
||||||
|
|
||||||
|
# Select the 'All' label on init
|
||||||
|
self.label_view.get_selection().select_iter(
|
||||||
|
self.liststore.get_iter_first())
|
||||||
|
|
||||||
|
def visible(self, visible):
|
||||||
|
if visible:
|
||||||
|
self.scrolled.show()
|
||||||
|
else:
|
||||||
|
self.scrolled.hide()
|
||||||
|
self.hpaned.set_position(-1)
|
||||||
|
|
||||||
|
self.is_visible = visible
|
||||||
|
|
||||||
|
def on_selection_changed(self, selection):
|
||||||
|
try:
|
||||||
|
(model, row) = self.label_view.get_selection().get_selected()
|
||||||
|
except Exception, e:
|
||||||
|
log.debug(e)
|
||||||
|
# paths is likely None .. so lets return None
|
||||||
|
return None
|
||||||
|
|
||||||
|
value = model.get_value(row, 0)
|
||||||
|
if value == "All":
|
||||||
|
component.get("TorrentView").set_filter(None, None)
|
||||||
|
else:
|
||||||
|
component.get("TorrentView").set_filter("state", value)
|
||||||
|
|
|
@ -10,7 +10,7 @@ if not "label" in sclient.get_enabled_plugins():
|
||||||
|
|
||||||
#test filter items.
|
#test filter items.
|
||||||
print "# label_filter_items()"
|
print "# label_filter_items()"
|
||||||
for cat,filters in sclient.label_filter_items():
|
for cat,filters in sclient.label_filter_items().iteritems():
|
||||||
print "-- %s --" % cat
|
print "-- %s --" % cat
|
||||||
for filter in filters:
|
for filter in filters:
|
||||||
print " * %s (%s)" % (filter[0],filter[1])
|
print " * %s (%s)" % (filter[0],filter[1])
|
||||||
|
@ -56,7 +56,7 @@ print len(sclient.label_get_filtered_ids({'label':'test'} ))
|
||||||
|
|
||||||
#test filter items.
|
#test filter items.
|
||||||
print "# label_filter_items()"
|
print "# label_filter_items()"
|
||||||
for cat,filters in sclient.label_filter_items():
|
for cat,filters in sclient.label_filter_items().iteritems():
|
||||||
if cat == "label":
|
if cat == "label":
|
||||||
print "-- %s --" % cat
|
print "-- %s --" % cat
|
||||||
for filter in filters:
|
for filter in filters:
|
||||||
|
|
Loading…
Reference in New Issue