core filtering in gtkui;breaks label plugin
This commit is contained in:
parent
eee10dab76
commit
aa4ed4a6c6
|
@ -73,7 +73,8 @@ class GtkUI(ui.UI):
|
||||||
log.debug(e) #fix this!
|
log.debug(e) #fix this!
|
||||||
|
|
||||||
log.debug(1.2)
|
log.debug(1.2)
|
||||||
self.sidebar.unload()
|
#disabled:
|
||||||
|
#self.sidebar.unload()
|
||||||
log.debug(2)
|
log.debug(2)
|
||||||
|
|
||||||
def get_pixmap(self, fname):
|
def get_pixmap(self, fname):
|
||||||
|
@ -83,9 +84,10 @@ class GtkUI(ui.UI):
|
||||||
|
|
||||||
def load_interface(self):
|
def load_interface(self):
|
||||||
#sidebar
|
#sidebar
|
||||||
if not self.sidebar:
|
#disabled
|
||||||
self.sidebar = sidebar.LabelSideBar()
|
#if not self.sidebar:
|
||||||
self.sidebar.load()
|
# self.sidebar = sidebar.LabelSideBar()
|
||||||
|
#self.sidebar.load()
|
||||||
|
|
||||||
#menu:
|
#menu:
|
||||||
log.debug("add items to torrentview-popup menu.")
|
log.debug("add items to torrentview-popup menu.")
|
||||||
|
|
|
@ -0,0 +1,223 @@
|
||||||
|
#
|
||||||
|
# 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 3 of the License, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# deluge is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with deluge. If not, write to:
|
||||||
|
# The Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# In addition, as a special exception, the copyright holders give
|
||||||
|
# permission to link the code of portions of this program with the OpenSSL
|
||||||
|
# library.
|
||||||
|
# You must obey the GNU General Public License in all respects for all of
|
||||||
|
# the code used other than OpenSSL. If you modify file(s) with this
|
||||||
|
# exception, you may extend this exception to your version of the file(s),
|
||||||
|
# but you are not obligated to do so. If you do not wish to do so, delete
|
||||||
|
# this exception statement from your version. If you delete this exception
|
||||||
|
# statement from all source files in the program, then also delete it here.
|
||||||
|
|
||||||
|
import 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"
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar-treeview
|
||||||
|
class FilterTreeView(component.Component):
|
||||||
|
def __init__(self):
|
||||||
|
component.Component.__init__(self, "FilterTreeView", interval=2000)
|
||||||
|
self.window = component.get("MainWindow")
|
||||||
|
glade = self.window.main_glade
|
||||||
|
self.hpaned = glade.get_widget("hpaned")
|
||||||
|
self.scrolled = glade.get_widget("scrolledwindow_sidebar")
|
||||||
|
self.sidebar = component.get("SideBar")
|
||||||
|
self.is_visible = True
|
||||||
|
self.filters = {}
|
||||||
|
self.label_view = gtk.TreeView()
|
||||||
|
self.sidebar.add_tab(self.label_view, "filters", _("Filters"))
|
||||||
|
|
||||||
|
|
||||||
|
# Create the liststore
|
||||||
|
#cat,value,count , pixmap , visible
|
||||||
|
self.treestore = gtk.TreeStore(str, str, int, gtk.gdk.Pixbuf, bool)
|
||||||
|
|
||||||
|
#add Cat nodes:
|
||||||
|
self.cat_nodes = {}
|
||||||
|
|
||||||
|
# Create the column
|
||||||
|
column = gtk.TreeViewColumn(_("Filters"))
|
||||||
|
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
|
||||||
|
render = gtk.CellRendererPixbuf()
|
||||||
|
self.renderpix = render
|
||||||
|
column.pack_start(render, expand=False)
|
||||||
|
column.add_attribute(render, 'pixbuf', 3)
|
||||||
|
render = gtk.CellRendererText()
|
||||||
|
column.pack_start(render, expand=False)
|
||||||
|
column.set_cell_data_func(render, self.render_cell_data,None)
|
||||||
|
|
||||||
|
self.label_view.append_column(column)
|
||||||
|
|
||||||
|
#style:
|
||||||
|
self.label_view.set_show_expanders(False)
|
||||||
|
self.label_view.set_headers_visible(False)
|
||||||
|
|
||||||
|
self.label_view.set_model(self.treestore)
|
||||||
|
self.label_view.get_selection().connect("changed", self.on_selection_changed)
|
||||||
|
self.create_model_filter()
|
||||||
|
|
||||||
|
#init.....
|
||||||
|
self._start()
|
||||||
|
self.hpaned.set_position(170)
|
||||||
|
self.label_view.connect("button-press-event", self.on_button_press_event)
|
||||||
|
|
||||||
|
def create_model_filter(self):
|
||||||
|
self.model_filter = self.treestore.filter_new()
|
||||||
|
self.model_filter.set_visible_column(4)
|
||||||
|
self.label_view.set_model(self.model_filter)
|
||||||
|
|
||||||
|
def cb_update_filter_tree(self, filter_items):
|
||||||
|
#create missing cat_nodes
|
||||||
|
for cat in filter_items:
|
||||||
|
if not cat in self.cat_nodes:
|
||||||
|
self.cat_nodes[cat] = self.treestore.append(None, ["cat", _(cat), 0, None, False])
|
||||||
|
|
||||||
|
#update rows
|
||||||
|
visible_filters = []
|
||||||
|
for cat,filters in filter_items.iteritems():
|
||||||
|
for value, count in filters:
|
||||||
|
self.update_row(cat, value , count)
|
||||||
|
visible_filters.append((cat, value))
|
||||||
|
|
||||||
|
# hide root-categories not returned by core-part of the plugin.
|
||||||
|
for cat in self.cat_nodes:
|
||||||
|
if cat in filter_items:
|
||||||
|
self.treestore.set_value(self.cat_nodes[cat], 4, True)
|
||||||
|
else:
|
||||||
|
self.treestore.set_value(self.cat_nodes[cat], 4, False)
|
||||||
|
|
||||||
|
# hide items not returned by core-plugin.
|
||||||
|
for f in self.filters:
|
||||||
|
if not f in visible_filters:
|
||||||
|
self.treestore.set_value(self.filters[f], 4, False)
|
||||||
|
|
||||||
|
# obsolete?
|
||||||
|
self.label_view.expand_all()
|
||||||
|
|
||||||
|
def update_row(self, cat, value , count):
|
||||||
|
if (cat, value) in self.filters:
|
||||||
|
row = self.filters[(cat, value)]
|
||||||
|
self.treestore.set_value(row, 2, count)
|
||||||
|
else:
|
||||||
|
pix = self.get_pixmap(cat, value)
|
||||||
|
row = self.treestore.append(self.cat_nodes[cat],[cat, value, count , pix, True])
|
||||||
|
self.filters[(cat, value)] = row
|
||||||
|
self.treestore.set_value(row, 4, True)
|
||||||
|
|
||||||
|
def render_cell_data(self, column, cell, model, row, data):
|
||||||
|
"cell renderer"
|
||||||
|
cat = model.get_value(row, 0)
|
||||||
|
value = model.get_value(row, 1)
|
||||||
|
count = model.get_value(row, 2)
|
||||||
|
|
||||||
|
if cat == "state":
|
||||||
|
self.renderpix.set_property("visible", True)
|
||||||
|
else:
|
||||||
|
self.renderpix.set_property("visible", False)
|
||||||
|
|
||||||
|
cell.set_property('editable', False)
|
||||||
|
if cat == "cat":
|
||||||
|
txt = value
|
||||||
|
col = gtk.gdk.color_parse('#EEEEEE')
|
||||||
|
else:
|
||||||
|
txt = "%s (%s)" % (value, count)
|
||||||
|
col = gtk.gdk.color_parse('white')
|
||||||
|
|
||||||
|
cell.set_property('text', txt)
|
||||||
|
cell.set_property("cell-background-gdk",col)
|
||||||
|
self.renderpix.set_property("cell-background-gdk",col)
|
||||||
|
|
||||||
|
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 on_selection_changed(self, selection):
|
||||||
|
try:
|
||||||
|
(model, row) = self.label_view.get_selection().get_selected()
|
||||||
|
if not row:
|
||||||
|
log.debug("nothing selected")
|
||||||
|
return
|
||||||
|
|
||||||
|
cat = model.get_value(row, 0)
|
||||||
|
value = model.get_value(row, 1)
|
||||||
|
|
||||||
|
filter_dict = {cat: [value]}
|
||||||
|
if value == "All" or cat == "cat":
|
||||||
|
filter_dict = {}
|
||||||
|
|
||||||
|
component.get("TorrentView").set_filter(filter_dict)
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
log.debug(e)
|
||||||
|
# paths is likely None .. so lets return None
|
||||||
|
return None
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
try:
|
||||||
|
aclient.get_filter_tree(self.cb_update_filter_tree)
|
||||||
|
except Exception, e:
|
||||||
|
log.debug(e)
|
||||||
|
|
||||||
|
|
||||||
|
### Callbacks ###
|
||||||
|
def on_button_press_event(self, widget, event):
|
||||||
|
"""This is a callback for showing the right-click context menu.
|
||||||
|
NOT YET!
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
# We only care about right-clicks
|
||||||
|
if event.button == 3:
|
||||||
|
x, y = event.get_coords()
|
||||||
|
path = self.label_view.get_path_at_pos(int(x), int(y))
|
||||||
|
if not path:
|
||||||
|
return
|
||||||
|
row = self.model_filter.get_iter(path[0])
|
||||||
|
cat = self.model_filter.get_value(row, 0)
|
||||||
|
value = self.model_filter.get_value(row, 1)
|
||||||
|
count = self.model_filter.get_value(row, 2)
|
||||||
|
|
||||||
|
#log.debug("right-click->cat='%s',value='%s'", cat ,value)
|
||||||
|
|
||||||
|
if cat == "label":
|
||||||
|
self.show_label_menu(value, count, event)
|
||||||
|
elif (cat == "cat" and value == "Label"): #add button on root node.
|
||||||
|
self.show_label_menu(None, 0, event)
|
||||||
|
"""
|
|
@ -2,19 +2,19 @@
|
||||||
# gtkui.py
|
# gtkui.py
|
||||||
#
|
#
|
||||||
# Copyright (C) 2007 Andrew Resch ('andar') <andrewresch@gmail.com>
|
# Copyright (C) 2007 Andrew Resch ('andar') <andrewresch@gmail.com>
|
||||||
#
|
#
|
||||||
# Deluge is free software.
|
# Deluge is free software.
|
||||||
#
|
#
|
||||||
# You may redistribute it and/or modify it under the terms of the
|
# You may redistribute it and/or modify it under the terms of the
|
||||||
# GNU General Public License, as published by the Free Software
|
# GNU General Public License, as published by the Free Software
|
||||||
# Foundation; either version 3 of the License, or (at your option)
|
# Foundation; either version 3 of the License, or (at your option)
|
||||||
# any later version.
|
# any later version.
|
||||||
#
|
#
|
||||||
# deluge is distributed in the hope that it will be useful,
|
# deluge is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
# See the GNU General Public License for more details.
|
# See the GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with deluge. If not, write to:
|
# along with deluge. If not, write to:
|
||||||
# The Free Software Foundation, Inc.,
|
# The Free Software Foundation, Inc.,
|
||||||
|
@ -52,6 +52,7 @@ from toolbar import ToolBar
|
||||||
from torrentview import TorrentView
|
from torrentview import TorrentView
|
||||||
from torrentdetails import TorrentDetails
|
from torrentdetails import TorrentDetails
|
||||||
from sidebar import SideBar
|
from sidebar import SideBar
|
||||||
|
from filtertreeview import FilterTreeView
|
||||||
from preferences import Preferences
|
from preferences import Preferences
|
||||||
from systemtray import SystemTray
|
from systemtray import SystemTray
|
||||||
from statusbar import StatusBar
|
from statusbar import StatusBar
|
||||||
|
@ -59,7 +60,7 @@ from connectionmanager import ConnectionManager
|
||||||
from signals import Signals
|
from signals import Signals
|
||||||
from pluginmanager import PluginManager
|
from pluginmanager import PluginManager
|
||||||
from ipcinterface import IPCInterface
|
from ipcinterface import IPCInterface
|
||||||
|
|
||||||
from queuedtorrents import QueuedTorrents
|
from queuedtorrents import QueuedTorrents
|
||||||
from addtorrentdialog import AddTorrentDialog
|
from addtorrentdialog import AddTorrentDialog
|
||||||
from coreconfig import CoreConfig
|
from coreconfig import CoreConfig
|
||||||
|
@ -119,13 +120,13 @@ class GtkUI:
|
||||||
# Initialize gdk threading
|
# Initialize gdk threading
|
||||||
gtk.gdk.threads_init()
|
gtk.gdk.threads_init()
|
||||||
gobject.threads_init()
|
gobject.threads_init()
|
||||||
|
|
||||||
# Initialize gettext
|
# Initialize gettext
|
||||||
if deluge.common.windows_check():
|
if deluge.common.windows_check():
|
||||||
locale.setlocale(locale.LC_ALL, '')
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
else:
|
else:
|
||||||
locale.setlocale(locale.LC_MESSAGES, '')
|
locale.setlocale(locale.LC_MESSAGES, '')
|
||||||
locale.bindtextdomain("deluge",
|
locale.bindtextdomain("deluge",
|
||||||
pkg_resources.resource_filename(
|
pkg_resources.resource_filename(
|
||||||
"deluge", "i18n"))
|
"deluge", "i18n"))
|
||||||
locale.textdomain("deluge")
|
locale.textdomain("deluge")
|
||||||
|
@ -137,7 +138,7 @@ class GtkUI:
|
||||||
gettext.install("deluge",
|
gettext.install("deluge",
|
||||||
pkg_resources.resource_filename(
|
pkg_resources.resource_filename(
|
||||||
"deluge", "i18n"))
|
"deluge", "i18n"))
|
||||||
|
|
||||||
# Setup signals
|
# Setup signals
|
||||||
try:
|
try:
|
||||||
import gnome.ui
|
import gnome.ui
|
||||||
|
@ -159,7 +160,7 @@ class GtkUI:
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
return 1
|
return 1
|
||||||
SetConsoleCtrlHandler(win_handler)
|
SetConsoleCtrlHandler(win_handler)
|
||||||
|
|
||||||
# Make sure gtkui.conf has at least the defaults set
|
# Make sure gtkui.conf has at least the defaults set
|
||||||
self.config = deluge.configmanager.ConfigManager("gtkui.conf", DEFAULT_PREFS)
|
self.config = deluge.configmanager.ConfigManager("gtkui.conf", DEFAULT_PREFS)
|
||||||
|
|
||||||
|
@ -180,21 +181,21 @@ class GtkUI:
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
log.error("Unable to find deluged: %s", e)
|
log.error("Unable to find deluged: %s", e)
|
||||||
self.config["classic_mode"] = False
|
self.config["classic_mode"] = False
|
||||||
|
|
||||||
# We need to check on exit if it was started in classic mode to ensure we
|
# We need to check on exit if it was started in classic mode to ensure we
|
||||||
# shutdown the daemon.
|
# shutdown the daemon.
|
||||||
self.started_in_classic = self.config["classic_mode"]
|
self.started_in_classic = self.config["classic_mode"]
|
||||||
|
|
||||||
# Start the Dbus Interface before anything else.. Just in case we are
|
# Start the Dbus Interface before anything else.. Just in case we are
|
||||||
# already running.
|
# already running.
|
||||||
self.queuedtorrents = QueuedTorrents()
|
self.queuedtorrents = QueuedTorrents()
|
||||||
|
|
||||||
self.ipcinterface = IPCInterface(args)
|
self.ipcinterface = IPCInterface(args)
|
||||||
|
|
||||||
# We make sure that the UI components start once we get a core URI
|
# We make sure that the UI components start once we get a core URI
|
||||||
client.connect_on_new_core(self._on_new_core)
|
client.connect_on_new_core(self._on_new_core)
|
||||||
client.connect_on_no_core(self._on_no_core)
|
client.connect_on_no_core(self._on_no_core)
|
||||||
|
|
||||||
# Initialize various components of the gtkui
|
# Initialize various components of the gtkui
|
||||||
self.mainwindow = MainWindow()
|
self.mainwindow = MainWindow()
|
||||||
self.menubar = MenuBar()
|
self.menubar = MenuBar()
|
||||||
|
@ -202,6 +203,7 @@ class GtkUI:
|
||||||
self.torrentview = TorrentView()
|
self.torrentview = TorrentView()
|
||||||
self.torrentdetails = TorrentDetails()
|
self.torrentdetails = TorrentDetails()
|
||||||
self.sidebar = SideBar()
|
self.sidebar = SideBar()
|
||||||
|
self.filtertreeview = FilterTreeView()
|
||||||
self.preferences = Preferences()
|
self.preferences = Preferences()
|
||||||
self.systemtray = SystemTray()
|
self.systemtray = SystemTray()
|
||||||
self.statusbar = StatusBar()
|
self.statusbar = StatusBar()
|
||||||
|
@ -210,15 +212,15 @@ class GtkUI:
|
||||||
# Start the signal receiver
|
# Start the signal receiver
|
||||||
self.signal_receiver = Signals()
|
self.signal_receiver = Signals()
|
||||||
self.coreconfig = CoreConfig()
|
self.coreconfig = CoreConfig()
|
||||||
|
|
||||||
# Initalize the plugins
|
# Initalize the plugins
|
||||||
self.plugins = PluginManager()
|
self.plugins = PluginManager()
|
||||||
|
|
||||||
# Show the connection manager
|
# Show the connection manager
|
||||||
self.connectionmanager = ConnectionManager()
|
self.connectionmanager = ConnectionManager()
|
||||||
if self.config["show_connection_manager_on_start"] and not self.config["classic_mode"]:
|
if self.config["show_connection_manager_on_start"] and not self.config["classic_mode"]:
|
||||||
self.connectionmanager.show()
|
self.connectionmanager.show()
|
||||||
|
|
||||||
# Start the gtk main loop
|
# Start the gtk main loop
|
||||||
try:
|
try:
|
||||||
gtk.gdk.threads_enter()
|
gtk.gdk.threads_enter()
|
||||||
|
@ -226,7 +228,7 @@ class GtkUI:
|
||||||
gtk.gdk.threads_leave()
|
gtk.gdk.threads_leave()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
else:
|
else:
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
|
|
||||||
def shutdown(self, *args, **kwargs):
|
def shutdown(self, *args, **kwargs):
|
||||||
|
@ -234,7 +236,7 @@ class GtkUI:
|
||||||
|
|
||||||
# Make sure the config is saved.
|
# Make sure the config is saved.
|
||||||
self.config.save()
|
self.config.save()
|
||||||
|
|
||||||
# Shutdown all components
|
# Shutdown all components
|
||||||
component.shutdown()
|
component.shutdown()
|
||||||
if self.started_in_classic:
|
if self.started_in_classic:
|
||||||
|
@ -246,9 +248,9 @@ class GtkUI:
|
||||||
gtk.main_quit()
|
gtk.main_quit()
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _on_new_core(self, data):
|
def _on_new_core(self, data):
|
||||||
component.start()
|
component.start()
|
||||||
|
|
||||||
def _on_no_core(self, data):
|
def _on_no_core(self, data):
|
||||||
component.stop()
|
component.stop()
|
||||||
|
|
Loading…
Reference in New Issue