[POS-commit] r6433 - in stoqlib/trunk: . data/glade stoqlib/database stoqlib/domain stoqlib/gui stoqlib/gui/base stoqlib/gui/dialogs stoqlib/gui/search stoqlib/gui/slaves stoqlib/gui/wizards

Johan Dahlin jdahlin at async.com.br
Wed Apr 25 15:50:38 BRT 2007


Author: jdahlin
Date: Wed Apr 25 15:50:38 2007
New Revision: 6433

Removed:
   stoqlib/trunk/data/glade/TillHistoryDialog.glade
   stoqlib/trunk/stoqlib/gui/base/searchbar.py
   stoqlib/trunk/stoqlib/gui/slaves/filterslave.py
   stoqlib/trunk/stoqlib/gui/slaves/fiscalslave.py
   stoqlib/trunk/stoqlib/gui/slaves/productslave.py
Modified:
   stoqlib/trunk/data/glade/PurchaseSelectionStep.glade
   stoqlib/trunk/setup.py
   stoqlib/trunk/stoqlib/database/runtime.py
   stoqlib/trunk/stoqlib/domain/person.py
   stoqlib/trunk/stoqlib/gui/base/columns.py
   stoqlib/trunk/stoqlib/gui/base/dialogs.py
   stoqlib/trunk/stoqlib/gui/base/search.py
   stoqlib/trunk/stoqlib/gui/dialogs/tillhistory.py
   stoqlib/trunk/stoqlib/gui/interfaces.py
   stoqlib/trunk/stoqlib/gui/search/categorysearch.py
   stoqlib/trunk/stoqlib/gui/search/fiscalsearch.py
   stoqlib/trunk/stoqlib/gui/search/giftcertificatesearch.py
   stoqlib/trunk/stoqlib/gui/search/personsearch.py
   stoqlib/trunk/stoqlib/gui/search/productsearch.py
   stoqlib/trunk/stoqlib/gui/search/receivingsearch.py
   stoqlib/trunk/stoqlib/gui/search/salesearch.py
   stoqlib/trunk/stoqlib/gui/search/sellablesearch.py
   stoqlib/trunk/stoqlib/gui/search/servicesearch.py
   stoqlib/trunk/stoqlib/gui/search/stationsearch.py
   stoqlib/trunk/stoqlib/gui/search/tillsearch.py
   stoqlib/trunk/stoqlib/gui/slaves/individualslave.py
   stoqlib/trunk/stoqlib/gui/wizards/receivingwizard.py

Log:
#3330: Use SearchContainer from kiwi in stoqlib

Modified: stoqlib/trunk/data/glade/PurchaseSelectionStep.glade
==============================================================================
--- stoqlib/trunk/data/glade/PurchaseSelectionStep.glade	(original)
+++ stoqlib/trunk/data/glade/PurchaseSelectionStep.glade	Wed Apr 25 15:50:38 2007
@@ -31,23 +31,11 @@
                         </child>
                     </widget>
                     <packing>
-                        <property name="expand">False</property>
+                        <property name="expand">True</property>
                         <property name="position">1</property>
                     </packing>
                 </child>
                 <child>
-                    <widget class="ObjectList" id="orders">
-                        <property name="is_focus">True</property>
-                        <property name="selection_mode">single</property>
-                        <property name="shadow_type">in</property>
-                        <property name="visible">True</property>
-                        <property name="vscrollbar_policy">automatic</property>
-                    </widget>
-                    <packing>
-                        <property name="position">2</property>
-                    </packing>
-                </child>
-                <child>
                     <widget class="GtkHBox" id="hbox1">
                         <property name="visible">True</property>
                         <child>
@@ -75,7 +63,7 @@
                     </widget>
                     <packing>
                         <property name="expand">False</property>
-                        <property name="position">3</property>
+                        <property name="position">2</property>
                     </packing>
                 </child>
             </widget>

Modified: stoqlib/trunk/setup.py
==============================================================================
--- stoqlib/trunk/setup.py	(original)
+++ stoqlib/trunk/setup.py	Wed Apr 25 15:50:38 2007
@@ -128,7 +128,7 @@
       description="A powerful retail system library",
       long_description="""
       Stoqlib offers many special tools for retail system applications
-      such reports infrastructure, basic dialogs and searchbars and
+      such reports infrastructure, basic dialogs, search windows and
       domain data in a persistent level.
       """,
       url=website,

Modified: stoqlib/trunk/stoqlib/database/runtime.py
==============================================================================
--- stoqlib/trunk/stoqlib/database/runtime.py	(original)
+++ stoqlib/trunk/stoqlib/database/runtime.py	Wed Apr 25 15:50:38 2007
@@ -93,6 +93,9 @@
         self._obsolete = True
 
     def get(self, obj):
+        if obj is None:
+            return None
+
         if not isinstance(obj, (SQLObject, InheritableSQLObject)):
             raise TypeError("obj must be a SQLObject, not %r" % (obj,))
 

Modified: stoqlib/trunk/stoqlib/domain/person.py
==============================================================================
--- stoqlib/trunk/stoqlib/domain/person.py	(original)
+++ stoqlib/trunk/stoqlib/domain/person.py	Wed Apr 25 15:50:38 2007
@@ -74,7 +74,9 @@
 
 from sqlobject import (DateTimeCol, UnicodeCol, IntCol,
                        ForeignKey, MultipleJoin, BoolCol, SQLObject)
-from sqlobject.sqlbuilder import func, AND
+from sqlobject.sqlbuilder import func, AND, INNERJOINOn, LEFTJOINOn
+from sqlobject.viewable import Viewable
+
 from zope.interface import implements
 
 from stoqlib.database.columns import PriceCol, DecimalCol
@@ -793,3 +795,127 @@
     cpf = UnicodeCol()
     rg_number = UnicodeCol()
     phone_number = UnicodeCol()
+
+    @property
+    def client(self):
+        return PersonAdaptToClient.get(self.client_id,
+                                       connection=self._connection)
+
+class EmployeeView(Viewable):
+    columns = dict(
+        id=Person.q.id,
+        employee_id=PersonAdaptToEmployee.q.id,
+        name=Person.q.name,
+        role=EmployeeRole.q.name,
+        status=PersonAdaptToEmployee.q.status,
+        registry_number=PersonAdaptToEmployee.q.registry_number,
+        )
+
+    joins = [
+        INNERJOINOn(None, PersonAdaptToEmployee,
+                   Person.q.id == PersonAdaptToEmployee.q._originalID),
+        INNERJOINOn(None, EmployeeRole,
+                   PersonAdaptToEmployee.q.roleID == EmployeeRole.q.id),
+        ]
+
+    def get_status_string(self):
+        return PersonAdaptToEmployee.statuses[self.status]
+
+    @property
+    def employee(self):
+        return PersonAdaptToEmployee.get(self.employee_id,
+                                         connection=self.get_connection())
+
+class SupplierView(Viewable):
+    columns = dict(
+        id=Person.q.id,
+        name=Person.q.name,
+        phone_number=Person.q.phone_number,
+        fancy_name=_PersonAdaptToCompany.q.fancy_name,
+        cnpj=_PersonAdaptToCompany.q.cnpj,
+        supplier_id=PersonAdaptToSupplier.q.id,
+        status=PersonAdaptToSupplier.q.status,
+        )
+
+    joins = [
+        INNERJOINOn(None, PersonAdaptToSupplier,
+                   Person.q.id == PersonAdaptToSupplier.q._originalID),
+        LEFTJOINOn(None, _PersonAdaptToCompany,
+                   Person.q.id == _PersonAdaptToCompany.q._originalID),
+        ]
+
+    def get_status_string(self):
+        return PersonAdaptToSupplier.statuses[self.status]
+
+    @property
+    def supplier(self):
+        return PersonAdaptToSupplier.get(self.supplier_id,
+                                         connection=self.get_connection())
+
+class TransporterView(Viewable):
+    """
+    @cvar id:
+    @cvar name:
+    @cvar phone_number:
+    @cvar transporter_id:
+    @cvar status:
+    @cvar freight_percentage:
+    """
+    columns = dict(
+        id=Person.q.id,
+        name=Person.q.name,
+        phone_number=Person.q.phone_number,
+        transporter_id=PersonAdaptToTransporter.q.id,
+        freight_percentage=PersonAdaptToTransporter.q.freight_percentage,
+        )
+
+    joins = [
+        INNERJOINOn(None, PersonAdaptToTransporter,
+                   Person.q.id == PersonAdaptToTransporter.q._originalID),
+        ]
+
+    @property
+    def transporter(self):
+        return PersonAdaptToTransporter.get(self.transporter_id,
+                                            connection=self.get_connection())
+
+
+class BranchView(Viewable):
+    columns = dict(
+        id=Person.q.id,
+        name=Person.q.name,
+        branch_id=PersonAdaptToBranch.q.id,
+        phone_number=Person.q.phone_number,
+        )
+
+    joins = [
+        INNERJOINOn(None, PersonAdaptToBranch,
+                   Person.q.id == PersonAdaptToBranch.q._originalID),
+        ]
+
+    @property
+    def branch(self):
+        return PersonAdaptToBranch.get(self.branch_id,
+                                       connection=self.get_connection())
+
+
+class CreditProviderView(Viewable):
+    columns = dict(
+        id=Person.q.id,
+        name=Person.q.name,
+        provider_id=PersonAdaptToCreditProvider.q.id,
+        phone_number=Person.q.phone_number,
+        short_name=PersonAdaptToCreditProvider.q.short_name,
+        is_active=PersonAdaptToCreditProvider.q.is_active,
+        )
+
+    joins = [
+        INNERJOINOn(None, PersonAdaptToCreditProvider,
+                   Person.q.id == PersonAdaptToCreditProvider.q._originalID),
+        ]
+
+    @property
+    def provider(self):
+        return PersonAdaptToCreditProvider.get(self.provider_id,
+                                               connection=self.get_connection())
+

Modified: stoqlib/trunk/stoqlib/gui/base/columns.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/base/columns.py	(original)
+++ stoqlib/trunk/stoqlib/gui/base/columns.py	Wed Apr 25 15:50:38 2007
@@ -27,26 +27,6 @@
 from kiwi.accessor import kgetattr
 from kiwi.ui.widgets.list import Column
 
-from stoqlib.lib.component import Adapter
-
-
-class FacetColumn(Column):
-    def __init__(self, iface, *args, **kwargs):
-        self._iface = iface
-        Column.__init__(self, *args, **kwargs)
-
-    def get_attribute(self, instance, name, default=None):
-        if not isinstance(instance, Adapter):
-            facet = self._iface(instance, None)
-        else:
-            original = instance.get_adapted()
-            facet = self._iface(original, None)
-        if not facet:
-            return
-        return kgetattr(facet, name, default)
-
-    def get_iface(self):
-        return self._iface
 
 class ForeignKeyColumn(Column):
     """

Modified: stoqlib/trunk/stoqlib/gui/base/dialogs.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/base/dialogs.py	(original)
+++ stoqlib/trunk/stoqlib/gui/base/dialogs.py	Wed Apr 25 15:50:38 2007
@@ -216,6 +216,10 @@
                 dialog, widget))
         widget.connect('activate', self.cancel)
 
+    @property
+    def action_area(self):
+        return self.get_toplevel().action_area
+
 
     #
     # Kiwi handlers

Modified: stoqlib/trunk/stoqlib/gui/base/search.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/base/search.py	(original)
+++ stoqlib/trunk/stoqlib/gui/base/search.py	Wed Apr 25 15:50:38 2007
@@ -25,19 +25,20 @@
 """ Implementation of basic dialogs for searching data """
 
 import gtk
-from kiwi.utils import gsignal
+from kiwi.argcheck import argcheck
+from kiwi.db.sqlobj import SQLObjectQueryExecuter
+from kiwi.enums import SearchFilterPosition
 from kiwi.ui.delegates import GladeSlaveDelegate
-from kiwi.ui.objectlist import ObjectList
+from kiwi.ui.search import ComboSearchFilter, SearchSlaveDelegate
 from kiwi.ui.widgets.list import SummaryLabel
-from kiwi.argcheck import argcheck
-from sqlobject.sresults import SelectResults
-from sqlobject.dbconnection import Transaction
+from kiwi.utils import gsignal
+from sqlobject.main import SQLObject
 
-from stoqlib.database.database import rollback_and_begin
+from stoqlib.database.database import finish_transaction
+from stoqlib.database.runtime import get_connection, new_transaction
 from stoqlib.exceptions import DatabaseInconsistency
 from stoqlib.gui.base.dialogs import BasicDialog, run_dialog
 from stoqlib.gui.editors.baseeditor import BaseEditor
-from stoqlib.gui.base.searchbar import SearchBar
 from stoqlib.lib.component import Adapter
 from stoqlib.lib.translation import stoqlib_gettext
 
@@ -86,7 +87,6 @@
     >>> def __init__(self, *args):
     ...     SearchDialog.__init__(self)
 
-    Some important parameters:
     @cvar table: the table type which we will query on to get the objects.
     @cvar searchbar_labels: labels for SearchBar entry and date fields
     @cvar searchbar_result_strings: a tuple where each item has a singular
@@ -96,13 +96,11 @@
     title = ''
     table = None
     search_table = None
+    search_labels = None
     selection_mode = gtk.SELECTION_BROWSE
-    searchbar_labels = None
-    searchbar_result_strings = None
-    searching_by_date = False
     size = ()
 
-    @argcheck(Transaction, object, object, bool, basestring, int)
+    @argcheck(object, object, object, bool, basestring, int)
     def __init__(self, conn, table=None, search_table=None, hide_footer=True,
                  title='', selection_mode=None):
         """
