[ontv] SearchDialog rewritten to stop depending on libglade



commit df6c5065d1cb08ae6bf3899c2efa19a203736ff6
Author: Olof Kindgren <olki src gnome org>
Date:   Wed Dec 30 21:25:36 2009 +0100

    SearchDialog rewritten to stop depending on libglade
    
    * Most things in SearchDialog is moved to dialogs.ui
    * The treeview/liststore is rewritten so that it loads all content
    when the dialog is loaded and filters the rows, instead of
    dynamically  rewriting the GtkListStore
    * Right click menu is removed. The "add reminder" menu item is now
    a separate button instead.

 data/ontv.ui    |   91 +++++++++++++++++++++----
 ontv/dialogs.py |  203 ++++++++++++++++++------------------------------------
 ontv/gui.py     |    3 +-
 3 files changed, 148 insertions(+), 149 deletions(-)
---
diff --git a/data/ontv.ui b/data/ontv.ui
index 64f455f..8d9126a 100644
--- a/data/ontv.ui
+++ b/data/ontv.ui
@@ -21,6 +21,19 @@
       <column type="gchararray"/>
     </columns>
   </object>
+  <object class="GtkListStore" id="search_model">
+    <columns>
+      <!-- column-name col_time -->
+      <column type="gchararray"/>
+      <!-- column-name col_title -->
+      <column type="gchararray"/>
+      <!-- column-name col_program -->
+      <column type="PyObject"/>
+    </columns>
+  </object>
+  <object class="GtkTreeModelFilter" id="search_model_filter">
+    <property name="child_model">search_model</property>
+  </object>
   <object class="GtkDialog" id="preferences_dialog">
     <property name="width_request">530</property>
     <property name="height_request">520</property>
@@ -106,7 +119,6 @@
                                     <property name="xalign">1</property>
                                     <property name="label" translatable="yes">_Output file:</property>
                                     <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">output_file_entry</property>
                                   </object>
                                   <packing>
                                     <property name="top_attach">1</property>
@@ -132,7 +144,6 @@
                                     <property name="xalign">1</property>
                                     <property name="label" translatable="yes">_Grabber command:</property>
                                     <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">grabber_command_entry</property>
                                   </object>
                                   <packing>
                                     <property name="x_options"></property>
@@ -252,7 +263,6 @@
                                             <property name="use_underline">True</property>
                                             <property name="active">True</property>
                                             <property name="draw_indicator">True</property>
-                                            <property name="group">upcoming_programs_below_radiobutton</property>
                                           </object>
                                           <packing>
                                             <property name="position">1</property>
@@ -320,7 +330,6 @@
                         <property name="yalign">0</property>
                         <property name="label" translatable="yes">_Select channels to monitor in preferred order:</property>
                         <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">channels_treeview</property>
                       </object>
                       <packing>
                         <property name="expand">False</property>
@@ -419,7 +428,6 @@
                         <property name="yalign">0</property>
                         <property name="label" translatable="yes">_Current reminders:</property>
                         <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">reminders_treeview</property>
                       </object>
                       <packing>
                         <property name="expand">False</property>
@@ -459,7 +467,6 @@
                             <property name="yalign">0</property>
                             <property name="label" translatable="yes">_Program:</property>
                             <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">program_entry</property>
                           </object>
                           <packing>
                             <property name="x_options"></property>
@@ -484,7 +491,6 @@
                             <property name="yalign">0</property>
                             <property name="label" translatable="yes">_Channel:</property>
                             <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">channels_comboboxentry</property>
                           </object>
                           <packing>
                             <property name="top_attach">1</property>
@@ -522,7 +528,6 @@
                             <property name="xalign">0</property>
                             <property name="label" translatable="yes">_Notify</property>
                             <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">notify_spinbutton</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
@@ -534,7 +539,6 @@
                           <object class="GtkSpinButton" id="notify_spinbutton">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
