[tracker/tracker-needle-model-rewrite] WIP



commit e579c382fb35fd57d4ddf000fe2f6c263b2e8e0e
Author: Martyn Russell <martyn lanedo com>
Date:   Tue Feb 22 13:38:16 2011 +0900

    WIP

 src/tracker-needle/tracker-needle.vala |  133 ++++++++++++++++----------------
 src/tracker-needle/tracker-query.vala  |   44 +++++++++++
 src/tracker-needle/tracker-view.vala   |  100 +++++++++++++++++++++++-
 3 files changed, 207 insertions(+), 70 deletions(-)
---
diff --git a/src/tracker-needle/tracker-needle.vala b/src/tracker-needle/tracker-needle.vala
index 0f8f54f..e86d21c 100644
--- a/src/tracker-needle/tracker-needle.vala
+++ b/src/tracker-needle/tracker-needle.vala
@@ -51,7 +51,6 @@ public class Tracker.Needle {
 	private int size_small = 0;
 	private int size_medium = 0;
 	private int size_big = 0;
-	static bool current_view = true;
 	static bool current_find_in = true;
 
 	public Needle () {
@@ -184,16 +183,26 @@ public class Tracker.Needle {
 		return false;
 	}
 
-	private ListStore? get_store_for_active_view () {
+	private Widget? get_active_view () {
 		if (view_icons.active) {
-			return sw_icons.store;
+			return sw_icons;
 		} else if (view_filelist.active) {
-			return sw_filelist.store;
+			return sw_filelist;
 		} else if (view_categories.active) {
-			return sw_categories.store;
+			return sw_categories;
+		}
+
+		debug ("No views active?!?!");
+		return null;
+	}
+
+	private ListStore? get_active_view_store () {
+		Widget view = get_active_view ();
+
+		if (view) {
+			return view.store;
 		}
 
-		debug ("No views active to get store?!?!");
 		return null;
 	}
 
@@ -205,81 +214,69 @@ public class Tracker.Needle {
 		last_search_id = Timeout.add_seconds (1, search_run);
 	}
 
-	private async void search_simple (ListStore store) requires (store != null) {
+	private async void search_simple (Widget view)
+	requires (view != null) {
 		Tracker.Query query = new Tracker.Query ();
 		Tracker.Sparql.Cursor cursor = null;
 
+		if (find_in_contents.active) {
+			query.type = Tracker.Query.Type.ALL;
+		} else {
+			query.type = Tracker.Query.Type.ALL_ONLY_IN_TITLES;
+		}
+		
 		query.limit = 1000;
 		query.criteria = search.get_text ();
 
+		view.query = query;
+
 		debug ("Doing simple search using store:%p", store);
 
 		try {
-			if (find_in_contents.active) {
-				cursor = yield query.perform_async (query.Type.ALL);
-			} else {
-				cursor = yield query.perform_async (query.Type.ALL_ONLY_IN_TITLES);
-			}
+			cursor = yield query.count_async (query.type);
 
 			if (cursor == null) {
 				search_finished (store);
 				return;
 			}
 
-			store.clear ();
+			view.store.clear ();
 
-			var screen = window.get_screen ();
-			var theme = IconTheme.get_for_screen (screen);
+			int64 count = 0;
+			bool success = yield cursor.next_async ();
 
-			while (true) {
-				bool b = yield cursor.next_async ();
-				if (!b) {
-					break;
-				}
+			if (!success) {
+				search_finished (store);
+				return;
+			}
 
-				for (int i = 0; i < cursor.n_columns; i++) {
-					if (i == 0) {
-						debug ("--> %s", cursor.get_string (i));
-					} else {
-						debug ("  --> %s", cursor.get_string (i));
-					}
-				}
+			count = cursor.get_integer (0);
+			debug ("--> %lld", count);
+
+			var screen = window.get_screen ();
+			var theme = IconTheme.get_for_screen (screen);
+			var default_image = tracker_pixbuf_new_from_name (theme, "text-x-generic", size_small);
 
-				// Get icon
-				string urn = cursor.get_string (0);
-				string _file = cursor.get_string (1);
-				string title = cursor.get_string (2);
-				string _file_time = cursor.get_string (3);
-				string _file_size = cursor.get_string (4);
-				string tooltip = cursor.get_string (7);
-				Gdk.Pixbuf pixbuf_small = tracker_pixbuf_new_from_file (theme, _file, size_small, false);
-				Gdk.Pixbuf pixbuf_big = tracker_pixbuf_new_from_file (theme, _file, size_big, false);
-				string file_size = GLib.format_size_for_display (_file_size.to_int());
-				string file_time = tracker_time_format_from_iso8601 (_file_time);
-
-				// Insert into model
+			// Populate shell entries here and populate on expose to avoid
+			// load times being too long with many items
+			for (int i = 0; i < count; i++) {
 				TreeIter iter;
 
-				// FIXME: should optimise this a bit more, inserting 2 images into a list eek
-				store.append (out iter);
-				store.set (iter,
-					       0, pixbuf_small, // Small Image
-					       1, pixbuf_big,   // Large Image
-					       2, urn,          // URN
-					       3, _file,        // URL
-					       4, title,        // Title
-					       5, null,         // Subtitle
-					       6, file_time,    // Column2: Time
-					       7, file_size,    // Column3: Size
-					       8, tooltip,      // Tooltip
-					       -1);
+				view.store.append (out iter);
+				view.store.set (iter,
+				                0, default_image,// Small Image
+				                1, null,         // Large Image
+				                2, null,         // URN
+				                3, null,         // URL
+				                4, "...",        // Title
+				                5, null,         // Subtitle
+				                6, null,         // Column2: Time
+				                7, null,         // Column3: Size
+				                8, _("Loading"), // Tooltip
+				                -1);
 			}
-		} catch (GLib.Error e) {
-			warning ("Could not iterate query results: %s", e.message);
-			search_finished (store);
-			return;
-		}
 
+		// FIXME: hookup from outside too in view
 		search_finished (store);
 	}
 
@@ -308,8 +305,10 @@ public class Tracker.Needle {
 
 			Tracker.Sparql.Cursor cursor;
 
-			query.limit = 1000;
 			query.criteria = search.get_text ();
+			
+//			query.limit = 1000;
+
 
 			try {
 				cursor = yield query.perform_async (type);
@@ -495,9 +494,15 @@ public class Tracker.Needle {
 	private bool search_run () {
 		last_search_id = 0;
 
+		Widget view = get_active_view ();
+		
+		if (view == null) {
+			return false;
+		}
+
 		string str = search.get_text ();
 		string criteria = str.strip ();
-		ListStore store = get_store_for_active_view ();
+		ListStore store = view.store ();
 
 		if (criteria.length < 1) {
 			if (store != null) {
@@ -539,7 +544,7 @@ public class Tracker.Needle {
 		if (view_categories.active) {
 			search_detailed (store);
 		} else {
-			search_simple (store);
+			search_simple (view);
 		}
 
 		return false;
@@ -568,11 +573,11 @@ public class Tracker.Needle {
 		find_in_titles.visible = show_find_in;
 
 		search_run ();
-		//current_view = rows;
 	}
 
 	private void find_in_toggled () {
-		if (current_find_in == find_in_contents.active) {
+		if (!find_in_contents.active &&
+			!find_in_titles.active) {
 			return;
 		}
 
@@ -583,8 +588,6 @@ public class Tracker.Needle {
 			debug ("Find in toggled to 'titles'");
 			search_run ();
 		}
-
-		current_find_in = find_in_contents.active;
 	}
 
 	private void launch_selected (TreeModel model, TreePath path, int col) {
diff --git a/src/tracker-needle/tracker-query.vala b/src/tracker-needle/tracker-query.vala
index 87c7fd8..c2f1501 100644
--- a/src/tracker-needle/tracker-query.vala
+++ b/src/tracker-needle/tracker-query.vala
@@ -53,6 +53,50 @@ public class Tracker.Query {
 		}
 	}
 
+	public async Sparql.Cursor? count_async (Type query_type, Cancellable? cancellable = null) throws IOError
+	requires (connection != null) {
+		Sparql.Cursor cursor = null;
+
+		if (criteria == null || criteria.length < 1) {
+			warning ("Criteria was NULL or an empty string, no query performed");
+			return null;
+		}
+
+		if (limit < 1) {
+			warning ("Limit was < 1, no query performed");
+			return null;
+		}
+
+		string criteria_escaped = Tracker.Sparql.escape_string (criteria);
+
+		switch (query_type) {
+		case Type.ALL:
+			query = @"SELECT COUNT(?u) WHERE { ?u fts:match \"$criteria_escaped\" . ?u nfo:belongsToContainer ?c ; tracker:available true . } OFFSET $offset LIMIT $limit";
+			break;
+			
+		case Type.ALL_ONLY_IN_TITLES:
+			query = @"SELECT COUNT(?u) WHERE { ?u a nfo:FileDataObject ; nfo:belongsToContainer ?c ; tracker:available true . FILTER(fn:contains(nfo:fileName(?u), \"$criteria_escaped\")) } OFFSET $offset LIMIT $limit";
+			break;
+		}
+
+		debug ("Running query: '%s'", query);
+
+		try {
+			cursor = yield connection.query_async (query, null);
+		} catch (Sparql.Error ea) {
+			warning ("Could not run Sparql query: %s", ea.message);
+		} catch (GLib.IOError eb) {
+			warning ("Could not run Sparql query: %s", eb.message);
+		} catch (GLib.DBusError ec) {
+			warning ("Could not run Sparql query: %s", ec.message);
+		}
+
+		debug ("Done");
+
+		return cursor;
+
+	}
+
 	public async Sparql.Cursor? perform_async (Type query_type, Cancellable? cancellable = null) throws IOError
 	requires (connection != null) {
 		Sparql.Cursor cursor = null;
diff --git a/src/tracker-needle/tracker-view.vala b/src/tracker-needle/tracker-view.vala
index 814285d..c06ef37 100644
--- a/src/tracker-needle/tracker-view.vala
+++ b/src/tracker-needle/tracker-view.vala
@@ -32,11 +32,22 @@ public class Tracker.View : ScrolledWindow {
 		private set;
 	}
 
+	public Query.Type query_type {
+		get; set;
+	}
+
 	public ListStore store {
 		get;
 		private set;
 	}
 
+	public Tracker.View view {
+		get; set;
+	}
+
+	// So we have 1 cursor per range of results 1->50
+	private Tracker.Sparql.Cursor[] cursors = null;
+
 	private Widget view = null;
 
 	public View (Display? _display = Display.NO_RESULTS, ListStore? _store) {
@@ -44,9 +55,11 @@ public class Tracker.View : ScrolledWindow {
 
 		display = _display;
 
+		// Default to this
+		find = Find.IN_TITLES;
+
 		if (_store != null) {
 			store = _store;
-			debug ("using store:%p", store);
 		} else {
 			// Setup treeview
 			store = new ListStore (10,
@@ -60,7 +73,6 @@ public class Tracker.View : ScrolledWindow {
 			                       typeof (string),      // Column 3
 			                       typeof (string),      // Tooltip
 			                       typeof (bool));       // Category hint
-			debug ("Creating store:%p", store);
 		}
 
 		switch (display) {
@@ -98,6 +110,10 @@ public class Tracker.View : ScrolledWindow {
 		base.show_all ();
 	}
 
+	public ~View() {
+		// FIXME: clean up array of cursors
+	}
+
 	private void setup_model () {
 		switch (display) {
 		case Display.FILE_ICONS: {
@@ -217,15 +233,89 @@ public class Tracker.View : ScrolledWindow {
 		}
 	}
 
+	private void get_cursor_for_index (int index)
+	requires (index >= 0) {
+		// So index is the real index in the list.
+		try {
+			cursor = yield query.perform_async (query_type);
+
+			if (cursor == null) {
+				search_finished (store);
+				return;
+			}
+
+			while (true) {
+				success = yield cursor.next_async ();
+				if (!success) {
+					break;
+				}
+			}
+
+			// Debugging
+//			for (int i = 0; i < cursor.n_columns; i++) {
+//				if (i == 0) {
+//					debug ("--> %s", cursor.get_string (i));
+//				} else {
+//					debug ("  --> %s", cursor.get_string (i));
+//				}
+//			}
+
+			debug ("--> %s", cursor.get_string (1));
+
+//				string urn = cursor.get_string (0);
+//				string _file = cursor.get_string (1);
+//				string title = cursor.get_string (2);
+//				string _file_time = cursor.get_string (3);
+//				string _file_size = cursor.get_string (4);
+//				string tooltip = cursor.get_string (7);
+//				Gdk.Pixbuf pixbuf_small = tracker_pixbuf_new_from_file (theme, _file, size_small, false);
+//				Gdk.Pixbuf pixbuf_big = tracker_pixbuf_new_from_file (theme, _file, size_big, false);
+//				string file_size = GLib.format_size_for_display (_file_size.to_int());
+//				string file_time = tracker_time_format_from_iso8601 (_file_time);
+
+				// FIXME: should optimise this a bit more, inserting 2 images into a list eek
+//				store.append (out iter);
+//				store.set (iter,
+//					       0, pixbuf_small, // Small Image
+//					       1, pixbuf_big,   // Large Image
+//					       2, urn,          // URN
+//					       3, _file,        // URL
+//					       4, title,        // Title
+//					       5, null,         // Subtitle
+//					       6, file_time,    // Column2: Time
+//					       7, file_size,    // Column3: Size
+//					       8, tooltip,      // Tooltip
+//					       -1);
+
+		} catch (GLib.Error e) {
+			warning ("Could not iterate query results: %s", e.message);
+			search_finished (store);
+			return;
+		}
+	}
+
+	private void get_details () {
+	}
+
 	private void cell_renderer_func (CellLayout   cell_layout,
 	                                 CellRenderer cell,
 	                                 TreeModel    tree_model,
 	                                 TreeIter     iter) {
 		Gdk.Color color;
 		Style style;
-		bool show_row_hint;
-
-		tree_model.get (iter, 9, out show_row_hint, -1);
+		string title = null;
+		bool show_row_hint = false;
+
+		tree_model.get (iter,
+		                4, out title,
+		                9, out show_row_hint,
+		                -1);
+
+		if (title == "...") {
+			TreePath path = tree_model.get_path (iter);
+			int index = path.get_indices ()[0];
+			debug ("expose for item %d", index);
+		}
 
 		style = view.get_style ();
 



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