From a0a29773d69e71a98f276bc7f3b274372a3f3275 Mon Sep 17 00:00:00 2001 From: Eugene Gagarin Date: Mon, 6 Apr 2009 13:11:31 +0400 Subject: [PATCH] added deb search possibility (edit */application.py for switch between deb and file search) --- src/mvc/controllers/application.py | 10 ++-- src/mvc/controllers/debsearch.py | 97 ++++++++++++++++++++++++++++++++++++ src/mvc/models/application.py | 6 ++- src/mvc/models/debsearch.py | 18 +++++++ src/mvc/views/application.py | 18 +++++-- src/mvc/views/debsearch.py | 87 ++++++++++++++++++++++++++++++++ 6 files changed, 226 insertions(+), 10 deletions(-) create mode 100755 src/mvc/controllers/debsearch.py create mode 100755 src/mvc/models/debsearch.py create mode 100755 src/mvc/views/debsearch.py diff --git a/src/mvc/controllers/application.py b/src/mvc/controllers/application.py index 24dc8cd..489f9ba 100755 --- a/src/mvc/controllers/application.py +++ b/src/mvc/controllers/application.py @@ -1,7 +1,9 @@ from gtkmvc import Controller import gtk -from filesearch import FilesearchCtrl +#from filesearch import FilesearchCtrl +from debsearch import DebsearchCtrl + from views.about import AboutView @@ -10,13 +12,15 @@ class ApplicationCtrl(Controller): def __init__(self, model): Controller.__init__(self, model) - self.filesearch = FilesearchCtrl(model.filesearch) +# self.filesearch = FilesearchCtrl(model.filesearch) + self.debsearch = DebsearchCtrl(model.debsearch) def register_view(self, view): """Creates subviews and connect signals""" Controller.register_view(self, view) - self.view.create_sub_views(self.filesearch) + #self.view.create_sub_views(self.filesearch) + self.view.create_sub_views(self.debsearch) # connects the signals: self.view['main_window'].connect('destroy', gtk.main_quit) diff --git a/src/mvc/controllers/debsearch.py b/src/mvc/controllers/debsearch.py new file mode 100755 index 0000000..2a2a5f8 --- /dev/null +++ b/src/mvc/controllers/debsearch.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*-coding: utf-8 -*- +# vim: sw=4 ts=4 expandtab ai +# pylint: disable-msg=C0301 + +from gtkmvc import Controller +import gtk + +import apt_pkg +from heapq import nlargest + +from views.debsearch import DebsearchView + + +class DebsearchCtrl(Controller): + """Controller of the Debian packages search plugin""" + + def __init__(self, model): + Controller.__init__(self, model) + + def register_view(self, view): + Controller.register_view(self, view) + + # connects the signals: + self.view['start_btn'].connect('released', self.start_btn_released_cb) + self.view['stop_btn'].connect('clicked', self.on_stop_btn_clicked) + self.view['qty_spin'].connect("value_changed", self.on_qty_spin_value_changed) + + # sets initial values for the view + self.view.set_quantity_value(self.model.quantity) + + # ----------------------------------------------------- + # user callbacks + # ----------------------------------------------------- + + def debgetter(self): + apt_pkg.InitConfig() + apt_pkg.InitSystem() + cache = apt_pkg.GetCache() + for pkg in cache.Packages: + # pkg is from a list of packages, sorted by name. + self.view['statusbar'].push(self.view['context_id'], pkg.Name) ### FIXME + if pkg.CurrentState == apt_pkg.CurStateInstalled: + pkgsize = [version.InstalledSize for version in pkg.VersionList][0] + yield pkgsize, pkg.Name + + def size_convert(self, size): + """Return string with package size in b or Kb or Mb or Gb or Tb.""" + + for i, unit in enumerate(['%d b', '%.1f Kb', '%.2f Mb', '%.3f Gb', '%.4f Tb']): + if size < 1024**(i+1): + return unit % (size/1024.**i) + return '>1024 Tb' + + # ----------------------------------------------------- + # gtk signals + # ----------------------------------------------------- + + def on_qty_spin_value_changed(self, sb): + """Get packages qty from SpinButton.""" + self.model.quantity = sb.get_value_as_int() + + def start_btn_released_cb(self, btn): + """Start package search. Button "Go" activate callback.""" + + self.view['start_btn'].set_sensitive(False) + self.view['stop_btn'].set_sensitive(True) + + # Clear list + self.view['liststore'].clear() + + # Align columns + self.view['treeview'].columns_autosize() + + # Get biggest packages + for psize, packg in nlargest(self.model.quantity, self.debgetter()): + # Fill treemodel: package name, size as string, byte size + self.view['liststore'].append([packg, self.size_convert(psize), psize]) + + self.view['start_btn'].set_sensitive(True) + self.view['stop_btn'].set_sensitive(False) + + def on_stop_btn_clicked(self, btn): + """Stop search. "Stop" button clicked callback.""" + print 'Stop clicked' + self.model.stopit = True + + # ----------------------------------------------------- + # observable properties + # ----------------------------------------------------- + + def property_quantity_value_change(self, model, old, new): + pass + #self.view.set_quantity_value(new) + + def property_stopit_value_change(self, model, old, new): + self.view.set_stopit_value(new) diff --git a/src/mvc/models/application.py b/src/mvc/models/application.py index d19d02c..10a133a 100755 --- a/src/mvc/models/application.py +++ b/src/mvc/models/application.py @@ -1,6 +1,7 @@ from gtkmvc import Model -from filesearch import FilesearchModel +#from filesearch import FilesearchModel +from debsearch import DebsearchModel class ApplicationModel(Model): @@ -8,4 +9,5 @@ class ApplicationModel(Model): def __init__(self): Model.__init__(self) - self.filesearch = FilesearchModel() +# self.filesearch = FilesearchModel() + self.debsearch = DebsearchModel() diff --git a/src/mvc/models/debsearch.py b/src/mvc/models/debsearch.py new file mode 100755 index 0000000..a0a632f --- /dev/null +++ b/src/mvc/models/debsearch.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# -*-coding: utf-8 -*- +# vim: sw=4 ts=4 expandtab ai +# pylint: disable-msg=C0301 + +from gtkmvc import Model + + +class DebsearchModel(Model): + + # observable properties + __properties__ = { + 'quantity' : 10, + 'stopit' : False + } + + def __init__(self): + Model.__init__(self) diff --git a/src/mvc/views/application.py b/src/mvc/views/application.py index df53d75..ede8dd7 100755 --- a/src/mvc/views/application.py +++ b/src/mvc/views/application.py @@ -1,7 +1,8 @@ from gtkmvc import View import gtk -from filesearch import FilesearchView +#from filesearch import FilesearchView +from debsearch import DebsearchView class ApplicationView(View): @@ -9,7 +10,8 @@ class ApplicationView(View): def __init__(self, ctrl): View.__init__(self, ctrl, register=False) - self.filesearch = None +# self.filesearch = None + self.debsearch = None self.__build_widgets() ctrl.register_view(self) @@ -17,6 +19,7 @@ class ApplicationView(View): self['main_window'] = gtk.Window() self['main_window'].set_default_size(500, 350) self['main_window'].set_border_width(4) + self['main_window'].set_wmclass('MainWindow', 'FindIT') self['about_btn'] = gtk.Button('About') self['quit_btn'] = gtk.Button('Exit') @@ -34,7 +37,12 @@ class ApplicationView(View): self['main_window'].add(self['vbox']) self['main_window'].show_all() - def create_sub_views(self, filesearch_ctrl): +# def create_sub_views(self, filesearch_ctrl): +# """Creates and connects sub views""" +# self.filesearch = FilesearchView(filesearch_ctrl) # not a top level +# self['vbox'].pack_start(self.filesearch['vbox']) + + def create_sub_views(self, debsearch_ctrl): """Creates and connects sub views""" - self.filesearch = FilesearchView(filesearch_ctrl) # not a top level - self['vbox'].pack_start(self.filesearch['vbox']) + self.debsearch = DebsearchView(debsearch_ctrl) # not a top level + self['vbox'].pack_start(self.debsearch['vbox']) diff --git a/src/mvc/views/debsearch.py b/src/mvc/views/debsearch.py new file mode 100755 index 0000000..f1be44e --- /dev/null +++ b/src/mvc/views/debsearch.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*-coding: utf-8 -*- +# vim: sw=4 ts=4 expandtab ai +# pylint: disable-msg=C0301 + +from gtkmvc import View +import gtk, gobject + + +class DebsearchView(View): + """A view for the Debian packages search plugin""" + + def __init__(self, ctrl): + View.__init__(self, ctrl, register=False) + self.__build_widgets() + ctrl.register_view(self) + + def __build_widgets(self): + + hbox = gtk.HBox(False, 4) + + # "Packages quantity" label + qty_label = gtk.Label('Packages quantity') + + # "Packages quantity" spin + self['qty_spin'] = gtk.SpinButton() + self['qty_spin'].set_numeric(True) + self['qty_spin'].set_range(0, 65536) + self['qty_spin'].set_increments(1, 10) + + # "Go" button + self['start_btn'] = gtk.Button('Go') + + # "Stop" button + self['stop_btn'] = gtk.Button('Stop') + self['stop_btn'].set_sensitive(False) + + hbox.pack_start(qty_label, False, False, 0) + hbox.pack_start(self['qty_spin'], False, False, 0) + hbox.pack_start(self['start_btn']) + hbox.pack_start(self['stop_btn']) + + # Packages list + self['liststore'] = gtk.ListStore(str, str, gobject.TYPE_INT64) + self['liststore'].append(['', '', 0]) + + self['treeview'] = gtk.TreeView(self['liststore']) + self['treeview'].set_headers_visible(1) + + swin = gtk.ScrolledWindow() + swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + swin.add(self['treeview']) + + # Size column + size_col = gtk.TreeViewColumn('Size') + cell1 = gtk.CellRendererText() + cell1.set_property('width', 90) + size_col.pack_start(cell1, True) + size_col.add_attribute(cell1, 'text', 1) + self['treeview'].append_column(size_col) + + # Package name column + name_col = gtk.TreeViewColumn('Name') + cell2 = gtk.CellRendererText() + name_col.pack_start(cell2, True) + name_col.add_attribute(cell2, 'text', 0) + self['treeview'].append_column(name_col) + + # Column sorting + self['treeview'].set_search_column(1) + name_col.set_sort_column_id(0) + size_col.set_sort_column_id(2) + + self['statusbar'] = gtk.Statusbar() + self['context_id'] = self['statusbar'].get_context_id("Current package") + + self['vbox'] = gtk.VBox(False, 4) + self['vbox'].pack_start(hbox, False, False, 0) + self['vbox'].pack_start(swin) + self['vbox'].pack_start(self['statusbar'], False, False, 0) + self['vbox'].show_all() + + def set_quantity_value(self, val): + self['qty_spin'].set_value(val) + + def set_stopit_value(self, val): + pass -- 1.7.9.5