@@ -116,13 +114,36 @@
         """
 
         self.conn = conn
+        self.search_table = self._setup_search_table(table, search_table)
+        self.selection_mode = self._setup_selection_mode(selection_mode)
+        self.summary_label = None
+
+        BasicDialog.__init__(self)
+        BasicDialog._initialize(self, hide_footer=hide_footer,
+                                main_label_text=self.main_label_text,
+                                title=title or self.title,
+                                size=self.size)
+
+        self.executer = SQLObjectQueryExecuter(get_connection())
+        self.set_table(self.search_table)
+
+        self.disable_ok()
+        self.set_ok_label(_('Se_lect Items'))
+        self._setup_search()
+        self._setup_details_slave()
+
+        self.create_filters()
+        self.setup_widgets()
+
+    def _setup_search_table(self, table, search_table):
         search_table = search_table or self.search_table
         table = table or self.table
         if not (table or search_table):
             raise ValueError(
                 "%r must define a table or search_table attribute" % self)
-        self.search_table = search_table or table
+        return search_table or table
 
+    def _setup_selection_mode(self, selection_mode):
         # For consistency do not allow none or single, in other words,
         # only allowed values are browse and multiple so we always will
         # be able to use both the keyboard and the mouse to select items
@@ -131,63 +152,18 @@
         if (selection_mode != gtk.SELECTION_BROWSE and
             selection_mode != gtk.SELECTION_MULTIPLE):
             raise ValueError('Invalid selection mode %r' % selection_mode)
-        self.selection_mode = selection_mode
-
-        BasicDialog.__init__(self)
-        title = title or self.title
-        self.summary_label = None
-        BasicDialog._initialize(self, hide_footer=hide_footer,
-                                main_label_text=self.main_label_text,
-                                title=title, size=self.size)
-        self.set_ok_label(_('Se_lect Items'))
-        self.setup_slaves()
+        return selection_mode
 
-    def _sync(self, *args):
-        rollback_and_begin(self.conn)
-
-    def _check_searchbar_settings(self, value, attr_name):
-        if not value:
-            return False
-        if not isinstance(value, tuple):
-            raise TypeError("%s attribute must be of typle tuple, "
-                            "got %s" % (attr_name, type(value)))
-        return True
-
-    def _setup_searchbar(self):
-        columns = self.get_columns()
-        query_args = self.get_query_args()
-        use_dates = self.searching_by_date
-        self.search_bar = SearchBar(self.conn, self.search_table,
-                                    columns, query_args=query_args,
-                                    filter_slave=self.get_filter_slave(),
-                                    searching_by_date=use_dates)
-        self.search_bar.set_query_callback(self.query)
-        extra_query = self.get_extra_query
-        if extra_query:
-            self.search_bar.register_extra_query_callback(extra_query)
-        self.search_bar.connect('before-search-activate', self._sync)
-        self.search_bar.connect('search-activate', self.update_klist)
-        if self._check_searchbar_settings(self.searchbar_result_strings,
-                                          "searchbar_result_strings"):
-            self.set_result_strings(*self.searchbar_result_strings)
-        if self._check_searchbar_settings(self.searchbar_labels,
-                                          "searchbar_labels"):
-            self.set_searchbar_labels(*self.searchbar_labels)
-        self.after_search_bar_created()
-        self.attach_slave('header', self.search_bar)
-
-    def _setup_klist(self):
-        self.klist_vbox = gtk.VBox()
-        self.klist = ObjectList(self.get_columns(), mode=self.selection_mode)
-        self.klist_vbox.pack_start(self.klist)
-        self.klist_vbox.show_all()
-        # XXX: I think that BasicDialog must be redesigned, if so we don't
-        # need this ".remove" crap
-        self.main.remove(self.main_label)
-        self.main.add(self.klist_vbox)
-        self.klist.show()
-        self.klist.connect('cell_edited', self.on_cell_edited)
-        self.klist.connect('selection-changed', self._on_selection_changed)
+    def _setup_search(self):
+        self.search = SearchSlaveDelegate(self.get_columns())
+        self.search.set_query_executer(self.executer)
+        self.attach_slave('main', self.search)
+        self.header.hide()
+
+        self.results = self.search.search.results
+        self.results.connect('cell-edited', self._on_results__cell_edited)
+        self.results.connect('selection-changed',
+                             self._on_results__selection_changed)
 
     def _setup_details_slave(self):
         # FIXME: Gross hack
@@ -212,146 +188,120 @@
     # Public API
     #
 
-    def set_searchtable(self, search_table):
-        self.search_table = search_table
-        self.search_bar.set_searchtable(search_table)
+    @argcheck(bool)
+    def set_details_button_sensitive(self, value):
+        self._details_slave.details_button.set_sensitive(value)
 
-    def set_searchbar_columns(self, columns):
-        self.search_bar.set_columns(columns)
+    def get_selection(self):
+        mode = self.results.get_selection_mode()
+        if mode == gtk.SELECTION_BROWSE:
+            return self.results.get_selected()
+        return self.results.get_selected_rows()
 
-    def set_searchbar_search_string(self, search_str):
-        self.search_bar.set_search_string(search_str)
+    def confirm(self):
+        self.retval = self.get_selection()
+        self.close()
 
-    def perform_search(self):
-        self.search_bar.search_items()
+    def cancel(self, *args):
+        self.retval = []
+        self.close()
 
-    def setup_summary_label(self, column_name, label_text):
+    def add_summary_label(self, column_name, label_text):
+        """
+        @param column_name:
+        @param label_text:
+        """
         if self.summary_label is not None:
-            self.klist_vbox.remove(self.summary_label)
-        value_format = '<b>%s</b>'
-        self.clear_klist()
-        self.summary_label = SummaryLabel(klist=self.klist,
+            self.results_vbox.remove(self.summary_label)
+        self.summary_label = SummaryLabel(klist=self.results,
                                           column=column_name,
                                           label=label_text,
-                                          value_format=value_format)
+                                          value_format='<b>%s</b>')
         self.summary_label.show()
-        self.klist_vbox.pack_start(self.summary_label, False)
+        self.results_vbox.pack_start(self.summary_label, False)
 
-    def setup_slaves(self, **kwargs):
-        self.disable_ok()
-        self._setup_klist()
-        self._setup_searchbar()
-        self._setup_details_slave()
+    def set_table(self, table):
+        self.executer.set_table(table)
+        self.search_table = table
 
-    @argcheck(bool)
-    def set_details_button_sensitive(self, value):
-        self._details_slave.details_button.set_sensitive(value)
+    # FIXME: -> remove/use
 
-    def get_query_args(self):
-        """An optional list of SQLObject arguments for select function."""
+    def set_searchbar_labels(self, *args):
+        search_filter = self.search.get_primary_filter()
+        search_filter.set_label(args[0])
 
-    def get_extra_query(self):
-        """An optional SQLObject.sqlbuilder query for select statement."""
+    def set_result_strings(self, *args):
+        pass
 
-    def get_filter_slave(self):
-        """Returns a slave which will be used as filter by SearchBar.
-        By default it returns None which means that no filter will be
-        attached. Redefine this method in child when it's needed
+    def set_text_field_columns(self, columns):
         """
-        return None
-
-    def after_search_bar_created(self):
-        """This method will be called after creating the SearchBar
-        instance.  Redefine this method in child when it's needed
+        See L{SearchSlaveDelegate.set_text_field_columns}
         """
+        self.search.set_text_field_columns(columns)
 
-    def on_cell_edited(self, klist, obj, attr):
-        """Override this method on child when it's needed to perform some
-        tasks when editing a row.
+    def add_filter(self, search_filter, position=SearchFilterPosition.BOTTOM,
+                   columns=None, callback=None):
         """
-
-    def _on_selection_changed(self, klist, selected):
-        self.update_widgets()
-
-    def set_searchbar_labels(self, search_entry_lbl, date_search_lbl=None):
-        # Second argument is only used by Stoq's SearchableAppWindow
-        self.search_bar.set_searchbar_labels(search_entry_lbl,
-                                             date_search_lbl)
-
-    def set_result_strings(self, singular_form, plural_form):
-        """This method defines strings to be used in the
-        search_results_label for SearchBar class.
+        See L{SearchSlaveDelegate.add_filter}
         """
-        self.search_bar.set_result_strings(singular_form, plural_form)
+        self.search.add_filter(search_filter, position, columns, callback)
 
-    def get_selection(self):
-        mode = self.klist.get_selection_mode()
-        if mode == gtk.SELECTION_BROWSE:
-            return self.klist.get_selected()
-        return self.klist.get_selected_rows()
+    #
+    # Filters
+    #
 
-    def clear_klist(self):
-        self.klist.clear()
-        self.update_widgets()
+    def create_branch_filter(self, label=None):
+        from stoqlib.domain.person import PersonAdaptToBranch
+        from stoqlib.database.runtime import get_current_branch
+        branches = PersonAdaptToBranch.get_active_branches(self.conn)
+        items = [(b.person.name, b.id) for b in branches]
+        #if not items:
+        #    raise ValueError('You should have at least one branch at '
+        #                      'this point')
+        items.insert(0, (_("Any"), None))
 
-    def confirm(self):
-        objs = self.get_selection()
-        self.retval = objs
-        self.close()
+        if not label:
+            label = _('Branch')
+        branch_filter = ComboSearchFilter(label, items)
+        current = get_current_branch(self.conn)
+        if current:
+            branch_filter.select(current.id)
 
-    def cancel(self, *args):
-        self.retval = []
-        self.close()
+        return branch_filter
 
     #
-    # Hooks
+    # Callbacks
     #
 
-    def update_klist(self, slave, objs):
-        """A hook called by SearchBar and instances."""
-        if not objs:
-            self.klist.clear()
-            self.disable_ok()
-            self.update_widgets()
-            return
-
-        if isinstance(objs, (list, tuple)):
-            count = len(objs)
-        elif isinstance(objs, SelectResults):
-            count = objs.count()
-        else:
-            msg = 'Invalid type for result objects: Type: %s'
-            raise TypeError, msg % type(objs)
+    def _on_results__cell_edited(self, results, obj, attr):
+        """Override this method on child when it's needed to perform some
+        tasks when editing a row.
+        """
 
-        if count:
-            self.klist.add_list(objs)
-            objs = iter(objs)
-            selected = objs.next()
-            self.klist.select(selected)
-            self.enable_ok()
-        if self.summary_label:
-            self.summary_label.update_total()
+    def _on_results__selection_changed(self, results, selected):
         self.update_widgets()
 
-    def update_widgets(self):
-        """ Subclass can have an 'update_widgets', and this method will be
-        called when a signal is emitted by 'Filter' or 'Clear' buttons and
-        also when a list item is selected. """
-
-    def query(self, table, query, queries):
-        """Override this to control the queries made by the
-        searchbar, see searchbar.set_query_callback for documentation
-        """
-        return table.select(query, **queries)
-
     #
-    # Specification of methods that all subclasses *must* to implement
+    # Hooks
     #
 
+    def create_filters(self):
+        raise NotImplementedError(
+            "create_filters() must be implemented in %r" % self)
+
+    def setup_widgets(self):
+        pass
+
     def get_columns(self):
         raise NotImplementedError(
             "get_columns() must be implemented in %r" % self)
 
+    def update_widgets(self):
+        """
+        Subclass can have an 'update_widgets', and this method will be
+        called when a signal is emitted by 'Filter' or 'Clear' buttons and
+        also when a list item is selected. """
+
 
 class SearchEditorToolBar(GladeSlaveDelegate):
     """ Slave for internal use of SearchEditor, offering an eventbox for a