-                            <property name="adjustment">adjustment1</property>
                             <property name="climb_rate">1</property>
                             <property name="numeric">True</property>
                           </object>
@@ -695,7 +699,6 @@
                     <property name="xalign">0</property>
                     <property name="label" translatable="yes">_Search:</property>
                     <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">search_entry</property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -707,6 +710,7 @@
                   <object class="GtkEntry" id="search_entry">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
+                    <signal name="changed" handler="on_search_entry_changed"/>
                   </object>
                   <packing>
                     <property name="position">1</property>
@@ -715,6 +719,13 @@
                 <child>
                   <object class="GtkComboBox" id="channels_combobox">
                     <property name="visible">True</property>
+                    <signal name="changed" handler="on_channels_combobox_changed"/>
+                    <child>
+                      <object class="GtkCellRendererText" id="search_channel_crt"/>
+                      <attributes>
+                        <attribute name="text">0</attribute>
+                      </attributes>
+                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -738,9 +749,39 @@
                   <object class="GtkTreeView" id="search_treeview">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
+                    <property name="model">search_model_filter</property>
                     <property name="headers_visible">False</property>
                     <property name="rules_hint">True</property>
                     <property name="enable_search">False</property>
+                    <signal name="row_activated" handler="on_search_treeview_row_activated"/>
+                    <child>
+                      <object class="GtkTreeViewColumn" id="time_column">
+                        <property name="title">Air time</property>
+                        <child>
+                          <object class="GtkCellRendererText" id="search_treeview_crt">
+                            <property name="xpad">3</property>
+                            <property name="ypad">3</property>
+                          </object>
+                          <attributes>
+                            <attribute name="markup">0</attribute>
+                          </attributes>
+                        </child>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkTreeViewColumn" id="program_column">
+                        <property name="title">Program</property>
+                        <child>
+                          <object class="GtkCellRendererText" id="search_treeview_crtext">
+                            <property name="xpad">3</property>
+                            <property name="ypad">3</property>
+                          </object>
+                          <attributes>
+                            <attribute name="markup">1</attribute>
+                          </attributes>
+                        </child>
+                      </object>
+                    </child>
                   </object>
                 </child>
               </object>
@@ -758,12 +799,28 @@
             <property name="visible">True</property>
             <property name="layout_style">end</property>
             <child>
+              <object class="GtkButton" id="search_add_reminderbutton">
+                <property name="label" translatable="yes">_Add reminder</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+                <signal name="clicked" handler="on_search_add_reminderbutton_clicked"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
               <object class="GtkButton" id="details_button">
                 <property name="visible">True</property>
                 <property name="sensitive">False</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
                 <property name="receives_default">False</property>
+                <signal name="clicked" handler="on_details_button_clicked"/>
                 <child>
                   <object class="GtkAlignment" id="alignment7">
                     <property name="visible">True</property>
@@ -809,7 +866,7 @@
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
-                <property name="position">0</property>
+                <property name="position">1</property>
               </packing>
             </child>
             <child>
@@ -820,13 +877,17 @@
                 <property name="can_default">True</property>
                 <property name="receives_default">False</property>
                 <property name="use_stock">True</property>
+                <signal name="clicked" handler="on_search_closebutton_clicked"/>
               </object>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
-                <property name="position">1</property>
+                <property name="position">2</property>
               </packing>
             </child>
+            <child>
+              <placeholder/>
+            </child>
           </object>
           <packing>
             <property name="expand">False</property>
@@ -837,6 +898,7 @@
       </object>
     </child>
     <action-widgets>
+      <action-widget response="0">search_add_reminderbutton</action-widget>
       <action-widget response="-7">details_button</action-widget>
       <action-widget response="-7">search_closebutton</action-widget>
     </action-widgets>
@@ -1065,7 +1127,6 @@
               <object class="GtkIconView" id="channel_iconview">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="model">channel_icon_store</property>
                 <signal name="item_activated" handler="on_channel_iconview_item_activated"/>
                 <signal name="selection_changed" handler="on_channel_iconview_selection_changed"/>
               </object>
