added deb search possibility (edit */application.py for switch between deb and file...
authorEugene Gagarin <mosfet07@ya.ru>
Mon, 6 Apr 2009 09:11:31 +0000 (13:11 +0400)
committerEugene Gagarin <mosfet07@ya.ru>
Mon, 6 Apr 2009 09:11:31 +0000 (13:11 +0400)
src/mvc/controllers/application.py
src/mvc/controllers/debsearch.py [new file with mode: 0755]
src/mvc/models/application.py
src/mvc/models/debsearch.py [new file with mode: 0755]
src/mvc/views/application.py
src/mvc/views/debsearch.py [new file with mode: 0755]

index 24dc8cd..489f9ba 100755 (executable)
@@ -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 (executable)
index 0000000..2a2a5f8
--- /dev/null
@@ -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)
index d19d02c..10a133a 100755 (executable)
@@ -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 (executable)
index 0000000..a0a632f
--- /dev/null
@@ -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)
index df53d75..ede8dd7 100755 (executable)
@@ -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 (executable)
index 0000000..f1be44e
--- /dev/null
@@ -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