[tracker/needle: 1/33] tracker-needle: Initial Needle app
- From: Martyn James Russell <mr src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/needle: 1/33] tracker-needle: Initial Needle app
- Date: Thu, 2 Sep 2010 16:55:36 +0000 (UTC)
commit 32099b220272a291ba238d19bdd76173d58ce9b3
Author: Martyn Russell <martyn lanedo com>
Date: Sat May 29 00:24:16 2010 +0100
tracker-needle: Initial Needle app
configure.ac | 1 +
src/Makefile.am | 1 +
src/needle/Makefile.am | 42 +++++++
src/needle/needle.ui | 173 +++++++++++++++++++++++++++++
src/needle/needle.vala | 281 ++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 498 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 83b4666..b59e838 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1921,6 +1921,7 @@ AC_CONFIG_FILES([
src/tracker-search-tool/Makefile
src/tracker-search-tool/tracker-search-tool.desktop.in
src/tracker-explorer/Makefile
+ src/needle/Makefile
src/tracker-utils/Makefile
src/tracker-writeback/Makefile
src/plugins/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 640e0ec..cba6a7f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -27,6 +27,7 @@ SUBDIRS = \
tracker-utils \
tracker-extract \
tracker-writeback \
+ needle \
vapi
if HAVE_TRACKER_PREFERENCES
diff --git a/src/needle/Makefile.am b/src/needle/Makefile.am
new file mode 100644
index 0000000..6e45acc
--- /dev/null
+++ b/src/needle/Makefile.am
@@ -0,0 +1,42 @@
+include $(top_srcdir)/Makefile.decl
+
+bin_PROGRAMS = needle
+
+needle_VALASOURCES = \
+ needle.vala
+
+needle_SOURCES = \
+ $(needle_VALASOURCES:.vala=.c)
+
+needle.vala.stamp: $(needle_VALASOURCES)
+ $(VALAC) -C -g --pkg dbus-glib-1 --pkg gtk+-2.0 $^
+ touch needle.vala.stamp
+
+needle_CFLAGS = \
+ -DTRACKER_UI_DIR=\"$(datadir)/tracker/\" \
+ -DSRCDIR=\"$(abs_srcdir)/\" \
+ $(TRACKER_APPS_CFLAGS) \
+ $(TRACKER_VALA_CFLAGS) \
+ $(WARN_CFLAGS) \
+ $(GCOV_CFLAGS)
+
+needle_LDADD = \
+ $(TRACKER_APPS_LIBS) \
+ $(TRACKER_VALA_LIBS) \
+ $(GCOV_LIBS)
+
+uidir = $(datadir)/tracker
+ui_DATA = needle.ui
+
+EXTRA_DIST = \
+ $(needle_VALASOURCES) \
+ $(ui_DATA) \
+ needle.vala.stamp
+
+MAINTAINERCLEANFILES = \
+ needle.vala.stamp \
+ $(needle_VALASOURCES:.vala=.c)
+
+BUILT_SOURCES = \
+ needle.vala.stamp
+
diff --git a/src/needle/needle.ui b/src/needle/needle.ui
new file mode 100644
index 0000000..0646634
--- /dev/null
+++ b/src/needle/needle.ui
@@ -0,0 +1,173 @@
+<?xml version="1.0"?>
+<interface>
+ <!-- interface-requires gtk+ 2.12 -->
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkListStore" id="liststore_results"/>
+ <object class="GtkWindow" id="window_needle">
+ <property name="title" translatable="yes">Needle</property>
+ <property name="default_width">640</property>
+ <property name="default_height">480</property>
+ <child>
+ <object class="GtkVBox" id="vbox_main">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkToolbar" id="toolbar_main">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkToolButton" id="toolbutton_back">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">toolbutton1</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-go-back</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="toolbutton_forward">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">toolbutton1</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-go-forward</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparatorToolItem" id="toolbutton1">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioToolButton" id="toolbutton_view_list">
+ <property name="visible">True</property>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">_List</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="group">toolbutton_view_icons</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioToolButton" id="toolbutton_view_icons">
+ <property name="visible">True</property>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">_Icons</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparatorToolItem" id="toolbutton2">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolItem" id="toolbutton_search_label">
+ <property name="visible">True</property>
+ <property name="is_important">True</property>
+ <child>
+ <object class="GtkLabel" id="label_search">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Search:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry_search</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolItem" id="toolbutton_search_entry">
+ <property name="visible">True</property>
+ <property name="is_important">True</property>
+ <child>
+ <object class="GtkEntry" id="entry_search">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox_view">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow_treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+ <object class="GtkTreeView" id="treeview_results">
+ <property name="can_focus">True</property>
+ <property name="model">liststore_results</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow_iconview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+ <object class="GtkIconView" id="iconview_results">
+ <property name="can_focus">True</property>
+ <property name="model">liststore_results</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/src/needle/needle.vala b/src/needle/needle.vala
new file mode 100644
index 0000000..317083c
--- /dev/null
+++ b/src/needle/needle.vala
@@ -0,0 +1,281 @@
+//
+// Copyright 2010, Martyn Russell <martyn lanedo com>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+//
+
+using Gtk;
+
+[CCode (cname = "TRACKER_UI_DIR")]
+extern static const string UIDIR;
+
+[CCode (cname = "SRCDIR")]
+extern static const string SRCDIR;
+
+[DBus (name = "org.freedesktop.Tracker1.Resources")]
+interface Resources : GLib.Object {
+ public abstract string[,] SparqlQuery (string query) throws DBus.Error;
+}
+
+public class Needle {
+ private const string UI_FILE = "needle.ui";
+ private Resources tracker;
+ private Window window;
+ private ToolButton back;
+ private ToolButton forward;
+ private ToolButton view_list;
+ private ToolButton view_icons;
+ private Entry search;
+ private ScrolledWindow sw_treeview;
+ private TreeView treeview;
+ private ScrolledWindow sw_iconview;
+ private IconView iconview;
+ private uint last_search_id = 0;
+ private ListStore store;
+
+ public void show () {
+ setup_dbus ();
+ setup_ui ();
+
+ window.show ();
+ }
+
+ private void setup_dbus () {
+ try {
+ var conn = DBus.Bus.get (DBus.BusType.SESSION);
+ tracker = (Resources) conn.get_object ("org.freedesktop.Tracker1",
+ "/org/freedesktop/Tracker1/Resources",
+ "org.freedesktop.Tracker1.Resources");
+ } catch (DBus.Error e) {
+ var msg = new MessageDialog (null,
+ DialogFlags.MODAL,
+ MessageType.ERROR,
+ ButtonsType.CANCEL,
+ "Error connecting to D-Bus session bus, %s",
+ e.message);
+ msg.run ();
+ Gtk.main_quit ();
+ }
+ }
+
+ private void setup_ui () {
+ var builder = new Builder ();
+
+ try {
+ //try load from source tree first.
+ builder.add_from_file (SRCDIR + UI_FILE);
+ } catch (GLib.Error e) {
+ //now the install location
+ try {
+ builder.add_from_file (UIDIR + UI_FILE);
+ } catch (GLib.Error e) {
+ var msg = new MessageDialog (null,
+ DialogFlags.MODAL,
+ MessageType.ERROR,
+ ButtonsType.CANCEL,
+ "Failed to load UI file, %s\n",
+ e.message);
+ msg.run ();
+ Gtk.main_quit();
+ }
+ }
+
+ window = builder.get_object ("window_needle") as Window;
+ window.destroy += Gtk.main_quit;
+
+ back = builder.get_object ("toolbutton_back") as ToolButton;
+ back.clicked += back_clicked;
+ back.set_sensitive(false);
+
+ forward = builder.get_object ("toolbutton_forward") as ToolButton;
+ forward.clicked += forward_clicked;
+ forward.set_sensitive(false);
+
+ view_list = builder.get_object ("toolbutton_view_list") as ToolButton;
+ view_list.clicked += view_list_clicked;
+
+ // The default
+ view_icons = builder.get_object ("toolbutton_view_icons") as ToolButton;
+ view_icons.clicked += view_icons_clicked;
+
+ search = builder.get_object ("entry_search") as Entry;
+ search.changed += search_changed;
+
+ sw_treeview = builder.get_object ("scrolledwindow_treeview") as ScrolledWindow;
+ treeview = builder.get_object ("treeview_results") as TreeView;
+ sw_iconview = builder.get_object ("scrolledwindow_iconview") as ScrolledWindow;
+ iconview = builder.get_object ("iconview_results") as IconView;
+ setup_ui_results (treeview, iconview);
+
+ sw_iconview.show_all ();
+ sw_treeview.hide ();
+ }
+
+ private void setup_ui_results (TreeView treeview, IconView iconview) {
+ // Setup treeview
+ store = new ListStore (5,
+ typeof (Gdk.Pixbuf), // Icon
+ typeof (string), // URN
+ typeof (string), // URL
+ typeof (string), // Filename
+ typeof (string)); // Description
+ treeview.set_model (store);
+
+ // view.insert_column_with_attributes (-1, "URN", new CellRendererText (), "text", 0, null);
+ treeview.insert_column_with_attributes (-1, "", new CellRendererPixbuf (), "pixbuf", 0, null);
+ treeview.insert_column_with_attributes (-1, "Filename", new CellRendererText (), "text", 3, null);
+ treeview.row_activated += view_row_selected;
+
+ // Setup iconview
+ iconview.set_model (store);
+ iconview.set_item_width (96);
+ iconview.set_selection_mode (Gtk.SelectionMode.SINGLE);
+ iconview.set_pixbuf_column (0);
+ iconview.set_text_column (3);
+ //iconview.row_activated += view_row_selected;
+ }
+
+ private void search_changed (Entry entry) {
+ if (last_search_id != 0) {
+ Source.remove (last_search_id);
+ }
+
+ last_search_id = Timeout.add_seconds (1, search_run);
+ }
+
+ private bool search_run () {
+ // Need to escape this string
+ string query;
+
+ query = "SELECT ?u nie:url(?u) nfo:fileName(?u) tracker:coalesce(nie:title(?u), \"Unknown\") WHERE { ?u fts:match \"%s\" } ORDER BY DESC(fts:rank(?u)) OFFSET 0 LIMIT 100".printf ((search).text);
+ debug ("Query:'%s'", query);
+
+ try {
+ var result = tracker.SparqlQuery (query);
+
+ store.clear ();
+
+ var screen = window.get_screen ();
+ var theme = IconTheme.get_for_screen (screen);
+
+ for (int i = 0; i < result.length[0]; i++) {
+ debug ("--> %s", result[i,0]);
+ debug (" --> %s", result[i,1]);
+ debug (" --> %s", result[i,2]);
+
+ // Get Icon
+ var file = File.new_for_uri (result[i,1]);
+ var pixbuf = null as Gdk.Pixbuf;
+
+ if (file.query_exists (null)) {
+ try {
+ var file_info = file.query_info ("standard::icon",
+ FileQueryInfoFlags.NONE,
+ null);
+
+ if (file_info != null) {
+ var icon = file_info.get_icon ();
+
+ if (icon != null) {
+ //var names = ((ThemedIcon) icon).get_names ();
+
+ // See bug #618574
+ // var icon_info = theme.choose_icon (names, 48, IconLookupFlags.USE_BUILTIN);
+
+ // if (icon_info != null) {
+ // try {
+ // pixbuf = icon_info.load_icon ();
+ // } catch (GLib.Error e) {
+ // Do something
+ // }
+ // }
+ }
+ }
+ } catch (GLib.Error e) {
+ // Do something
+ }
+ }
+
+ if (pixbuf == null) {
+ try {
+ // pixbuf = theme.load_icon (theme.get_example_icon_name (), 48, IconLookupFlags.USE_BUILTIN);
+ pixbuf = theme.load_icon ("text-x-generic", 48, IconLookupFlags.USE_BUILTIN);
+ } catch (GLib.Error e) {
+ // Do something
+ }
+ }
+
+ // Insert into model
+ TreeIter iter;
+
+ store.append (out iter);
+ store.set (iter,
+ 0, pixbuf,
+ 1, result[i,0],
+ 2, result[i,1],
+ 3, result[i,2],
+ -1);
+ }
+ } catch (DBus.Error e) {
+ // Do nothing
+ }
+
+ last_search_id = 0;
+
+ return false;
+ }
+
+ private void forward_clicked () {
+ // Do nothing
+ }
+
+ private void back_clicked () {
+ // Do nothing
+ }
+
+ private void view_list_clicked () {
+ sw_iconview.hide ();
+ sw_treeview.show_all ();
+ }
+
+ private void view_icons_clicked () {
+ sw_iconview.show_all ();
+ sw_treeview.hide ();
+ }
+
+ private void view_row_selected (TreeView view, TreePath path, TreeViewColumn column) {
+ TreeIter iter;
+
+ var model = view.get_model ();
+ model.get_iter (out iter, path);
+
+ weak string filename;
+ model.get (iter, 1, out filename);
+
+ debug ("Selected filename:'%s'", filename);
+ }
+}
+
+static int main (string[] args) {
+ Gtk.init (ref args);
+
+ Needle n = new Needle();
+ n.show();
+ Gtk.main ();
+
+ return 0;
+}
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]