@@ -1161,4 +1222,8 @@ Ville P&#xE4;tsi &lt;drc gnu org&gt;</property>
       </object>
     </child>
   </object>
+  <object class="GtkImage" id="image1">
+    <property name="visible">True</property>
+    <property name="stock">gtk-add</property>
+  </object>
 </interface>
diff --git a/ontv/dialogs.py b/ontv/dialogs.py
index 570e3fd..6ba0684 100644
--- a/ontv/dialogs.py
+++ b/ontv/dialogs.py
@@ -143,7 +143,7 @@ class PreferencesDialog:
 
         self.__make_channels_treeview()
         self.__make_reminders_treeview()
-        self.sd.create_search_treeview_menu(self.reminders_treeview.get_model())
+        #self.sd.create_search_treeview_menu(self.reminders_treeview.get_model())
         self.pw.set_reminders_model(self.reminders_treeview.get_model())
 
         self.channels_combobox_model = gtk.ListStore(str)
@@ -678,165 +678,109 @@ class ProgramDialog:
         self.dialog.show()
 
 TIMEOUT = 100
+COL_TIME  = 0
+COL_DESCR = 1
+COL_PROG  = 2
 
 class SearchDialog:
     def __init__(self, xmltvfile, reminders):
         xmltvfile.connect("loading-done", self.__xmltvfile_loading_done)
         self.reminders = reminders
-
-        self.__get_widgets()
-        self.__make_channels_combobox()
-        self.__make_search_treeview()
-        self.__connect_widgets()
-
-        self.search_label.set_mnemonic_widget(self.search_entry)
-
+        self.__init_ui()
         self.__timeout_id = 0
 
-    def __get_widgets(self):
-        xml = gtk.glade.XML(gui.glade_file, domain=NAME.lower())
-
-        self.dialog = xml.get_widget("search_dialog")
-        self.close_button = xml.get_widget("search_closebutton")
-        self.details_button = xml.get_widget("details_button")
-
-        self.search_label = xml.get_widget("search_label")
-        self.search_entry = xml.get_widget("search_entry")
-        self.channels_combobox = xml.get_widget("channels_combobox")
-
-        self.search_treeview = xml.get_widget("search_treeview")
-
-    def __make_channels_combobox(self):
-        crt = gtk.CellRendererText()
-        self.channels_combobox.pack_start(crt, True)
-        self.channels_combobox.add_attribute(crt, 'text', 0)
-
-    def __make_search_treeview(self):
-        search_model = gtk.ListStore(object)
-        self.search_treeview.set_model(search_model)
-
-        crt = gtk.CellRendererText()
-        crt.props.xpad = 3
-        crt.props.ypad = 3
-        time_column = gtk.TreeViewColumn("Air time", crt)
-        time_column.set_cell_data_func(crt, self.__crt_cell_data_func)
-        self.search_treeview.append_column(time_column)
-
-        crtext = gtk.CellRendererText()
-        crtext.props.xpad = 3
-        crtext.props.ypad = 3
-        program_column = gtk.TreeViewColumn("Program", crtext)
-        program_column.set_cell_data_func(crtext, self.__crtext_cell_data_func)
-        self.search_treeview.append_column(program_column)
-
-    def __crt_cell_data_func(self, column, cell, model, iter):
-        program = model.get_value(iter, 0)
-        markup = "<b>%s-%s</b>\n<i>%s</i>"
-        cell.props.markup = markup % (program.start_time, program.stop_time,
-                                      program.date)
-
-    def __crtext_cell_data_func(self, column, cell, model, iter):
-        program = model.get_value(iter, 0)
-        markup = "<b>%s</b>\n<i>%s</i>"
-        cell.props.markup = markup % (program.markup_escaped_title,
-                                      program.channel.markup_escaped_name)
-
-    def __connect_widgets(self):
-        self.dialog.connect("delete-event", self.__dialog_delete)
-
-        self.search_entry.connect("changed", self.__search_entry_changed)
-
+    def __init_ui(self):
+        builder = gtk.Builder()
+        builder.add_from_file(gui.ui_file)
+        
+        self.dialog = builder.get_object("search_dialog")
+        self.details_button = builder.get_object("details_button")
+        self.add_reminder_button = builder.get_object("search_add_reminderbutton")
+        self.search_entry = builder.get_object("search_entry")
+        self.channels_combobox = builder.get_object("channels_combobox")
+        self.search_treeview = builder.get_object("search_treeview")
+        self.search_model = builder.get_object("search_model")
+
+        self.search_model_filter = builder.get_object("search_model_filter")
+        self.search_model_filter.set_visible_func(self.filter)
+        
+        builder.get_object("search_label").set_mnemonic_widget(self.search_entry)
+        builder.connect_signals(self)
+        
         selection = self.search_treeview.get_selection()
         selection.connect("changed", self.__search_treeview_selection_changed)