@@ -442,6 +392,7 @@
                               hide_footer=hide_footer, title=title,
                               selection_mode=selection_mode)
 
+        self._setup_slaves()
         if hide_toolbar:
             self.accept_edit_data = False
             self._toolbar.get_toplevel().hide()
@@ -463,15 +414,15 @@
             if not self.has_edit_button:
                 self.hide_edit_button()
         self._selected = None
-        self.klist.connect('double_click', self._on_list__double_click)
+        self.results.connect('double_click', self._on_results__double_click)
         self.update_widgets()
 
-    def setup_slaves(self):
-        SearchDialog.setup_slaves(self)
+
+    def _setup_slaves(self):
         self._toolbar = SearchEditorToolBar()
-        self.attach_slave('extra_holder', self._toolbar)
         self._toolbar.connect("edit", self._on_toolbar__edit)
         self._toolbar.connect("add", self._on_toolbar__new)
+        self.attach_slave('extra_holder', self._toolbar)
 
     # Public API
 
@@ -481,7 +432,7 @@
         self._toolbar.edit_button.set_sensitive(value)
 
     def update_widgets(self, *args):
-        self._toolbar.edit_button.set_sensitive(len(self.klist))
+        self._toolbar.edit_button.set_sensitive(len(self.results))
 
     def hide_edit_button(self):
         self.accept_edit_data = False
@@ -499,12 +450,12 @@
         if self._selected:
             selected = self._selected
             selected.sync()
-            self.klist.update(selected)
+            self.results.update(selected)
         else:
             # user just added a new instance
             selected = self.get_searchlist_model(model)
-            self.klist.append(selected)
-        self.klist.select(selected)
+            self.results.append(selected)
+        self.results.select(selected)
 
     def run(self, obj=None):
         self._selected = obj
@@ -516,20 +467,27 @@
             else:
                 adapted = obj
             obj = self.interface(adapted)
+
         rv = self.run_editor(obj)
-        if not rv:
-            rollback_and_begin(self.conn)
-            return
+        if rv:
+            if self.editor_class.model_iface:
+                rv = rv.get_adapted()
 
-        if self.editor_class.model_iface:
-            rv = rv.get_adapted()
+            self.search.refresh()
+            self.enable_ok()
 
-        self.conn.commit()
-        self.update_edited_item(rv)
-        self.enable_ok()
+    def run_dialog(self, editor_class, parent, *args):
+        run_dialog(editor_class, parent, *args)
 
     def run_editor(self, obj):
-        return run_dialog(self.editor_class, self, self.conn, obj)
+        trans = new_transaction()
+        retval = self.run_dialog(self.editor_class, self, trans,
+                                 trans.get(obj))
+        if finish_transaction(trans, retval):
+            assert isinstance(retval, SQLObject)
+            retval = type(retval).get(retval.id, connection=self.conn)
+        trans.close()
+        return retval
 
     # Private
 
@@ -538,15 +496,15 @@
             return
 
         if obj is None:
-            if self.klist.get_selection_mode() == gtk.SELECTION_MULTIPLE:
-                obj = self.klist.get_selected_rows()
+            if self.results.get_selection_mode() == gtk.SELECTION_MULTIPLE:
+                obj = self.results.get_selected_rows()
                 qty = len(obj)
                 if qty != 1:
                     raise AssertionError(
                       "There should be only one item selected. Got %s items"
                       % qty)
             else:
-                obj = self.klist.get_selected()
+                obj = self.results.get_selected()
                 if not obj:
                     raise AssertionError(
                         "There should be at least one item selected")
@@ -561,7 +519,7 @@
     def _on_toolbar__new(self, toolbar):
         self.run()
 
-    def _on_list__double_click(self, list, obj):
+    def _on_results__double_click(self, results, obj):
         self._edit(obj)
 
     #

Modified: stoqlib/trunk/stoqlib/gui/dialogs/tillhistory.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/dialogs/tillhistory.py	(original)
+++ stoqlib/trunk/stoqlib/gui/dialogs/tillhistory.py	Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
 # vi:si:et:sw=4:sts=4:ts=4
 
 ##
-## Copyright (C) 2005-2007 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2007 Async Open Source <http://www.async.com.br>
 ## All rights reserved
 ##
 ## This program is free software; you can redistribute it and/or modify
@@ -19,10 +19,7 @@
 ## along with this program; if not, write to the Free Software
 ## Foundation, Inc., or visit: http://www.gnu.org/.
 ##
-## Author(s):       Henrique Romano         <henrique at async.com.br>
-##                  Bruno Rafael Garcia     <brg at async.com.br>
-##                  Evandro Vale Miquelito  <evandro at async.com.br>
-##                  Johan Dahlin            <jdahlin at async.com.br>
+## Author(s):       Johan Dahlin            <jdahlin at async.com.br>
 ##
 """ Implementation of classes related to till operations.  """
 
@@ -31,116 +28,40 @@
 
 import gtk
 from kiwi.datatypes import currency
-from kiwi.ui.delegates import GladeSlaveDelegate
+from kiwi.ui.search import DateSearchFilter, Today
 from kiwi.ui.widgets.list import Column, ColoredColumn
-from sqlobject.sqlbuilder import IN
 
-from stoqlib.database.database import finish_transaction, rollback_and_begin
-from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import payment_value_colorize
-from stoqlib.lib.validators import get_formatted_price
-from stoqlib.domain.interfaces import IPaymentGroup
-from stoqlib.domain.sale import Sale
-from stoqlib.domain.till import TillEntry, Till
-from stoqlib.domain.payment.payment import Payment
-from stoqlib.gui.base.searchbar import SearchBar
-from stoqlib.gui.base.dialogs import BasicWrappingDialog, run_dialog
+from stoqlib.database.database import finish_transaction
+from stoqlib.domain.till import TillEntry
+from stoqlib.gui.base.search import SearchDialog
+from stoqlib.gui.base.dialogs import run_dialog
 from stoqlib.gui.editors.tilleditor import (CashAdvanceEditor, CashInEditor,
                                             CashOutEditor)
+from stoqlib.lib.translation import stoqlib_gettext
+from stoqlib.lib.defaults import payment_value_colorize
 
 _ = stoqlib_gettext
 
 
-class TillHistoryDialog(GladeSlaveDelegate):
-    app_name = _('Till History')
-    gladefile = 'TillHistoryDialog'
-    widgets = ('cash_out_button',
-               'cash_advance_button',
-               'cash_in_button',
-               'total_balance_label',
-               'payments')
-
-    title = _('Current Till History')
-    size = (750, -1)
-
-    def __init__(self, conn):
-        GladeSlaveDelegate.__init__(self, gladefile=self.gladefile)
-        self.main_dialog = BasicWrappingDialog(self, self.title,
-                                               size=self.size,
-                                               hide_footer=True)
-        self.conn = conn
-        self._setup_widgets()
-        self._setup_slaves()
-        self._update_widgets()
-        self.main_dialog.set_title(self._get_title())
-        self.search_bar.search_items()
-        self._check_initial_cash_amount()
-
-    def on_cancel(self):
-        # XXX We need a proper base class in stoqlib to avoid redefining this
-        # method here. bug 2217
-        self.main_dialog.close()
-
-    def _get_title(self):
-        today_format = _('%d of %B')
-        today_str = datetime.date.today().strftime(today_format)
-        return _('Stoq - %s of %s') % (self.app_name, today_str)
-
-    def _sync(self, *args):
-        rollback_and_begin(self.conn)
-
-    def _setup_slaves(self):
-        self.search_bar = SearchBar(self.conn, TillEntry,
-                                    self._get_columns(),
-                                    searching_by_date=True)
-        self.search_bar.register_extra_query_callback(self.get_extra_query)
-        self.search_bar.set_searchbar_labels(_('Items Matching'))
-        self.search_bar.set_result_strings(_('item'), _('items'))
-        self.search_bar.connect('search-activate', self._update_list)
-        self.search_bar.connect('before-search-activate', self._sync)
-        self.attach_slave('searchbar_holder', self.search_bar)
-
-    def _update_widgets(self):
-        self.selected_item = self.payments.get_selected_rows()
-        self.canceled_items = 0
-        self.selected = 0
-
-    def _setup_widgets(self):
-        self.payments.set_columns(self._get_columns())
-        self.payments.set_visible_rows(10)
-        self.payments.set_selection_mode(gtk.SELECTION_MULTIPLE)
-        self._update_total()
+class TillHistoryDialog(SearchDialog):
+    size = (780, -1)
+    table = TillEntry
+    selection_mode = gtk.SELECTION_MULTIPLE
+    searchbar_labels = _('Till Entries matching:')
+
+    @property
+    def title(self):
+        return _('Till history %s') % (
+            datetime.date.today().strftime(_('%d of %B')))
 
-    def _run_editor(self, editor_class):
-        model = run_dialog(editor_class, self, self.conn)
-        if finish_transaction(self.conn, model):
-            self.search_bar.search_items()
-            self.payments.unselect_all()
-            self._select_last_item()
-
-    def _select_last_item(self):
-        if len(self.payments):
-            self.payments.select(self.payments[-1])
-
-    def _update_list(self, slave, objs):
-        self.payments.add_list(objs)
-        self._update_total()
-
-    def _update_total(self, *args):
-        total_balance = currency(0)
-        for item in self.payments:
-            total_balance += item.value
-        total_balance_str = get_formatted_price(total_balance)
-        self.total_balance_label.set_text(total_balance_str)
-        if total_balance < 0:
-            self.total_balance_label.set_color('red')
-        else:
-            self.total_balance_label.set_color('black')
+    #
+    # SearchDialog
+    #
 
