Switch to side-by-side view

--- a
+++ b/src/desktop/unity-lens-recoll/recollscope/rclsearch.py
@@ -0,0 +1,158 @@
+
+import sys
+from gi.repository import GLib, GObject, Gio
+from gi.repository import Dee
+from gi.repository import Unity
+
+import recoll
+
+# These category ids must match the order in which we add them to the lens
+CATEGORY_ALL = 0
+
+# typing timeout: we don't want to start a search for every
+# char? Unity does batch on its side, but we may want more control ?
+# Or not ? I'm not sure this does any good on a moderate size index.
+# Set to 0 to not use it (default). Kept around because this still might be
+# useful with a very big index ?
+TYPING_TIMEOUT = 0
+
+class Scope (Unity.Scope):
+
+	def __init__ (self):
+		Unity.Scope.__init__ (self, dbus_path="/org/recoll/unitylensrecoll/scope/main")
+		
+		# Listen for changes and requests
+		self.connect ("notify::active-search", self._on_search_changed)
+		self.connect ("notify::active-global-search", self._on_global_search_changed)
+
+		# Bliss loaded the apps_tree menu here, let's connect to 
+                # the index
+                self.db = recoll.connect()
+
+                self.db.setAbstractParams(maxchars=200, 
+                                          contextwords=4)
+		
+                self.timeout_id = None
+
+	def get_search_string (self):
+		search = self.props.active_search
+		return search.props.search_string if search else None
+	
+	def get_global_search_string (self):
+		search = self.props.active_global_search
+		return search.props.search_string if search else None
+	
+	def search_finished (self):
+		search = self.props.active_search
+		if search:
+			search.emit("finished")
+	
+	def global_search_finished (self):
+		search = self.props.active_global_search
+		if search:
+			search.emit("finished")
+	def reset (self):
+		self._do_browse (self.props.results_model)
+		self._do_browse (self.props.global_results_model)
+	
+	def _on_search_changed (self, scope, param_spec):
+		search = self.get_search_string()
+		results = scope.props.results_model
+		
+#		print "Search changed to: '%s'" % search
+		
+		self._update_results_model (search, results)
+	
+	def _on_global_search_changed (self, scope, param_spec):
+		search = self.get_global_search_string()
+		results = scope.props.global_results_model
+		
+#		print "Global search changed to: '%s'" % search
+		
+		self._update_results_model (search, results)
+		
+	def _update_results_model (self, search_string, model):
+		if search_string:
+			self._do_search (search_string, model)
+		else:
+			self._do_browse (model)
+	
+	def _do_browse (self, model):
+                if self.timeout_id is not None:
+                        GObject.source_remove(self.timeout_id)
+		model.clear ()
+
+                if model is self.props.results_model:
+                        self.search_finished()
+                else:
+                        self.global_search_finished()
+
+        def _on_timeout(self, search_string, model):
+                if self.timeout_id is not None:
+                        GObject.source_remove(self.timeout_id)
+                self.timeout_id = None
+                self._really_do_search(search_string, model)
+                if model is self.props.results_model:
+                        self.search_finished()
+                else:
+                        self.global_search_finished()
+
+	def _do_search (self, search_string, model):
+                if TYPING_TIMEOUT == 0:
+                        self._really_do_search(search_string, model)
+                        return True
+                
+                if self.timeout_id is not None:
+                        GObject.source_remove(self.timeout_id)
+                self.timeout_id = \
+                    GObject.timeout_add(TYPING_TIMEOUT, self._on_timeout, 
+                                        search_string, model)
+
+        def _really_do_search(self, search_string, model):
+#                print "really_do_search:[", search_string, "]"
+
+                model.clear ()
+		if search_string == "":
+                        return True
+
+                # Do the recoll thing
+                query = self.db.query()
+                try:
+                        nres = query.execute(search_string)
+                except:
+                        return
+
+                actual_results = 0
+                while query.next >= 0 and query.next < nres: 
+                        try:
+                                doc = query.fetchone()
+                        except:
+                                break
+
+                        # No sense in returning unusable results (until
+                        # I get an idea of what to do with them)
+                        if doc.ipath != "":
+                                continue
+
+                        titleorfilename = doc.title
+                        if titleorfilename == "":
+                                titleorfilename = doc.filename
+
+                        icon = Gio.content_type_get_icon(doc.mimetype)
+                        if icon:
+                                iconname = icon.get_names()[0]
+
+                        abstract = self.db.makeDocAbstract(doc, query).encode('utf-8')
+
+			model.append (doc.url,
+                                      iconname,
+			              CATEGORY_ALL,
+			              doc.mimetype,
+			              titleorfilename,
+			              abstract,
+			              doc.url)
+
+                        actual_results += 1
+                        if actual_results >= 20:
+                                break
+