-        self.search_treeview.connect("row-activated",
-                                     self.__search_treeview_row_activated)
 
-        self.close_button.connect("clicked", self.__close_button_clicked)
-        self.details_button.connect("clicked", self.__details_button_clicked)
 
-    def __dialog_delete(self, dialog, event):
-        self.dialog.hide()
-        return True
+    def init_model(self):
+        for channel in self.listings.channels:
+            for program in self.listings.channels[channel].programs:
+                time = "<b>%s-%s</b>\n<i>%s</i>" % (program.start_time,
+                                                    program.stop_time,
+                                                    program.date)
+                
+                description = "<b>%s</b>\n<i>%s</i>" % (program.markup_escaped_title,
+                                                        program.channel.markup_escaped_name)
+                self.search_model.append([time,description,program])
 
-    def __search_entry_changed(self, entry):
+    def on_search_entry_changed(self, entry):
         if self.__timeout_id > 0:
             gobject.source_remove(self.__timeout_id)
 
-        self.__timeout_id = gobject.timeout_add(TIMEOUT, self.__search)
-
-    def __search(self):
-        search_model = self.search_treeview.get_model()
-        search_model.clear()
-        program_column = self.search_treeview.get_column(1)
-        search = self.search_entry.get_text().strip().lower().split()
-        active = self.channels_combobox.get_active()
-        channels_model = self.channels_combobox.get_model()
-        channel = channels_model[active][0]
-
-        if len(search) > 0:
-            matches = self.listings.search_program(search, channel)
-            iter = search_model.get_iter_first()
-            for row in search_model:
-                program = row[0]
-                if not program in matches:
-                    search_model.remove(iter)
-                else:
-                    matches.remove(program)
-                    search_model.iter_next(iter)
-
-            for program in matches:
-                search_model.append([program])
-                program_column.queue_resize()
-
-        program_column.queue_resize()
-        self.search_treeview.set_cursor(0)
-        return False
+        self.__timeout_id = gobject.timeout_add(TIMEOUT, self.search_model_filter.refilter)
+
+    def on_channels_combobox_changed(self,combobox):
+        self.search_model_filter.refilter()
+
+    def filter(self, model, iter):
+        if iter:
+            program = model.get_value(iter, COL_PROG)
+            if program:
+                active = self.channels_combobox.get_active()
+                channels_model = self.channels_combobox.get_model()
+                channel = channels_model[active][0]
+                if (channel == _("All")) or (channel == program.channel.name):
+                    return self.search_entry.get_text().strip().lower() in program.title.lower()
 
     def __search_treeview_selection_changed(self, selection):
         (search_model, search_iter) = selection.get_selected()
         if search_iter:
             self.details_button.set_sensitive(True)
-            program = search_model.get_value(search_iter, 0)
+            program = search_model.get_value(search_iter, COL_PROG)
             reminder = Reminder(program.title,
                                 program.channel.markup_escaped_name)
             if not reminder in self.reminders.reminders:
-                self.search_treeview_menu.add_reminder_imi.set_sensitive(True)
+                self.add_reminder_button.set_sensitive(True)
             else:
-                self.search_treeview_menu.add_reminder_imi.set_sensitive(False)
+                self.add_reminder_button.set_sensitive(False)
         else:
             self.details_button.set_sensitive(False)
-            self.search_treeview_menu.add_reminder_imi.set_sensitive(False)
-
-    def __search_treeview_row_activated(self, treeview, path, column):
-        self.details_button.emit("clicked")
-
-    def __search_treeview_button_press(self, treeview, event, menu):
-        if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
-            search_model = treeview.get_model()
-            path = treeview.get_path_at_pos(int(event.x), int(event.y))[0]
-            program = search_model[path][0]
-            if program.description and program.description != "":
-                self.search_treeview_menu.details_imi.set_sensitive(True)
-            else:
-                self.search_treeview_menu.details_imi.set_sensitive(False)
+            self.add_reminder_button.set_sensitive(False)
 
-            menu.popup(None, None, None, event.button, event.time)
+    def on_search_treeview_row_activated(self, treeview, path, column):
+        program = gui.get_selected_value(treeview)
+        pd = ProgramDialog(program)
+        pd.show()
 
-    def __close_button_clicked(self, button):
+    def on_search_closebutton_clicked(self, button):
         self.dialog.hide()
 
-    def __details_button_clicked(self, button):
-        program = gui.get_selected_value(self.search_treeview)
-        self.__show_program_dialog(program)
+    def on_search_add_reminderbutton_clicked(self, button):
+        selection = self.search_treeview.get_selection()
+        (model, iter) = selection.get_selected()
+        if iter:
+            program = model.get_value(iter, COL_PROG)
+            reminder = Reminder(program.title, program.channel.markup_escaped_name)
+            if self.reminders.add(reminder):
+                self.reminders.save()
 
-    def __show_program_dialog(self, program):
-        pd = ProgramDialog(program)
-        pd.show()
+    def on_details_button_clicked(self, button):
+        self.on_search_treeview_row_activated(self.search_treeview,None, None)
 
     def __xmltvfile_loading_done(self, xmltvfile, listings):
         if listings:
             self.listings = listings
             self.search_entry.emit("changed")
+            self.init_model()
 
     def set_all_as_combo_active(self, combobox):
         channels_model = combobox.get_model()
@@ -847,17 +791,6 @@ class SearchDialog:
                 break
             channels_iter = channels_model.iter_next(channels_iter)
 
-    def create_search_treeview_menu(self, reminders_model):
-        self.search_treeview_menu = gui.ProgramContextMenu(self.get_program,
-                                                           self.reminders,
-                                                           reminders_model)
-        self.search_treeview.connect("button-press-event",
-                                     self.__search_treeview_button_press,
-                                     self.search_treeview_menu)
-
-    def get_program(self):
-        return gui.get_selected_value(self.search_treeview)
-
     def show(self, uicomponent=None, verb=None):
         self.present()
 
diff --git a/ontv/gui.py b/ontv/gui.py
index 941f117..2989344 100644
--- a/ontv/gui.py
+++ b/ontv/gui.py
@@ -35,6 +35,7 @@ glade_file = os.path.join(DATA_DIR, "ontv.glade")
 ui_file    = os.path.join(DATA_DIR, "ontv.ui")
 icon_theme = gtk.icon_theme_get_default()
 
+COL_PROG = 2
 def get_icon_list(sizes):
     icon_list = []
     for size in sizes:
@@ -76,7 +77,7 @@ def get_selected_value(treeview):
     selection = treeview.get_selection()
     (model, iter) = selection.get_selected()
     if iter:
-        value = model.get_value(iter, 0)
+        value = model.get_value(iter, COL_PROG)
         return value
     return None
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]