-    def _get_columns(self, *args):
+    def get_columns(self, *args):
         return [Column('id', _('Number'), data_type=int, width=80,
                         format='%03d', sorted=True),
-                Column('date', _('Due Date'),
+                Column('date', _('Date'),
                        data_type=datetime.date, width=110),
                 Column('description', _('Description'), data_type=str,
                        expand=True,
@@ -148,42 +69,36 @@
                 ColoredColumn('value', _('Value'), data_type=currency,
                               color='red', data_func=payment_value_colorize,
                               width=140)]
+    def create_filters(self):
+        self.set_text_field_columns(['description'])
 
-    def _check_initial_cash_amount(self):
-        # This method is wrong.
-        # A good way to get the initial cash amount payment would be to
-        # use the payment_id.
-        # Waiting for bug 2524
-        for item in self.selected_item:
-            if item.description == _('Initial cash amount'):
-                return True
-        return False
+        date_filter = DateSearchFilter(_('Date:'))
+        date_filter.select(Today)
+        self.add_filter(date_filter, columns=['date'])
+
+    def setup_widgets(self):
+        self.results.set_visible_rows(10)
+        self._add_editor_button(_('Cash _Advance...'), CashAdvanceEditor)
+        self._add_editor_button(_('Cash _In...'), CashInEditor)
+        self._add_editor_button(_('Cash _Out...'), CashOutEditor)
+
+    def _add_editor_button(self, name, editor_class):
+        b = gtk.Button(name)
+        b.connect('clicked', lambda b: self._run_editor(editor_class))
+        b.set_use_underline(True)
+        self.action_area.set_layout(gtk.BUTTONBOX_START)
+        self.action_area.pack_start(b, False, False, 6)
+        b.show()
 
     #
-    # Searchbar callbacks
+    # Private API
     #
 
-    def get_extra_query(self):
-        current_till = Till.get_current(self.conn)
-        assert current_till
-        group_ids = []
-        for sale in Sale.get_available_sales(self.conn, current_till):
-            group = IPaymentGroup(sale)
-            group_ids.append(group.id)
-        return IN(Payment.q.groupID, group_ids)
-
-    #
-    # Kiwi handlers
-    #
-
-    def on_payments__selection_changed(self, *args):
-        self._update_widgets()
-
-    def on_cash_out_button__clicked(self, button):
-        self._run_editor(CashOutEditor)
-
-    def on_cash_in_button__clicked(self, button):
-        self._run_editor(CashInEditor)
+    def _run_editor(self, editor_class):
+        model = run_dialog(editor_class, self, self.conn)
+        if finish_transaction(self.conn, model):
+            self.search.refresh()
+            self.results.unselect_all()
+            if len(self.results):
+                self.results.select(self.results[-1])
 
-    def on_cash_advance_button__clicked(self, button):
-        self._run_editor(CashAdvanceEditor)

Modified: stoqlib/trunk/stoqlib/gui/interfaces.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/interfaces.py	(original)
+++ stoqlib/trunk/stoqlib/gui/interfaces.py	Wed Apr 25 15:50:38 2007
@@ -21,51 +21,3 @@
 ##
 ## Author(s):   Johan Dahlin      <jdahlin at async.com.br>
 ##
-
-from zope.interface import Interface
-
-class ISearchBarEntrySlave(Interface):
-    """
-    This interface represents a slave which you can embed in a SearchBar.
-    """
-
-    def get_slave():
-        """
-        Returns the slave which we embed in the search bar
-        """
-
-    def start_animation():
-        """
-        Start the search animation. This is called when a search is begun.
-        """
-
-    def stop_animation():
-        """
-        Stop the search animation. This is called after a search is done.
-        """
-
-    def clear():
-        """
-        Clear all interactive widgets inside the slave
-        """
-
-    def get_extra_queries():
-        """
-        Return a list of queries that will be combined with an AND in
-        the searchbar itself.
-        It can return an empty list if desired.
-        """
-
-    def get_search_string():
-        pass
-
-    def set_search_string(search_str):
-        pass
-
-    def set_search_label(label):
-        pass
-
-    def set_focus():
-        """
-        Grab the focus
-        """

Modified: stoqlib/trunk/stoqlib/gui/search/categorysearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/categorysearch.py	(original)
+++ stoqlib/trunk/stoqlib/gui/search/categorysearch.py	Wed Apr 25 15:50:38 2007
@@ -50,6 +50,10 @@
         self.set_searchbar_labels(self.searchbar_label)
         self.set_result_strings(*self.result_strings)
 
+    def create_filters(self):
+        self.set_text_field_columns(['description'])
+        self.executer.add_query_callback(self._get_query)
+
     def get_columns(self):
         return [
             Column("description", _("Description"), data_type=str,
@@ -61,7 +65,11 @@
                    width=190),
             ]
 
-    def get_extra_query(self):
+    #
+    # Private
+    #
+
+    def _get_query(self, states):
         return SellableCategory.q.categoryID != None
 
 class BaseSellableCatSearch(SellableCategorySearch):
@@ -71,6 +79,10 @@
     result_strings = _('base category'), _('base categories')
     editor = BaseSellableCategoryEditor
 
+    def create_filters(self):
+        self.set_text_field_columns(['description'])
+        self.executer.add_query_callback(self._get_query)
+
     def get_columns(self):
         columns = SellableCategorySearch.get_columns(self)
         del columns[-1]
@@ -81,5 +93,9 @@
             )
         return columns
 
-    def get_extra_query(self):
+    #
+    # Private
+    #
+
+    def _get_query(self, states):
         return SellableCategory.q.categoryID == None

Modified: stoqlib/trunk/stoqlib/gui/search/fiscalsearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/fiscalsearch.py	(original)
+++ stoqlib/trunk/stoqlib/gui/search/fiscalsearch.py	Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
 # vi:si:et:sw=4:sts=4:ts=4
 
 ##
-## Copyright (C) 2005, 2006 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2005-2007 Async Open Source <http://www.async.com.br>
 ## All rights reserved
 ##
 ## This program is free software; you can redistribute it and/or modify
@@ -20,25 +20,25 @@
 ## Foundation, Inc., or visit: http://www.gnu.org/.
 ##
 ##  Author(s): Evandro Vale Miquelito   <evandro at async.com.br>
-##
+##             Johan Dahlin             <jdahlin at async.com.br>
 ##
 """ Search dialogs for fiscal objects """
 
 import datetime
 
 import gtk
-from kiwi.ui.widgets.list import Column
 from kiwi.datatypes import currency
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter
+from kiwi.ui.widgets.list import Column
 
+from stoqlib.domain.fiscal import CfopData, IcmsIpiView, IssView
 from stoqlib.enums import FiscalBookEntry
-from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX
 from stoqlib.gui.base.search import SearchEditor
-from stoqlib.gui.editors.fiscaleditor import CfopEditor
-from stoqlib.gui.slaves.fiscalslave import FiscalBookEntryFilterSlave
-from stoqlib.gui.editors.fiscaleditor import FiscalBookEntryEditor
-from stoqlib.domain.fiscal import CfopData, IcmsIpiView, IssView
-
+from stoqlib.gui.editors.fiscaleditor import (CfopEditor,
+                                              FiscalBookEntryEditor)
+from stoqlib.lib.defaults import fiscal_book_entries
+from stoqlib.lib.translation import stoqlib_gettext
 
 _ = stoqlib_gettext
 
@@ -54,6 +54,9 @@
     # SearchDialog Hooks
     #
 
+    def create_filters(self):
+        self.set_text_field_columns(['description', 'code'])
+
     def get_columns(self):
         return [Column('code', _('CFOP'), data_type=str, sorted=True,
                        width=90),
@@ -70,35 +73,35 @@
     has_new_button = False
     searchbar_result_strings = _("fiscal entry"), _("fiscal entries")
 
-    def _setup_columns(self, columns, table, col_name, summary_label_text):
+    def _setup_columns(self, column, table, col_name, summary_label_text):
         label_text = '<b>%s</b>' % summary_label_text
-        self.klist.set_columns(columns)
-        self.set_searchtable(table)
-        self.set_searchbar_columns(columns)
-        self.setup_summary_label(col_name, label_text)
+        columns = self.get_columns() + [column]
+        self.results.set_columns(columns)
+        self.set_table(table)
+        #self.setup_summary_label(col_name, label_text)
 
     def _setup_icms_columns(self):
-        cols = self.get_columns() + [Column('icms_value',
-                                            title=_('ICMS Total'),
-                                            justify=gtk.JUSTIFY_RIGHT,
-                                            data_type=currency, width=120)]
-        self._setup_columns(cols, IcmsIpiView, 'icms_value',
+        col = Column('icms_value',
+                     title=_('ICMS Total'),
+                     justify=gtk.JUSTIFY_RIGHT,
+                     data_type=currency, width=120)
+        self._setup_columns(col, IcmsIpiView, 'icms_value',
                             _("ICMS Total:"))
 
     def _setup_ipi_columns(self):
-        cols = self.get_columns() + [Column('ipi_value',
-                                            title=_('IPI Total'),
-                                            justify=gtk.JUSTIFY_RIGHT,
-                                            data_type=currency, width=120)]
-        self._setup_columns(cols, IcmsIpiView, 'ipi_value',
+        col = Column('ipi_value',
+                     title=_('IPI Total'),
+                     justify=gtk.JUSTIFY_RIGHT,
+                     data_type=currency, width=120)
+        self._setup_columns(col, IcmsIpiView, 'ipi_value',
                             _("IPI Total:"))
 
     def _setup_iss_columns(self):
-        cols = self.get_columns() + [Column('iss_value',
-                                            title=_('ISS Total'),
-                                            justify=gtk.JUSTIFY_RIGHT,
-                                            data_type=currency, width=120)]
-        self._setup_columns(cols, IssView, 'iss_value',
+        col = Column('iss_value',
+                     title=_('ISS Total'),
+                     justify=gtk.JUSTIFY_RIGHT,
+                     data_type=currency, width=120)
+        self._setup_columns(col, IssView, 'iss_value',
                             _("ISS Total:"))
 
     #
@@ -117,9 +120,8 @@
                        data_type=str, expand=True)]
 
 
-    def get_extra_query(self):
-        branch = self.filter_slave.get_selected_branch()
-        entry_type = self.filter_slave.get_selected_entry_type()
+    def _get_entry_type_query(self, state):
+        entry_type = state.value
         if entry_type == FiscalBookEntry.ICMS:
             self._setup_icms_columns()
         elif entry_type == FiscalBookEntry.ISS:
@@ -129,17 +131,21 @@
         else:
             raise ValueError("Invalid fical book entry type, got %s"
                              % entry_type)
-        if branch != ALL_ITEMS_INDEX:
-            return self.search_table.q.branch_id == branch.id
 
     #
     # SearchDialog Hooks
     #
 
-    def get_filter_slave(self):
-        self.filter_slave = FiscalBookEntryFilterSlave(self.conn)
-        return self.filter_slave
-
-    def after_search_bar_created(self):
-        self.filter_slave.connect('status-changed',
-                                  self.search_bar.search_items)
+    def create_filters(self):
+        self.set_text_field_columns([])
+
+        branch_filter = self.create_branch_filter(_('In branch:'))
+        branch_filter.select(None)
+        self.add_filter(branch_filter, columns=['branch_id'])
+
+        items = [(v, k)
+                    for k, v in fiscal_book_entries.items()]
+        entry_type = ComboSearchFilter(_('Show entries of type'), items)
+        self.add_filter(entry_type, callback=self._get_entry_type_query,
+                        position=SearchFilterPosition.TOP)
+

Modified: stoqlib/trunk/stoqlib/gui/search/giftcertificatesearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/giftcertificatesearch.py	(original)
+++ stoqlib/trunk/stoqlib/gui/search/giftcertificatesearch.py	Wed Apr 25 15:50:38 2007
@@ -27,13 +27,13 @@
 import gtk
 
 from kiwi.datatypes import currency
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter
 
 from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX
 from stoqlib.domain.sellable import ASellable
 from stoqlib.domain.giftcertificate import (GiftCertificateType,
                                             GiftCertificateView)
-from stoqlib.gui.slaves.filterslave import FilterSlave
 from stoqlib.gui.base.search import SearchEditor
 from stoqlib.gui.base.columns import Column
 from stoqlib.gui.editors.giftcertificateeditor import (
@@ -53,31 +53,20 @@
         SearchEditor.__init__(self, conn, self.table, self.editor_class,
                               hide_footer=hide_footer,
                               title=self.title)
-        self.search_bar.set_result_strings(_('gift certificate type'),
-                                           _('gift certificate types'))
-        self.search_bar.set_searchbar_labels(_('matching'))
+        self.set_searchbar_labels(_('matching'))
 
     #
     # SearchDialog Hooks
     #
 
-    def get_filter_slave(self):
-        certificates = [(_('Active'), True), (_('Inactive'), False)]
-        certificates.insert(0, (_('Any'), ALL_ITEMS_INDEX))
-        self.filter_slave = FilterSlave(certificates, selected=ALL_ITEMS_INDEX)
-        self.filter_slave.set_filter_label(_('Show gift certificate types '
-                                             'with status'))
-        return self.filter_slave
-
-    def after_search_bar_created(self):
-        self.filter_slave.connect('status-changed',
-                                  self.search_bar.search_items)
-
-    def on_cell_edited(self, klist, obj, attr):
-        # Waiting for bug 2177. We should only call commit for
-        # self.conn here.
-        conn = obj.get_connection()
-        conn.commit()
+    def create_filters(self):
+        self.set_text_field_columns([])
+        certificates = [(_('Any'), None),
+                        (_('Active'), True),
+                        (_('Inactive'), False)]
+        status_filter = ComboSearchFilter(
+            _('Show gift certificate types with status'), certificates)
+        self.add_filter(status_filter, SearchFilterPosition.TOP, ['is_active'])
 
     #
     # SearchEditor Hooks
@@ -102,11 +91,6 @@
                 Column('is_active', _('Active'), data_type=bool,
                        editable=True)]
 
-    def get_extra_query(self):
-        status = self.filter_slave.get_selected_status()
-        if status != ALL_ITEMS_INDEX:
-            return GiftCertificateType.q.is_active == status
-
 
 class GiftCertificateSearch(SearchEditor):
     """A search dialog for gift certificates. A gift certificate is a
@@ -123,34 +107,31 @@
                               hide_toolbar=hide_toolbar,
                               title=self.title)
         self.hide_edit_button()
-        self.search_bar.set_result_strings(_('gift certificate'),
-                                           _('gift certificates'))
-        self.search_bar.set_searchbar_labels(_('matching'))
+        self.set_result_strings(_('gift certificate'),
+                                _('gift certificates'))
+        self.set_searchbar_labels(_('matching'))
 
     #
     # SearchDialog Hooks
     #
 
-    def get_filter_slave(self):
+    def create_filters(self):
+        self.set_text_field_columns([])
         statuses = [(value, constant)
                     for constant, value in ASellable.statuses.items()]
-        statuses.insert(0, (_('Any'), ALL_ITEMS_INDEX))
-        selected = ASellable.STATUS_AVAILABLE
-        self.filter_slave = FilterSlave(statuses, selected=selected)
-        self.filter_slave.set_filter_label(_('Show gift certificates with '
-                                             'status'))
-        return self.filter_slave
-
-    def after_search_bar_created(self):
-        self.filter_slave.connect('status-changed',
-                                  self.search_bar.search_items)
+        statuses.insert(0, (_('Any'), None))
+        status_filter = ComboSearchFilter(
+            _('Show gift certificates with status'), statuses)
+        status_filter.select(ASellable.STATUS_AVAILABLE)
+        self.add_filter(status_filter, SearchFilterPosition.TOP, ['status'])
+
 
     #
     # SearchEditor Hooks
     #
 
     def update_edited_item(self, *args):
-        self.search_bar.search_items()
+        self.search.refresh()
 
     def get_columns(self):
         return [Column('id', _('Number'), data_type=int,
@@ -163,8 +144,3 @@
                        data_type=currency, width=120),
                 Column('on_sale_price', title=_('On Sale Price'),
                        data_type=currency, width=140)]
-
-    def get_extra_query(self):
-        status = self.filter_slave.get_selected_status()
-        if status != ALL_ITEMS_INDEX:
-            return self.table.q.status == status

Modified: stoqlib/trunk/stoqlib/gui/search/personsearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/personsearch.py	(original)
+++ stoqlib/trunk/stoqlib/gui/search/personsearch.py	Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
 # vi:si:et:sw=4:sts=4:ts=4
 
 ##
-## Copyright (C) 2005, 2006 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2005-2007 Async Open Source <http://www.async.com.br>
 ## All rights reserved
 ##
 ## This program is free software; you can redistribute it and/or modify
@@ -22,15 +22,16 @@
 ## Author(s):   Evandro Vale Miquelito      <evandro at async.com.br>
 ##              Henrique Romano             <henrique at async.com.br>
 ##              Ariqueli Tejada Fonseca     <aritf at async.com.br>
+##              Johan Dahlin                <jdahlin at async.com.br>
 ##
 """ Search dialogs for person objects """
 
-from sqlobject.sqlbuilder import LEFTJOINOn, AND, OR
-from kiwi.ui.widgets.list import Column
 from kiwi.argcheck import argcheck
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter
+from kiwi.ui.widgets.list import Column
 
 from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX
 from stoqlib.lib.validators import format_phone_number
 from stoqlib.gui.editors.personeditor import (ClientEditor, SupplierEditor,
                                               EmployeeEditor,
@@ -40,14 +41,14 @@
                                               FinanceProviderEditor)
 from stoqlib.gui.base.search import SearchEditor
 from stoqlib.gui.base.dialogs import run_dialog
-from stoqlib.gui.base.columns import FacetColumn, ForeignKeyColumn
 from stoqlib.gui.dialogs.clientdetails import ClientDetailsDialog
-from stoqlib.gui.slaves.filterslave import FilterSlave
-from stoqlib.domain.interfaces import (ICompany, ISupplier, IEmployee,
-                                       IClient, ICreditProvider,
-                                       ITransporter, IBranch)
-from stoqlib.domain.person import (Person, EmployeeRole, ClientView,
-                                   PersonAdaptToEmployee)
+from stoqlib.domain.person import (EmployeeRole,
+                                   PersonAdaptToBranch, BranchView,
+                                   PersonAdaptToClient, ClientView,
+                                   PersonAdaptToCreditProvider, CreditProviderView,
+                                   PersonAdaptToEmployee, EmployeeView,
+                                   TransporterView,
+                                   SupplierView)
 from stoqlib.gui.wizards.personwizard import run_person_role_dialog
 
 _ = stoqlib_gettext
@@ -72,131 +73,98 @@
         self.set_searchbar_labels(self.search_lbl_text)
         self.set_result_strings(*self.result_strings)
 
-    def run_editor(self, obj):
-        return run_person_role_dialog(self.editor_class, self,
-                                      self.conn, obj)
-
+    def run_dialog(self, editor_class, parent, *args):
+        run_person_role_dialog(editor_class, parent, *args)
 
 class EmployeeSearch(BasePersonSearch):
     title = _('Employee Search')
     editor_class = EmployeeEditor
-    table = PersonAdaptToEmployee
+    table = EmployeeView
     search_lbl_text = _('matching:')
     result_strings = _('employee'), _('employees')
-    filter_label = _('Show employees with status')
 
     #
     # SearchDialog Hooks
     #
 
-    def get_filter_slave(self):
-        employees = [(value, key) for key, value in
-                     self.table.statuses.items()]
-        employees.insert(0, (_('Any'), ALL_ITEMS_INDEX))
-        self.filter_slave = FilterSlave(employees, selected=ALL_ITEMS_INDEX)
-        self.filter_slave.set_filter_label(self.filter_label)
-        return self.filter_slave
-
-    def after_search_bar_created(self):
-        self.filter_slave.connect('status-changed',
-                                  self.search_bar.search_items)
+    def create_filters(self):
+        self.set_text_field_columns(['name', 'role', 'registry_number'])
+        items = [(value, key) for key, value in
+                 PersonAdaptToEmployee.statuses.items()]
+        items.insert(0, (_('Any'), None))
+        status_filter = ComboSearchFilter(_('Show employees with status'),
+                                          items)
+        self.add_filter(status_filter, SearchFilterPosition.TOP, ['status'])
 
     def get_columns(self):
-        return [ForeignKeyColumn(Person, 'name', _('Name'), str,
-                                 width=250, adapted=True,
-                                 expand=True),
-                ForeignKeyColumn(EmployeeRole, 'name', _('Role'),
-                                 str, width=250, obj_field='role'),
+        return [Column('name', _('Name'), str,
+                       width=250, expand=True),
+                Column('role', _('Role'), str,
+                       width=250),
                 Column('registry_number', _('Registry Number'), str,
                        width=150),
                 Column('status_string', _('Status'), str)]
 
-    def get_extra_query(self):
-        employee_table = Person.getAdapterClass(IEmployee)
-        query = employee_table.q._originalID == Person.q.id
-        status = self.filter_slave.get_selected_status()
-        if status != ALL_ITEMS_INDEX:
-            query = AND(query, employee_table.q.status == status)
-        return query
-
-    def get_query_args(self):
-        return dict(join=LEFTJOINOn(
-            self.table, EmployeeRole,
-            self.table.q.roleID == EmployeeRole.q.id))
-
-    def get_searchlist_model(self, model):
-        return IEmployee(model)
+    def get_editor_model(self, model):
+        return model.employee
 
 
 class SupplierSearch(BasePersonSearch):
     title = _('Supplier Search')
     editor_class = SupplierEditor
     size = (750, 450)
-    table = Person
-    interface = ISupplier
+    table = SupplierView
     search_lbl_text = _('Suppliers Matching:')
     result_strings = _('supplier'), _('suppliers')
 
     #
-    # Hooks
+    # SearchDialog hooks
     #
 
+    def create_filters(self):
+        self.set_text_field_columns(['name', 'phone_number', 'cnpj'])
+
     def get_columns(self):
         return [Column('name', _('Name'), str,
                        sorted=True, width=250, expand=True),
                 Column('phone_number', _('Phone Number'), str,
                        format_func=format_phone_number, width=110),
-                FacetColumn(ICompany, 'fancy_name', _('Fancy Name'), str,
-                            width=180),
-                FacetColumn(ICompany, 'cnpj', _('CNPJ'), str, width=140)]
-
-    def get_extra_query(self):
-        supplier_table = Person.getAdapterClass(ISupplier)
-        return Person.q.id == supplier_table.q._originalID
-
-    def get_query_args(self):
-        company_table = Person.getAdapterClass(ICompany)
-        return dict(join=LEFTJOINOn(
-            Person, company_table,
-            Person.q.id == company_table.q._originalID))
-
+                Column('fancy_name', _('Fancy Name'), str,
+                       width=180),
+                Column('cnpj', _('CNPJ'), str, width=140)]
 
 class AbstractCreditProviderSearch(BasePersonSearch):
     title = ""
-    table = Person
-    interface = ICreditProvider
+    table = CreditProviderView
     search_lbl_text = ''
     result_strings = None
     editor_class = None
 
     def __init__(self, conn, title='', hide_footer=True):
-        self.provider_table = self.table.getAdapterClass(ICreditProvider)
+        self.provider_table = PersonAdaptToCreditProvider
         BasePersonSearch.__init__(self, conn, title, hide_footer)
 
+    def create_filters(self):
+        self.set_text_field_columns(['name', 'phone_number', 'short_name'])
+        self.executer.add_query_callback(self._get_query)
+
     def get_columns(self):
         return [Column('name', title=_('Name'),
                        data_type=str, sorted=True, expand=True),
                 Column('phone_number', _('Phone Number'), str,
                        format_func=format_phone_number, width=130),
-                FacetColumn(ICreditProvider, 'short_name',
-                            title=_('Short Name'), data_type=str,
-                            width=150),
-                FacetColumn(ICreditProvider, 'is_active',
-                            title=_('Active'), data_type=bool,
-                            editable=True)]
-
-    def on_cell_edited(self, klist, obj, attr):
-        conn = obj.get_connection()
-        conn.commit()
+                Column('short_name', _('Short Name'), str,
+                       width=150),
+                Column('is_active', _('Active'), bool)]
 
     def get_provider_type(self):
         raise NotImplementedError("This method must be defined on child")
 
-    def get_extra_query(self):
-        q1 = self.table.q.id == self.provider_table.q._originalID
-        q2 = self.provider_table.q.provider_type == self.get_provider_type()
-        return AND(q1, q2)
+    def get_editor_model(self, provider_view):
+        return provider_view.provider
 
+    def _get_query(self, states):
+        return self.provider_table.q.provider_type == self.get_provider_type()
 
 class CardProviderSearch(AbstractCreditProviderSearch):
     title = _('Card Provider Search')
@@ -229,24 +197,14 @@
     # SearchDialog Hooks
     #
 
-    def get_filter_slave(self):
-        client_table = Person.getAdapterClass(IClient)
-        statuses = [(value, key) for key, value in
-                    client_table.statuses.items()]
-        statuses.insert(0, (_('Any'), ALL_ITEMS_INDEX))
-        self.filter_slave = FilterSlave(statuses, selected=ALL_ITEMS_INDEX)
-        filter_label = _('Show clients with status')
-        self.filter_slave.set_filter_label(filter_label)
-        return self.filter_slave
-
-    def after_search_bar_created(self):
-        self.filter_slave.connect('status-changed',
-                                  self.search_bar.search_items)
-
-    @argcheck(ClientView)
-    def get_editor_model(self, client_view):
-        return Person.iget(IClient, client_view.client_id,
-                           connection=self.conn)
+    def create_filters(self):
+        self.set_text_field_columns(['name', 'cpf', 'rg_number', 'phone_number'])
+        statuses = [(v, k) for k, v in PersonAdaptToClient.statuses.items()]
+        statuses.insert(0, (_('Any'), None))
+        status_filter = ComboSearchFilter(_('Show clients with status'),
+                                          statuses)
+        status_filter.select(None)
+        self.add_filter(status_filter, SearchFilterPosition.TOP, ['status'])
 
     def get_columns(self):
         return [Column('name', _('Name'), str,
@@ -256,41 +214,37 @@
                 Column('cpf', _('CPF'), str, width=130),
                 Column('rg_number', _('RG'), str, width=120)]
 
-    def get_extra_query(self):
-        status = self.filter_slave.get_selected_status()
-        if status != ALL_ITEMS_INDEX:
-            return self.table.q.status == status
+    @argcheck(ClientView)
+    def get_editor_model(self, client_view):
+        return client_view.client
 
     def on_details_button_clicked(self, *args):
-        items = self.klist.get_selected()
-        client = Person.iget(IClient, items.client_id, connection=self.conn)
-        run_dialog(ClientDetailsDialog, self, self.conn, client)
+        selected = self.results.get_selected()
+        run_dialog(ClientDetailsDialog, self, self.conn, selected.client)
 
     def update_widgets(self, *args):
-        items = self.klist.get_selected()
-        self.set_details_button_sensitive(items is not None)
-        self.set_edit_button_sensitive(items is not None)
+        client_view = self.results.get_selected()
+        self.set_details_button_sensitive(client_view is not None)
+        self.set_edit_button_sensitive(client_view is not None)
 
 
 class TransporterSearch(BasePersonSearch):
     title = _('Transporter Search')
     editor_class = TransporterEditor
-    table = Person
-    interface = ITransporter
+    table = TransporterView
     search_lbl_text = _('matching:')
     result_strings = _('transporter'), _('transporters')
 
-    def get_filter_slave(self):
-        items = [(_('Active Transporters'), True),
-                 (_('Inactive Transporters'), False)]
-        items.insert(0, (_('Any Transporters'), ALL_ITEMS_INDEX))
-        self.filter_slave = FilterSlave(items, selected=ALL_ITEMS_INDEX)
-        self.filter_slave.set_filter_label(_('Show:'))
-        return self.filter_slave
-
-    def after_search_bar_created(self):
-        self.filter_slave.connect('status-changed',
-                                  self.search_bar.search_items)
+    def create_filters(self):
+        self.set_text_field_columns(['name', 'phone_number'])
+        items = [(_('Active'), True),
+                 (_('Inactive'), False)]
+        items.insert(0, (_('Any'), None))
+
+        status_filter = ComboSearchFilter(_('Show transporters with status'),
+                                          items)
+        status_filter.select(None)
+        self.add_filter(status_filter, SearchFilterPosition.TOP, ['is_active'])
 
     def get_columns(self):
         return [Column('name', title=_('Name'),
@@ -298,37 +252,29 @@
                        expand=True),
                 Column('phone_number', _('Phone Number'), str,
                        format_func=format_phone_number, width=180),
-                FacetColumn(ITransporter, 'freight_percentage',
-                            title=_('Freight (%)'), data_type=float,
-                            width=150),
-                FacetColumn(ITransporter, 'status_string',
-                            title=_('Status'), data_type=str)]
-
-    def get_extra_query(self):
-        transporter_table = self.table.getAdapterClass(ITransporter)
-        query = self.table.q.id == transporter_table.q._originalID
-        status = self.filter_slave.get_selected_status()
-        if status != ALL_ITEMS_INDEX:
-            query = AND(query, transporter_table.q.is_active == status)
-        return query
+                Column('freight_percentage', _('Freight (%)'), float,
+                       width=150)]
 
 
 class EmployeeRoleSearch(SearchEditor):
     title = _('Employee Role Search')
     editor_class = EmployeeRoleEditor
     table = EmployeeRole
-    size = (425, 390)
+    size = (-1, 390)
 
     def __init__(self, conn):
         SearchEditor.__init__(self, conn, EmployeeRoleSearch.table,
                               EmployeeRoleSearch.editor_class)
-        self.set_searchbar_labels(_('Role Matching'))
         self.set_result_strings(_('role'), _('roles'))
 
     #
     # SearchEditor Hooks
     #
 
+    def create_filters(self):
+        self.set_text_field_columns(['name'])
+        self.set_searchbar_labels(_('Role Matching'))
+
     def get_columns(self):
         return [Column('name', _('Role'), str, sorted=True)]
 
@@ -337,7 +283,7 @@
     size = (750, 500)
     title = _('Branch Search')
     editor_class = BranchEditor
-    table = Person.getAdapterClass(IBranch)
+    table = BranchView
     search_lbl_text = _('matching')
     result_strings = (_('branch'), _('branches'))
 
@@ -345,46 +291,37 @@
     # SearchEditor Hooks
     #
 
+    def create_filters(self):
+        self.set_text_field_columns(['name', 'phone_number'])
+        statuses = [(value, key)
+                    for key, value in PersonAdaptToBranch.statuses.items()]
+        statuses.insert(0, (_('Any'), None))
+        status_filter = ComboSearchFilter(_('Show branches with status'),
+                                          statuses)
+        status_filter.select(None)
+        self.executer.add_filter_query_callback(
+            status_filter, self._get_status_query)
+        self.search.add_filter(status_filter, SearchFilterPosition.TOP)
+
     def get_columns(self):
-        return [ForeignKeyColumn(Person, 'name', _('Name'), data_type=str,
-                                 width=200, adapted=True, expand=True),
-                ForeignKeyColumn(Person, 'phone_number',
-                                 _('Phone Number'), data_type=str,
-                                 width=150, adapted=True),
-                ForeignKeyColumn(Person, 'name', _('Manager'), data_type=str,
-                                 width=250, obj_field='manager'),
+        return [Column( 'name', _('Name'), str,
+                       width=200, expand=True),
+                Column('phone_number', _('Phone Number'), str,
+                       width=150),
+                #Column('manager_name', _('Manager'), str,
+                #       width=250),
                 Column('status_str', _('Status'), data_type=str)]
 
-    def get_extra_query(self):
-        table = Person.getAdapterClass(IBranch)
-        query = OR(Person.q.id == self.table.q.managerID,
-                   Person.q.id == self.table.q._originalID)
-
-        status = self.filter_slave.get_selected_status()
-        if status == self.table.STATUS_ACTIVE:
-            query = AND(query, table.q.is_active == True)
-        elif status == self.table.STATUS_INACTIVE:
-            query = AND(query, table.q.is_active == False)
-
-        return query
-
-    def get_searchlist_model(self, person):
-        return IBranch(person)
+    def get_editor_model(self, branch_view):
+        return branch_view.branch
 
     #
-    # SearchDialog Hooks
+    # Private
     #
 
-    def get_filter_slave(self):
-        statuses = [(value, key)
-                    for key, value in self.table.statuses.items()]
-        statuses.insert(0, (_('Any'), ALL_ITEMS_INDEX))
-        filter_label = _('Show branches with status')
-        self.filter_slave = FilterSlave(statuses, selected=ALL_ITEMS_INDEX)
-        self.filter_slave.set_filter_label(filter_label)
-        return self.filter_slave
-
-    def after_search_bar_created(self):
-        self.filter_slave.connect('status-changed',
-                                  self.search_bar.search_items)
+    def _get_status_query(self, state):
+        if state.value == PersonAdaptToBranch.STATUS_ACTIVE:
+            return PersonAdaptToBranch.q.is_active == True
+        elif state.value == PersonAdaptToBranch.STATUS_INACTIVE:
+            return PersonAdaptToBranch.q.is_active == False
 

Modified: stoqlib/trunk/stoqlib/gui/search/productsearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/productsearch.py	(original)
+++ stoqlib/trunk/stoqlib/gui/search/productsearch.py	Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
 # vi:si:et:sw=4:sts=4:ts=4
 
 ##
-## Copyright (C) 2005, 2006 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2005-2007 Async Open Source <http://www.async.com.br>
 ## All rights reserved
 ##
 ## This program is free software; you can redistribute it and/or modify
@@ -21,6 +21,7 @@
 ##
 ## Author(s):   Bruno Rafael Garcia         <brg at async.com.br>
 ##              Evandro Vale Miquelito      <evandro at async.com.br>
+##              Johan Dahlin                <jdahlin at async.com.br>
 ##
 """ Search dialogs for product objects """
 
@@ -28,16 +29,18 @@
 
 import gtk
 from kiwi.datatypes import currency
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter
 from kiwi.ui.objectlist import Column
 
+from stoqlib.domain.person import PersonAdaptToBranch
 from stoqlib.domain.product import Product
+from stoqlib.domain.sellable import ASellable
 from stoqlib.domain.views import ProductFullStockView
 from stoqlib.gui.editors.producteditor import ProductEditor
-from stoqlib.gui.slaves.productslave import ProductFilterSlave
 from stoqlib.gui.search.sellablesearch import SellableSearch
 from stoqlib.gui.base.dialogs import print_report
 from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX
 from stoqlib.lib.validators import format_quantity
 from stoqlib.reporting.product import ProductReport
 
@@ -78,23 +81,37 @@
         if hide_price_column:
             self._hide_column('price')
         self.set_edit_button_sensitive(False)
-        self.klist.connect('selection-changed', self.on_selection_changed)
+        self.results.connect('selection-changed', self.on_selection_changed)
 
     def _hide_column(self, colname):
-        column = self.klist.get_column_by_name(colname)
-        col_index = self.klist.get_columns().index(column)
-        self.klist.set_column_visibility(col_index, False)
+        column = self.results.get_column_by_name(colname)
+        col_index = self.results.get_columns().index(column)
+        self.results.set_column_visibility(col_index, False)
 
     def on_print_button_clicked(self, button):
-        print_report(ProductReport, list(self.klist))
+        print_report(ProductReport, list(self.results))
 
     #
     # SearchDialog Hooks
     #
 
-    def get_filter_slave(self):
-        self.filter_slave = ProductFilterSlave(self.conn)
-        return self.filter_slave
+    def create_filters(self):
+        self.set_text_field_columns(['description'])
+        self.executer.set_query(self._executer_query)
+
+        # Branch
+        branch_filter = self.create_branch_filter(_('In branch:'))
+        branch_filter.select(None)
+        self.add_filter(branch_filter, columns=[])
+        self.branch_filter = branch_filter
+
+        # Status
+        statuses = [(desc, id) for id, desc in ASellable.statuses.items()]
+        statuses.insert(0, (_('Any'), None))
+        status_filter = ComboSearchFilter(_('with status:'), statuses)
+        status_filter.select(None)
+        self.add_filter(status_filter, columns=['status'],
+                        position=SearchFilterPosition.TOP)
 
     def get_branch(self):
         # We have not a filter for branches in this dialog and in this case
@@ -114,7 +131,7 @@
                 Column('barcode', title=_('Barcode'), data_type=str,
                        width=120),
                 Column('description', title=_('Description'), data_type=str,
-                       expand=True),
+                       width=150),
                 Column('supplier_name', title=_('Supplier'), data_type=str,
                        width=150),
                 Column('cost', _('Cost'), data_type=currency,
@@ -125,18 +142,13 @@
                        format_func=format_quantity,
                        data_type=Decimal, width=100)]
 
-    def get_extra_query(self):
-        status = self.filter_slave.get_selected_status()
-        if status != ALL_ITEMS_INDEX:
-            return self.search_table.q.status == status
-
-    def query(self, table, query, args):
-        branch = self.filter_slave.get_selected_branch()
-        if branch == ALL_ITEMS_INDEX:
-            branch = None
+    def _executer_query(self, query, conn):
+        branch = self.branch_filter.get_state().value
+        if branch is not None:
+            branch = PersonAdaptToBranch.get(branch, connection=conn)
         return ProductFullStockView.select_by_branch(query, branch,
-                                                     connection=self.conn)
+                                                     connection=conn)
 
-    def on_selection_changed(self, klist, selected):
+    def on_selection_changed(self, results, selected):
         can_edit = bool(selected)
         self.set_edit_button_sensitive(can_edit)

Modified: stoqlib/trunk/stoqlib/gui/search/receivingsearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/receivingsearch.py	(original)
+++ stoqlib/trunk/stoqlib/gui/search/receivingsearch.py	Wed Apr 25 15:50:38 2007
@@ -35,7 +35,7 @@
 from stoqlib.domain.receiving import ReceivingOrder
 from stoqlib.reporting.purchase_receival import PurchaseReceivalReport
 from stoqlib.gui.dialogs.receivingdialog import ReceivingOrderDetailsDialog
-from stoqlib.gui.base.dialogs import run_dialog
+from stoqlib.gui.base.dialogs import print_report, run_dialog
 
 _ = stoqlib_gettext
 
@@ -85,7 +85,7 @@
         self._show_receiving_order(receiving_order)
 
     def on_print_button_clicked(self, button):
-        self.search_bar.print_report(PurchaseReceivalReport, list(self.klist))
+        print_report(PurchaseReceivalReport, list(self.klist))
 
     def on_details_button_clicked(self, button):
         items = self.klist.get_selected_rows()

Modified: stoqlib/trunk/stoqlib/gui/search/salesearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/salesearch.py	(original)
+++ stoqlib/trunk/stoqlib/gui/search/salesearch.py	Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
 # vi:si:et:sw=4:sts=4:ts=4
 
 ##
-## Copyright (C) 2005, 2006 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2005-2007 Async Open Source <http://www.async.com.br>
 ## All rights reserved
 ##
 ## This program is free software; you can redistribute it and/or modify
@@ -20,6 +20,7 @@
 ## Foundation, Inc., or visit: http://www.gnu.org/.
 ##
 ## Author(s):       Bruno Rafael Garcia      <brg at async.com.br>
+##                  Johan Dahlin             <jdahlin at async.com.br>
 ##
 ##
 """ Search dialogs for sale objects """
@@ -30,14 +31,14 @@
 
 import gtk
 from kiwi.datatypes import currency
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter
 from kiwi.ui.widgets.list import Column
 
 from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX
 from stoqlib.lib.validators import format_quantity
 from stoqlib.gui.base.search import SearchDialog
 from stoqlib.domain.sale import Sale, SaleView
-from stoqlib.gui.slaves.filterslave import FilterSlave
 from stoqlib.gui.slaves.saleslave import SaleListToolbar
 
 _ = stoqlib_gettext
@@ -52,22 +53,21 @@
     def __init__(self, conn):
         SearchDialog.__init__(self, conn, self.search_table,
                               title=self.title)
-        self._setup_widgets()
         self._setup_slaves()
 
-    def _setup_slaves(self):
-        slave = SaleListToolbar(self.conn, self.klist, self)
-        slave.disable_editing()
-        self.attach_slave("extra_holder", slave)
-
-    def _setup_widgets(self):
-        self.search_bar.set_result_strings(_('sale'), _('sales'))
-        self.search_bar.set_searchbar_labels(_('matching:'))
-
     #
-    # SearchBar Hooks
+    # SearchDialog Hooks
     #
 
+    def create_filters(self):
+        self.set_text_field_columns(['client_name', 'salesperson_name'])
+        self.set_searchbar_labels(_('matching:'))
+        items = [(value, key) for key, value in Sale.statuses.items()]
+        items.insert(0, (_('Any'), None))
+
+        status_filter = ComboSearchFilter(_('Show sales witbh status'), items)
+        self.add_filter(status_filter, SearchFilterPosition.TOP, ['status'])
+
     def get_columns(self):
         return [Column('id', title=_('Number'), width=70,
                        data_type=int, sorted=True),
@@ -83,22 +83,11 @@
                 Column('total', title=_('Total'), data_type=currency,
                        width=80)]
 
-    def get_extra_query(self):
-        status = self.filter_slave.get_selected_status()
-        if status != ALL_ITEMS_INDEX:
-            return SaleView.q.status == status
-
     #
-    # SearchDialog Hooks
+    # Private
     #
 
-    def get_filter_slave(self):
-        items = [(value, key) for key, value in Sale.statuses.items()]
-        items.insert(0, (_('Any'), ALL_ITEMS_INDEX))
-        self.filter_slave = FilterSlave(items, selected=Sale.STATUS_CONFIRMED)
-        self.filter_slave.set_filter_label(_('Show sales with status'))
-        return self.filter_slave
-
-    def after_search_bar_created(self):
-        self.filter_slave.connect('status-changed',
-                                  self.search_bar.search_items)
+    def _setup_slaves(self):
+        slave = SaleListToolbar(self.conn, self.results, self)
+        slave.disable_editing()
+        self.attach_slave("extra_holder", slave)

Modified: stoqlib/trunk/stoqlib/gui/search/sellablesearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/sellablesearch.py	(original)
+++ stoqlib/trunk/stoqlib/gui/search/sellablesearch.py	Wed Apr 25 15:50:38 2007
@@ -30,22 +30,19 @@
 
 import gtk
 from kiwi.datatypes import currency
+from kiwi.enums import SearchFilterPosition
 from kiwi.ui.objectlist import Column
 from sqlobject.sqlbuilder import AND, OR
 
-from stoqlib.database.runtime import get_current_branch
 from stoqlib.gui.base.columns import AccessorColumn
 from stoqlib.gui.base.search import SearchEditor
-from stoqlib.gui.slaves.filterslave import FilterSlave
 from stoqlib.lib.parameters import sysparam
 from stoqlib.lib.validators import format_quantity
-from stoqlib.lib.defaults import ALL_BRANCHES, ALL_ITEMS_INDEX
 from stoqlib.lib.translation import stoqlib_gettext
 from stoqlib.domain.sellable import (ASellable, SellableView,
                                      SellableFullStockView)
 from stoqlib.domain.product import Product
-from stoqlib.domain.person import Person
-from stoqlib.domain.interfaces import IBranch, ISellable, IStorable
+from stoqlib.domain.interfaces import ISellable, IStorable
 
 _ = stoqlib_gettext
 
@@ -75,6 +72,7 @@
         """
         self.quantity = quantity
         self.has_stock_mode = sysparam(conn).HAS_STOCK_MODE
+        self._delivery_service = sysparam(conn).DELIVERY_SERVICE
         SearchEditor.__init__(self, conn, table=self.table,
                               search_table=self.search_table,
                               editor_class=self.editor_class,
@@ -108,6 +106,17 @@
     # Hooks
     #
 
+    def create_filters(self):
+        #if not self.has_stock_mode:
+        #    return
+        self.set_text_field_columns(['description'])
+        branch_filter = self.create_branch_filter(
+            _('Show sale items at'))
+        self.executer.add_filter_query_callback(
+            branch_filter, self._get_branch_query)
+        self.executer.add_query_callback(self._get_query)
+        self.search.add_filter(branch_filter, SearchFilterPosition.TOP)
+
     def get_columns(self):
         """Hook called by SearchEditor"""
         columns = [Column('id', title=_('Code'), data_type=int,
@@ -130,54 +139,8 @@
             columns.append(column)
         return columns
 
-    def _get_available_stock(self, sellable_view):
-        if sellable_view.stock is None:
-            return None
-        return sellable_view.stock - self.current_sale_stock.get(
-            sellable_view.id, 0)
-
-    def get_extra_query(self):
-        """Hook called by SearchBar"""
-        branch_query = None
-        if (not self.has_stock_mode
-            or self.filter_slave.get_selected_status() == ALL_ITEMS_INDEX):
-            self.set_searchtable(SellableFullStockView)
-            branch_query = 1 == 1
-        else:
-            self.set_searchtable(SellableView)
-            branch = self.filter_slave.get_selected_status()
-            branch_query = OR(SellableView.q.branch_id == branch.id,
-                              SellableView.q.branch_id == None)
-        service = sysparam(self.conn).DELIVERY_SERVICE
-        return AND(self.search_table.q.id != service.id,
-                   (self.search_table.q.status
-                    == ASellable.STATUS_AVAILABLE),
-                   branch_query)
-
-    def get_filter_slave(self):
-        if not self.has_stock_mode:
-            return
-        # FIXME: Implement and use IDescribable on PersonAdaptToBranch
-        table = Person.getAdapterClass(IBranch)
-        branch_list = table.get_active_branches(self.conn)
-        items = [(branch.person.name, branch)
-                    for branch in branch_list]
-        if not items:
-            raise ValueError('You should have at least one branch at '
-                             'this point')
-        items.insert(0, ALL_BRANCHES)
-        selected = get_current_branch(self.conn)
-        self.filter_slave = FilterSlave(items, selected=selected)
-        self.filter_slave.set_filter_label(_('Show sale items at'))
-        return self.filter_slave
-
-    def after_search_bar_created(self):
-        if self.has_stock_mode:
-            self.filter_slave.connect('status-changed',
-                                      self.search_bar.search_items)
-
     def update_widgets(self):
-        sellable_view = self.klist.get_selected()
+        sellable_view = self.results.get_selected()
         if not sellable_view:
             return
         sellable = ASellable.get(sellable_view.id, self.conn)
@@ -186,3 +149,33 @@
             self.ok_button.set_sensitive(False)
         else:
             self.ok_button.set_sensitive(True)
+
+    #
+    # Private
+    #
+
+    def _get_branch_query(self, state):
+        query = None
+        if self.has_stock_mode and state.value is not None:
+            table = SellableView
+            query = OR(SellableView.q.branch_id == state.value,
+                       SellableView.q.branch_id == None)
+        else:
+            table = SellableFullStockView
+
+        self.set_table(table)
+        return query
+
+    def _get_query(self, states):
+        query = self.search_table.q.status == ASellable.STATUS_AVAILABLE
+        if self._delivery_service:
+            query =  AND(query,
+                         self.search_table.q.id != self._delivery_service.id)
+        return query
+
+    def _get_available_stock(self, sellable_view):
+        if sellable_view.stock is None:
+            return None
+        return sellable_view.stock - self.current_sale_stock.get(
+            sellable_view.id, 0)
+

Modified: stoqlib/trunk/stoqlib/gui/search/servicesearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/servicesearch.py	(original)
+++ stoqlib/trunk/stoqlib/gui/search/servicesearch.py	Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
 # vi:si:et:sw=4:sts=4:ts=4
 
 ##
-## Copyright (C) 2006 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2006-2007 Async Open Source <http://www.async.com.br>
 ## All rights reserved
 ##
 ## This program is free software; you can redistribute it and/or modify
@@ -20,21 +20,22 @@
 ## Foundation, Inc., or visit: http://www.gnu.org/.
 ##
 ## Author(s):   Evandro Vale Miquelito      <evandro at async.com.br>
+##              Johan Dahlin                <jdahlin at async.com.br>
 ##
 ##
 """ Search dialogs for services """
 
 import gtk
-from kiwi.datatypes import currency
 from kiwi.argcheck import argcheck
+from kiwi.datatypes import currency
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter
 
 from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX
 from stoqlib.domain.sellable import ASellable
 from stoqlib.domain.service import Service, ServiceView
 from stoqlib.gui.base.columns import Column
 from stoqlib.gui.editors.serviceeditor import ServiceEditor
-from stoqlib.gui.slaves.filterslave import FilterSlave
 from stoqlib.gui.search.sellablesearch import SellableSearch
 
 _ = stoqlib_gettext
@@ -65,13 +66,15 @@
     # SearchDialog Hooks
     #
 
-    def get_filter_slave(self):
-        statuses = [(value, key)
-                        for key, value in ASellable.statuses.items()]
-        statuses.insert(0, (_('Any'), ALL_ITEMS_INDEX))
-        self.filter_slave = FilterSlave(statuses, selected=ALL_ITEMS_INDEX)
-        self.filter_slave.set_filter_label(_('Show services with status'))
-        return self.filter_slave
+    def create_filters(self):
+        self.set_text_field_columns(['description', 'barcode'])
+        items = [(v, k) for k, v in ASellable.statuses.items()]
+        items.insert(0, (_('Any'), None))
+        service_filter = ComboSearchFilter(_('Show services with status'),
+                                          items)
+        service_filter.select(None)
+        self.executer.add_query_callback(self._get_query)
+        self.add_filter(service_filter, SearchFilterPosition.TOP, ['status'])
 
     def get_branch(self):
         # We have not a filter for branches in this dialog and in this case
@@ -105,8 +108,3 @@
         columns.append(Column('unit', title=_('Unit'),
                               data_type=str, width=80))
         return columns
-
-    def get_extra_query(self):
-        status = self.filter_slave.get_selected_status()
-        if status != ALL_ITEMS_INDEX:
-            return self.search_table.q.status == status

Modified: stoqlib/trunk/stoqlib/gui/search/stationsearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/stationsearch.py	(original)
+++ stoqlib/trunk/stoqlib/gui/search/stationsearch.py	Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
 # vi:si:et:sw=4:sts=4:ts=4
 
 ##
-## Copyright (C) 2006 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2006-2007 Async Open Source <http://www.async.com.br>
 ## All rights reserved
 ##
 ## This program is free software; you can redistribute it and/or modify
@@ -20,19 +20,17 @@
 ## Foundation, Inc., or visit: http://www.gnu.org/.
 ##
 ## Author(s):   J. Victor Martins         <jvdm at sdf.lonestar.org>
+##              Johan Dahlin              <jdahlin at async.com.br>
 ##
 """ Search dialog for station objects """
 
+from kiwi.enums import SearchFilterPosition
 from kiwi.ui.objectlist import Column
 
-from stoqlib.domain.interfaces import IBranch
 from stoqlib.domain.station import BranchStation
-from stoqlib.domain.person import Person
 from stoqlib.gui.base.columns import AccessorColumn
 from stoqlib.gui.base.search import SearchEditor
 from stoqlib.gui.editors.stationeditor import StationEditor
-from stoqlib.gui.slaves.filterslave import FilterSlave
-from stoqlib.lib.defaults import ALL_BRANCHES, ALL_ITEMS_INDEX
 from stoqlib.lib.translation import stoqlib_gettext
 
 _ = stoqlib_gettext
@@ -42,25 +40,17 @@
     table = BranchStation
     editor_class = StationEditor
     searchbar_result_strings = _("Station"), _("Stations")
-    filter_label = _('Branch')
     size = (-1, 450)
 
     #
     # SearchDialog Hooks
     #
 
-    def get_filter_slave(self):
-        statuses = [ALL_BRANCHES]
-        # FIXME: Implement and use IDescribable on PersonAdaptToBranch
-        for branch in Person.iselect(IBranch, connection=self.conn):
-            statuses.append((branch.person.name, branch))
-        self.filter_slave = FilterSlave(statuses, selected=ALL_ITEMS_INDEX)
-        self.filter_slave.set_filter_label(self.filter_label)
-        return self.filter_slave
-
-    def after_search_bar_created(self):
-        self.filter_slave.connect('status-changed',
-                                  self.search_bar.search_items)
+    def create_filters(self):
+        self.set_text_field_columns(['name'])
+        branch_filter = self.create_branch_filter()
+        self.add_filter(branch_filter,
+                        SearchFilterPosition.TOP, ['branchID'])
 
     def get_columns(self):
         return [Column('name', _('Name'), data_type=str, sorted=True,
@@ -72,9 +62,3 @@
                                title=_('Branch'), data_type=str,
                                expand=True),
                 ]
-
-    def get_extra_query(self):
-        branch = self.filter_slave.get_selected_status()
-        if branch != ALL_ITEMS_INDEX:
-            return BranchStation.q.branchID == branch.id
-

Modified: stoqlib/trunk/stoqlib/gui/search/tillsearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/tillsearch.py	(original)
+++ stoqlib/trunk/stoqlib/gui/search/tillsearch.py	Wed Apr 25 15:50:38 2007
@@ -27,15 +27,15 @@
 import datetime
 
 import gtk
-from kiwi.ui.widgets.list import Column, ColoredColumn
 from kiwi.datatypes import currency
-from sqlobject.sqlbuilder import AND
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter, DateSearchFilter
+from kiwi.ui.widgets.list import Column, ColoredColumn
 
 from stoqlib.database.runtime import get_current_branch
 from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX, payment_value_colorize
+from stoqlib.lib.defaults import payment_value_colorize
 from stoqlib.gui.base.search import SearchDialog
-from stoqlib.gui.slaves.filterslave import FilterSlave
 from stoqlib.domain.till import TillFiscalOperationsView, Till
 
 
@@ -50,14 +50,29 @@
     searchbar_labels = _(u"matching:"),
     searchbar_result_strings = _(u"fiscal operation"), _(u"fiscal operations")
 
-    def __init__(self, conn):
-        SearchDialog.__init__(self, conn)
-        self.setup_summary_label('value', "<b>%s</b>" % (u"Total:"))
-
     #
     # SearchDialog Hooks
     #
 
+    def create_filters(self):
+        self.set_text_field_columns(['description'])
+        self.executer.add_query_callback(self._get_query)
+
+        # Status
+        items = [(v, k) for k, v in Till.statuses.items()
+                    if k != Till.STATUS_PENDING]
+        items.insert(0, (_(u'Any'), None))
+        status_filter = ComboSearchFilter(_(u'Show entries of type'), items)
+        status_filter.select(Till.STATUS_OPEN)
+        self.add_filter(status_filter,
+                        position=SearchFilterPosition.TOP,
+                        columns=['status'])
+
+        # Date
+        date_filter = DateSearchFilter(_('Date:'))
+        self.add_filter(
+            date_filter, columns=['date'])
+
     def get_columns(self, *args):
         return [Column('id', title=_('#'), width=60,
                        justify=gtk.JUSTIFY_RIGHT, format="%05d",
@@ -72,26 +87,11 @@
                        color='red', data_func=payment_value_colorize,
                        width=80)]
 
-    def get_extra_query(self):
-        branch_id = get_current_branch(self.conn).id
-        base_query = self.search_table.q.branch_id == branch_id
-        status = self.filter_slave.get_selected_status()
-        if status == ALL_ITEMS_INDEX:
-            return base_query
-        return AND(base_query, TillFiscalOperationsView.q.status == status)
-
-    def update_klist(self, *args):
-        SearchDialog.update_klist(self, *args)
-
-    def get_filter_slave(self):
-        items = [(value, key) for key, value in Till.statuses.items()
-                    if key != Till.STATUS_PENDING]
-        items.insert(0, (_(u'Any'), ALL_ITEMS_INDEX))
-        self.filter_slave = FilterSlave(items, selected=Till.STATUS_OPEN)
-        self.filter_slave.set_filter_label(_(u'Show entries of type'))
-        return self.filter_slave
-
-    def after_search_bar_created(self):
-        self.filter_slave.connect('status-changed',
-                                  self.search_bar.search_items)
+    #
+    # Private
+    #
+
+    def _get_query(self, state):
+        branch = get_current_branch(self.conn)
+        return self.search_table.q.branch_id == branch.id
 

Modified: stoqlib/trunk/stoqlib/gui/slaves/individualslave.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/slaves/individualslave.py	(original)
+++ stoqlib/trunk/stoqlib/gui/slaves/individualslave.py	Wed Apr 25 15:50:38 2007
@@ -109,7 +109,7 @@
         if self.model.birth_location:
             self.model.birth_location = self.model.birth_location.clone()
         else:
-            cityloc = CityLocation(connection=self.conn)
+            cityloc = CityLocation(connection=self.model.get_connection())
             self.model.birth_location = cityloc
         self.birth_loc_proxy = self.add_proxy(
             self.model.birth_location,

Modified: stoqlib/trunk/stoqlib/gui/wizards/receivingwizard.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/wizards/receivingwizard.py	(original)
+++ stoqlib/trunk/stoqlib/gui/wizards/receivingwizard.py	Wed Apr 25 15:50:38 2007
@@ -31,12 +31,13 @@
 
 import gtk
 from kiwi.datatypes import currency
+from kiwi.db.sqlobj import SQLObjectQueryExecuter
+from kiwi.ui.search import SearchSlaveDelegate, DateSearchFilter
 from kiwi.ui.widgets.list import Column
 
 from stoqlib.database.runtime import get_current_user
 from stoqlib.lib.translation import stoqlib_gettext
 from stoqlib.gui.base.wizards import WizardEditorStep, BaseWizard
-from stoqlib.gui.base.searchbar import SearchBar
 from stoqlib.gui.base.dialogs import run_dialog
 from stoqlib.gui.slaves.receivingslave import ReceivingInvoiceSlave
 from stoqlib.gui.search.productsearch import ProductSearch
@@ -75,9 +76,33 @@
         if sysparam(self.conn).RECEIVE_PRODUCTS_WITHOUT_ORDER:
             validation_value = True
         else:
-            validation_value = len(self.orders) == 1
+            validation_value = len(self.search.results) == 1
         self.wizard.refresh_next(validation_value)
 
+    def _create_search(self):
+        self.order_label.set_size('large')
+        self.order_label.set_bold(True)
+        self.search = SearchSlaveDelegate(self._get_columns())
+        self.attach_slave('searchbar_holder', self.search)
+        self.executer = SQLObjectQueryExecuter()
+        self.search.set_query_executer(self.executer)
+        self.executer.set_table(PurchaseOrderView)
+        self.executer.add_query_callback(self._get_extra_query)
+        self._create_filters()
+        self.search.results.connect('selection-changed',
+                                    self._on_results__selection_changed)
+        self.search.results.connect('row-activated',
+                                    self._on_results__row_activated)
+        self.search.focus_search_entry()
+
+    def _create_filters(self):
+        self.search.set_text_field_columns(['supplier_name'])
+        date_filter = DateSearchFilter(_('Date:'))
+        self.search.add_filter(date_filter, columns=['open_date'])
+
+    def _get_extra_query(self, states):
+        return PurchaseOrderView.q.status == PurchaseOrder.ORDER_CONFIRMED
+
     def _get_columns(self):
         return [Column('id', title=_('Number'), sorted=True,
                        data_type=str, width=80),
@@ -95,20 +120,8 @@
                 Column('total', title=_('Order Total'),
                        data_type=currency, width=120)]
 
-    def _get_extra_query(self):
-        return PurchaseOrderView.q.status == PurchaseOrder.ORDER_CONFIRMED
-
-    def on_searchbar_before_activate(self, *args):
-        self.conn.commit()
-
-    def on_searchbar_activate(self, slave, objs):
-        """Use this callback with SearchBar search-activate signal"""
-        self.orders.add_list(objs, clear=True)
-        has_selection = self.orders.get_selected() is not None
-        self.wizard.refresh_next(has_selection)
-
     def _update_view(self):
-        has_selection = self.orders.get_selected() is not None
+        has_selection = self.search.results.get_selected() is not None
         self.details_button.set_sensitive(has_selection)
         if not sysparam(self.conn).RECEIVE_PRODUCTS_WITHOUT_ORDER:
             self.wizard.refresh_next(has_selection)
@@ -123,7 +136,7 @@
         self.force_validation()
 
     def next_step(self):
-        selected = self.orders.get_selected()
+        selected = self.search.results.get_selected()
         purchase = selected.purchase
 
         # We cannot create the model in the wizard since we haven't
@@ -166,35 +179,28 @@
         return False
 
     def setup_slaves(self):
-        self.order_label.set_size('large')
-        self.order_label.set_bold(True)
-        self.orders.set_columns(self._get_columns())
-        self.searchbar = SearchBar(self.conn, PurchaseOrderView,
-                                   self._get_columns(),
-                                   searching_by_date=True)
-        self.searchbar.register_extra_query_callback(self._get_extra_query)
-        self.searchbar.set_result_strings(_('order'), _('orders'))
-        self.searchbar.set_searchbar_labels(_('Orders Maching:'))
-        self.searchbar.connect('before-search-activate',
-                               self.on_searchbar_before_activate)
-        self.searchbar.connect('search-activate', self.on_searchbar_activate)
-        self.attach_slave('searchbar_holder', self.searchbar)
-        self.searchbar.set_focus()
+        self._create_search()
 
     #
     # Kiwi callbacks
     #
 
-    def on_orders__row_activated(self, klist, purchase_order_view):
-        run_dialog(PurchaseDetailsDialog, self, self.conn,
-                   model=purchase_order_view.purchase)
+#     def on_searchbar_activate(self, slave, objs):
+#         """Use this callback with SearchBar search-activate signal"""
+#         self.results.add_list(objs, clear=True)
+#         has_selection = self.results.get_selected() is not None
+#         self.wizard.refresh_next(has_selection)
 
-    def on_orders__selection_changed(self, *args):
+    def _on_results__selection_changed(self, results, purchase_order_view):
         self.force_validation()
         self._update_view()
 
+    def _on_results__row_activated(self, results, purchase_order_view):
+        run_dialog(PurchaseDetailsDialog, self, self.conn,
+                   model=purchase_order_view.purchase)
+
     def on_details_button__clicked(self, *args):
-        selected = self.orders.get_selected()
+        selected = self.search.results.get_selected()
         if not selected:
             raise ValueError('You should have one order selected '
                              'at this point, got nothing')


More information about the POS-commit mailing list