4435 lines
132 KiB
Diff
4435 lines
132 KiB
Diff
|
--- /dev/null 2007-01-16 08:16:47.736226048 -0500
|
|||
|
+++ gtk+-2.10.8/gtk/gtksearchenginetracker.h 2007-01-17 01:21:08.000000000 -0500
|
|||
|
@@ -0,0 +1,59 @@
|
|||
|
+/*
|
|||
|
+ * Copyright (C) 2005 Mr Jamie McCracken
|
|||
|
+ *
|
|||
|
+ * This library is free software; you can redistribute it and/or
|
|||
|
+ * modify it under the terms of the GNU Lesser General Public
|
|||
|
+ * License as published by the Free Software Foundation; either
|
|||
|
+ * version 2 of the License, or (at your option) any later version.
|
|||
|
+ *
|
|||
|
+ * This library 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
|
|||
|
+ * Lesser General Public License for more details.
|
|||
|
+ *
|
|||
|
+ * You should have received a copy of the GNU Lesser General Public
|
|||
|
+ * License along with this library; if not, write to the
|
|||
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|||
|
+ *
|
|||
|
+ * Author: Jamie McCracken (jamiemcc@gnome.org)
|
|||
|
+ *
|
|||
|
+ * Based on nautilus-search-engine-tracker.h
|
|||
|
+ */
|
|||
|
+
|
|||
|
+#ifndef __GTK_SEARCH_ENGINE_TRACKER_H__
|
|||
|
+#define __GTK_SEARCH_ENGINE_TRACKER_H__
|
|||
|
+
|
|||
|
+#include "gtksearchengine.h"
|
|||
|
+
|
|||
|
+G_BEGIN_DECLS
|
|||
|
+
|
|||
|
+#define GTK_TYPE_SEARCH_ENGINE_TRACKER (_gtk_search_engine_tracker_get_type ())
|
|||
|
+#define GTK_SEARCH_ENGINE_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SEARCH_ENGINE_TRACKER, GtkSearchEngineTracker))
|
|||
|
+#define GTK_SEARCH_ENGINE_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SEARCH_ENGINE_TRACKER, GtkSearchEngineTrackerClass))
|
|||
|
+#define GTK_IS_SEARCH_ENGINE_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SEARCH_ENGINE_TRACKER))
|
|||
|
+#define GTK_IS_SEARCH_ENGINE_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SEARCH_ENGINE_TRACKER))
|
|||
|
+#define GTK_SEARCH_ENGINE_TRACKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SEARCH_ENGINE_TRACKER, GtkSearchEngineTrackerClass))
|
|||
|
+
|
|||
|
+typedef struct _GtkSearchEngineTracker GtkSearchEngineTracker;
|
|||
|
+typedef struct _GtkSearchEngineTrackerClass GtkSearchEngineTrackerClass;
|
|||
|
+typedef struct _GtkSearchEngineTrackerPrivate GtkSearchEngineTrackerPrivate;
|
|||
|
+
|
|||
|
+struct _GtkSearchEngineTracker
|
|||
|
+{
|
|||
|
+ GtkSearchEngine parent;
|
|||
|
+
|
|||
|
+ GtkSearchEngineTrackerPrivate *priv;
|
|||
|
+};
|
|||
|
+
|
|||
|
+struct _GtkSearchEngineTrackerClass
|
|||
|
+{
|
|||
|
+ GtkSearchEngineClass parent_class;
|
|||
|
+};
|
|||
|
+
|
|||
|
+GType _gtk_search_engine_tracker_get_type (void);
|
|||
|
+
|
|||
|
+GtkSearchEngine* _gtk_search_engine_tracker_new (void);
|
|||
|
+
|
|||
|
+G_END_DECLS
|
|||
|
+
|
|||
|
+#endif /* __GTK_SEARCH_ENGINE_TRACKER_H__ */
|
|||
|
--- /dev/null 2007-01-16 08:16:47.736226048 -0500
|
|||
|
+++ gtk+-2.10.8/gtk/gtksearchengine.h 2007-01-17 01:21:08.000000000 -0500
|
|||
|
@@ -0,0 +1,91 @@
|
|||
|
+/*
|
|||
|
+ * Copyright (C) 2005 Novell, Inc.
|
|||
|
+ *
|
|||
|
+ * This library is free software; you can redistribute it and/or
|
|||
|
+ * modify it under the terms of the GNU Lesser General Public
|
|||
|
+ * License as published by the Free Software Foundation; either
|
|||
|
+ * version 2 of the License, or (at your option) any later version.
|
|||
|
+ *
|
|||
|
+ * This library 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
|
|||
|
+ * Lesser General Public License for more details.
|
|||
|
+ *
|
|||
|
+ * You should have received a copy of the GNU Lesser General Public
|
|||
|
+ * License along with this library; if not, write to the
|
|||
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|||
|
+ *
|
|||
|
+ * Author: Anders Carlsson <andersca@imendio.com>
|
|||
|
+ *
|
|||
|
+ * Based on nautilus-search-engine.h
|
|||
|
+ */
|
|||
|
+
|
|||
|
+#ifndef __GTK_SEARCH_ENGINE_H__
|
|||
|
+#define __GTK_SEARCH_ENGINE_H__
|
|||
|
+
|
|||
|
+#include <glib-object.h>
|
|||
|
+#include "gtkquery.h"
|
|||
|
+
|
|||
|
+G_BEGIN_DECLS
|
|||
|
+
|
|||
|
+#define GTK_TYPE_SEARCH_ENGINE (_gtk_search_engine_get_type ())
|
|||
|
+#define GTK_SEARCH_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SEARCH_ENGINE, GtkSearchEngine))
|
|||
|
+#define GTK_SEARCH_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SEARCH_ENGINE, GtkSearchEngineClass))
|
|||
|
+#define GTK_IS_SEARCH_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SEARCH_ENGINE))
|
|||
|
+#define GTK_IS_SEARCH_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SEARCH_ENGINE))
|
|||
|
+#define GTK_SEARCH_ENGINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SEARCH_ENGINE, GtkSearchEngineClass))
|
|||
|
+
|
|||
|
+typedef struct _GtkSearchEngine GtkSearchEngine;
|
|||
|
+typedef struct _GtkSearchEngineClass GtkSearchEngineClass;
|
|||
|
+typedef struct _GtkSearchEnginePrivate GtkSearchEnginePrivate;
|
|||
|
+
|
|||
|
+struct _GtkSearchEngine
|
|||
|
+{
|
|||
|
+ GObject parent;
|
|||
|
+
|
|||
|
+ GtkSearchEnginePrivate *priv;
|
|||
|
+};
|
|||
|
+
|
|||
|
+struct _GtkSearchEngineClass
|
|||
|
+{
|
|||
|
+ GObjectClass parent_class;
|
|||
|
+
|
|||
|
+ /* VTable */
|
|||
|
+ void (*set_query) (GtkSearchEngine *engine,
|
|||
|
+ GtkQuery *query);
|
|||
|
+ void (*start) (GtkSearchEngine *engine);
|
|||
|
+ void (*stop) (GtkSearchEngine *engine);
|
|||
|
+ gboolean (*is_indexed) (GtkSearchEngine *engine);
|
|||
|
+
|
|||
|
+ /* Signals */
|
|||
|
+ void (*hits_added) (GtkSearchEngine *engine,
|
|||
|
+ GList *hits);
|
|||
|
+ void (*hits_subtracted) (GtkSearchEngine *engine,
|
|||
|
+ GList *hits);
|
|||
|
+ void (*finished) (GtkSearchEngine *engine);
|
|||
|
+ void (*error) (GtkSearchEngine *engine,
|
|||
|
+ const gchar *error_message);
|
|||
|
+};
|
|||
|
+
|
|||
|
+GType _gtk_search_engine_get_type (void);
|
|||
|
+gboolean _gtk_search_engine_enabled (void);
|
|||
|
+
|
|||
|
+GtkSearchEngine* _gtk_search_engine_new (void);
|
|||
|
+
|
|||
|
+void _gtk_search_engine_set_query (GtkSearchEngine *engine,
|
|||
|
+ GtkQuery *query);
|
|||
|
+void _gtk_search_engine_start (GtkSearchEngine *engine);
|
|||
|
+void _gtk_search_engine_stop (GtkSearchEngine *engine);
|
|||
|
+gboolean _gtk_search_engine_is_indexed (GtkSearchEngine *engine);
|
|||
|
+
|
|||
|
+void _gtk_search_engine_hits_added (GtkSearchEngine *engine,
|
|||
|
+ GList *hits);
|
|||
|
+void _gtk_search_engine_hits_subtracted (GtkSearchEngine *engine,
|
|||
|
+ GList *hits);
|
|||
|
+void _gtk_search_engine_finished (GtkSearchEngine *engine);
|
|||
|
+void _gtk_search_engine_error (GtkSearchEngine *engine,
|
|||
|
+ const gchar *error_message);
|
|||
|
+
|
|||
|
+G_END_DECLS
|
|||
|
+
|
|||
|
+#endif /* __GTK_SEARCH_ENGINE_H__ */
|
|||
|
--- /dev/null 2007-01-16 08:16:47.736226048 -0500
|
|||
|
+++ gtk+-2.10.8/gtk/gtksearchenginebeagle.h 2007-01-17 01:21:08.000000000 -0500
|
|||
|
@@ -0,0 +1,59 @@
|
|||
|
+/*
|
|||
|
+ * Copyright (C) 2005 Novell, Inc.
|
|||
|
+ *
|
|||
|
+ * This library is free software; you can redistribute it and/or
|
|||
|
+ * modify it under the terms of the GNU Lesser General Public
|
|||
|
+ * License as published by the Free Software Foundation; either
|
|||
|
+ * version 2 of the License, or (at your option) any later version.
|
|||
|
+ *
|
|||
|
+ * This library 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
|
|||
|
+ * Lesser General Public License for more details.
|
|||
|
+ *
|
|||
|
+ * You should have received a copy of the GNU Lesser General Public
|
|||
|
+ * License along with this library; if not, write to the
|
|||
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|||
|
+ *
|
|||
|
+ * Author: Anders Carlsson <andersca@imendio.com>
|
|||
|
+ *
|
|||
|
+ * Based on nautilus-search-engine-beagle.h
|
|||
|
+ */
|
|||
|
+
|
|||
|
+#ifndef __GTK_SEARCH_ENGINE_BEAGLE_H__
|
|||
|
+#define __GTK_SEARCH_ENGINE_BEAGLE_H__
|
|||
|
+
|
|||
|
+#include "gtksearchengine.h"
|
|||
|
+
|
|||
|
+G_BEGIN_DECLS
|
|||
|
+
|
|||
|
+#define GTK_TYPE_SEARCH_ENGINE_BEAGLE (_gtk_search_engine_beagle_get_type ())
|
|||
|
+#define GTK_SEARCH_ENGINE_BEAGLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SEARCH_ENGINE_BEAGLE, GtkSearchEngineBeagle))
|
|||
|
+#define GTK_SEARCH_ENGINE_BEAGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SEARCH_ENGINE_BEAGLE, GtkSearchEngineBeagleClass))
|
|||
|
+#define GTK_IS_SEARCH_ENGINE_BEAGLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SEARCH_ENGINE_BEAGLE))
|
|||
|
+#define GTK_IS_SEARCH_ENGINE_BEAGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SEARCH_ENGINE_BEAGLE))
|
|||
|
+#define GTK_SEARCH_ENGINE_BEAGLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SEARCH_ENGINE_BEAGLE, GtkSearchEngineBeagleClass))
|
|||
|
+
|
|||
|
+typedef struct _GtkSearchEngineBeagle GtkSearchEngineBeagle;
|
|||
|
+typedef struct _GtkSearchEngineBeagleClass GtkSearchEngineBeagleClass;
|
|||
|
+typedef struct _GtkSearchEngineBeaglePrivate GtkSearchEngineBeaglePrivate;
|
|||
|
+
|
|||
|
+struct _GtkSearchEngineBeagle
|
|||
|
+{
|
|||
|
+ GtkSearchEngine parent;
|
|||
|
+
|
|||
|
+ GtkSearchEngineBeaglePrivate *priv;
|
|||
|
+};
|
|||
|
+
|
|||
|
+struct _GtkSearchEngineBeagleClass
|
|||
|
+{
|
|||
|
+ GtkSearchEngineClass parent_class;
|
|||
|
+};
|
|||
|
+
|
|||
|
+GType _gtk_search_engine_beagle_get_type (void);
|
|||
|
+
|
|||
|
+GtkSearchEngine* _gtk_search_engine_beagle_new (void);
|
|||
|
+
|
|||
|
+G_END_DECLS
|
|||
|
+
|
|||
|
+#endif /* __GTK_SEARCH_ENGINE_BEAGLE_H__ */
|
|||
|
--- /dev/null 2007-01-16 08:16:47.736226048 -0500
|
|||
|
+++ gtk+-2.10.8/gtk/gtksearchengine.c 2007-01-17 01:21:08.000000000 -0500
|
|||
|
@@ -0,0 +1,197 @@
|
|||
|
+/*
|
|||
|
+ * Copyright (C) 2005 Novell, Inc.
|
|||
|
+ *
|
|||
|
+ * This library is free software; you can redistribute it and/or
|
|||
|
+ * modify it under the terms of the GNU Lesser General Public
|
|||
|
+ * License as published by the Free Software Foundation; either
|
|||
|
+ * version 2 of the License, or (at your option) any later version.
|
|||
|
+ *
|
|||
|
+ * This library 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
|
|||
|
+ * Lesser General Public License for more details.
|
|||
|
+ *
|
|||
|
+ * You should have received a copy of the GNU Lesser General Public
|
|||
|
+ * License along with this library; if not, write to the
|
|||
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|||
|
+ *
|
|||
|
+ * Author: Anders Carlsson <andersca@imendio.com>
|
|||
|
+ *
|
|||
|
+ * Based on nautilus-search-engine.c
|
|||
|
+ */
|
|||
|
+
|
|||
|
+#include <config.h>
|
|||
|
+#include "gtksearchengine.h"
|
|||
|
+#include "gtksearchenginebeagle.h"
|
|||
|
+#include "gtksearchenginesimple.h"
|
|||
|
+#include "gtksearchenginetracker.h"
|
|||
|
+
|
|||
|
+#define HAVE_BEAGLE 1
|
|||
|
+#define HAVE_TRACKER 1
|
|||
|
+
|
|||
|
+enum
|
|||
|
+{
|
|||
|
+ HITS_ADDED,
|
|||
|
+ HITS_SUBTRACTED,
|
|||
|
+ FINISHED,
|
|||
|
+ ERROR,
|
|||
|
+ LAST_SIGNAL
|
|||
|
+};
|
|||
|
+
|
|||
|
+static guint signals[LAST_SIGNAL];
|
|||
|
+
|
|||
|
+G_DEFINE_ABSTRACT_TYPE (GtkSearchEngine, _gtk_search_engine, G_TYPE_OBJECT);
|
|||
|
+
|
|||
|
+static void
|
|||
|
+finalize (GObject *object)
|
|||
|
+{
|
|||
|
+ G_OBJECT_CLASS (_gtk_search_engine_parent_class)->finalize (object);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+_gtk_search_engine_class_init (GtkSearchEngineClass *class)
|
|||
|
+{
|
|||
|
+ GObjectClass *gobject_class;
|
|||
|
+
|
|||
|
+ gobject_class = G_OBJECT_CLASS (class);
|
|||
|
+ gobject_class->finalize = finalize;
|
|||
|
+
|
|||
|
+ signals[HITS_ADDED] =
|
|||
|
+ g_signal_new ("hits-added",
|
|||
|
+ G_TYPE_FROM_CLASS (class),
|
|||
|
+ G_SIGNAL_RUN_LAST,
|
|||
|
+ G_STRUCT_OFFSET (GtkSearchEngineClass, hits_added),
|
|||
|
+ NULL, NULL,
|
|||
|
+ g_cclosure_marshal_VOID__POINTER,
|
|||
|
+ G_TYPE_NONE, 1,
|
|||
|
+ G_TYPE_POINTER);
|
|||
|
+
|
|||
|
+ signals[HITS_SUBTRACTED] =
|
|||
|
+ g_signal_new ("hits-subtracted",
|
|||
|
+ G_TYPE_FROM_CLASS (class),
|
|||
|
+ G_SIGNAL_RUN_LAST,
|
|||
|
+ G_STRUCT_OFFSET (GtkSearchEngineClass, hits_subtracted),
|
|||
|
+ NULL, NULL,
|
|||
|
+ g_cclosure_marshal_VOID__POINTER,
|
|||
|
+ G_TYPE_NONE, 1,
|
|||
|
+ G_TYPE_POINTER);
|
|||
|
+
|
|||
|
+ signals[FINISHED] =
|
|||
|
+ g_signal_new ("finished",
|
|||
|
+ G_TYPE_FROM_CLASS (class),
|
|||
|
+ G_SIGNAL_RUN_LAST,
|
|||
|
+ G_STRUCT_OFFSET (GtkSearchEngineClass, finished),
|
|||
|
+ NULL, NULL,
|
|||
|
+ g_cclosure_marshal_VOID__VOID,
|
|||
|
+ G_TYPE_NONE, 0);
|
|||
|
+
|
|||
|
+ signals[ERROR] =
|
|||
|
+ g_signal_new ("error",
|
|||
|
+ G_TYPE_FROM_CLASS (class),
|
|||
|
+ G_SIGNAL_RUN_LAST,
|
|||
|
+ G_STRUCT_OFFSET (GtkSearchEngineClass, error),
|
|||
|
+ NULL, NULL,
|
|||
|
+ g_cclosure_marshal_VOID__STRING,
|
|||
|
+ G_TYPE_NONE, 1,
|
|||
|
+ G_TYPE_STRING);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+_gtk_search_engine_init (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+}
|
|||
|
+
|
|||
|
+GtkSearchEngine *
|
|||
|
+_gtk_search_engine_new (void)
|
|||
|
+{
|
|||
|
+ GtkSearchEngine *engine;
|
|||
|
+
|
|||
|
+#ifdef HAVE_BEAGLE
|
|||
|
+ engine = _gtk_search_engine_beagle_new ();
|
|||
|
+ if (engine)
|
|||
|
+ return engine;
|
|||
|
+#endif
|
|||
|
+
|
|||
|
+#ifdef HAVE_TRACKER
|
|||
|
+ engine = _gtk_search_engine_tracker_new ();
|
|||
|
+ if (engine)
|
|||
|
+ return engine;
|
|||
|
+#endif
|
|||
|
+
|
|||
|
+ engine = _gtk_search_engine_simple_new ();
|
|||
|
+ return engine;
|
|||
|
+}
|
|||
|
+
|
|||
|
+void
|
|||
|
+_gtk_search_engine_set_query (GtkSearchEngine *engine,
|
|||
|
+ GtkQuery *query)
|
|||
|
+{
|
|||
|
+ g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
|||
|
+ g_return_if_fail (GTK_SEARCH_ENGINE_GET_CLASS (engine)->set_query != NULL);
|
|||
|
+
|
|||
|
+ GTK_SEARCH_ENGINE_GET_CLASS (engine)->set_query (engine, query);
|
|||
|
+}
|
|||
|
+
|
|||
|
+void
|
|||
|
+_gtk_search_engine_start (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+ g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
|||
|
+ g_return_if_fail (GTK_SEARCH_ENGINE_GET_CLASS (engine)->start != NULL);
|
|||
|
+
|
|||
|
+ GTK_SEARCH_ENGINE_GET_CLASS (engine)->start (engine);
|
|||
|
+}
|
|||
|
+
|
|||
|
+void
|
|||
|
+_gtk_search_engine_stop (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+ g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
|||
|
+ g_return_if_fail (GTK_SEARCH_ENGINE_GET_CLASS (engine)->stop != NULL);
|
|||
|
+
|
|||
|
+ GTK_SEARCH_ENGINE_GET_CLASS (engine)->stop (engine);
|
|||
|
+}
|
|||
|
+
|
|||
|
+gboolean
|
|||
|
+_gtk_search_engine_is_indexed (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+ g_return_val_if_fail (GTK_IS_SEARCH_ENGINE (engine), FALSE);
|
|||
|
+ g_return_val_if_fail (GTK_SEARCH_ENGINE_GET_CLASS (engine)->is_indexed != NULL, FALSE);
|
|||
|
+
|
|||
|
+ return GTK_SEARCH_ENGINE_GET_CLASS (engine)->is_indexed (engine);
|
|||
|
+}
|
|||
|
+
|
|||
|
+void
|
|||
|
+_gtk_search_engine_hits_added (GtkSearchEngine *engine,
|
|||
|
+ GList *hits)
|
|||
|
+{
|
|||
|
+ g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
|||
|
+
|
|||
|
+ g_signal_emit (engine, signals[HITS_ADDED], 0, hits);
|
|||
|
+}
|
|||
|
+
|
|||
|
+
|
|||
|
+void
|
|||
|
+_gtk_search_engine_hits_subtracted (GtkSearchEngine *engine,
|
|||
|
+ GList *hits)
|
|||
|
+{
|
|||
|
+ g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
|||
|
+
|
|||
|
+ g_signal_emit (engine, signals[HITS_SUBTRACTED], 0, hits);
|
|||
|
+}
|
|||
|
+
|
|||
|
+
|
|||
|
+void
|
|||
|
+_gtk_search_engine_finished (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+ g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
|||
|
+
|
|||
|
+ g_signal_emit (engine, signals[FINISHED], 0);
|
|||
|
+}
|
|||
|
+
|
|||
|
+void
|
|||
|
+_gtk_search_engine_error (GtkSearchEngine *engine,
|
|||
|
+ const gchar *error_message)
|
|||
|
+{
|
|||
|
+ g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
|||
|
+
|
|||
|
+ g_signal_emit (engine, signals[ERROR], 0, error_message);
|
|||
|
+}
|
|||
|
--- /dev/null 2007-01-16 08:16:47.736226048 -0500
|
|||
|
+++ gtk+-2.10.8/gtk/gtksearchenginetracker.c 2007-01-17 01:21:08.000000000 -0500
|
|||
|
@@ -0,0 +1,362 @@
|
|||
|
+/*
|
|||
|
+ * Copyright (C) 2005 Mr Jamie McCracken
|
|||
|
+ *
|
|||
|
+ * This library is free software; you can redistribute it and/or
|
|||
|
+ * modify it under the terms of the GNU Lesser General Public
|
|||
|
+ * License as published by the Free Software Foundation; either
|
|||
|
+ * version 2 of the License, or (at your option) any later version.
|
|||
|
+ *
|
|||
|
+ * This library 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
|
|||
|
+ * Lesser General Public License for more details.
|
|||
|
+ *
|
|||
|
+ * You should have received a copy of the GNU Lesser General Public
|
|||
|
+ * License along with this library; if not, write to the
|
|||
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|||
|
+ *
|
|||
|
+ * Author: Jamie McCracken <jamiemcc@gnome.org>
|
|||
|
+ *
|
|||
|
+ * Based on nautilus-search-engine-tracker.c
|
|||
|
+ */
|
|||
|
+
|
|||
|
+#include <config.h>
|
|||
|
+#include <gmodule.h>
|
|||
|
+#include "gtksearchenginetracker.h"
|
|||
|
+#if 0
|
|||
|
+#include <tracker.h>
|
|||
|
+#endif
|
|||
|
+
|
|||
|
+typedef struct _TrackerClient TrackerClient;
|
|||
|
+
|
|||
|
+typedef void (*TrackerArrayReply) (char **result, GError *error, gpointer user_data);
|
|||
|
+
|
|||
|
+static TrackerClient * (*tracker_connect) (gboolean enable_warnings) = NULL;
|
|||
|
+static void (*tracker_disconnect) (TrackerClient *client) = NULL;
|
|||
|
+static void (*tracker_cancel_last_call) (TrackerClient *client) = NULL;
|
|||
|
+
|
|||
|
+static void (*tracker_search_metadata_by_text_async) (TrackerClient *client,
|
|||
|
+ const char *query,
|
|||
|
+ TrackerArrayReply callback,
|
|||
|
+ gpointer user_data) = NULL;
|
|||
|
+static void (*tracker_search_metadata_by_text_and_mime_async) (TrackerClient *client,
|
|||
|
+ const char *query,
|
|||
|
+ const char **mimes,
|
|||
|
+ TrackerArrayReply callback,
|
|||
|
+ gpointer user_data) = NULL;
|
|||
|
+static void (*tracker_search_metadata_by_text_and_location_async) (TrackerClient *client,
|
|||
|
+ const char *query,
|
|||
|
+ const char *location,
|
|||
|
+ TrackerArrayReply callback,
|
|||
|
+ gpointer user_data) = NULL;
|
|||
|
+static void (*tracker_search_metadata_by_text_and_mime_and_location_async) (TrackerClient *client,
|
|||
|
+ const char *query,
|
|||
|
+ const char **mimes,
|
|||
|
+ const char *location,
|
|||
|
+ TrackerArrayReply callback,
|
|||
|
+ gpointer user_data) = NULL;
|
|||
|
+
|
|||
|
+static struct TrackerDlMapping
|
|||
|
+{
|
|||
|
+ const char *fn_name;
|
|||
|
+ gpointer *fn_ptr_ref;
|
|||
|
+} tracker_dl_mapping[] =
|
|||
|
+{
|
|||
|
+#define MAP(a) { #a, (gpointer *)&a }
|
|||
|
+ MAP (tracker_connect),
|
|||
|
+ MAP (tracker_disconnect),
|
|||
|
+ MAP (tracker_cancel_last_call),
|
|||
|
+ MAP (tracker_search_metadata_by_text_async),
|
|||
|
+ MAP (tracker_search_metadata_by_text_and_mime_async),
|
|||
|
+ MAP (tracker_search_metadata_by_text_and_location_async),
|
|||
|
+ MAP (tracker_search_metadata_by_text_and_mime_and_location_async)
|
|||
|
+#undef MAP
|
|||
|
+};
|
|||
|
+
|
|||
|
+static void
|
|||
|
+open_libtracker (void)
|
|||
|
+{
|
|||
|
+ static gboolean done = FALSE;
|
|||
|
+
|
|||
|
+ if (!done)
|
|||
|
+ {
|
|||
|
+ int i;
|
|||
|
+ GModule *tracker;
|
|||
|
+
|
|||
|
+ done = TRUE;
|
|||
|
+
|
|||
|
+ tracker = g_module_open ("libtracker.so.0", G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
|
|||
|
+ if (!tracker)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
+ for (i = 0; i < G_N_ELEMENTS (tracker_dl_mapping); i++)
|
|||
|
+ {
|
|||
|
+ if (!g_module_symbol (tracker, tracker_dl_mapping[i].fn_name,
|
|||
|
+ tracker_dl_mapping[i].fn_ptr_ref))
|
|||
|
+ {
|
|||
|
+ g_warning ("Missing symbol '%s' in libtracker\n",
|
|||
|
+ tracker_dl_mapping[i].fn_name);
|
|||
|
+ g_module_close (tracker);
|
|||
|
+
|
|||
|
+ for (i = 0; i < G_N_ELEMENTS (tracker_dl_mapping); i++)
|
|||
|
+ tracker_dl_mapping[i].fn_ptr_ref = NULL;
|
|||
|
+
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+}
|
|||
|
+
|
|||
|
+struct _GtkSearchEngineTrackerPrivate
|
|||
|
+{
|
|||
|
+ GtkQuery *query;
|
|||
|
+ TrackerClient *client;
|
|||
|
+ gboolean query_pending;
|
|||
|
+};
|
|||
|
+
|
|||
|
+G_DEFINE_TYPE (GtkSearchEngineTracker, _gtk_search_engine_tracker, GTK_TYPE_SEARCH_ENGINE);
|
|||
|
+
|
|||
|
+
|
|||
|
+static void
|
|||
|
+finalize (GObject *object)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineTracker *tracker;
|
|||
|
+
|
|||
|
+ tracker = GTK_SEARCH_ENGINE_TRACKER (object);
|
|||
|
+
|
|||
|
+ if (tracker->priv->query)
|
|||
|
+ {
|
|||
|
+ g_object_unref (tracker->priv->query);
|
|||
|
+ tracker->priv->query = NULL;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ tracker_disconnect (tracker->priv->client);
|
|||
|
+
|
|||
|
+ G_OBJECT_CLASS (_gtk_search_engine_tracker_parent_class)->finalize (object);
|
|||
|
+}
|
|||
|
+
|
|||
|
+
|
|||
|
+static void
|
|||
|
+search_callback (gchar **results,
|
|||
|
+ GError *error,
|
|||
|
+ gpointer user_data)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineTracker *tracker;
|
|||
|
+ gchar **results_p;
|
|||
|
+ GList *hit_uris;
|
|||
|
+
|
|||
|
+ tracker = GTK_SEARCH_ENGINE_TRACKER (user_data);
|
|||
|
+ hit_uris = NULL;
|
|||
|
+
|
|||
|
+ tracker->priv->query_pending = FALSE;
|
|||
|
+
|
|||
|
+ if (error)
|
|||
|
+ {
|
|||
|
+ _gtk_search_engine_error ( GTK_SEARCH_ENGINE (tracker), error->message);
|
|||
|
+ g_error_free (error);
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ if (!results)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
+ for (results_p = results; *results_p; results_p++)
|
|||
|
+ {
|
|||
|
+ gchar *uri;
|
|||
|
+
|
|||
|
+ uri = g_filename_to_uri ((char *)*results_p, NULL, NULL);
|
|||
|
+ if (uri)
|
|||
|
+ hit_uris = g_list_prepend (hit_uris, (char *)uri);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ _gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (tracker), hit_uris);
|
|||
|
+ _gtk_search_engine_finished (GTK_SEARCH_ENGINE (tracker));
|
|||
|
+
|
|||
|
+ g_strfreev (results);
|
|||
|
+ g_list_foreach (hit_uris, (GFunc)g_free, NULL);
|
|||
|
+ g_list_free (hit_uris);
|
|||
|
+}
|
|||
|
+
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gtk_search_engine_tracker_start (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineTracker *tracker;
|
|||
|
+ GList *mimetypes, *l;
|
|||
|
+ gchar *search_text, *location, *location_uri;
|
|||
|
+ gchar **mimes;
|
|||
|
+ gint i, mime_count;
|
|||
|
+
|
|||
|
+ tracker = GTK_SEARCH_ENGINE_TRACKER (engine);
|
|||
|
+
|
|||
|
+ if (tracker->priv->query_pending)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
+ if (tracker->priv->query == NULL)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
+ search_text = _gtk_query_get_text (tracker->priv->query);
|
|||
|
+
|
|||
|
+ mimetypes = _gtk_query_get_mime_types (tracker->priv->query);
|
|||
|
+
|
|||
|
+ location_uri = _gtk_query_get_location (tracker->priv->query);
|
|||
|
+
|
|||
|
+ if (location_uri)
|
|||
|
+ {
|
|||
|
+ location = g_filename_from_uri (location_uri, NULL, NULL);
|
|||
|
+ g_free (location_uri);
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ location = NULL;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ mime_count = g_list_length (mimetypes);
|
|||
|
+
|
|||
|
+ i = 0;
|
|||
|
+
|
|||
|
+ /* convert list into array */
|
|||
|
+ if (mime_count > 0)
|
|||
|
+ {
|
|||
|
+ mimes = g_new (gchar *, (mime_count + 1));
|
|||
|
+
|
|||
|
+ for (l = mimetypes; l != NULL; l = l->next)
|
|||
|
+ {
|
|||
|
+ mimes[i] = g_strdup (l->data);
|
|||
|
+ i++;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ mimes[mime_count] = NULL;
|
|||
|
+
|
|||
|
+ if (location)
|
|||
|
+ {
|
|||
|
+ tracker_search_metadata_by_text_and_mime_and_location_async (tracker->priv->client,
|
|||
|
+ search_text, (const char **)mimes, location,
|
|||
|
+ search_callback,
|
|||
|
+ tracker);
|
|||
|
+ g_free (location);
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ tracker_search_metadata_by_text_and_mime_async (tracker->priv->client,
|
|||
|
+ search_text, (const char**)mimes,
|
|||
|
+ search_callback,
|
|||
|
+ tracker);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ g_strfreev (mimes);
|
|||
|
+
|
|||
|
+
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ if (location)
|
|||
|
+ {
|
|||
|
+ tracker_search_metadata_by_text_and_location_async (tracker->priv->client,
|
|||
|
+ search_text,
|
|||
|
+ location,
|
|||
|
+ search_callback,
|
|||
|
+ tracker);
|
|||
|
+ g_free (location);
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ tracker_search_metadata_by_text_async (tracker->priv->client,
|
|||
|
+ search_text,
|
|||
|
+ search_callback,
|
|||
|
+ tracker);
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ tracker->priv->query_pending = TRUE;
|
|||
|
+ g_free (search_text);
|
|||
|
+ g_list_foreach (mimetypes, (GFunc)g_free, NULL);
|
|||
|
+ g_list_free (mimetypes);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gtk_search_engine_tracker_stop (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineTracker *tracker;
|
|||
|
+
|
|||
|
+ tracker = GTK_SEARCH_ENGINE_TRACKER (engine);
|
|||
|
+
|
|||
|
+ if (tracker->priv->query && tracker->priv->query_pending)
|
|||
|
+ {
|
|||
|
+ tracker_cancel_last_call (tracker->priv->client);
|
|||
|
+ tracker->priv->query_pending = FALSE;
|
|||
|
+ }
|
|||
|
+}
|
|||
|
+
|
|||
|
+static gboolean
|
|||
|
+gtk_search_engine_tracker_is_indexed (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+ return TRUE;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gtk_search_engine_tracker_set_query (GtkSearchEngine *engine,
|
|||
|
+ GtkQuery *query)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineTracker *tracker;
|
|||
|
+
|
|||
|
+ tracker = GTK_SEARCH_ENGINE_TRACKER (engine);
|
|||
|
+
|
|||
|
+ if (query)
|
|||
|
+ g_object_ref (query);
|
|||
|
+
|
|||
|
+ if (tracker->priv->query)
|
|||
|
+ g_object_unref (tracker->priv->query);
|
|||
|
+
|
|||
|
+ tracker->priv->query = query;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+_gtk_search_engine_tracker_class_init (GtkSearchEngineTrackerClass *class)
|
|||
|
+{
|
|||
|
+ GObjectClass *gobject_class;
|
|||
|
+ GtkSearchEngineClass *engine_class;
|
|||
|
+
|
|||
|
+ gobject_class = G_OBJECT_CLASS (class);
|
|||
|
+ gobject_class->finalize = finalize;
|
|||
|
+
|
|||
|
+ engine_class = GTK_SEARCH_ENGINE_CLASS (class);
|
|||
|
+ engine_class->set_query = gtk_search_engine_tracker_set_query;
|
|||
|
+ engine_class->start = gtk_search_engine_tracker_start;
|
|||
|
+ engine_class->stop = gtk_search_engine_tracker_stop;
|
|||
|
+ engine_class->is_indexed = gtk_search_engine_tracker_is_indexed;
|
|||
|
+
|
|||
|
+ g_type_class_add_private (gobject_class, sizeof (GtkSearchEngineTrackerPrivate));
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+_gtk_search_engine_tracker_init (GtkSearchEngineTracker *engine)
|
|||
|
+{
|
|||
|
+ engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine, GTK_TYPE_SEARCH_ENGINE_TRACKER, GtkSearchEngineTrackerPrivate);
|
|||
|
+}
|
|||
|
+
|
|||
|
+
|
|||
|
+GtkSearchEngine *
|
|||
|
+_gtk_search_engine_tracker_new (void)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineTracker *engine;
|
|||
|
+ TrackerClient *tracker_client;
|
|||
|
+
|
|||
|
+ open_libtracker ();
|
|||
|
+
|
|||
|
+ if (!tracker_connect)
|
|||
|
+ return NULL;
|
|||
|
+
|
|||
|
+ tracker_client = tracker_connect (FALSE);
|
|||
|
+
|
|||
|
+ if (!tracker_client)
|
|||
|
+ return NULL;
|
|||
|
+
|
|||
|
+ engine = g_object_new (GTK_TYPE_SEARCH_ENGINE_TRACKER, NULL);
|
|||
|
+
|
|||
|
+ engine->priv->client = tracker_client;
|
|||
|
+
|
|||
|
+ engine->priv->query_pending = FALSE;
|
|||
|
+
|
|||
|
+ return GTK_SEARCH_ENGINE (engine);
|
|||
|
+}
|
|||
|
--- gtk+-2.10.8/gtk/Makefile.am.search 2007-01-16 22:14:43.000000000 -0500
|
|||
|
+++ gtk+-2.10.8/gtk/Makefile.am 2007-01-17 01:21:08.000000000 -0500
|
|||
|
@@ -332,6 +332,11 @@
|
|||
|
|
|||
|
# GTK+ header files that don't get installed
|
|||
|
gtk_private_h_sources = \
|
|||
|
+ gtkquery.h \
|
|||
|
+ gtksearchengine.h \
|
|||
|
+ gtksearchenginebeagle.h \
|
|||
|
+ gtksearchenginetracker.h\
|
|||
|
+ gtksearchenginesimple.h \
|
|||
|
gtkdndcursors.h \
|
|||
|
gtkentryprivate.h \
|
|||
|
gtkfilechooserdefault.h \
|
|||
|
@@ -374,6 +379,11 @@
|
|||
|
|
|||
|
# GTK+ C sources to build the library from
|
|||
|
gtk_base_c_sources = \
|
|||
|
+ gtkquery.c \
|
|||
|
+ gtksearchengine.c \
|
|||
|
+ gtksearchenginebeagle.c \
|
|||
|
+ gtksearchenginetracker.c\
|
|||
|
+ gtksearchenginesimple.c \
|
|||
|
fnmatch.c \
|
|||
|
gtkaboutdialog.c \
|
|||
|
gtkaccelgroup.c \
|
|||
|
--- gtk+-2.10.8/gtk/gtkfilechooserdefault.c.search 2007-01-16 22:14:43.000000000 -0500
|
|||
|
+++ gtk+-2.10.8/gtk/gtkfilechooserdefault.c 2007-01-17 01:21:08.000000000 -0500
|
|||
|
@@ -78,6 +78,8 @@
|
|||
|
#include <errno.h>
|
|||
|
#include <string.h>
|
|||
|
#include <time.h>
|
|||
|
+#include <sys/stat.h>
|
|||
|
+#include <sys/types.h>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
@@ -171,13 +173,20 @@
|
|||
|
SHORTCUTS_COL_PIXBUF,
|
|||
|
SHORTCUTS_COL_NAME,
|
|||
|
SHORTCUTS_COL_DATA,
|
|||
|
- SHORTCUTS_COL_IS_VOLUME,
|
|||
|
+ SHORTCUTS_COL_TYPE,
|
|||
|
SHORTCUTS_COL_REMOVABLE,
|
|||
|
SHORTCUTS_COL_PIXBUF_VISIBLE,
|
|||
|
SHORTCUTS_COL_HANDLE,
|
|||
|
SHORTCUTS_COL_NUM_COLUMNS
|
|||
|
};
|
|||
|
|
|||
|
+typedef enum {
|
|||
|
+ SHORTCUT_TYPE_PATH,
|
|||
|
+ SHORTCUT_TYPE_VOLUME,
|
|||
|
+ SHORTCUT_TYPE_SEPARATOR,
|
|||
|
+ SHORTCUT_TYPE_SEARCH
|
|||
|
+} ShortcutType;
|
|||
|
+
|
|||
|
/* Column numbers for the file list */
|
|||
|
enum {
|
|||
|
FILE_LIST_COL_NAME,
|
|||
|
@@ -186,6 +195,16 @@
|
|||
|
FILE_LIST_COL_NUM_COLUMNS
|
|||
|
};
|
|||
|
|
|||
|
+/* Column numbers for the search model.
|
|||
|
+ * Keep this in sync with search_setup_model()
|
|||
|
+ */
|
|||
|
+enum {
|
|||
|
+ SEARCH_MODEL_COL_PATH,
|
|||
|
+ SEARCH_MODEL_COL_DISPLAY_NAME,
|
|||
|
+ SEARCH_MODEL_COL_COLLATION_KEY,
|
|||
|
+ SEARCH_MODEL_COL_STAT
|
|||
|
+};
|
|||
|
+
|
|||
|
/* Identifiers for target types */
|
|||
|
enum {
|
|||
|
GTK_TREE_MODEL_ROW,
|
|||
|
@@ -225,9 +244,19 @@
|
|||
|
static const int num_file_list_dest_targets = (sizeof (file_list_dest_targets)
|
|||
|
/ sizeof (file_list_dest_targets[0]));
|
|||
|
|
|||
|
+static gboolean
|
|||
|
+search_is_possible (GtkFileChooserDefault *impl)
|
|||
|
+{
|
|||
|
+ if (impl->search_engine == NULL)
|
|||
|
+ impl->search_engine = _gtk_search_engine_new ();
|
|||
|
+
|
|||
|
+ return impl->search_engine != NULL;
|
|||
|
+}
|
|||
|
|
|||
|
/* Interesting places in the shortcuts bar */
|
|||
|
typedef enum {
|
|||
|
+ SHORTCUTS_SEARCH,
|
|||
|
+ SHORTCUTS_SEARCH_SEPARATOR,
|
|||
|
SHORTCUTS_HOME,
|
|||
|
SHORTCUTS_DESKTOP,
|
|||
|
SHORTCUTS_VOLUMES,
|
|||
|
@@ -419,6 +448,14 @@
|
|||
|
GtkFileChooserDefault *impl);
|
|||
|
static void location_switch_to_path_bar (GtkFileChooserDefault *impl);
|
|||
|
|
|||
|
+static void search_stop_searching (GtkFileChooserDefault *impl);
|
|||
|
+static void search_clear_model (GtkFileChooserDefault *impl,
|
|||
|
+ gboolean remove_from_treeview);
|
|||
|
+static gboolean search_should_respond (GtkFileChooserDefault *impl);
|
|||
|
+static void search_switch_to_browse_mode (GtkFileChooserDefault *impl);
|
|||
|
+static GSList *search_get_selected_paths (GtkFileChooserDefault *impl);
|
|||
|
+static void search_entry_activate_cb (GtkEntry *entry,
|
|||
|
+ gpointer data);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
@@ -428,26 +465,26 @@
|
|||
|
GtkTreeModelFilter parent;
|
|||
|
|
|||
|
GtkFileChooserDefault *impl;
|
|||
|
-} ShortcutsModelFilter;
|
|||
|
+} ShortcutsPaneModelFilter;
|
|||
|
|
|||
|
typedef struct {
|
|||
|
GtkTreeModelFilterClass parent_class;
|
|||
|
-} ShortcutsModelFilterClass;
|
|||
|
+} ShortcutsPaneModelFilterClass;
|
|||
|
|
|||
|
-#define SHORTCUTS_MODEL_FILTER_TYPE (_shortcuts_model_filter_get_type ())
|
|||
|
-#define SHORTCUTS_MODEL_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHORTCUTS_MODEL_FILTER_TYPE, ShortcutsModelFilter))
|
|||
|
+#define SHORTCUTS_PANE_MODEL_FILTER_TYPE (_shortcuts_pane_model_filter_get_type ())
|
|||
|
+#define SHORTCUTS_PANE_MODEL_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHORTCUTS_PANE_MODEL_FILTER_TYPE, ShortcutsPaneModelFilter))
|
|||
|
|
|||
|
-static void shortcuts_model_filter_drag_source_iface_init (GtkTreeDragSourceIface *iface);
|
|||
|
+static void shortcuts_pane_model_filter_drag_source_iface_init (GtkTreeDragSourceIface *iface);
|
|||
|
|
|||
|
-G_DEFINE_TYPE_WITH_CODE (ShortcutsModelFilter,
|
|||
|
- _shortcuts_model_filter,
|
|||
|
+G_DEFINE_TYPE_WITH_CODE (ShortcutsPaneModelFilter,
|
|||
|
+ _shortcuts_pane_model_filter,
|
|||
|
GTK_TYPE_TREE_MODEL_FILTER,
|
|||
|
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
|
|||
|
- shortcuts_model_filter_drag_source_iface_init))
|
|||
|
+ shortcuts_pane_model_filter_drag_source_iface_init))
|
|||
|
|
|||
|
-static GtkTreeModel *shortcuts_model_filter_new (GtkFileChooserDefault *impl,
|
|||
|
- GtkTreeModel *child_model,
|
|||
|
- GtkTreePath *root);
|
|||
|
+static GtkTreeModel *shortcuts_pane_model_filter_new (GtkFileChooserDefault *impl,
|
|||
|
+ GtkTreeModel *child_model,
|
|||
|
+ GtkTreePath *root);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
@@ -663,6 +700,7 @@
|
|||
|
impl->reload_state = RELOAD_EMPTY;
|
|||
|
impl->pending_select_paths = NULL;
|
|||
|
impl->location_mode = LOCATION_MODE_PATH_BAR;
|
|||
|
+ impl->operation_mode = OPERATION_MODE_BROWSE;
|
|||
|
|
|||
|
gtk_box_set_spacing (GTK_BOX (impl), 12);
|
|||
|
|
|||
|
@@ -678,22 +716,24 @@
|
|||
|
GtkTreeIter *iter)
|
|||
|
{
|
|||
|
gpointer col_data;
|
|||
|
- gboolean is_volume;
|
|||
|
+ ShortcutType shortcut_type;
|
|||
|
GtkFileSystemHandle *handle;
|
|||
|
|
|||
|
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), iter,
|
|||
|
SHORTCUTS_COL_DATA, &col_data,
|
|||
|
- SHORTCUTS_COL_IS_VOLUME, &is_volume,
|
|||
|
+ SHORTCUTS_COL_TYPE, &shortcut_type,
|
|||
|
SHORTCUTS_COL_HANDLE, &handle,
|
|||
|
-1);
|
|||
|
|
|||
|
if (handle)
|
|||
|
gtk_file_system_cancel_operation (handle);
|
|||
|
|
|||
|
- if (!col_data)
|
|||
|
+ if (!(shortcut_type == SHORTCUT_TYPE_PATH ||
|
|||
|
+ shortcut_type == SHORTCUT_TYPE_VOLUME) ||
|
|||
|
+ !col_data)
|
|||
|
return;
|
|||
|
|
|||
|
- if (is_volume)
|
|||
|
+ if (shortcut_type == SHORTCUT_TYPE_VOLUME)
|
|||
|
{
|
|||
|
GtkFileSystemVolume *volume;
|
|||
|
|
|||
|
@@ -704,6 +744,8 @@
|
|||
|
{
|
|||
|
GtkFilePath *path;
|
|||
|
|
|||
|
+ g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
|
|||
|
+
|
|||
|
path = col_data;
|
|||
|
gtk_file_path_free (path);
|
|||
|
}
|
|||
|
@@ -790,8 +832,11 @@
|
|||
|
GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object);
|
|||
|
GSList *l;
|
|||
|
|
|||
|
- if (impl->shortcuts_filter_model)
|
|||
|
- g_object_unref (impl->shortcuts_filter_model);
|
|||
|
+ if (impl->shortcuts_pane_filter_model)
|
|||
|
+ g_object_unref (impl->shortcuts_pane_filter_model);
|
|||
|
+
|
|||
|
+ if (impl->shortcuts_combo_filter_model)
|
|||
|
+ g_object_unref (impl->shortcuts_combo_filter_model);
|
|||
|
|
|||
|
shortcuts_free (impl);
|
|||
|
|
|||
|
@@ -829,6 +874,8 @@
|
|||
|
if (impl->sort_model)
|
|||
|
g_object_unref (impl->sort_model);
|
|||
|
|
|||
|
+ search_clear_model (impl, FALSE);
|
|||
|
+
|
|||
|
g_free (impl->preview_display_name);
|
|||
|
|
|||
|
g_free (impl->edited_new_text);
|
|||
|
@@ -1080,6 +1127,14 @@
|
|||
|
update_preview_widget_visibility (impl);
|
|||
|
}
|
|||
|
|
|||
|
+/* Renders a "Search" icon at an appropriate size for a tree view */
|
|||
|
+static GdkPixbuf *
|
|||
|
+render_search_icon (GtkFileChooserDefault *impl)
|
|||
|
+{
|
|||
|
+ return gtk_widget_render_icon (GTK_WIDGET (impl), GTK_STOCK_FIND, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL);
|
|||
|
+}
|
|||
|
+
|
|||
|
+
|
|||
|
/* Re-reads all the icons for the shortcuts, used when the theme changes */
|
|||
|
struct ReloadIconsData
|
|||
|
{
|
|||
|
@@ -1150,19 +1205,20 @@
|
|||
|
do
|
|||
|
{
|
|||
|
gpointer data;
|
|||
|
- gboolean is_volume;
|
|||
|
+ ShortcutType shortcut_type;
|
|||
|
gboolean pixbuf_visible;
|
|||
|
GdkPixbuf *pixbuf;
|
|||
|
|
|||
|
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
|
|||
|
SHORTCUTS_COL_DATA, &data,
|
|||
|
- SHORTCUTS_COL_IS_VOLUME, &is_volume,
|
|||
|
+ SHORTCUTS_COL_TYPE, &shortcut_type,
|
|||
|
SHORTCUTS_COL_PIXBUF_VISIBLE, &pixbuf_visible,
|
|||
|
-1);
|
|||
|
|
|||
|
- if (pixbuf_visible && data)
|
|||
|
+ pixbuf = NULL;
|
|||
|
+ if (pixbuf_visible)
|
|||
|
{
|
|||
|
- if (is_volume)
|
|||
|
+ if (shortcut_type == SHORTCUT_TYPE_VOLUME)
|
|||
|
{
|
|||
|
GtkFileSystemVolume *volume;
|
|||
|
|
|||
|
@@ -1177,46 +1233,53 @@
|
|||
|
if (pixbuf)
|
|||
|
g_object_unref (pixbuf);
|
|||
|
}
|
|||
|
- else if (gtk_file_system_path_is_local (impl->file_system, (GtkFilePath *)data))
|
|||
|
- {
|
|||
|
- const GtkFilePath *path;
|
|||
|
- struct ReloadIconsData *info;
|
|||
|
- GtkTreePath *tree_path;
|
|||
|
- GtkFileSystemHandle *handle;
|
|||
|
-
|
|||
|
- path = data;
|
|||
|
-
|
|||
|
- info = g_new0 (struct ReloadIconsData, 1);
|
|||
|
- info->impl = g_object_ref (impl);
|
|||
|
- tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
|
|||
|
- info->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->shortcuts_model), tree_path);
|
|||
|
- gtk_tree_path_free (tree_path);
|
|||
|
-
|
|||
|
- handle = gtk_file_system_get_info (impl->file_system, path,
|
|||
|
- GTK_FILE_INFO_ICON,
|
|||
|
- shortcuts_reload_icons_get_info_cb,
|
|||
|
- info);
|
|||
|
- impl->reload_icon_handles = g_slist_append (impl->reload_icon_handles, handle);
|
|||
|
- }
|
|||
|
- else
|
|||
|
+ else if (shortcut_type == SHORTCUT_TYPE_PATH)
|
|||
|
+ {
|
|||
|
+ if (gtk_file_system_path_is_local (impl->file_system, (GtkFilePath *)data))
|
|||
|
+ {
|
|||
|
+ const GtkFilePath *path;
|
|||
|
+ struct ReloadIconsData *info;
|
|||
|
+ GtkTreePath *tree_path;
|
|||
|
+ GtkFileSystemHandle *handle;
|
|||
|
+
|
|||
|
+ path = data;
|
|||
|
+
|
|||
|
+ info = g_new0 (struct ReloadIconsData, 1);
|
|||
|
+ info->impl = g_object_ref (impl);
|
|||
|
+ tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
|
|||
|
+ info->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->shortcuts_model), tree_path);
|
|||
|
+ gtk_tree_path_free (tree_path);
|
|||
|
+
|
|||
|
+ handle = gtk_file_system_get_info (impl->file_system, path,
|
|||
|
+ GTK_FILE_INFO_ICON,
|
|||
|
+ shortcuts_reload_icons_get_info_cb,
|
|||
|
+ info);
|
|||
|
+ impl->reload_icon_handles = g_slist_append (impl->reload_icon_handles, handle);
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ GtkIconTheme *icon_theme;
|
|||
|
+
|
|||
|
+ /* Don't call get_info for remote paths to avoid latency and
|
|||
|
+ * auth dialogs.
|
|||
|
+ * If we switch to a better bookmarks file format (XBEL), we
|
|||
|
+ * should use mime info to get a better icon.
|
|||
|
+ */
|
|||
|
+ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
|
|||
|
+ pixbuf = gtk_icon_theme_load_icon (icon_theme, "gnome-fs-directory",
|
|||
|
+ impl->icon_size, 0, NULL);
|
|||
|
+
|
|||
|
+ gtk_list_store_set (impl->shortcuts_model, &iter,
|
|||
|
+ SHORTCUTS_COL_PIXBUF, pixbuf,
|
|||
|
+ -1);
|
|||
|
+
|
|||
|
+ if (pixbuf)
|
|||
|
+ g_object_unref (pixbuf);
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+ else if (shortcut_type == SHORTCUT_TYPE_SEARCH)
|
|||
|
{
|
|||
|
- GtkIconTheme *icon_theme;
|
|||
|
-
|
|||
|
- /* Don't call get_info for remote paths to avoid latency and
|
|||
|
- * auth dialogs.
|
|||
|
- * If we switch to a better bookmarks file format (XBEL), we
|
|||
|
- * should use mime info to get a better icon.
|
|||
|
- */
|
|||
|
- icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
|
|||
|
- pixbuf = gtk_icon_theme_load_icon (icon_theme, "gnome-fs-directory",
|
|||
|
- impl->icon_size, 0, NULL);
|
|||
|
-
|
|||
|
- gtk_list_store_set (impl->shortcuts_model, &iter,
|
|||
|
- SHORTCUTS_COL_PIXBUF, pixbuf,
|
|||
|
- -1);
|
|||
|
-
|
|||
|
- if (pixbuf)
|
|||
|
- g_object_unref (pixbuf);
|
|||
|
+ pixbuf = render_search_icon (impl);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
@@ -1348,7 +1411,6 @@
|
|||
|
{
|
|||
|
gint pos = -1;
|
|||
|
gboolean cancelled = handle->cancelled;
|
|||
|
- gboolean is_volume = FALSE;
|
|||
|
GdkPixbuf *pixbuf;
|
|||
|
GtkTreePath *path;
|
|||
|
GtkTreeIter iter;
|
|||
|
@@ -1413,12 +1475,15 @@
|
|||
|
SHORTCUTS_COL_PIXBUF, pixbuf,
|
|||
|
SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE,
|
|||
|
SHORTCUTS_COL_NAME, request->label_copy,
|
|||
|
- SHORTCUTS_COL_IS_VOLUME, is_volume,
|
|||
|
+ SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_PATH,
|
|||
|
SHORTCUTS_COL_REMOVABLE, request->removable,
|
|||
|
-1);
|
|||
|
|
|||
|
- if (request->impl->shortcuts_filter_model)
|
|||
|
- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (request->impl->shortcuts_filter_model));
|
|||
|
+ if (request->impl->shortcuts_pane_filter_model)
|
|||
|
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (request->impl->shortcuts_pane_filter_model));
|
|||
|
+
|
|||
|
+ if (request->impl->shortcuts_combo_filter_model)
|
|||
|
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (request->impl->shortcuts_combo_filter_model));
|
|||
|
|
|||
|
if (request->type == SHORTCUTS_CURRENT_FOLDER
|
|||
|
&& request->impl->save_folder_combo != NULL)
|
|||
|
@@ -1430,7 +1495,7 @@
|
|||
|
g_signal_handlers_block_by_func (request->impl->save_folder_combo,
|
|||
|
G_CALLBACK (save_folder_combo_changed_cb),
|
|||
|
request->impl);
|
|||
|
- gtk_combo_box_set_active (GTK_COMBO_BOX (request->impl->save_folder_combo), pos);
|
|||
|
+ gtk_combo_box_set_active (GTK_COMBO_BOX (request->impl->save_folder_combo), request->impl->has_search ? pos - 2 : pos);
|
|||
|
g_signal_handlers_unblock_by_func (request->impl->save_folder_combo,
|
|||
|
G_CALLBACK (save_folder_combo_changed_cb),
|
|||
|
request->impl);
|
|||
|
@@ -1504,7 +1569,7 @@
|
|||
|
static void
|
|||
|
shortcuts_insert_path (GtkFileChooserDefault *impl,
|
|||
|
int pos,
|
|||
|
- gboolean is_volume,
|
|||
|
+ ShortcutType shortcut_type,
|
|||
|
GtkFileSystemVolume *volume,
|
|||
|
const GtkFilePath *path,
|
|||
|
const char *label,
|
|||
|
@@ -1517,79 +1582,89 @@
|
|||
|
GtkTreeIter iter;
|
|||
|
GtkIconTheme *icon_theme;
|
|||
|
|
|||
|
- profile_start ("start", is_volume ? "volume" : (char *) path);
|
|||
|
+ profile_start ("start", (shortcut_type == SHORTCUT_TYPE_VOLUME) ? "volume"
|
|||
|
+ : ((shortcut_type == SHORTCUT_TYPE_PATH) ? (char *) path : NULL));
|
|||
|
|
|||
|
- if (is_volume)
|
|||
|
+ if (shortcut_type == SHORTCUT_TYPE_VOLUME)
|
|||
|
{
|
|||
|
data = volume;
|
|||
|
label_copy = gtk_file_system_volume_get_display_name (impl->file_system, volume);
|
|||
|
pixbuf = gtk_file_system_volume_render_icon (impl->file_system, volume, GTK_WIDGET (impl),
|
|||
|
impl->icon_size, NULL);
|
|||
|
}
|
|||
|
- else if (gtk_file_system_path_is_local (impl->file_system, path))
|
|||
|
+ else if (shortcut_type == SHORTCUT_TYPE_PATH)
|
|||
|
{
|
|||
|
- struct ShortcutsInsertRequest *request;
|
|||
|
- GtkFileSystemHandle *handle;
|
|||
|
- GtkTreePath *p;
|
|||
|
-
|
|||
|
- request = g_new0 (struct ShortcutsInsertRequest, 1);
|
|||
|
- request->impl = g_object_ref (impl);
|
|||
|
- request->path = gtk_file_path_copy (path);
|
|||
|
- request->name_only = TRUE;
|
|||
|
- request->removable = removable;
|
|||
|
- request->pos = pos;
|
|||
|
- request->type = type;
|
|||
|
- if (label)
|
|||
|
- request->label_copy = g_strdup (label);
|
|||
|
+ if (gtk_file_system_path_is_local (impl->file_system, path))
|
|||
|
+ {
|
|||
|
+ struct ShortcutsInsertRequest *request;
|
|||
|
+ GtkFileSystemHandle *handle;
|
|||
|
+ GtkTreePath *p;
|
|||
|
+
|
|||
|
+ request = g_new0 (struct ShortcutsInsertRequest, 1);
|
|||
|
+ request->impl = g_object_ref (impl);
|
|||
|
+ request->path = gtk_file_path_copy (path);
|
|||
|
+ request->name_only = TRUE;
|
|||
|
+ request->removable = removable;
|
|||
|
+ request->pos = pos;
|
|||
|
+ request->type = type;
|
|||
|
+ if (label)
|
|||
|
+ request->label_copy = g_strdup (label);
|
|||
|
+
|
|||
|
+ if (pos == -1)
|
|||
|
+ gtk_list_store_append (impl->shortcuts_model, &iter);
|
|||
|
+ else
|
|||
|
+ gtk_list_store_insert (impl->shortcuts_model, &iter, pos);
|
|||
|
+
|
|||
|
+ p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
|
|||
|
+ request->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->shortcuts_model), p);
|
|||
|
+ gtk_tree_path_free (p);
|
|||
|
+
|
|||
|
+ handle = gtk_file_system_get_info (request->impl->file_system, request->path,
|
|||
|
+ GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_IS_HIDDEN | GTK_FILE_INFO_ICON,
|
|||
|
+ get_file_info_finished, request);
|
|||
|
+
|
|||
|
+ gtk_list_store_set (impl->shortcuts_model, &iter,
|
|||
|
+ SHORTCUTS_COL_DATA, gtk_file_path_copy (path),
|
|||
|
+ SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_PATH,
|
|||
|
+ SHORTCUTS_COL_HANDLE, handle,
|
|||
|
+ -1);
|
|||
|
|
|||
|
- if (pos == -1)
|
|||
|
- gtk_list_store_append (impl->shortcuts_model, &iter);
|
|||
|
+ shortcuts_update_count (impl, type, 1);
|
|||
|
+
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
else
|
|||
|
- gtk_list_store_insert (impl->shortcuts_model, &iter, pos);
|
|||
|
+ {
|
|||
|
+ /* Don't call get_info for remote paths to avoid latency and
|
|||
|
+ * auth dialogs.
|
|||
|
+ */
|
|||
|
+ data = gtk_file_path_copy (path);
|
|||
|
+ if (label)
|
|||
|
+ label_copy = g_strdup (label);
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ gchar *uri;
|
|||
|
|
|||
|
- p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
|
|||
|
- request->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->shortcuts_model), p);
|
|||
|
- gtk_tree_path_free (p);
|
|||
|
-
|
|||
|
- handle = gtk_file_system_get_info (request->impl->file_system, request->path,
|
|||
|
- GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_IS_HIDDEN | GTK_FILE_INFO_ICON,
|
|||
|
- get_file_info_finished, request);
|
|||
|
-
|
|||
|
- gtk_list_store_set (impl->shortcuts_model, &iter,
|
|||
|
- SHORTCUTS_COL_DATA, gtk_file_path_copy (path),
|
|||
|
- SHORTCUTS_COL_IS_VOLUME, is_volume,
|
|||
|
- SHORTCUTS_COL_HANDLE, handle,
|
|||
|
- -1);
|
|||
|
+ uri = gtk_file_system_path_to_uri (impl->file_system, path);
|
|||
|
|
|||
|
- shortcuts_update_count (impl, type, 1);
|
|||
|
+ label_copy = _gtk_file_chooser_label_for_uri (uri);
|
|||
|
|
|||
|
- return;
|
|||
|
+ g_free (uri);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ /* If we switch to a better bookmarks file format (XBEL), we
|
|||
|
+ * should use mime info to get a better icon.
|
|||
|
+ */
|
|||
|
+ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
|
|||
|
+ pixbuf = gtk_icon_theme_load_icon (icon_theme, "gnome-fs-directory",
|
|||
|
+ impl->icon_size, 0, NULL);
|
|||
|
+ }
|
|||
|
}
|
|||
|
- else
|
|||
|
+ else
|
|||
|
{
|
|||
|
- /* Don't call get_info for remote paths to avoid latency and
|
|||
|
- * auth dialogs.
|
|||
|
- */
|
|||
|
- data = gtk_file_path_copy (path);
|
|||
|
- if (label)
|
|||
|
- label_copy = g_strdup (label);
|
|||
|
- else
|
|||
|
- {
|
|||
|
- gchar *uri;
|
|||
|
-
|
|||
|
- uri = gtk_file_system_path_to_uri (impl->file_system, path);
|
|||
|
-
|
|||
|
- label_copy = _gtk_file_chooser_label_for_uri (uri);
|
|||
|
+ g_assert_not_reached ();
|
|||
|
|
|||
|
- g_free (uri);
|
|||
|
- }
|
|||
|
-
|
|||
|
- /* If we switch to a better bookmarks file format (XBEL), we
|
|||
|
- * should use mime info to get a better icon.
|
|||
|
- */
|
|||
|
- icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
|
|||
|
- pixbuf = gtk_icon_theme_load_icon (icon_theme, "gnome-fs-directory",
|
|||
|
- impl->icon_size, 0, NULL);
|
|||
|
+ return;
|
|||
|
}
|
|||
|
|
|||
|
if (pos == -1)
|
|||
|
@@ -1604,13 +1679,16 @@
|
|||
|
SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE,
|
|||
|
SHORTCUTS_COL_NAME, label_copy,
|
|||
|
SHORTCUTS_COL_DATA, data,
|
|||
|
- SHORTCUTS_COL_IS_VOLUME, is_volume,
|
|||
|
+ SHORTCUTS_COL_TYPE, shortcut_type,
|
|||
|
SHORTCUTS_COL_REMOVABLE, removable,
|
|||
|
SHORTCUTS_COL_HANDLE, NULL,
|
|||
|
-1);
|
|||
|
|
|||
|
- if (impl->shortcuts_filter_model)
|
|||
|
- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model));
|
|||
|
+ if (impl->shortcuts_pane_filter_model)
|
|||
|
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model));
|
|||
|
+
|
|||
|
+ if (impl->shortcuts_combo_filter_model)
|
|||
|
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model));
|
|||
|
|
|||
|
if (type == SHORTCUTS_CURRENT_FOLDER && impl->save_folder_combo != NULL)
|
|||
|
{
|
|||
|
@@ -1622,7 +1700,8 @@
|
|||
|
g_signal_handlers_block_by_func (impl->save_folder_combo,
|
|||
|
G_CALLBACK (save_folder_combo_changed_cb),
|
|||
|
impl);
|
|||
|
- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), combo_pos);
|
|||
|
+ gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo),
|
|||
|
+ impl->has_search ? combo_pos - 2 : combo_pos);
|
|||
|
g_signal_handlers_unblock_by_func (impl->save_folder_combo,
|
|||
|
G_CALLBACK (save_folder_combo_changed_cb),
|
|||
|
impl);
|
|||
|
@@ -1636,6 +1715,30 @@
|
|||
|
profile_end ("end", NULL);
|
|||
|
}
|
|||
|
|
|||
|
+static void
|
|||
|
+shortcuts_append_search (GtkFileChooserDefault *impl)
|
|||
|
+{
|
|||
|
+ GdkPixbuf *pixbuf;
|
|||
|
+ GtkTreeIter iter;
|
|||
|
+
|
|||
|
+ pixbuf = render_search_icon (impl);
|
|||
|
+
|
|||
|
+ gtk_list_store_append (impl->shortcuts_model, &iter);
|
|||
|
+ gtk_list_store_set (impl->shortcuts_model, &iter,
|
|||
|
+ SHORTCUTS_COL_PIXBUF, pixbuf,
|
|||
|
+ SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE,
|
|||
|
+ SHORTCUTS_COL_NAME, _("Search"),
|
|||
|
+ SHORTCUTS_COL_DATA, NULL,
|
|||
|
+ SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_SEARCH,
|
|||
|
+ SHORTCUTS_COL_REMOVABLE, FALSE,
|
|||
|
+ -1);
|
|||
|
+
|
|||
|
+ if (pixbuf)
|
|||
|
+ g_object_unref (pixbuf);
|
|||
|
+
|
|||
|
+ impl->has_search = TRUE;
|
|||
|
+}
|
|||
|
+
|
|||
|
/* Appends an item for the user's home directory to the shortcuts model */
|
|||
|
static void
|
|||
|
shortcuts_append_home (GtkFileChooserDefault *impl)
|
|||
|
@@ -1654,7 +1757,8 @@
|
|||
|
|
|||
|
home_path = gtk_file_system_filename_to_path (impl->file_system, home);
|
|||
|
|
|||
|
- shortcuts_insert_path (impl, -1, FALSE, NULL, home_path, NULL, FALSE, SHORTCUTS_HOME);
|
|||
|
+ shortcuts_insert_path (impl, -1, SHORTCUT_TYPE_PATH, NULL, home_path, NULL, FALSE, SHORTCUTS_HOME);
|
|||
|
+ impl->has_home = TRUE;
|
|||
|
|
|||
|
gtk_file_path_free (home_path);
|
|||
|
|
|||
|
@@ -1687,7 +1791,9 @@
|
|||
|
path = gtk_file_system_filename_to_path (impl->file_system, name);
|
|||
|
g_free (name);
|
|||
|
|
|||
|
- shortcuts_insert_path (impl, -1, FALSE, NULL, path, _("Desktop"), FALSE, SHORTCUTS_DESKTOP);
|
|||
|
+ shortcuts_insert_path (impl, -1, SHORTCUT_TYPE_PATH, NULL, path, _("Desktop"), FALSE, SHORTCUTS_DESKTOP);
|
|||
|
+ impl->has_desktop = TRUE;
|
|||
|
+
|
|||
|
/* We do not actually pop up an error dialog if there is no desktop directory
|
|||
|
* because some people may really not want to have one.
|
|||
|
*/
|
|||
|
@@ -1726,7 +1832,7 @@
|
|||
|
label = gtk_file_system_get_bookmark_label (impl->file_system, path);
|
|||
|
|
|||
|
/* NULL GError, but we don't really want to show error boxes here */
|
|||
|
- shortcuts_insert_path (impl, start_row + num_inserted, FALSE, NULL, path, label, TRUE, SHORTCUTS_BOOKMARKS);
|
|||
|
+ shortcuts_insert_path (impl, start_row + num_inserted, SHORTCUT_TYPE_PATH, NULL, path, label, TRUE, SHORTCUTS_BOOKMARKS);
|
|||
|
num_inserted++;
|
|||
|
|
|||
|
g_free (label);
|
|||
|
@@ -1745,6 +1851,16 @@
|
|||
|
int n;
|
|||
|
|
|||
|
n = 0;
|
|||
|
+
|
|||
|
+ if (where == SHORTCUTS_SEARCH)
|
|||
|
+ goto out;
|
|||
|
+
|
|||
|
+ n += impl->has_search ? 1 : 0;
|
|||
|
+
|
|||
|
+ if (where == SHORTCUTS_SEARCH_SEPARATOR)
|
|||
|
+ goto out;
|
|||
|
+
|
|||
|
+ n += impl->has_search ? 1 : 0;
|
|||
|
|
|||
|
if (where == SHORTCUTS_HOME)
|
|||
|
goto out;
|
|||
|
@@ -1842,15 +1958,18 @@
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
- shortcuts_insert_path (impl, start_row + n, TRUE, volume, NULL, NULL, FALSE, SHORTCUTS_VOLUMES);
|
|||
|
+ shortcuts_insert_path (impl, start_row + n, SHORTCUT_TYPE_VOLUME, volume, NULL, NULL, FALSE, SHORTCUTS_VOLUMES);
|
|||
|
n++;
|
|||
|
}
|
|||
|
|
|||
|
impl->num_volumes = n;
|
|||
|
g_slist_free (list);
|
|||
|
|
|||
|
- if (impl->shortcuts_filter_model)
|
|||
|
- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model));
|
|||
|
+ if (impl->shortcuts_pane_filter_model)
|
|||
|
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model));
|
|||
|
+
|
|||
|
+ if (impl->shortcuts_combo_filter_model)
|
|||
|
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model));
|
|||
|
|
|||
|
impl->changing_folder = old_changing_folders;
|
|||
|
|
|||
|
@@ -1860,11 +1979,13 @@
|
|||
|
/* Inserts a separator node in the shortcuts list */
|
|||
|
static void
|
|||
|
shortcuts_insert_separator (GtkFileChooserDefault *impl,
|
|||
|
- ShortcutsIndex where)
|
|||
|
+ ShortcutsIndex where)
|
|||
|
{
|
|||
|
GtkTreeIter iter;
|
|||
|
|
|||
|
- g_assert (where == SHORTCUTS_BOOKMARKS_SEPARATOR || where == SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
|
|||
|
+ g_assert (where == SHORTCUTS_SEARCH_SEPARATOR ||
|
|||
|
+ where == SHORTCUTS_BOOKMARKS_SEPARATOR ||
|
|||
|
+ where == SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
|
|||
|
|
|||
|
gtk_list_store_insert (impl->shortcuts_model, &iter,
|
|||
|
shortcuts_get_index (impl, where));
|
|||
|
@@ -1873,6 +1994,7 @@
|
|||
|
SHORTCUTS_COL_PIXBUF_VISIBLE, FALSE,
|
|||
|
SHORTCUTS_COL_NAME, NULL,
|
|||
|
SHORTCUTS_COL_DATA, NULL,
|
|||
|
+ SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_SEPARATOR,
|
|||
|
-1);
|
|||
|
}
|
|||
|
|
|||
|
@@ -1885,7 +2007,7 @@
|
|||
|
GtkTreeIter iter;
|
|||
|
GtkFilePath *list_selected = NULL;
|
|||
|
GtkFilePath *combo_selected = NULL;
|
|||
|
- gboolean is_volume;
|
|||
|
+ ShortcutType shortcut_type;
|
|||
|
gpointer col_data;
|
|||
|
|
|||
|
profile_start ("start", NULL);
|
|||
|
@@ -1898,10 +2020,10 @@
|
|||
|
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model),
|
|||
|
&iter,
|
|||
|
SHORTCUTS_COL_DATA, &col_data,
|
|||
|
- SHORTCUTS_COL_IS_VOLUME, &is_volume,
|
|||
|
+ SHORTCUTS_COL_TYPE, &shortcut_type,
|
|||
|
-1);
|
|||
|
|
|||
|
- if (col_data && !is_volume)
|
|||
|
+ if (col_data && shortcut_type == SHORTCUT_TYPE_PATH)
|
|||
|
list_selected = gtk_file_path_copy (col_data);
|
|||
|
}
|
|||
|
|
|||
|
@@ -1909,13 +2031,18 @@
|
|||
|
gtk_combo_box_get_active_iter (GTK_COMBO_BOX (impl->save_folder_combo),
|
|||
|
&iter))
|
|||
|
{
|
|||
|
+ GtkTreeIter child_iter;
|
|||
|
+
|
|||
|
+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model),
|
|||
|
+ &child_iter,
|
|||
|
+ &iter);
|
|||
|
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model),
|
|||
|
- &iter,
|
|||
|
+ &child_iter,
|
|||
|
SHORTCUTS_COL_DATA, &col_data,
|
|||
|
- SHORTCUTS_COL_IS_VOLUME, &is_volume,
|
|||
|
+ SHORTCUTS_COL_TYPE, &shortcut_type,
|
|||
|
-1);
|
|||
|
|
|||
|
- if (col_data && !is_volume)
|
|||
|
+ if (col_data && shortcut_type == SHORTCUT_TYPE_PATH)
|
|||
|
combo_selected = gtk_file_path_copy (col_data);
|
|||
|
}
|
|||
|
|
|||
|
@@ -1933,8 +2060,11 @@
|
|||
|
if (impl->num_bookmarks > 0)
|
|||
|
shortcuts_insert_separator (impl, SHORTCUTS_BOOKMARKS_SEPARATOR);
|
|||
|
|
|||
|
- if (impl->shortcuts_filter_model)
|
|||
|
- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model));
|
|||
|
+ if (impl->shortcuts_pane_filter_model)
|
|||
|
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model));
|
|||
|
+
|
|||
|
+ if (impl->shortcuts_combo_filter_model)
|
|||
|
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model));
|
|||
|
|
|||
|
if (list_selected)
|
|||
|
{
|
|||
|
@@ -1948,8 +2078,8 @@
|
|||
|
|
|||
|
pos = shortcut_find_position (impl, combo_selected);
|
|||
|
if (pos != -1)
|
|||
|
- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo),
|
|||
|
- pos);
|
|||
|
+ gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo),
|
|||
|
+ impl->has_search ? pos - 2 : pos);
|
|||
|
gtk_file_path_free (combo_selected);
|
|||
|
}
|
|||
|
|
|||
|
@@ -1994,11 +2124,11 @@
|
|||
|
if (base_path &&
|
|||
|
strcmp (gtk_file_path_get_string (base_path), gtk_file_path_get_string (impl->current_folder)) == 0)
|
|||
|
{
|
|||
|
- shortcuts_insert_path (impl, pos, TRUE, volume, NULL, NULL, FALSE, SHORTCUTS_CURRENT_FOLDER);
|
|||
|
+ shortcuts_insert_path (impl, pos, SHORTCUT_TYPE_VOLUME, volume, NULL, NULL, FALSE, SHORTCUTS_CURRENT_FOLDER);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
- shortcuts_insert_path (impl, pos, FALSE, NULL, impl->current_folder, NULL, FALSE, SHORTCUTS_CURRENT_FOLDER);
|
|||
|
+ shortcuts_insert_path (impl, pos, SHORTCUT_TYPE_PATH, NULL, impl->current_folder, NULL, FALSE, SHORTCUTS_CURRENT_FOLDER);
|
|||
|
if (volume)
|
|||
|
gtk_file_system_volume_free (impl->file_system, volume);
|
|||
|
}
|
|||
|
@@ -2007,7 +2137,8 @@
|
|||
|
gtk_file_path_free (base_path);
|
|||
|
}
|
|||
|
else if (impl->save_folder_combo != NULL)
|
|||
|
- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), pos);
|
|||
|
+ gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo),
|
|||
|
+ impl->has_search ? pos - 2 : pos);
|
|||
|
}
|
|||
|
|
|||
|
/* Updates the current folder row in the shortcuts model */
|
|||
|
@@ -2029,9 +2160,9 @@
|
|||
|
|
|||
|
/* Filter function used for the shortcuts filter model */
|
|||
|
static gboolean
|
|||
|
-shortcuts_filter_cb (GtkTreeModel *model,
|
|||
|
- GtkTreeIter *iter,
|
|||
|
- gpointer data)
|
|||
|
+shortcuts_pane_filter_cb (GtkTreeModel *model,
|
|||
|
+ GtkTreeIter *iter,
|
|||
|
+ gpointer data)
|
|||
|
{
|
|||
|
GtkFileChooserDefault *impl;
|
|||
|
GtkTreePath *path;
|
|||
|
@@ -2058,11 +2189,17 @@
|
|||
|
GDK_TYPE_PIXBUF, /* pixbuf */
|
|||
|
G_TYPE_STRING, /* name */
|
|||
|
G_TYPE_POINTER, /* path or volume */
|
|||
|
- G_TYPE_BOOLEAN, /* is the previous column a volume? */
|
|||
|
+ G_TYPE_INT, /* ShortcutType */
|
|||
|
G_TYPE_BOOLEAN, /* removable */
|
|||
|
G_TYPE_BOOLEAN, /* pixbuf cell visibility */
|
|||
|
G_TYPE_POINTER); /* GtkFileSystemHandle */
|
|||
|
|
|||
|
+ if (search_is_possible (impl))
|
|||
|
+ {
|
|||
|
+ shortcuts_append_search (impl);
|
|||
|
+ shortcuts_insert_separator (impl, SHORTCUTS_SEARCH_SEPARATOR);
|
|||
|
+ }
|
|||
|
+
|
|||
|
if (impl->file_system)
|
|||
|
{
|
|||
|
shortcuts_append_home (impl);
|
|||
|
@@ -2070,12 +2207,12 @@
|
|||
|
shortcuts_add_volumes (impl);
|
|||
|
}
|
|||
|
|
|||
|
- impl->shortcuts_filter_model = shortcuts_model_filter_new (impl,
|
|||
|
- GTK_TREE_MODEL (impl->shortcuts_model),
|
|||
|
- NULL);
|
|||
|
+ impl->shortcuts_pane_filter_model = shortcuts_pane_model_filter_new (impl,
|
|||
|
+ GTK_TREE_MODEL (impl->shortcuts_model),
|
|||
|
+ NULL);
|
|||
|
|
|||
|
- gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model),
|
|||
|
- shortcuts_filter_cb,
|
|||
|
+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model),
|
|||
|
+ shortcuts_pane_filter_cb,
|
|||
|
impl,
|
|||
|
NULL);
|
|||
|
}
|
|||
|
@@ -2293,16 +2430,16 @@
|
|||
|
for (i = 0; i < current_folder_separator_idx; i++)
|
|||
|
{
|
|||
|
gpointer col_data;
|
|||
|
- gboolean is_volume;
|
|||
|
+ ShortcutType shortcut_type;
|
|||
|
|
|||
|
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
|
|||
|
SHORTCUTS_COL_DATA, &col_data,
|
|||
|
- SHORTCUTS_COL_IS_VOLUME, &is_volume,
|
|||
|
+ SHORTCUTS_COL_TYPE, &shortcut_type,
|
|||
|
-1);
|
|||
|
|
|||
|
if (col_data)
|
|||
|
{
|
|||
|
- if (is_volume)
|
|||
|
+ if (shortcut_type == SHORTCUT_TYPE_VOLUME)
|
|||
|
{
|
|||
|
GtkFileSystemVolume *volume;
|
|||
|
GtkFilePath *base_path;
|
|||
|
@@ -2318,7 +2455,7 @@
|
|||
|
if (exists)
|
|||
|
return i;
|
|||
|
}
|
|||
|
- else
|
|||
|
+ else if (shortcut_type == SHORTCUT_TYPE_PATH)
|
|||
|
{
|
|||
|
GtkFilePath *model_path;
|
|||
|
|
|||
|
@@ -2424,7 +2561,7 @@
|
|||
|
if (!gtk_tree_selection_get_selected (selection, NULL, &parent_iter))
|
|||
|
return FALSE;
|
|||
|
|
|||
|
- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model),
|
|||
|
+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model),
|
|||
|
iter,
|
|||
|
&parent_iter);
|
|||
|
return TRUE;
|
|||
|
@@ -2447,11 +2584,12 @@
|
|||
|
SHORTCUTS_COL_DATA, &col_data,
|
|||
|
SHORTCUTS_COL_REMOVABLE, &removable,
|
|||
|
-1);
|
|||
|
- g_assert (col_data != NULL);
|
|||
|
|
|||
|
if (!removable)
|
|||
|
return;
|
|||
|
|
|||
|
+ g_assert (col_data != NULL);
|
|||
|
+
|
|||
|
path = col_data;
|
|||
|
|
|||
|
error = NULL;
|
|||
|
@@ -2608,6 +2746,16 @@
|
|||
|
gboolean active;
|
|||
|
gchar *tip;
|
|||
|
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH)
|
|||
|
+ {
|
|||
|
+ gtk_widget_set_sensitive (impl->browse_shortcuts_add_button, FALSE);
|
|||
|
+
|
|||
|
+ if (impl->browse_files_popup_menu_add_shortcut_item)
|
|||
|
+ gtk_widget_set_sensitive (impl->browse_files_popup_menu_add_shortcut_item, FALSE);
|
|||
|
+
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
selection_check (impl, &num_selected, NULL, &all_folders);
|
|||
|
|
|||
|
if (num_selected == 0)
|
|||
|
@@ -3121,7 +3269,7 @@
|
|||
|
{
|
|||
|
GtkTreeIter iter;
|
|||
|
gpointer col_data;
|
|||
|
- gboolean is_volume;
|
|||
|
+ ShortcutType shortcut_type;
|
|||
|
GtkTreePath *path;
|
|||
|
int old_position;
|
|||
|
int bookmarks_index;
|
|||
|
@@ -3146,10 +3294,10 @@
|
|||
|
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
|
|||
|
SHORTCUTS_COL_NAME, &name,
|
|||
|
SHORTCUTS_COL_DATA, &col_data,
|
|||
|
- SHORTCUTS_COL_IS_VOLUME, &is_volume,
|
|||
|
+ SHORTCUTS_COL_TYPE, &shortcut_type,
|
|||
|
-1);
|
|||
|
g_assert (col_data != NULL);
|
|||
|
- g_assert (!is_volume);
|
|||
|
+ g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
|
|||
|
|
|||
|
file_path = col_data;
|
|||
|
file_path_copy = gtk_file_path_copy (file_path); /* removal below will free file_path, so we need a copy */
|
|||
|
@@ -3233,17 +3381,11 @@
|
|||
|
GtkTreeIter *iter,
|
|||
|
gpointer data)
|
|||
|
{
|
|||
|
- gint column = GPOINTER_TO_INT (data);
|
|||
|
- gchar *text;
|
|||
|
+ ShortcutType shortcut_type;
|
|||
|
|
|||
|
- gtk_tree_model_get (model, iter, column, &text, -1);
|
|||
|
+ gtk_tree_model_get (model, iter, SHORTCUTS_COL_TYPE, &shortcut_type, -1);
|
|||
|
|
|||
|
- if (!text)
|
|||
|
- return TRUE;
|
|||
|
-
|
|||
|
- g_free (text);
|
|||
|
-
|
|||
|
- return FALSE;
|
|||
|
+ return shortcut_type == SHORTCUT_TYPE_SEPARATOR;
|
|||
|
}
|
|||
|
|
|||
|
/* Since GtkTreeView has a keybinding attached to '/', we need to catch
|
|||
|
@@ -3488,7 +3630,7 @@
|
|||
|
/* Accessible object name for the file chooser's shortcuts pane */
|
|||
|
atk_object_set_name (gtk_widget_get_accessible (impl->browse_shortcuts_tree_view), _("Places"));
|
|||
|
|
|||
|
- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), impl->shortcuts_filter_model);
|
|||
|
+ gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), impl->shortcuts_pane_filter_model);
|
|||
|
|
|||
|
gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
|
|||
|
GDK_BUTTON1_MASK,
|
|||
|
@@ -3561,8 +3703,7 @@
|
|||
|
|
|||
|
gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
|
|||
|
shortcuts_row_separator_func,
|
|||
|
- GINT_TO_POINTER (SHORTCUTS_COL_NAME),
|
|||
|
- NULL);
|
|||
|
+ NULL, NULL);
|
|||
|
|
|||
|
gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), column);
|
|||
|
|
|||
|
@@ -3933,6 +4074,8 @@
|
|||
|
{
|
|||
|
file_list_build_popup_menu (impl);
|
|||
|
|
|||
|
+ /* FMQ: handle OPERATION_MODE_SEARCH */
|
|||
|
+
|
|||
|
/* The sensitivity of the Add to Bookmarks item is set in
|
|||
|
* bookmarks_check_add_sensitivity()
|
|||
|
*/
|
|||
|
@@ -4032,6 +4175,28 @@
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
+/* Sets the sort column IDs for the file list based on the operation mode */
|
|||
|
+static void
|
|||
|
+file_list_set_sort_column_ids (GtkFileChooserDefault *impl)
|
|||
|
+{
|
|||
|
+ int name_id, mtime_id;
|
|||
|
+
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_BROWSE)
|
|||
|
+ {
|
|||
|
+ name_id = FILE_LIST_COL_NAME;
|
|||
|
+ mtime_id = FILE_LIST_COL_MTIME;
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ name_id = SEARCH_MODEL_COL_PATH;
|
|||
|
+ mtime_id = SEARCH_MODEL_COL_STAT;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ gtk_tree_view_column_set_sort_column_id (impl->list_name_column, name_id);
|
|||
|
+ gtk_tree_view_column_set_sort_column_id (impl->list_mtime_column, mtime_id);
|
|||
|
+}
|
|||
|
+
|
|||
|
+
|
|||
|
/* Creates the widgets for the file list */
|
|||
|
static GtkWidget *
|
|||
|
create_file_list (GtkFileChooserDefault *impl)
|
|||
|
@@ -4045,7 +4210,7 @@
|
|||
|
|
|||
|
swin = gtk_scrolled_window_new (NULL, NULL);
|
|||
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
|
|||
|
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
|||
|
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
|
|||
|
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin),
|
|||
|
GTK_SHADOW_IN);
|
|||
|
|
|||
|
@@ -4135,6 +4300,7 @@
|
|||
|
gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_SIZE);
|
|||
|
gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
|
|||
|
#endif
|
|||
|
+
|
|||
|
/* Modification time column */
|
|||
|
|
|||
|
column = gtk_tree_view_column_new ();
|
|||
|
@@ -4145,8 +4311,11 @@
|
|||
|
gtk_tree_view_column_pack_start (column, renderer, TRUE);
|
|||
|
gtk_tree_view_column_set_cell_data_func (column, renderer,
|
|||
|
list_mtime_data_func, impl, NULL);
|
|||
|
- gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_MTIME);
|
|||
|
gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
|
|||
|
+ impl->list_mtime_column = column;
|
|||
|
+
|
|||
|
+ file_list_set_sort_column_ids (impl);
|
|||
|
+
|
|||
|
gtk_widget_show_all (swin);
|
|||
|
|
|||
|
return swin;
|
|||
|
@@ -4254,9 +4423,59 @@
|
|||
|
return;
|
|||
|
|
|||
|
if (gtk_combo_box_get_active_iter (combo, &iter))
|
|||
|
- shortcuts_activate_iter (impl, &iter);
|
|||
|
+ {
|
|||
|
+ GtkTreeIter child_iter;
|
|||
|
+
|
|||
|
+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model),
|
|||
|
+ &child_iter,
|
|||
|
+ &iter);
|
|||
|
+ shortcuts_activate_iter (impl, &child_iter);
|
|||
|
+ }
|
|||
|
}
|
|||
|
|
|||
|
+/* Filter function used to filter out the Search item and its separator.
|
|||
|
+ * Used for the "Save in folder" combo box, so that these items do not appear in it.
|
|||
|
+ */
|
|||
|
+static gboolean
|
|||
|
+shortcuts_combo_filter_func (GtkTreeModel *model,
|
|||
|
+ GtkTreeIter *iter,
|
|||
|
+ gpointer data)
|
|||
|
+{
|
|||
|
+ GtkFileChooserDefault *impl;
|
|||
|
+ GtkTreePath *tree_path;
|
|||
|
+ gint *indices;
|
|||
|
+ int idx;
|
|||
|
+ gboolean retval;
|
|||
|
+
|
|||
|
+ impl = GTK_FILE_CHOOSER_DEFAULT (data);
|
|||
|
+
|
|||
|
+ g_assert (model == GTK_TREE_MODEL (impl->shortcuts_model));
|
|||
|
+
|
|||
|
+ tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), iter);
|
|||
|
+ g_assert (tree_path != NULL);
|
|||
|
+
|
|||
|
+ indices = gtk_tree_path_get_indices (tree_path);
|
|||
|
+
|
|||
|
+ retval = TRUE;
|
|||
|
+
|
|||
|
+ if (impl->has_search)
|
|||
|
+ {
|
|||
|
+ idx = shortcuts_get_index (impl, SHORTCUTS_SEARCH);
|
|||
|
+ if (idx == indices[0])
|
|||
|
+ retval = FALSE;
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ idx = shortcuts_get_index (impl, SHORTCUTS_SEARCH_SEPARATOR);
|
|||
|
+ if (idx == indices[0])
|
|||
|
+ retval = FALSE;
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ gtk_tree_path_free (tree_path);
|
|||
|
+
|
|||
|
+ return retval;
|
|||
|
+ }
|
|||
|
+
|
|||
|
/* Creates the combo box with the save folders */
|
|||
|
static GtkWidget *
|
|||
|
save_folder_combo_create (GtkFileChooserDefault *impl)
|
|||
|
@@ -4264,8 +4483,14 @@
|
|||
|
GtkWidget *combo;
|
|||
|
GtkCellRenderer *cell;
|
|||
|
|
|||
|
+ impl->shortcuts_combo_filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->shortcuts_model), NULL);
|
|||
|
+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model),
|
|||
|
+ shortcuts_combo_filter_func,
|
|||
|
+ impl,
|
|||
|
+ NULL);
|
|||
|
+
|
|||
|
combo = g_object_new (GTK_TYPE_COMBO_BOX,
|
|||
|
- "model", impl->shortcuts_model,
|
|||
|
+ "model", impl->shortcuts_combo_filter_model,
|
|||
|
"focus-on-click", FALSE,
|
|||
|
NULL);
|
|||
|
gtk_widget_show (combo);
|
|||
|
@@ -4287,8 +4512,7 @@
|
|||
|
|
|||
|
gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo),
|
|||
|
shortcuts_row_separator_func,
|
|||
|
- GINT_TO_POINTER (SHORTCUTS_COL_NAME),
|
|||
|
- NULL);
|
|||
|
+ NULL, NULL);
|
|||
|
|
|||
|
g_signal_connect (combo, "changed",
|
|||
|
G_CALLBACK (save_folder_combo_changed_cb), impl);
|
|||
|
@@ -4622,6 +4846,7 @@
|
|||
|
hbox = gtk_hbox_new (FALSE, 12);
|
|||
|
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
|||
|
gtk_widget_show (hbox);
|
|||
|
+ impl->browse_path_bar_hbox = hbox;
|
|||
|
|
|||
|
location_button_create (impl);
|
|||
|
gtk_box_pack_start (GTK_BOX (hbox), impl->location_button, FALSE, FALSE, 0);
|
|||
|
@@ -5210,6 +5435,9 @@
|
|||
|
impl->shortcuts_activate_iter_handle = NULL;
|
|||
|
}
|
|||
|
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH)
|
|||
|
+ search_stop_searching (impl);
|
|||
|
+
|
|||
|
remove_settings_signal (impl, gtk_widget_get_screen (GTK_WIDGET (impl)));
|
|||
|
|
|||
|
G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->dispose (object);
|
|||
|
@@ -5487,31 +5715,32 @@
|
|||
|
|
|||
|
GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->map (widget);
|
|||
|
|
|||
|
- switch (impl->reload_state)
|
|||
|
- {
|
|||
|
- case RELOAD_EMPTY:
|
|||
|
- /* The user didn't explicitly give us a folder to display, so we'll use the cwd */
|
|||
|
- current_working_dir = g_get_current_dir ();
|
|||
|
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (impl), current_working_dir);
|
|||
|
- g_free (current_working_dir);
|
|||
|
- break;
|
|||
|
-
|
|||
|
- case RELOAD_HAS_FOLDER:
|
|||
|
- /* Nothing; we are already loading or loaded, so we don't need to reload */
|
|||
|
- break;
|
|||
|
-
|
|||
|
- case RELOAD_WAS_UNMAPPED:
|
|||
|
- /* Just reload the current folder; else continue the pending load. */
|
|||
|
- if (impl->current_folder)
|
|||
|
- {
|
|||
|
- pending_select_paths_store_selection (impl);
|
|||
|
- change_folder_and_display_error (impl, impl->current_folder);
|
|||
|
- }
|
|||
|
- break;
|
|||
|
-
|
|||
|
- default:
|
|||
|
- g_assert_not_reached ();
|
|||
|
- }
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_BROWSE)
|
|||
|
+ switch (impl->reload_state)
|
|||
|
+ {
|
|||
|
+ case RELOAD_EMPTY:
|
|||
|
+ /* The user didn't explicitly give us a folder to display, so we'll use the cwd */
|
|||
|
+ current_working_dir = g_get_current_dir ();
|
|||
|
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (impl), current_working_dir);
|
|||
|
+ g_free (current_working_dir);
|
|||
|
+ break;
|
|||
|
+
|
|||
|
+ case RELOAD_HAS_FOLDER:
|
|||
|
+ /* Nothing; we are already loading or loaded, so we don't need to reload */
|
|||
|
+ break;
|
|||
|
+
|
|||
|
+ case RELOAD_WAS_UNMAPPED:
|
|||
|
+ /* Just reload the current folder; else continue the pending load. */
|
|||
|
+ if (impl->current_folder)
|
|||
|
+ {
|
|||
|
+ pending_select_paths_store_selection (impl);
|
|||
|
+ change_folder_and_display_error (impl, impl->current_folder);
|
|||
|
+ }
|
|||
|
+ break;
|
|||
|
+
|
|||
|
+ default:
|
|||
|
+ g_assert_not_reached ();
|
|||
|
+ }
|
|||
|
|
|||
|
bookmarks_changed_cb (impl->file_system, impl);
|
|||
|
|
|||
|
@@ -5982,12 +6211,6 @@
|
|||
|
* but rather on behalf of something else like GtkFileChooserButton. In
|
|||
|
* that case, the chooser's selection should be what the caller expects,
|
|||
|
* as the user can't see that something else got selected. See bug #165264.
|
|||
|
- *
|
|||
|
- * Also, we don't select the first file if we are not in OPEN mode. Doing
|
|||
|
- * so would change the contents of the filename entry for SAVE or
|
|||
|
- * CREATE_FOLDER, which is undesired; in SELECT_FOLDER, we don't want to
|
|||
|
- * select a *different* folder from the one into which the user just
|
|||
|
- * navigated.
|
|||
|
*/
|
|||
|
if (GTK_WIDGET_MAPPED (impl) && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
|
|||
|
browse_files_select_first_row (impl);
|
|||
|
@@ -6034,17 +6257,11 @@
|
|||
|
profile_end ("end", NULL);
|
|||
|
}
|
|||
|
|
|||
|
-/* Gets rid of the old list model and creates a new one for the current folder */
|
|||
|
-static gboolean
|
|||
|
-set_list_model (GtkFileChooserDefault *impl,
|
|||
|
- GError **error)
|
|||
|
+static void
|
|||
|
+stop_loading_and_clear_list_model (GtkFileChooserDefault *impl)
|
|||
|
{
|
|||
|
- g_assert (impl->current_folder != NULL);
|
|||
|
-
|
|||
|
- profile_start ("start", NULL);
|
|||
|
-
|
|||
|
load_remove_timer (impl); /* This changes the state to LOAD_EMPTY */
|
|||
|
-
|
|||
|
+
|
|||
|
if (impl->browse_files_model)
|
|||
|
{
|
|||
|
g_object_unref (impl->browse_files_model);
|
|||
|
@@ -6056,6 +6273,20 @@
|
|||
|
g_object_unref (impl->sort_model);
|
|||
|
impl->sort_model = NULL;
|
|||
|
}
|
|||
|
+
|
|||
|
+ gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Gets rid of the old list model and creates a new one for the current folder */
|
|||
|
+static gboolean
|
|||
|
+set_list_model (GtkFileChooserDefault *impl,
|
|||
|
+ GError **error)
|
|||
|
+{
|
|||
|
+ g_assert (impl->current_folder != NULL);
|
|||
|
+
|
|||
|
+ profile_start ("start", NULL);
|
|||
|
+
|
|||
|
+ stop_loading_and_clear_list_model (impl);
|
|||
|
|
|||
|
set_busy_cursor (impl, TRUE);
|
|||
|
gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
|
|||
|
@@ -6130,6 +6361,9 @@
|
|||
|
struct update_chooser_entry_selected_foreach_closure closure;
|
|||
|
const char *file_part;
|
|||
|
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH || !impl->location_entry)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
if (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|
|||
|
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
|
|||
|
|| ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
|
|||
|
@@ -6151,35 +6385,40 @@
|
|||
|
}
|
|||
|
else if (closure.num_selected == 1)
|
|||
|
{
|
|||
|
- GtkTreeIter child_iter;
|
|||
|
- const GtkFileInfo *info;
|
|||
|
- gboolean change_entry;
|
|||
|
-
|
|||
|
- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
|
|||
|
- &child_iter,
|
|||
|
- &closure.first_selected_iter);
|
|||
|
-
|
|||
|
- info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
|
|||
|
-
|
|||
|
- /* If the cursor moved to the row of the newly created folder,
|
|||
|
- * retrieving info will return NULL.
|
|||
|
- */
|
|||
|
- if (!info)
|
|||
|
- return;
|
|||
|
-
|
|||
|
- g_free (impl->browse_files_last_selected_name);
|
|||
|
- impl->browse_files_last_selected_name = g_strdup (gtk_file_info_get_display_name (info));
|
|||
|
-
|
|||
|
- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
|
|||
|
- || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
|||
|
- change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */
|
|||
|
- else
|
|||
|
- change_entry = TRUE; /* ... unless we are in one of the folder modes */
|
|||
|
-
|
|||
|
- if (change_entry)
|
|||
|
- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->browse_files_last_selected_name);
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_BROWSE)
|
|||
|
+ {
|
|||
|
+ GtkTreeIter child_iter;
|
|||
|
+ const GtkFileInfo *info;
|
|||
|
+ gboolean change_entry;
|
|||
|
+
|
|||
|
+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
|
|||
|
+ &child_iter,
|
|||
|
+ &closure.first_selected_iter);
|
|||
|
+
|
|||
|
+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
|
|||
|
+
|
|||
|
+ /* If the cursor moved to the row of the newly created folder,
|
|||
|
+ * retrieving info will return NULL.
|
|||
|
+ */
|
|||
|
+ if (!info)
|
|||
|
+ return;
|
|||
|
|
|||
|
- return;
|
|||
|
+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
|
|||
|
+ || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|
|||
|
+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
|
|||
|
+ change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */
|
|||
|
+ else
|
|||
|
+ change_entry = TRUE; /* ... unless we are in CREATE_FOLDER mode */
|
|||
|
+
|
|||
|
+ if (change_entry)
|
|||
|
+ file_part = gtk_file_info_get_display_name (info);
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &closure.first_selected_iter,
|
|||
|
+ SEARCH_MODEL_COL_DISPLAY_NAME, &file_part,
|
|||
|
+ -1);
|
|||
|
+ }
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
@@ -6386,6 +6625,8 @@
|
|||
|
|
|||
|
profile_start ("start", (char *) path);
|
|||
|
|
|||
|
+ search_switch_to_browse_mode (impl);
|
|||
|
+
|
|||
|
g_assert (path != NULL);
|
|||
|
|
|||
|
if (impl->local_only &&
|
|||
|
@@ -6427,6 +6668,9 @@
|
|||
|
{
|
|||
|
GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
|
|||
|
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH)
|
|||
|
+ return NULL;
|
|||
|
+
|
|||
|
if (impl->reload_state == RELOAD_EMPTY)
|
|||
|
{
|
|||
|
char *current_working_dir;
|
|||
|
@@ -6487,9 +6731,9 @@
|
|||
|
return FALSE;
|
|||
|
|
|||
|
if (!parent_path)
|
|||
|
- return _gtk_file_chooser_set_current_folder_path (chooser, path, error);
|
|||
|
+ return _gtk_file_chooser_set_current_folder_path (chooser, path, error);
|
|||
|
|
|||
|
- if (impl->load_state == LOAD_EMPTY)
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH || impl->load_state == LOAD_EMPTY)
|
|||
|
same_path = FALSE;
|
|||
|
else
|
|||
|
{
|
|||
|
@@ -6585,6 +6829,16 @@
|
|||
|
gtk_file_chooser_default_select_all (GtkFileChooser *chooser)
|
|||
|
{
|
|||
|
GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
|
|||
|
+
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH)
|
|||
|
+ {
|
|||
|
+ GtkTreeSelection *selection;
|
|||
|
+
|
|||
|
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
|
|||
|
+ gtk_tree_selection_select_all (selection);
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
if (impl->select_multiple)
|
|||
|
gtk_tree_model_foreach (GTK_TREE_MODEL (impl->sort_model),
|
|||
|
maybe_select, impl);
|
|||
|
@@ -6714,6 +6968,10 @@
|
|||
|
struct get_paths_closure info;
|
|||
|
GtkWindow *toplevel;
|
|||
|
GtkWidget *current_focus;
|
|||
|
+ gboolean file_list_seen;
|
|||
|
+
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH)
|
|||
|
+ return search_get_selected_paths (impl);
|
|||
|
|
|||
|
info.impl = impl;
|
|||
|
info.result = NULL;
|
|||
|
@@ -6725,12 +6983,14 @@
|
|||
|
else
|
|||
|
current_focus = NULL;
|
|||
|
|
|||
|
+ file_list_seen = FALSE;
|
|||
|
if (current_focus == impl->browse_files_tree_view)
|
|||
|
{
|
|||
|
GtkTreeSelection *selection;
|
|||
|
|
|||
|
file_list:
|
|||
|
|
|||
|
+ file_list_seen = TRUE;
|
|||
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
|
|||
|
gtk_tree_selection_selected_foreach (selection, get_paths_foreach, &info);
|
|||
|
|
|||
|
@@ -6765,8 +7025,12 @@
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
- g_assert (info.path_from_entry != NULL);
|
|||
|
- info.result = g_slist_prepend (info.result, info.path_from_entry);
|
|||
|
+ if (info.path_from_entry)
|
|||
|
+ info.result = g_slist_prepend (info.result, info.path_from_entry);
|
|||
|
+ else if (!file_list_seen)
|
|||
|
+ goto file_list;
|
|||
|
+ else
|
|||
|
+ return NULL;
|
|||
|
}
|
|||
|
else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view)
|
|||
|
goto file_list;
|
|||
|
@@ -6935,7 +7199,7 @@
|
|||
|
|
|||
|
pos = shortcuts_get_pos_for_shortcut_folder (data->impl, data->impl->num_shortcuts);
|
|||
|
|
|||
|
- shortcuts_insert_path (data->impl, pos, FALSE, NULL, data->path, NULL, FALSE, SHORTCUTS_SHORTCUTS);
|
|||
|
+ shortcuts_insert_path (data->impl, pos, SHORTCUT_TYPE_PATH, NULL, data->path, NULL, FALSE, SHORTCUTS_SHORTCUTS);
|
|||
|
|
|||
|
out:
|
|||
|
g_object_unref (data->impl);
|
|||
|
@@ -7049,15 +7313,15 @@
|
|||
|
for (i = 0; i < impl->num_shortcuts; i++)
|
|||
|
{
|
|||
|
gpointer col_data;
|
|||
|
- gboolean is_volume;
|
|||
|
+ ShortcutType shortcut_type;
|
|||
|
GtkFilePath *shortcut;
|
|||
|
|
|||
|
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
|
|||
|
SHORTCUTS_COL_DATA, &col_data,
|
|||
|
- SHORTCUTS_COL_IS_VOLUME, &is_volume,
|
|||
|
+ SHORTCUTS_COL_TYPE, &shortcut_type,
|
|||
|
-1);
|
|||
|
g_assert (col_data != NULL);
|
|||
|
- g_assert (!is_volume);
|
|||
|
+ g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
|
|||
|
|
|||
|
shortcut = col_data;
|
|||
|
if (gtk_file_path_compare (shortcut, path) == 0)
|
|||
|
@@ -7106,15 +7370,15 @@
|
|||
|
for (i = 0; i < impl->num_shortcuts; i++)
|
|||
|
{
|
|||
|
gpointer col_data;
|
|||
|
- gboolean is_volume;
|
|||
|
+ ShortcutType shortcut_type;
|
|||
|
GtkFilePath *shortcut;
|
|||
|
|
|||
|
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
|
|||
|
SHORTCUTS_COL_DATA, &col_data,
|
|||
|
- SHORTCUTS_COL_IS_VOLUME, &is_volume,
|
|||
|
+ SHORTCUTS_COL_TYPE, &shortcut_type,
|
|||
|
-1);
|
|||
|
g_assert (col_data != NULL);
|
|||
|
- g_assert (!is_volume);
|
|||
|
+ g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
|
|||
|
|
|||
|
shortcut = col_data;
|
|||
|
list = g_slist_prepend (list, gtk_file_path_copy (shortcut));
|
|||
|
@@ -7449,6 +7713,23 @@
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
+/* Gives the focus to the browse tree view only if it is visible */
|
|||
|
+static void
|
|||
|
+focus_browse_tree_view_if_possible (GtkFileChooserDefault *impl)
|
|||
|
+{
|
|||
|
+ gboolean do_focus;
|
|||
|
+
|
|||
|
+ if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|
|||
|
+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
|
|||
|
+ && !gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander)))
|
|||
|
+ do_focus = FALSE;
|
|||
|
+ else
|
|||
|
+ do_focus = TRUE;
|
|||
|
+
|
|||
|
+ if (do_focus)
|
|||
|
+ gtk_widget_grab_focus (impl->browse_files_tree_view);
|
|||
|
+}
|
|||
|
+
|
|||
|
static void
|
|||
|
action_create_folder_cb (GtkFileSystemHandle *handle,
|
|||
|
const GtkFilePath *path,
|
|||
|
@@ -7714,6 +7995,9 @@
|
|||
|
|
|||
|
g_assert (impl->action >= GTK_FILE_CHOOSER_ACTION_OPEN && impl->action <= GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
|
|||
|
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH)
|
|||
|
+ return search_should_respond (impl);
|
|||
|
+
|
|||
|
selection_check (impl, &num_selected, &all_files, &all_folders);
|
|||
|
|
|||
|
if (num_selected > 2)
|
|||
|
@@ -7850,7 +8134,7 @@
|
|||
|
{
|
|||
|
shortcuts_activate_iter (impl, &iter);
|
|||
|
|
|||
|
- gtk_widget_grab_focus (impl->browse_files_tree_view);
|
|||
|
+ focus_browse_tree_view_if_possible (impl);
|
|||
|
}
|
|||
|
else
|
|||
|
goto file_list;
|
|||
|
@@ -7864,6 +8148,11 @@
|
|||
|
*/
|
|||
|
goto file_list;
|
|||
|
}
|
|||
|
+ else if (impl->operation_mode == OPERATION_MODE_SEARCH && impl->toplevel_last_focus_widget == impl->search_entry)
|
|||
|
+ {
|
|||
|
+ search_entry_activate_cb (GTK_ENTRY (impl->search_entry), impl);
|
|||
|
+ return FALSE;
|
|||
|
+ }
|
|||
|
else if (impl->location_entry && impl->toplevel_last_focus_widget == impl->location_entry)
|
|||
|
{
|
|||
|
/* The focus is on a dialog's action area button, *and* the widget that
|
|||
|
@@ -7913,15 +8202,452 @@
|
|||
|
gtk_widget_grab_focus (widget);
|
|||
|
}
|
|||
|
|
|||
|
+/* Callback used from gtk_tree_selection_selected_foreach(); gets the selected GtkFilePaths */
|
|||
|
static void
|
|||
|
-set_current_filter (GtkFileChooserDefault *impl,
|
|||
|
- GtkFileFilter *filter)
|
|||
|
+search_selected_foreach_get_path_cb (GtkTreeModel *model,
|
|||
|
+ GtkTreePath *path,
|
|||
|
+ GtkTreeIter *iter,
|
|||
|
+ gpointer data)
|
|||
|
{
|
|||
|
- if (impl->current_filter != filter)
|
|||
|
- {
|
|||
|
- int filter_index;
|
|||
|
+ GSList **list;
|
|||
|
+ const GtkFilePath *file_path;
|
|||
|
+ GtkFilePath *file_path_copy;
|
|||
|
|
|||
|
- /* NULL filters are allowed to reset to non-filtered status
|
|||
|
+ list = data;
|
|||
|
+
|
|||
|
+ gtk_tree_model_get (model, iter, SEARCH_MODEL_COL_PATH, &file_path, -1);
|
|||
|
+ file_path_copy = gtk_file_path_copy (file_path);
|
|||
|
+ *list = g_slist_prepend (*list, file_path_copy);
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Constructs a list of the selected paths in search mode */
|
|||
|
+static GSList *
|
|||
|
+search_get_selected_paths (GtkFileChooserDefault *impl)
|
|||
|
+{
|
|||
|
+ GSList *result;
|
|||
|
+ GtkTreeSelection *selection;
|
|||
|
+
|
|||
|
+ result = NULL;
|
|||
|
+
|
|||
|
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
|
|||
|
+ gtk_tree_selection_selected_foreach (selection, search_selected_foreach_get_path_cb, &result);
|
|||
|
+ result = g_slist_reverse (result);
|
|||
|
+
|
|||
|
+ return result;
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Called from ::should_respond(). We return whether there are selected files
|
|||
|
+ * in the search list.
|
|||
|
+ */
|
|||
|
+static gboolean
|
|||
|
+search_should_respond (GtkFileChooserDefault *impl)
|
|||
|
+{
|
|||
|
+ GtkTreeSelection *selection;
|
|||
|
+
|
|||
|
+ g_assert (impl->operation_mode == OPERATION_MODE_SEARCH);
|
|||
|
+
|
|||
|
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
|
|||
|
+ return (gtk_tree_selection_count_selected_rows (selection) != 0);
|
|||
|
+}
|
|||
|
+
|
|||
|
+
|
|||
|
+/* Adds one hit from the search engine to the search_model */
|
|||
|
+static void
|
|||
|
+search_add_hit (GtkFileChooserDefault *impl,
|
|||
|
+ gchar *uri)
|
|||
|
+{
|
|||
|
+ GtkFilePath *path;
|
|||
|
+ char *filename;
|
|||
|
+ char *display_name;
|
|||
|
+ char *collation_key;
|
|||
|
+ struct stat statbuf;
|
|||
|
+ struct stat *statbuf_copy;
|
|||
|
+ GtkTreeIter iter;
|
|||
|
+
|
|||
|
+ path = gtk_file_system_uri_to_path (impl->file_system, uri);
|
|||
|
+ if (!path)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
+ filename = gtk_file_system_path_to_filename (impl->file_system, path);
|
|||
|
+ if (!filename)
|
|||
|
+ {
|
|||
|
+ gtk_file_path_free (path);
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ if (stat (filename, &statbuf) != 0)
|
|||
|
+ {
|
|||
|
+ gtk_file_path_free (path);
|
|||
|
+ g_free (filename);
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ statbuf_copy = g_new (struct stat, 1);
|
|||
|
+ *statbuf_copy = statbuf;
|
|||
|
+
|
|||
|
+ display_name = g_filename_display_name (filename);
|
|||
|
+ collation_key = g_utf8_collate_key_for_filename (display_name, -1);
|
|||
|
+
|
|||
|
+ gtk_list_store_insert_with_values (impl->search_model, &iter, -1,
|
|||
|
+ SEARCH_MODEL_COL_PATH, path,
|
|||
|
+ SEARCH_MODEL_COL_DISPLAY_NAME, display_name,
|
|||
|
+ SEARCH_MODEL_COL_COLLATION_KEY, collation_key,
|
|||
|
+ SEARCH_MODEL_COL_STAT, statbuf_copy,
|
|||
|
+ -1);
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Callback used from GtkSearchEngine when we get new hits */
|
|||
|
+static void
|
|||
|
+search_engine_hits_added_cb (GtkSearchEngine *engine,
|
|||
|
+ GList *hits,
|
|||
|
+ gpointer data)
|
|||
|
+{
|
|||
|
+ GtkFileChooserDefault *impl;
|
|||
|
+ GList *l;
|
|||
|
+
|
|||
|
+ impl = GTK_FILE_CHOOSER_DEFAULT (data);
|
|||
|
+
|
|||
|
+ for (l = hits; l; l = l->next)
|
|||
|
+ search_add_hit (impl, (gchar*)l->data);
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Callback used from GtkSearchEngine when the query is done running */
|
|||
|
+static void
|
|||
|
+search_engine_finished_cb (GtkSearchEngine *engine,
|
|||
|
+ gpointer data)
|
|||
|
+{
|
|||
|
+ GtkFileChooserDefault *impl;
|
|||
|
+
|
|||
|
+ impl = GTK_FILE_CHOOSER_DEFAULT (data);
|
|||
|
+
|
|||
|
+ /* FMQ: if search was empty, say that we got no hits */
|
|||
|
+
|
|||
|
+ set_busy_cursor (impl, FALSE);
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Displays a generic error when we cannot create a GtkSearchEngine.
|
|||
|
+ * It would be better if _gtk_search_engine_new() gave us a GError
|
|||
|
+ * with a better message, but it doesn't do that right now.
|
|||
|
+ */
|
|||
|
+static void
|
|||
|
+search_error_could_not_create_client (GtkFileChooserDefault *impl)
|
|||
|
+{
|
|||
|
+ error_message (impl,
|
|||
|
+ _("Could not start the search process"),
|
|||
|
+ _("The program was not able to create a connection to the indexer "
|
|||
|
+ "daemon. Please make sure it is running."));
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+search_engine_error_cb (GtkSearchEngine *engine,
|
|||
|
+ const gchar *message,
|
|||
|
+ gpointer data)
|
|||
|
+{
|
|||
|
+ GtkFileChooserDefault *impl;
|
|||
|
+
|
|||
|
+ impl = GTK_FILE_CHOOSER_DEFAULT (data);
|
|||
|
+
|
|||
|
+ search_stop_searching (impl);
|
|||
|
+ error_message (impl, _("Could not send the search request"), message);
|
|||
|
+
|
|||
|
+ set_busy_cursor (impl, FALSE);
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Frees the data in the search_model */
|
|||
|
+static void
|
|||
|
+search_clear_model (GtkFileChooserDefault *impl,
|
|||
|
+ gboolean remove_from_treeview)
|
|||
|
+{
|
|||
|
+ GtkTreeIter iter;
|
|||
|
+
|
|||
|
+ if (!impl->search_model)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (impl->search_model), &iter))
|
|||
|
+ do
|
|||
|
+ {
|
|||
|
+ GtkFilePath *path;
|
|||
|
+ char *display_name;
|
|||
|
+ char *collation_key;
|
|||
|
+ struct stat *statbuf;
|
|||
|
+
|
|||
|
+ gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &iter,
|
|||
|
+ SEARCH_MODEL_COL_PATH, &path,
|
|||
|
+ SEARCH_MODEL_COL_DISPLAY_NAME, &display_name,
|
|||
|
+ SEARCH_MODEL_COL_COLLATION_KEY, &collation_key,
|
|||
|
+ SEARCH_MODEL_COL_STAT, &statbuf,
|
|||
|
+ -1);
|
|||
|
+
|
|||
|
+ gtk_file_path_free (path);
|
|||
|
+ g_free (display_name);
|
|||
|
+ g_free (collation_key);
|
|||
|
+ g_free (statbuf);
|
|||
|
+ }
|
|||
|
+ while (gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->search_model), &iter));
|
|||
|
+
|
|||
|
+ g_object_unref (impl->search_model);
|
|||
|
+ impl->search_model = NULL;
|
|||
|
+
|
|||
|
+ if (remove_from_treeview)
|
|||
|
+ gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Stops any ongoing searches; does not touch the search_model */
|
|||
|
+static void
|
|||
|
+search_stop_searching (GtkFileChooserDefault *impl)
|
|||
|
+{
|
|||
|
+ if (impl->search_query)
|
|||
|
+ {
|
|||
|
+ g_object_unref (impl->search_query);
|
|||
|
+ impl->search_query = NULL;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ if (impl->search_engine)
|
|||
|
+ {
|
|||
|
+ g_object_unref (impl->search_engine);
|
|||
|
+ impl->search_engine = NULL;
|
|||
|
+ }
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Stops any pending searches, clears the file list, and switches back to OPERATION_MODE_BROWSE */
|
|||
|
+static void
|
|||
|
+search_switch_to_browse_mode (GtkFileChooserDefault *impl)
|
|||
|
+{
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_BROWSE)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
+ search_stop_searching (impl);
|
|||
|
+ search_clear_model (impl, TRUE);
|
|||
|
+
|
|||
|
+ gtk_widget_destroy (impl->search_hbox);
|
|||
|
+ impl->search_hbox = NULL;
|
|||
|
+ impl->search_entry = NULL;
|
|||
|
+
|
|||
|
+ gtk_widget_show (impl->browse_path_bar);
|
|||
|
+ gtk_widget_show (impl->browse_new_folder_button);
|
|||
|
+
|
|||
|
+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
|
|||
|
+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
|
|||
|
+ {
|
|||
|
+ gtk_widget_show (impl->location_button);
|
|||
|
+
|
|||
|
+ if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
|
|||
|
+ gtk_widget_show (impl->location_entry_box);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ impl->operation_mode = OPERATION_MODE_BROWSE;
|
|||
|
+
|
|||
|
+ file_list_set_sort_column_ids (impl);
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Sort callback from the path column */
|
|||
|
+static gint
|
|||
|
+search_column_path_sort_func (GtkTreeModel *model,
|
|||
|
+ GtkTreeIter *a,
|
|||
|
+ GtkTreeIter *b,
|
|||
|
+ gpointer user_data)
|
|||
|
+{
|
|||
|
+ const char *collation_key_a, *collation_key_b;
|
|||
|
+
|
|||
|
+ gtk_tree_model_get (model, a, SEARCH_MODEL_COL_COLLATION_KEY, &collation_key_a, -1);
|
|||
|
+ gtk_tree_model_get (model, b, SEARCH_MODEL_COL_COLLATION_KEY, &collation_key_b, -1);
|
|||
|
+
|
|||
|
+ return strcmp (collation_key_a, collation_key_b);
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Sort callback from the modification time column */
|
|||
|
+static gint
|
|||
|
+search_column_mtime_sort_func (GtkTreeModel *model,
|
|||
|
+ GtkTreeIter *a,
|
|||
|
+ GtkTreeIter *b,
|
|||
|
+ gpointer user_data)
|
|||
|
+{
|
|||
|
+ const struct stat *statbuf_a, *statbuf_b;
|
|||
|
+
|
|||
|
+ /* Note that although we store a whole struct stat in the model, we only
|
|||
|
+ * compare the mtime here. If we add another column relative to a struct stat
|
|||
|
+ * (e.g. a file size column), we'll want another sort callback similar to this
|
|||
|
+ * one as well.
|
|||
|
+ */
|
|||
|
+
|
|||
|
+ gtk_tree_model_get (model, a, SEARCH_MODEL_COL_STAT, &statbuf_a, -1);
|
|||
|
+ gtk_tree_model_get (model, b, SEARCH_MODEL_COL_STAT, &statbuf_b, -1);
|
|||
|
+
|
|||
|
+ if (statbuf_a->st_mtime < statbuf_b->st_mtime)
|
|||
|
+ return -1;
|
|||
|
+ else if (statbuf_a->st_mtime > statbuf_b->st_mtime)
|
|||
|
+ return 1;
|
|||
|
+ else
|
|||
|
+ return 0;
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Creates the search_model and puts it in the tree view */
|
|||
|
+static void
|
|||
|
+search_setup_model (GtkFileChooserDefault *impl)
|
|||
|
+{
|
|||
|
+ g_assert (impl->search_model == NULL);
|
|||
|
+
|
|||
|
+ /* We store these columns in the search model:
|
|||
|
+ *
|
|||
|
+ * SEARCH_MODEL_COL_PATH - a GtkFilePath for the hit's URI (stored as a pointer, not as a GTK_TYPE_FILE_PATH)
|
|||
|
+ * SEARCH_MODEL_COL_DISPLAY_NAME - a string with the display name (stored as a pointer, not as a G_TYPE_STRING)
|
|||
|
+ * SEARCH_MODEL_COL_COLLATION_KEY - collation key for the filename (stored as a pointer, not as a G_TYPE_STRING)
|
|||
|
+ * SEARCH_MODEL_COL_STAT - pointer to a struct stat
|
|||
|
+ *
|
|||
|
+ * Keep this in sync with the enumeration defined near the beginning of this file.
|
|||
|
+ */
|
|||
|
+ impl->search_model = gtk_list_store_new (4,
|
|||
|
+ G_TYPE_POINTER,
|
|||
|
+ G_TYPE_POINTER,
|
|||
|
+ G_TYPE_POINTER,
|
|||
|
+ G_TYPE_POINTER);
|
|||
|
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->search_model),
|
|||
|
+ SEARCH_MODEL_COL_PATH,
|
|||
|
+ search_column_path_sort_func,
|
|||
|
+ impl,
|
|||
|
+ NULL);
|
|||
|
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->search_model),
|
|||
|
+ SEARCH_MODEL_COL_STAT,
|
|||
|
+ search_column_mtime_sort_func,
|
|||
|
+ impl,
|
|||
|
+ NULL);
|
|||
|
+
|
|||
|
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->search_model),
|
|||
|
+ SEARCH_MODEL_COL_STAT,
|
|||
|
+ GTK_SORT_DESCENDING);
|
|||
|
+
|
|||
|
+ gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), GTK_TREE_MODEL (impl->search_model));
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Creates a new query with the specified text and launches it */
|
|||
|
+static void
|
|||
|
+search_start_query (GtkFileChooserDefault *impl,
|
|||
|
+ const gchar *query_text)
|
|||
|
+{
|
|||
|
+ search_stop_searching (impl);
|
|||
|
+ search_clear_model (impl, TRUE);
|
|||
|
+ search_setup_model (impl);
|
|||
|
+ set_busy_cursor (impl, TRUE);
|
|||
|
+
|
|||
|
+ if (impl->search_engine == NULL)
|
|||
|
+ impl->search_engine = _gtk_search_engine_new ();
|
|||
|
+
|
|||
|
+ if (!impl->search_engine)
|
|||
|
+ {
|
|||
|
+ set_busy_cursor (impl, FALSE);
|
|||
|
+ search_error_could_not_create_client (impl); /* lame; we don't get an error code or anything */
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ impl->search_query = _gtk_query_new ();
|
|||
|
+ _gtk_query_set_text (impl->search_query, query_text);
|
|||
|
+
|
|||
|
+ g_signal_connect (impl->search_engine, "hits-added",
|
|||
|
+ G_CALLBACK (search_engine_hits_added_cb), impl);
|
|||
|
+ g_signal_connect (impl->search_engine, "finished",
|
|||
|
+ G_CALLBACK (search_engine_finished_cb), impl);
|
|||
|
+ g_signal_connect (impl->search_engine, "error",
|
|||
|
+ G_CALLBACK (search_engine_error_cb), impl);
|
|||
|
+
|
|||
|
+ _gtk_search_engine_start (impl->search_engine);
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Callback used when the user presses Enter while typing on the search entry; starts the query */
|
|||
|
+static void
|
|||
|
+search_entry_activate_cb (GtkEntry *entry,
|
|||
|
+ gpointer data)
|
|||
|
+{
|
|||
|
+ GtkFileChooserDefault *impl;
|
|||
|
+ const char *text;
|
|||
|
+
|
|||
|
+ impl = GTK_FILE_CHOOSER_DEFAULT (data);
|
|||
|
+
|
|||
|
+ text = gtk_entry_get_text (GTK_ENTRY (impl->search_entry));
|
|||
|
+ if (strlen (text) == 0)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
+ search_start_query (impl, text);
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Hides the path bar and creates the search entry */
|
|||
|
+static void
|
|||
|
+search_setup_widgets (GtkFileChooserDefault *impl)
|
|||
|
+{
|
|||
|
+ GtkWidget *label;
|
|||
|
+ gchar *text;
|
|||
|
+
|
|||
|
+ impl->search_hbox = gtk_hbox_new (FALSE, 12);
|
|||
|
+
|
|||
|
+ /* Label */
|
|||
|
+
|
|||
|
+ label = gtk_label_new (NULL);
|
|||
|
+ text = g_strdup_printf ("<b>%s</b>", _("Search:"));
|
|||
|
+ gtk_label_set_markup (GTK_LABEL (label), text);
|
|||
|
+ g_free (text);
|
|||
|
+ gtk_box_pack_start (GTK_BOX (impl->search_hbox), label, FALSE, FALSE, 0);
|
|||
|
+
|
|||
|
+ /* Entry */
|
|||
|
+
|
|||
|
+ impl->search_entry = gtk_entry_new ();
|
|||
|
+ g_signal_connect (impl->search_entry, "activate",
|
|||
|
+ G_CALLBACK (search_entry_activate_cb),
|
|||
|
+ impl);
|
|||
|
+ gtk_box_pack_start (GTK_BOX (impl->search_hbox), impl->search_entry, TRUE, TRUE, 0);
|
|||
|
+
|
|||
|
+ gtk_widget_hide (impl->browse_path_bar);
|
|||
|
+ gtk_widget_hide (impl->browse_new_folder_button);
|
|||
|
+
|
|||
|
+ /* Box for search widgets */
|
|||
|
+
|
|||
|
+ gtk_box_pack_start (GTK_BOX (impl->browse_path_bar_hbox), impl->search_hbox, TRUE, TRUE, 0);
|
|||
|
+ gtk_widget_show_all (impl->search_hbox);
|
|||
|
+
|
|||
|
+ /* Hide the location widgets temporarily */
|
|||
|
+
|
|||
|
+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
|
|||
|
+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
|
|||
|
+ {
|
|||
|
+ gtk_widget_hide (impl->location_button);
|
|||
|
+ gtk_widget_hide (impl->location_entry_box);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ gtk_widget_grab_focus (impl->search_entry);
|
|||
|
+
|
|||
|
+ /* FMQ: hide the filter combo? */
|
|||
|
+}
|
|||
|
+
|
|||
|
+/* Main entry point to the searching functions; this gets called when the user
|
|||
|
+ * activates the Search shortcut.
|
|||
|
+ */
|
|||
|
+static void
|
|||
|
+search_activate (GtkFileChooserDefault *impl)
|
|||
|
+{
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH)
|
|||
|
+ {
|
|||
|
+ gtk_widget_grab_focus (impl->search_entry);
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ impl->operation_mode = OPERATION_MODE_SEARCH;
|
|||
|
+
|
|||
|
+ g_assert (impl->search_hbox == NULL);
|
|||
|
+ g_assert (impl->search_entry == NULL);
|
|||
|
+ g_assert (impl->search_model == NULL);
|
|||
|
+
|
|||
|
+ stop_loading_and_clear_list_model (impl);
|
|||
|
+ search_setup_widgets (impl);
|
|||
|
+ file_list_set_sort_column_ids (impl);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+set_current_filter (GtkFileChooserDefault *impl,
|
|||
|
+ GtkFileFilter *filter)
|
|||
|
+{
|
|||
|
+ if (impl->current_filter != filter)
|
|||
|
+ {
|
|||
|
+ int filter_index;
|
|||
|
+
|
|||
|
+ /* NULL filters are allowed to reset to non-filtered status
|
|||
|
*/
|
|||
|
filter_index = g_slist_index (impl->filters, filter);
|
|||
|
if (impl->filters && filter && filter_index < 0)
|
|||
|
@@ -7961,28 +8687,44 @@
|
|||
|
{
|
|||
|
GtkTreePath *cursor_path;
|
|||
|
const GtkFilePath *new_path;
|
|||
|
- const GtkFileInfo *new_info;
|
|||
|
+ const char *new_display_name;
|
|||
|
|
|||
|
gtk_tree_view_get_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view), &cursor_path, NULL);
|
|||
|
- if (cursor_path && impl->sort_model)
|
|||
|
+ new_path = NULL;
|
|||
|
+ new_display_name = NULL;
|
|||
|
+ if (cursor_path)
|
|||
|
{
|
|||
|
- GtkTreeIter iter;
|
|||
|
- GtkTreeIter child_iter;
|
|||
|
-
|
|||
|
- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, cursor_path))
|
|||
|
- g_assert_not_reached ();
|
|||
|
-
|
|||
|
- gtk_tree_path_free (cursor_path);
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_BROWSE)
|
|||
|
+ {
|
|||
|
+ if (impl->sort_model)
|
|||
|
+ {
|
|||
|
+ GtkTreeIter iter;
|
|||
|
+ GtkTreeIter child_iter;
|
|||
|
+ const GtkFileInfo *new_info;
|
|||
|
+
|
|||
|
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, cursor_path);
|
|||
|
+ gtk_tree_path_free (cursor_path);
|
|||
|
+
|
|||
|
+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
|
|||
|
+
|
|||
|
+ new_path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
|
|||
|
+ new_info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
|
|||
|
+ if (new_info)
|
|||
|
+ new_display_name = gtk_file_info_get_display_name (new_info);
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ GtkTreeIter iter;
|
|||
|
|
|||
|
- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
|
|||
|
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model), &iter, cursor_path);
|
|||
|
+ gtk_tree_path_free (cursor_path);
|
|||
|
|
|||
|
- new_path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
|
|||
|
- new_info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
|
|||
|
- }
|
|||
|
- else
|
|||
|
- {
|
|||
|
- new_path = NULL;
|
|||
|
- new_info = NULL;
|
|||
|
+ gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &iter,
|
|||
|
+ SEARCH_MODEL_COL_PATH, &new_path,
|
|||
|
+ SEARCH_MODEL_COL_DISPLAY_NAME, &new_display_name,
|
|||
|
+ -1);
|
|||
|
+ }
|
|||
|
}
|
|||
|
|
|||
|
if (new_path != impl->preview_path &&
|
|||
|
@@ -7998,7 +8740,7 @@
|
|||
|
if (new_path)
|
|||
|
{
|
|||
|
impl->preview_path = gtk_file_path_copy (new_path);
|
|||
|
- impl->preview_display_name = g_strdup (gtk_file_info_get_display_name (new_info));
|
|||
|
+ impl->preview_display_name = g_strdup (new_display_name);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
@@ -8067,6 +8809,8 @@
|
|||
|
{
|
|||
|
GtkFilePath *path;
|
|||
|
|
|||
|
+ search_switch_to_browse_mode (impl);
|
|||
|
+
|
|||
|
/* We ref the file chooser since volume_mount() may run a main loop, and the
|
|||
|
* user could close the file chooser window in the meantime.
|
|||
|
*/
|
|||
|
@@ -8087,6 +8831,8 @@
|
|||
|
if (path != NULL)
|
|||
|
{
|
|||
|
change_folder_and_display_error (impl, path);
|
|||
|
+ focus_browse_tree_view_if_possible (impl);
|
|||
|
+
|
|||
|
gtk_file_path_free (path);
|
|||
|
}
|
|||
|
}
|
|||
|
@@ -8119,7 +8865,10 @@
|
|||
|
goto out;
|
|||
|
|
|||
|
if (!error && gtk_file_info_get_is_folder (info))
|
|||
|
- change_folder_and_display_error (data->impl, data->path);
|
|||
|
+ {
|
|||
|
+ change_folder_and_display_error (data->impl, data->path);
|
|||
|
+ focus_browse_tree_view_if_possible (data->impl);
|
|||
|
+ }
|
|||
|
else
|
|||
|
gtk_file_chooser_default_select_path (GTK_FILE_CHOOSER (data->impl), data->path, NULL);
|
|||
|
|
|||
|
@@ -8136,26 +8885,25 @@
|
|||
|
GtkTreeIter *iter)
|
|||
|
{
|
|||
|
gpointer col_data;
|
|||
|
- gboolean is_volume;
|
|||
|
+ ShortcutType shortcut_type;
|
|||
|
|
|||
|
if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY && impl->action != GTK_FILE_CHOOSER_ACTION_SAVE)
|
|||
|
_gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), "");
|
|||
|
|
|||
|
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), iter,
|
|||
|
SHORTCUTS_COL_DATA, &col_data,
|
|||
|
- SHORTCUTS_COL_IS_VOLUME, &is_volume,
|
|||
|
+ SHORTCUTS_COL_TYPE, &shortcut_type,
|
|||
|
-1);
|
|||
|
|
|||
|
- if (!col_data)
|
|||
|
- return; /* We are on a separator */
|
|||
|
-
|
|||
|
if (impl->shortcuts_activate_iter_handle)
|
|||
|
{
|
|||
|
gtk_file_system_cancel_operation (impl->shortcuts_activate_iter_handle);
|
|||
|
impl->shortcuts_activate_iter_handle = NULL;
|
|||
|
}
|
|||
|
|
|||
|
- if (is_volume)
|
|||
|
+ if (shortcut_type == SHORTCUT_TYPE_SEPARATOR)
|
|||
|
+ return;
|
|||
|
+ else if (shortcut_type == SHORTCUT_TYPE_VOLUME)
|
|||
|
{
|
|||
|
GtkFileSystemVolume *volume;
|
|||
|
|
|||
|
@@ -8163,7 +8911,7 @@
|
|||
|
|
|||
|
shortcuts_activate_volume (impl, volume);
|
|||
|
}
|
|||
|
- else
|
|||
|
+ else if (shortcut_type == SHORTCUT_TYPE_PATH)
|
|||
|
{
|
|||
|
struct ShortcutsActivateData *data;
|
|||
|
|
|||
|
@@ -8176,6 +8924,10 @@
|
|||
|
GTK_FILE_INFO_IS_FOLDER,
|
|||
|
shortcuts_activate_get_info_cb, data);
|
|||
|
}
|
|||
|
+ else if (shortcut_type == SHORTCUT_TYPE_SEARCH)
|
|||
|
+ {
|
|||
|
+ search_activate (impl);
|
|||
|
+ }
|
|||
|
}
|
|||
|
|
|||
|
/* Callback used when a row in the shortcuts list is activated */
|
|||
|
@@ -8188,15 +8940,13 @@
|
|||
|
GtkTreeIter iter;
|
|||
|
GtkTreeIter child_iter;
|
|||
|
|
|||
|
- if (!gtk_tree_model_get_iter (impl->shortcuts_filter_model, &iter, path))
|
|||
|
+ if (!gtk_tree_model_get_iter (impl->shortcuts_pane_filter_model, &iter, path))
|
|||
|
return;
|
|||
|
|
|||
|
- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model),
|
|||
|
+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model),
|
|||
|
&child_iter,
|
|||
|
&iter);
|
|||
|
shortcuts_activate_iter (impl, &child_iter);
|
|||
|
-
|
|||
|
- gtk_widget_grab_focus (impl->browse_files_tree_view);
|
|||
|
}
|
|||
|
|
|||
|
/* Handler for GtkWidget::key-press-event on the shortcuts list */
|
|||
|
@@ -8236,8 +8986,15 @@
|
|||
|
gpointer data)
|
|||
|
{
|
|||
|
GtkFileChooserDefault *impl = data;
|
|||
|
+ GtkTreeIter filter_iter;
|
|||
|
+ ShortcutType shortcut_type;
|
|||
|
|
|||
|
- return (*gtk_tree_path_get_indices (path) != shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR));
|
|||
|
+ if (!gtk_tree_model_get_iter (impl->shortcuts_pane_filter_model, &filter_iter, path))
|
|||
|
+ g_assert_not_reached ();
|
|||
|
+
|
|||
|
+ gtk_tree_model_get (impl->shortcuts_pane_filter_model, &filter_iter, SHORTCUTS_COL_TYPE, &shortcut_type, -1);
|
|||
|
+
|
|||
|
+ return shortcut_type != SHORTCUT_TYPE_SEPARATOR;
|
|||
|
}
|
|||
|
|
|||
|
static gboolean
|
|||
|
@@ -8249,6 +9006,9 @@
|
|||
|
{
|
|||
|
GtkFileChooserDefault *impl = data;
|
|||
|
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH)
|
|||
|
+ return TRUE;
|
|||
|
+
|
|||
|
if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
|
|||
|
impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
|
|||
|
{
|
|||
|
@@ -8274,7 +9034,7 @@
|
|||
|
GtkFileChooserDefault *impl)
|
|||
|
{
|
|||
|
/* See if we are in the new folder editable row for Save mode */
|
|||
|
- if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_BROWSE && impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
|||
|
{
|
|||
|
const GtkFileInfo *info;
|
|||
|
gboolean had_selection;
|
|||
|
@@ -8289,6 +9049,8 @@
|
|||
|
|
|||
|
out:
|
|||
|
|
|||
|
+ /* AQUI: cambiar las siguientes funciones para que acepten SEARCH */
|
|||
|
+
|
|||
|
update_chooser_entry (impl);
|
|||
|
check_preview_change (impl);
|
|||
|
bookmarks_check_add_sensitivity (impl);
|
|||
|
@@ -8306,6 +9068,12 @@
|
|||
|
GtkTreeIter iter, child_iter;
|
|||
|
const GtkFileInfo *info;
|
|||
|
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH)
|
|||
|
+ {
|
|||
|
+ g_signal_emit_by_name (impl, "file-activated");
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path))
|
|||
|
return;
|
|||
|
|
|||
|
@@ -8376,6 +9144,15 @@
|
|||
|
const GtkFileInfo *info;
|
|||
|
gboolean sensitive = TRUE;
|
|||
|
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH)
|
|||
|
+ {
|
|||
|
+ g_object_set (cell,
|
|||
|
+ "pixbuf", NULL,
|
|||
|
+ "sensitive", TRUE,
|
|||
|
+ NULL);
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
profile_start ("start", NULL);
|
|||
|
|
|||
|
info = get_list_file_info (impl, iter);
|
|||
|
@@ -8425,13 +9202,33 @@
|
|||
|
gpointer data)
|
|||
|
{
|
|||
|
GtkFileChooserDefault *impl = data;
|
|||
|
- const GtkFileInfo *info = get_list_file_info (impl, iter);
|
|||
|
- gboolean sensitive = TRUE;
|
|||
|
+ const GtkFileInfo *info;
|
|||
|
+ gboolean sensitive;
|
|||
|
+
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH)
|
|||
|
+ {
|
|||
|
+ char *display_name;
|
|||
|
+
|
|||
|
+ gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), iter,
|
|||
|
+ SEARCH_MODEL_COL_DISPLAY_NAME, &display_name,
|
|||
|
+ -1);
|
|||
|
+ g_object_set (cell,
|
|||
|
+ "text", display_name,
|
|||
|
+ "sensitive", TRUE,
|
|||
|
+ "ellipsize", PANGO_ELLIPSIZE_START,
|
|||
|
+ NULL);
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ info = get_list_file_info (impl, iter);
|
|||
|
+ sensitive = TRUE;
|
|||
|
|
|||
|
if (!info)
|
|||
|
{
|
|||
|
g_object_set (cell,
|
|||
|
"text", _("Type name of new folder"),
|
|||
|
+ "sensitive", TRUE,
|
|||
|
+ "ellipsize", PANGO_ELLIPSIZE_NONE,
|
|||
|
NULL);
|
|||
|
|
|||
|
return;
|
|||
|
@@ -8447,6 +9244,7 @@
|
|||
|
g_object_set (cell,
|
|||
|
"text", gtk_file_info_get_display_name (info),
|
|||
|
"sensitive", sensitive,
|
|||
|
+ "ellipsize", PANGO_ELLIPSIZE_END,
|
|||
|
NULL);
|
|||
|
}
|
|||
|
|
|||
|
@@ -8508,7 +9306,6 @@
|
|||
|
gpointer data)
|
|||
|
{
|
|||
|
GtkFileChooserDefault *impl;
|
|||
|
- const GtkFileInfo *info;
|
|||
|
GtkFileTime time_mtime;
|
|||
|
GDate mtime, now;
|
|||
|
int days_diff;
|
|||
|
@@ -8517,17 +9314,35 @@
|
|||
|
|
|||
|
impl = data;
|
|||
|
|
|||
|
- info = get_list_file_info (impl, iter);
|
|||
|
- if (!info)
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH)
|
|||
|
{
|
|||
|
- g_object_set (cell,
|
|||
|
- "text", "",
|
|||
|
- "sensitive", TRUE,
|
|||
|
- NULL);
|
|||
|
- return;
|
|||
|
+ struct stat *statbuf;
|
|||
|
+
|
|||
|
+ gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), iter,
|
|||
|
+ SEARCH_MODEL_COL_STAT, &statbuf,
|
|||
|
+ -1);
|
|||
|
+ time_mtime = statbuf->st_mtime;
|
|||
|
}
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ const GtkFileInfo *info;
|
|||
|
|
|||
|
- time_mtime = gtk_file_info_get_modification_time (info);
|
|||
|
+ info = get_list_file_info (impl, iter);
|
|||
|
+ if (!info)
|
|||
|
+ {
|
|||
|
+ g_object_set (cell,
|
|||
|
+ "text", "",
|
|||
|
+ "sensitive", TRUE,
|
|||
|
+ NULL);
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ time_mtime = gtk_file_info_get_modification_time (info);
|
|||
|
+
|
|||
|
+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
|
|||
|
+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
|
|||
|
+ sensitive = gtk_file_info_get_is_folder (info);
|
|||
|
+ }
|
|||
|
|
|||
|
if (time_mtime == 0)
|
|||
|
strcpy (buf, _("Unknown"));
|
|||
|
@@ -8558,10 +9373,6 @@
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
|
|||
|
- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
|
|||
|
- sensitive = gtk_file_info_get_is_folder (info);
|
|||
|
-
|
|||
|
g_object_set (cell,
|
|||
|
"text", buf,
|
|||
|
"sensitive", sensitive,
|
|||
|
@@ -8587,7 +9398,23 @@
|
|||
|
static void
|
|||
|
location_popup_handler (GtkFileChooserDefault *impl,
|
|||
|
const gchar *path)
|
|||
|
-{
|
|||
|
+{
|
|||
|
+ if (impl->operation_mode == OPERATION_MODE_SEARCH)
|
|||
|
+ {
|
|||
|
+ GtkWidget *widget_to_focus;
|
|||
|
+
|
|||
|
+ search_switch_to_browse_mode (impl); /* This will give us the location widgets back */
|
|||
|
+ if (impl->current_folder)
|
|||
|
+ change_folder_and_display_error (impl, impl->current_folder);
|
|||
|
+
|
|||
|
+ if (impl->location_mode == LOCATION_MODE_PATH_BAR)
|
|||
|
+ widget_to_focus = impl->browse_files_tree_view;
|
|||
|
+ else
|
|||
|
+ widget_to_focus = impl->location_entry;
|
|||
|
+
|
|||
|
+ gtk_widget_grab_focus (widget_to_focus);
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
|
|||
|
|| impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
|
|||
|
{
|
|||
|
@@ -8656,6 +9483,7 @@
|
|||
|
g_assert_not_reached ();
|
|||
|
|
|||
|
shortcuts_activate_iter (impl, &iter);
|
|||
|
+ focus_browse_tree_view_if_possible (impl);
|
|||
|
}
|
|||
|
|
|||
|
/* Handler for the "home-folder" keybinding signal */
|
|||
|
@@ -8700,26 +9528,26 @@
|
|||
|
/* Drag and drop interfaces */
|
|||
|
|
|||
|
static void
|
|||
|
-_shortcuts_model_filter_class_init (ShortcutsModelFilterClass *class)
|
|||
|
+_shortcuts_pane_model_filter_class_init (ShortcutsPaneModelFilterClass *class)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
-_shortcuts_model_filter_init (ShortcutsModelFilter *model)
|
|||
|
+_shortcuts_pane_model_filter_init (ShortcutsPaneModelFilter *model)
|
|||
|
{
|
|||
|
model->impl = NULL;
|
|||
|
}
|
|||
|
|
|||
|
/* GtkTreeDragSource::row_draggable implementation for the shortcuts filter model */
|
|||
|
static gboolean
|
|||
|
-shortcuts_model_filter_row_draggable (GtkTreeDragSource *drag_source,
|
|||
|
- GtkTreePath *path)
|
|||
|
+shortcuts_pane_model_filter_row_draggable (GtkTreeDragSource *drag_source,
|
|||
|
+ GtkTreePath *path)
|
|||
|
{
|
|||
|
- ShortcutsModelFilter *model;
|
|||
|
+ ShortcutsPaneModelFilter *model;
|
|||
|
int pos;
|
|||
|
int bookmarks_pos;
|
|||
|
|
|||
|
- model = SHORTCUTS_MODEL_FILTER (drag_source);
|
|||
|
+ model = SHORTCUTS_PANE_MODEL_FILTER (drag_source);
|
|||
|
|
|||
|
pos = *gtk_tree_path_get_indices (path);
|
|||
|
bookmarks_pos = shortcuts_get_index (model->impl, SHORTCUTS_BOOKMARKS);
|
|||
|
@@ -8729,13 +9557,13 @@
|
|||
|
|
|||
|
/* GtkTreeDragSource::drag_data_get implementation for the shortcuts filter model */
|
|||
|
static gboolean
|
|||
|
-shortcuts_model_filter_drag_data_get (GtkTreeDragSource *drag_source,
|
|||
|
- GtkTreePath *path,
|
|||
|
- GtkSelectionData *selection_data)
|
|||
|
+shortcuts_pane_model_filter_drag_data_get (GtkTreeDragSource *drag_source,
|
|||
|
+ GtkTreePath *path,
|
|||
|
+ GtkSelectionData *selection_data)
|
|||
|
{
|
|||
|
- ShortcutsModelFilter *model;
|
|||
|
+ ShortcutsPaneModelFilter *model;
|
|||
|
|
|||
|
- model = SHORTCUTS_MODEL_FILTER (drag_source);
|
|||
|
+ model = SHORTCUTS_PANE_MODEL_FILTER (drag_source);
|
|||
|
|
|||
|
/* FIXME */
|
|||
|
|
|||
|
@@ -8744,30 +9572,30 @@
|
|||
|
|
|||
|
/* Fill the GtkTreeDragSourceIface vtable */
|
|||
|
static void
|
|||
|
-shortcuts_model_filter_drag_source_iface_init (GtkTreeDragSourceIface *iface)
|
|||
|
+shortcuts_pane_model_filter_drag_source_iface_init (GtkTreeDragSourceIface *iface)
|
|||
|
{
|
|||
|
- iface->row_draggable = shortcuts_model_filter_row_draggable;
|
|||
|
- iface->drag_data_get = shortcuts_model_filter_drag_data_get;
|
|||
|
+ iface->row_draggable = shortcuts_pane_model_filter_row_draggable;
|
|||
|
+ iface->drag_data_get = shortcuts_pane_model_filter_drag_data_get;
|
|||
|
}
|
|||
|
|
|||
|
#if 0
|
|||
|
/* Fill the GtkTreeDragDestIface vtable */
|
|||
|
static void
|
|||
|
-shortcuts_model_filter_drag_dest_iface_init (GtkTreeDragDestIface *iface)
|
|||
|
+shortcuts_pane_model_filter_drag_dest_iface_init (GtkTreeDragDestIface *iface)
|
|||
|
{
|
|||
|
- iface->drag_data_received = shortcuts_model_filter_drag_data_received;
|
|||
|
- iface->row_drop_possible = shortcuts_model_filter_row_drop_possible;
|
|||
|
+ iface->drag_data_received = shortcuts_pane_model_filter_drag_data_received;
|
|||
|
+ iface->row_drop_possible = shortcuts_pane_model_filter_row_drop_possible;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
static GtkTreeModel *
|
|||
|
-shortcuts_model_filter_new (GtkFileChooserDefault *impl,
|
|||
|
- GtkTreeModel *child_model,
|
|||
|
- GtkTreePath *root)
|
|||
|
+shortcuts_pane_model_filter_new (GtkFileChooserDefault *impl,
|
|||
|
+ GtkTreeModel *child_model,
|
|||
|
+ GtkTreePath *root)
|
|||
|
{
|
|||
|
- ShortcutsModelFilter *model;
|
|||
|
+ ShortcutsPaneModelFilter *model;
|
|||
|
|
|||
|
- model = g_object_new (SHORTCUTS_MODEL_FILTER_TYPE,
|
|||
|
+ model = g_object_new (SHORTCUTS_PANE_MODEL_FILTER_TYPE,
|
|||
|
"child-model", child_model,
|
|||
|
"virtual-root", root,
|
|||
|
NULL);
|
|||
|
--- gtk+-2.10.8/gtk/gtkfilechooserprivate.h.search 2007-01-16 22:14:43.000000000 -0500
|
|||
|
+++ gtk+-2.10.8/gtk/gtkfilechooserprivate.h 2007-01-17 01:23:26.000000000 -0500
|
|||
|
@@ -25,6 +25,8 @@
|
|||
|
#include "gtkfilesystem.h"
|
|||
|
#include "gtkfilesystemmodel.h"
|
|||
|
#include "gtkliststore.h"
|
|||
|
+#include "gtksearchengine.h"
|
|||
|
+#include "gtkquery.h"
|
|||
|
#include "gtktooltips.h"
|
|||
|
#include "gtktreemodelsort.h"
|
|||
|
#include "gtktreestore.h"
|
|||
|
@@ -147,6 +149,11 @@
|
|||
|
LOCATION_MODE_FILENAME_ENTRY
|
|||
|
} LocationMode;
|
|||
|
|
|||
|
+typedef enum {
|
|||
|
+ OPERATION_MODE_BROWSE,
|
|||
|
+ OPERATION_MODE_SEARCH
|
|||
|
+} OperationMode;
|
|||
|
+
|
|||
|
struct _GtkFileChooserDefault
|
|||
|
{
|
|||
|
GtkVBox parent_instance;
|
|||
|
@@ -175,11 +182,19 @@
|
|||
|
GtkWidget *browse_files_popup_menu_add_shortcut_item;
|
|||
|
GtkWidget *browse_files_popup_menu_hidden_files_item;
|
|||
|
GtkWidget *browse_new_folder_button;
|
|||
|
+ GtkWidget *browse_path_bar_hbox;
|
|||
|
GtkWidget *browse_path_bar;
|
|||
|
|
|||
|
GtkFileSystemModel *browse_files_model;
|
|||
|
char *browse_files_last_selected_name;
|
|||
|
|
|||
|
+ /* Widgets for searching */
|
|||
|
+ GtkWidget *search_hbox;
|
|||
|
+ GtkWidget *search_entry;
|
|||
|
+ GtkSearchEngine *search_engine;
|
|||
|
+ GtkQuery *search_query;
|
|||
|
+ GtkListStore *search_model;
|
|||
|
+
|
|||
|
GtkWidget *filter_combo_hbox;
|
|||
|
GtkWidget *filter_combo;
|
|||
|
GtkWidget *preview_box;
|
|||
|
@@ -195,7 +210,16 @@
|
|||
|
LocationMode location_mode;
|
|||
|
|
|||
|
GtkListStore *shortcuts_model;
|
|||
|
- GtkTreeModel *shortcuts_filter_model;
|
|||
|
+
|
|||
|
+ /* Filter for the shortcuts pane. We filter out the "current folder" row and
|
|||
|
+ * the separator that we use for the "Save in folder" combo.
|
|||
|
+ */
|
|||
|
+ GtkTreeModel *shortcuts_pane_filter_model;
|
|||
|
+
|
|||
|
+ /* Filter for the "Save in folder" combo. We filter out the Search row and
|
|||
|
+ * its separator.
|
|||
|
+ */
|
|||
|
+ GtkTreeModel *shortcuts_combo_filter_model;
|
|||
|
|
|||
|
GtkTreeModelSort *sort_model;
|
|||
|
|
|||
|
@@ -215,6 +239,8 @@
|
|||
|
ReloadState reload_state;
|
|||
|
guint load_timeout_id;
|
|||
|
|
|||
|
+ OperationMode operation_mode;
|
|||
|
+
|
|||
|
GSList *pending_select_paths;
|
|||
|
|
|||
|
GtkFileFilter *current_filter;
|
|||
|
@@ -222,9 +248,6 @@
|
|||
|
|
|||
|
GtkTooltips *tooltips;
|
|||
|
|
|||
|
- gboolean has_home;
|
|||
|
- gboolean has_desktop;
|
|||
|
-
|
|||
|
int num_volumes;
|
|||
|
int num_shortcuts;
|
|||
|
int num_bookmarks;
|
|||
|
@@ -239,6 +262,7 @@
|
|||
|
|
|||
|
GtkTreeViewColumn *list_name_column;
|
|||
|
GtkCellRenderer *list_name_renderer;
|
|||
|
+ GtkTreeViewColumn *list_mtime_column;
|
|||
|
|
|||
|
GSource *edited_idle;
|
|||
|
char *edited_new_text;
|
|||
|
@@ -265,6 +289,9 @@
|
|||
|
guint list_sort_ascending : 1;
|
|||
|
guint changing_folder : 1;
|
|||
|
guint shortcuts_current_folder_active : 1;
|
|||
|
+ guint has_home : 1;
|
|||
|
+ guint has_desktop : 1;
|
|||
|
+ guint has_search : 1;
|
|||
|
guint expand_folders : 1;
|
|||
|
|
|||
|
#if 0
|
|||
|
--- /dev/null 2007-01-16 08:16:47.736226048 -0500
|
|||
|
+++ gtk+-2.10.8/gtk/gtksearchenginesimple.h 2007-01-17 01:21:08.000000000 -0500
|
|||
|
@@ -0,0 +1,59 @@
|
|||
|
+/*
|
|||
|
+ * Copyright (C) 2005 Red Hat, Inc
|
|||
|
+ *
|
|||
|
+ * This library is free software; you can redistribute it and/or
|
|||
|
+ * modify it under the terms of the GNU Lesser General Public
|
|||
|
+ * License as published by the Free Software Foundation; either
|
|||
|
+ * version 2 of the License, or (at your option) any later version.
|
|||
|
+ *
|
|||
|
+ * This library 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
|
|||
|
+ * Lesser General Public License for more details.
|
|||
|
+ *
|
|||
|
+ * You should have received a copy of the GNU Lesser General Public
|
|||
|
+ * License along with this library; if not, write to the
|
|||
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|||
|
+ *
|
|||
|
+ * Author: Alexander Larsson <alexl@redhat.com>
|
|||
|
+ *
|
|||
|
+ * Based on nautilus-search-engine-simple.h
|
|||
|
+ */
|
|||
|
+
|
|||
|
+#ifndef __GTK_SEARCH_ENGINE_SIMPLE_H__
|
|||
|
+#define __GTK_SEARCH_ENGINE_SIMPLE_H__
|
|||
|
+
|
|||
|
+#include "gtksearchengine.h"
|
|||
|
+
|
|||
|
+G_END_DECLS
|
|||
|
+
|
|||
|
+#define GTK_TYPE_SEARCH_ENGINE_SIMPLE (_gtk_search_engine_simple_get_type ())
|
|||
|
+#define GTK_SEARCH_ENGINE_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SEARCH_ENGINE_SIMPLE, GtkSearchEngineSimple))
|
|||
|
+#define GTK_SEARCH_ENGINE_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SEARCH_ENGINE_SIMPLE, GtkSearchEngineSimpleClass))
|
|||
|
+#define GTK_IS_SEARCH_ENGINE_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SEARCH_ENGINE_SIMPLE))
|
|||
|
+#define GTK_IS_SEARCH_ENGINE_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SEARCH_ENGINE_SIMPLE))
|
|||
|
+#define GTK_SEARCH_ENGINE_SIMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SEARCH_ENGINE_SIMPLE, GtkSearchEngineSimpleClass))
|
|||
|
+
|
|||
|
+typedef struct _GtkSearchEngineSimple GtkSearchEngineSimple;
|
|||
|
+typedef struct _GtkSearchEngineSimpleClass GtkSearchEngineSimpleClass;
|
|||
|
+typedef struct _GtkSearchEngineSimplePrivate GtkSearchEngineSimplePrivate;
|
|||
|
+
|
|||
|
+struct _GtkSearchEngineSimple
|
|||
|
+{
|
|||
|
+ GtkSearchEngine parent;
|
|||
|
+
|
|||
|
+ GtkSearchEngineSimplePrivate *priv;
|
|||
|
+};
|
|||
|
+
|
|||
|
+struct _GtkSearchEngineSimpleClass
|
|||
|
+{
|
|||
|
+ GtkSearchEngineClass parent_class;
|
|||
|
+};
|
|||
|
+
|
|||
|
+GType _gtk_search_engine_simple_get_type (void);
|
|||
|
+
|
|||
|
+GtkSearchEngine* _gtk_search_engine_simple_new (void);
|
|||
|
+
|
|||
|
+G_END_DECLS
|
|||
|
+
|
|||
|
+#endif /* __GTK_SEARCH_ENGINE_SIMPLE_H__ */
|
|||
|
--- /dev/null 2007-01-16 08:16:47.736226048 -0500
|
|||
|
+++ gtk+-2.10.8/gtk/gtksearchenginesimple.c 2007-01-17 01:21:08.000000000 -0500
|
|||
|
@@ -0,0 +1,378 @@
|
|||
|
+/*
|
|||
|
+ * Copyright (C) 2005 Red Hat, Inc
|
|||
|
+ *
|
|||
|
+ * This library is free software; you can redistribute it and/or
|
|||
|
+ * modify it under the terms of the GNU Lesser General Public
|
|||
|
+ * License as published by the Free Software Foundation; either
|
|||
|
+ * version 2 of the License, or (at your option) any later version.
|
|||
|
+ *
|
|||
|
+ * This library 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
|
|||
|
+ * Lesser General Public License for more details.
|
|||
|
+ *
|
|||
|
+ * You should have received a copy of the GNU Lesser General Public
|
|||
|
+ * License along with this library; if not, write to the
|
|||
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|||
|
+ *
|
|||
|
+ * Author: Alexander Larsson <alexl@redhat.com>
|
|||
|
+ *
|
|||
|
+ * Based on nautilus-search-engine-simple.c
|
|||
|
+ */
|
|||
|
+
|
|||
|
+#define _XOPEN_SOURCE 500
|
|||
|
+#define _GNU_SOURCE
|
|||
|
+
|
|||
|
+#include <config.h>
|
|||
|
+#include "gtksearchenginesimple.h"
|
|||
|
+
|
|||
|
+#define XDG_PREFIX _gtk_xdg
|
|||
|
+#include "xdgmime/xdgmime.h"
|
|||
|
+
|
|||
|
+#include <string.h>
|
|||
|
+#include <ftw.h>
|
|||
|
+#include <glib/gstrfuncs.h>
|
|||
|
+
|
|||
|
+#define BATCH_SIZE 500
|
|||
|
+
|
|||
|
+typedef struct
|
|||
|
+{
|
|||
|
+ GtkSearchEngineSimple *engine;
|
|||
|
+
|
|||
|
+ gchar *path;
|
|||
|
+ GList *mime_types;
|
|||
|
+ gchar **words;
|
|||
|
+ GList *found_list;
|
|||
|
+
|
|||
|
+ gint n_processed_files;
|
|||
|
+ GList *uri_hits;
|
|||
|
+
|
|||
|
+ /* accessed on both threads: */
|
|||
|
+ volatile gboolean cancelled;
|
|||
|
+} SearchThreadData;
|
|||
|
+
|
|||
|
+
|
|||
|
+struct _GtkSearchEngineSimplePrivate
|
|||
|
+{
|
|||
|
+ GtkQuery *query;
|
|||
|
+
|
|||
|
+ SearchThreadData *active_search;
|
|||
|
+
|
|||
|
+ gboolean query_finished;
|
|||
|
+};
|
|||
|
+
|
|||
|
+
|
|||
|
+G_DEFINE_TYPE (GtkSearchEngineSimple, _gtk_search_engine_simple, GTK_TYPE_SEARCH_ENGINE);
|
|||
|
+
|
|||
|
+static void
|
|||
|
+finalize (GObject *object)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineSimple *simple;
|
|||
|
+
|
|||
|
+ simple = GTK_SEARCH_ENGINE_SIMPLE (object);
|
|||
|
+
|
|||
|
+ if (simple->priv->query)
|
|||
|
+ {
|
|||
|
+ g_object_unref (simple->priv->query);
|
|||
|
+ simple->priv->query = NULL;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ g_free (simple->priv);
|
|||
|
+
|
|||
|
+ G_OBJECT_CLASS (_gtk_search_engine_simple_parent_class)->finalize (object);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static SearchThreadData *
|
|||
|
+search_thread_data_new (GtkSearchEngineSimple *engine,
|
|||
|
+ GtkQuery *query)
|
|||
|
+{
|
|||
|
+ SearchThreadData *data;
|
|||
|
+ char *text, *lower, *uri;
|
|||
|
+
|
|||
|
+ data = g_new0 (SearchThreadData, 1);
|
|||
|
+
|
|||
|
+ data->engine = engine;
|
|||
|
+ uri = _gtk_query_get_location (query);
|
|||
|
+ if (uri != NULL)
|
|||
|
+ {
|
|||
|
+ data->path = g_filename_from_uri (uri, NULL, NULL);
|
|||
|
+ g_free (uri);
|
|||
|
+ }
|
|||
|
+ if (data->path == NULL)
|
|||
|
+ data->path = g_strdup (g_get_home_dir ());
|
|||
|
+
|
|||
|
+ text = _gtk_query_get_text (query);
|
|||
|
+ lower = g_ascii_strdown (text, -1);
|
|||
|
+ data->words = g_strsplit (lower, " ", -1);
|
|||
|
+ g_free (text);
|
|||
|
+ g_free (lower);
|
|||
|
+
|
|||
|
+ data->mime_types = _gtk_query_get_mime_types (query);
|
|||
|
+
|
|||
|
+ return data;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+search_thread_data_free (SearchThreadData *data)
|
|||
|
+{
|
|||
|
+ g_free (data->path);
|
|||
|
+ g_strfreev (data->words);
|
|||
|
+ g_list_foreach (data->mime_types, (GFunc)g_free, NULL);
|
|||
|
+ g_list_free (data->mime_types);
|
|||
|
+ g_free (data);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static gboolean
|
|||
|
+search_thread_done_idle (gpointer user_data)
|
|||
|
+{
|
|||
|
+ SearchThreadData *data;
|
|||
|
+
|
|||
|
+ data = user_data;
|
|||
|
+
|
|||
|
+ if (!data->cancelled)
|
|||
|
+ {
|
|||
|
+ _gtk_search_engine_finished (GTK_SEARCH_ENGINE (data->engine));
|
|||
|
+ data->engine->priv->active_search = NULL;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ search_thread_data_free (data);
|
|||
|
+
|
|||
|
+ return FALSE;
|
|||
|
+}
|
|||
|
+
|
|||
|
+typedef struct
|
|||
|
+{
|
|||
|
+ GList *uris;
|
|||
|
+ SearchThreadData *thread_data;
|
|||
|
+} SearchHits;
|
|||
|
+
|
|||
|
+
|
|||
|
+static gboolean
|
|||
|
+search_thread_add_hits_idle (gpointer user_data)
|
|||
|
+{
|
|||
|
+ SearchHits *hits;
|
|||
|
+
|
|||
|
+ hits = user_data;
|
|||
|
+
|
|||
|
+ if (!hits->thread_data->cancelled)
|
|||
|
+ {
|
|||
|
+ _gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (hits->thread_data->engine),
|
|||
|
+ hits->uris);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ g_list_foreach (hits->uris, (GFunc)g_free, NULL);
|
|||
|
+ g_list_free (hits->uris);
|
|||
|
+ g_free (hits);
|
|||
|
+
|
|||
|
+ return FALSE;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+send_batch (SearchThreadData *data)
|
|||
|
+{
|
|||
|
+ SearchHits *hits;
|
|||
|
+
|
|||
|
+ data->n_processed_files = 0;
|
|||
|
+
|
|||
|
+ if (data->uri_hits)
|
|||
|
+ {
|
|||
|
+ hits = g_new (SearchHits, 1);
|
|||
|
+ hits->uris = data->uri_hits;
|
|||
|
+ hits->thread_data = data;
|
|||
|
+ g_idle_add (search_thread_add_hits_idle, hits);
|
|||
|
+ }
|
|||
|
+ data->uri_hits = NULL;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static GStaticPrivate search_thread_data = G_STATIC_PRIVATE_INIT;
|
|||
|
+
|
|||
|
+static int
|
|||
|
+search_visit_func (const char *fpath,
|
|||
|
+ const struct stat *sb,
|
|||
|
+ int typeflag,
|
|||
|
+ struct FTW *ftwbuf)
|
|||
|
+{
|
|||
|
+ SearchThreadData *data;
|
|||
|
+ gint i;
|
|||
|
+ const gchar *name;
|
|||
|
+ gchar *lower_name, *path, *mime_type;
|
|||
|
+ gchar *uri;
|
|||
|
+ gboolean hit;
|
|||
|
+ GList *l;
|
|||
|
+ gboolean is_hidden;
|
|||
|
+
|
|||
|
+ data = (SearchThreadData*)g_static_private_get (&search_thread_data);
|
|||
|
+
|
|||
|
+ if (data->cancelled)
|
|||
|
+ return FTW_STOP;
|
|||
|
+
|
|||
|
+ name = strrchr (fpath, '/');
|
|||
|
+ if (name)
|
|||
|
+ name++;
|
|||
|
+ else
|
|||
|
+ name = fpath;
|
|||
|
+
|
|||
|
+ path = g_build_filename (data->path, fpath, NULL);
|
|||
|
+
|
|||
|
+ is_hidden = *name == '.';
|
|||
|
+
|
|||
|
+ hit = FALSE;
|
|||
|
+
|
|||
|
+ if (!is_hidden)
|
|||
|
+ {
|
|||
|
+ lower_name = g_ascii_strdown (name, -1);
|
|||
|
+
|
|||
|
+ hit = TRUE;
|
|||
|
+ for (i = 0; data->words[i] != NULL; i++)
|
|||
|
+ {
|
|||
|
+ if (strstr (lower_name, data->words[i]) == NULL)
|
|||
|
+ {
|
|||
|
+ hit = FALSE;
|
|||
|
+ break;
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+ g_free (lower_name);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ if (hit && data->mime_types != NULL)
|
|||
|
+ {
|
|||
|
+ hit = FALSE;
|
|||
|
+ mime_type = xdg_mime_get_mime_type_for_file (path, (struct stat *)sb);
|
|||
|
+ for (l = data->mime_types; l != NULL; l = l->next)
|
|||
|
+ {
|
|||
|
+ if (strcmp (mime_type, l->data) == 0)
|
|||
|
+ {
|
|||
|
+ hit = TRUE;
|
|||
|
+ break;
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ g_free (mime_type);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ if (hit)
|
|||
|
+ {
|
|||
|
+ uri = g_filename_to_uri (path, NULL, NULL);
|
|||
|
+ data->uri_hits = g_list_prepend (data->uri_hits, uri);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ data->n_processed_files++;
|
|||
|
+
|
|||
|
+ if (data->n_processed_files > BATCH_SIZE)
|
|||
|
+ send_batch (data);
|
|||
|
+
|
|||
|
+ if (is_hidden)
|
|||
|
+ return FTW_SKIP_SUBTREE;
|
|||
|
+ else
|
|||
|
+ return FTW_CONTINUE;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static gpointer
|
|||
|
+search_thread_func (gpointer user_data)
|
|||
|
+{
|
|||
|
+ SearchThreadData *data;
|
|||
|
+
|
|||
|
+ data = user_data;
|
|||
|
+
|
|||
|
+ g_static_private_set (&search_thread_data, data, NULL);
|
|||
|
+
|
|||
|
+ nftw (data->path, search_visit_func, 20, FTW_ACTIONRETVAL | FTW_PHYS);
|
|||
|
+
|
|||
|
+ send_batch (data);
|
|||
|
+
|
|||
|
+ g_idle_add (search_thread_done_idle, data);
|
|||
|
+
|
|||
|
+ return NULL;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gtk_search_engine_simple_start (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineSimple *simple;
|
|||
|
+ SearchThreadData *data;
|
|||
|
+
|
|||
|
+ simple = GTK_SEARCH_ENGINE_SIMPLE (engine);
|
|||
|
+
|
|||
|
+ if (simple->priv->active_search != NULL)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
+ if (simple->priv->query == NULL)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
+ data = search_thread_data_new (simple, simple->priv->query);
|
|||
|
+
|
|||
|
+ g_thread_create (search_thread_func, data, FALSE, NULL);
|
|||
|
+
|
|||
|
+ simple->priv->active_search = data;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gtk_search_engine_simple_stop (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineSimple *simple;
|
|||
|
+
|
|||
|
+ simple = GTK_SEARCH_ENGINE_SIMPLE (engine);
|
|||
|
+
|
|||
|
+ if (simple->priv->active_search != NULL)
|
|||
|
+ {
|
|||
|
+ simple->priv->active_search->cancelled = TRUE;
|
|||
|
+ simple->priv->active_search = NULL;
|
|||
|
+ }
|
|||
|
+}
|
|||
|
+
|
|||
|
+static gboolean
|
|||
|
+gtk_search_engine_simple_is_indexed (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+ return FALSE;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gtk_search_engine_simple_set_query (GtkSearchEngine *engine,
|
|||
|
+ GtkQuery *query)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineSimple *simple;
|
|||
|
+
|
|||
|
+ simple = GTK_SEARCH_ENGINE_SIMPLE (engine);
|
|||
|
+
|
|||
|
+ if (query)
|
|||
|
+ g_object_ref (query);
|
|||
|
+
|
|||
|
+ if (simple->priv->query)
|
|||
|
+ g_object_unref (simple->priv->query);
|
|||
|
+
|
|||
|
+ simple->priv->query = query;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+_gtk_search_engine_simple_class_init (GtkSearchEngineSimpleClass *class)
|
|||
|
+{
|
|||
|
+ GObjectClass *gobject_class;
|
|||
|
+ GtkSearchEngineClass *engine_class;
|
|||
|
+
|
|||
|
+ gobject_class = G_OBJECT_CLASS (class);
|
|||
|
+ gobject_class->finalize = finalize;
|
|||
|
+
|
|||
|
+ engine_class = GTK_SEARCH_ENGINE_CLASS (class);
|
|||
|
+ engine_class->set_query = gtk_search_engine_simple_set_query;
|
|||
|
+ engine_class->start = gtk_search_engine_simple_start;
|
|||
|
+ engine_class->stop = gtk_search_engine_simple_stop;
|
|||
|
+ engine_class->is_indexed = gtk_search_engine_simple_is_indexed;
|
|||
|
+
|
|||
|
+ g_type_class_add_private (gobject_class, sizeof (GtkSearchEngineSimplePrivate));
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+_gtk_search_engine_simple_init (GtkSearchEngineSimple *engine)
|
|||
|
+{
|
|||
|
+ engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine, GTK_TYPE_SEARCH_ENGINE_SIMPLE, GtkSearchEngineSimplePrivate);
|
|||
|
+}
|
|||
|
+
|
|||
|
+GtkSearchEngine *
|
|||
|
+_gtk_search_engine_simple_new (void)
|
|||
|
+{
|
|||
|
+ GtkSearchEngine *engine;
|
|||
|
+
|
|||
|
+ engine = g_object_new (GTK_TYPE_SEARCH_ENGINE_SIMPLE, NULL);
|
|||
|
+
|
|||
|
+ return engine;
|
|||
|
+}
|
|||
|
--- /dev/null 2007-01-16 08:16:47.736226048 -0500
|
|||
|
+++ gtk+-2.10.8/gtk/gtksearchenginebeagle.c 2007-01-17 01:21:08.000000000 -0500
|
|||
|
@@ -0,0 +1,420 @@
|
|||
|
+/*
|
|||
|
+ * Copyright (C) 2005 Novell, Inc.
|
|||
|
+ *
|
|||
|
+ * This library is free software; you can redistribute it and/or
|
|||
|
+ * modify it under the terms of the GNU Lesser General Public
|
|||
|
+ * License as published by the Free Software Foundation; either
|
|||
|
+ * version 2 of the License, or (at your option) any later version.
|
|||
|
+ *
|
|||
|
+ * This library 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
|
|||
|
+ * Lesser General Public License for more details.
|
|||
|
+ *
|
|||
|
+ * You should have received a copy of the GNU Lesser General Public
|
|||
|
+ * License along with this library; if not, write to the
|
|||
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|||
|
+ *
|
|||
|
+ * Author: Anders Carlsson <andersca@imendio.com>
|
|||
|
+ *
|
|||
|
+ * Based on nautilus-search-engine-beagle.c
|
|||
|
+ */
|
|||
|
+
|
|||
|
+#include <config.h>
|
|||
|
+#include <gmodule.h>
|
|||
|
+#include "gtksearchenginebeagle.h"
|
|||
|
+#if 0
|
|||
|
+#include <beagle/beagle.h>
|
|||
|
+#endif
|
|||
|
+
|
|||
|
+/* We dlopen() all the following from libbeagle at runtime */
|
|||
|
+
|
|||
|
+typedef struct _BeagleHit BeagleHit;
|
|||
|
+typedef struct _BeagleQuery BeagleQuery;
|
|||
|
+typedef struct _BeagleClient BeagleClient;
|
|||
|
+typedef struct _BeagleRequest BeagleRequest;
|
|||
|
+typedef struct _BeagleFinishedResponse BeagleFinishedResponse;
|
|||
|
+typedef struct _BeagleHitsAddedResponse BeagleHitsAddedResponse;
|
|||
|
+typedef struct _BeagleHitsSubtractedResponse BeagleHitsSubtractedResponse;
|
|||
|
+typedef struct _BeagleQueryPartProperty BeagleQueryPartProperty;
|
|||
|
+typedef struct _BeagleQueryPart BeagleQueryPart;
|
|||
|
+
|
|||
|
+#define BEAGLE_HIT(x) ((BeagleHit *)(x))
|
|||
|
+#define BEAGLE_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), beagle_request_get_type(), BeagleRequest))
|
|||
|
+#define BEAGLE_QUERY_PART(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), beagle_query_part_get_type(), BeagleQueryPart))
|
|||
|
+
|
|||
|
+typedef enum
|
|||
|
+{
|
|||
|
+ BEAGLE_QUERY_PART_LOGIC_REQUIRED = 1,
|
|||
|
+ BEAGLE_QUERY_PART_LOGIC_PROHIBITED = 2
|
|||
|
+} BeagleQueryPartLogic;
|
|||
|
+
|
|||
|
+typedef enum
|
|||
|
+ {
|
|||
|
+ BEAGLE_PROPERTY_TYPE_UNKNOWN = 0,
|
|||
|
+ BEAGLE_PROPERTY_TYPE_TEXT = 1,
|
|||
|
+ BEAGLE_PROPERTY_TYPE_KEYWORD = 2,
|
|||
|
+ BEAGLE_PROPERTY_TYPE_DATE = 3,
|
|||
|
+ BEAGLE_PROPERTY_TYPE_LAST = 4
|
|||
|
+} BeaglePropertyType;
|
|||
|
+
|
|||
|
+/* *static* wrapper function pointers */
|
|||
|
+static gboolean (*beagle_client_send_request_async) (BeagleClient *client,
|
|||
|
+ BeagleRequest *request,
|
|||
|
+ GError **err) = NULL;
|
|||
|
+static G_CONST_RETURN char *(*beagle_hit_get_uri) (BeagleHit *hit) = NULL;
|
|||
|
+static GSList *(*beagle_hits_added_response_get_hits) (BeagleHitsAddedResponse *response) = NULL;
|
|||
|
+static GSList *(*beagle_hits_subtracted_response_get_uris) (BeagleHitsSubtractedResponse *response) = NULL;
|
|||
|
+static BeagleQuery *(*beagle_query_new) (void) = NULL;
|
|||
|
+static void (*beagle_query_add_text) (BeagleQuery *query,
|
|||
|
+ const char *str) = NULL;
|
|||
|
+static void (*beagle_query_add_hit_type) (BeagleQuery *query,
|
|||
|
+ const char *hit_type) = NULL;
|
|||
|
+static void (*beagle_query_add_mime_type) (BeagleQuery *query,
|
|||
|
+ const char *mime_type) = NULL;
|
|||
|
+static void (*beagle_query_set_max_hits) (BeagleQuery *query,
|
|||
|
+ gint max_hits) = NULL;
|
|||
|
+static BeagleQueryPartProperty *(*beagle_query_part_property_new) (void) = NULL;
|
|||
|
+static void (*beagle_query_part_set_logic) (BeagleQueryPart *part,
|
|||
|
+ BeagleQueryPartLogic logic) = NULL;
|
|||
|
+static void (*beagle_query_part_property_set_key) (BeagleQueryPartProperty *part,
|
|||
|
+ const char *key) = NULL;
|
|||
|
+static void (*beagle_query_part_property_set_value) (BeagleQueryPartProperty *part,
|
|||
|
+ const char * value) = NULL;
|
|||
|
+static void (*beagle_query_part_property_set_property_type) (BeagleQueryPartProperty *part,
|
|||
|
+ BeaglePropertyType prop_type) = NULL;
|
|||
|
+static void (*beagle_query_add_part) (BeagleQuery *query,
|
|||
|
+ BeagleQueryPart *part) = NULL;
|
|||
|
+static GType (*beagle_request_get_type) (void) = NULL;
|
|||
|
+static GType (*beagle_query_part_get_type) (void) = NULL;
|
|||
|
+static gboolean (*beagle_util_daemon_is_running) (void) = NULL;
|
|||
|
+static BeagleClient *(*beagle_client_new) (const char *client_name) = NULL;
|
|||
|
+
|
|||
|
+static struct BeagleDlMapping
|
|||
|
+{
|
|||
|
+ const char *fn_name;
|
|||
|
+ gpointer *fn_ptr_ref;
|
|||
|
+} beagle_dl_mapping[] =
|
|||
|
+{
|
|||
|
+#define MAP(a) { #a, (gpointer *)&a }
|
|||
|
+ MAP (beagle_client_send_request_async),
|
|||
|
+ MAP (beagle_hit_get_uri),
|
|||
|
+ MAP (beagle_hits_added_response_get_hits),
|
|||
|
+ MAP (beagle_hits_subtracted_response_get_uris),
|
|||
|
+ MAP (beagle_query_new),
|
|||
|
+ MAP (beagle_query_add_text),
|
|||
|
+ MAP (beagle_query_add_hit_type),
|
|||
|
+ MAP (beagle_query_add_mime_type),
|
|||
|
+ MAP (beagle_query_set_max_hits),
|
|||
|
+ MAP (beagle_query_part_property_new),
|
|||
|
+ MAP (beagle_query_part_set_logic),
|
|||
|
+ MAP (beagle_query_part_property_set_key),
|
|||
|
+ MAP (beagle_query_part_property_set_value),
|
|||
|
+ MAP (beagle_query_part_property_set_property_type),
|
|||
|
+ MAP (beagle_query_add_part),
|
|||
|
+ MAP (beagle_request_get_type),
|
|||
|
+ MAP (beagle_query_part_get_type),
|
|||
|
+ MAP (beagle_util_daemon_is_running),
|
|||
|
+ MAP (beagle_client_new)
|
|||
|
+#undef MAP
|
|||
|
+};
|
|||
|
+
|
|||
|
+static void
|
|||
|
+open_libbeagle (void)
|
|||
|
+{
|
|||
|
+ static gboolean done = FALSE;
|
|||
|
+
|
|||
|
+ if (!done)
|
|||
|
+ {
|
|||
|
+ int i;
|
|||
|
+ GModule *beagle;
|
|||
|
+
|
|||
|
+ done = TRUE;
|
|||
|
+
|
|||
|
+ beagle = g_module_open ("libbeagle.so.0", G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
|
|||
|
+ if (!beagle)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
+ for (i = 0; i < G_N_ELEMENTS (beagle_dl_mapping); i++)
|
|||
|
+ {
|
|||
|
+ if (!g_module_symbol (beagle, beagle_dl_mapping[i].fn_name,
|
|||
|
+ beagle_dl_mapping[i].fn_ptr_ref))
|
|||
|
+ {
|
|||
|
+ g_warning ("Missing symbol '%s' in libbeagle\n",
|
|||
|
+ beagle_dl_mapping[i].fn_name);
|
|||
|
+ g_module_close (beagle);
|
|||
|
+
|
|||
|
+ for (i = 0; i < G_N_ELEMENTS (beagle_dl_mapping); i++)
|
|||
|
+ beagle_dl_mapping[i].fn_ptr_ref = NULL;
|
|||
|
+
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+}
|
|||
|
+
|
|||
|
+
|
|||
|
+struct _GtkSearchEngineBeaglePrivate
|
|||
|
+{
|
|||
|
+ BeagleClient *client;
|
|||
|
+ GtkQuery *query;
|
|||
|
+
|
|||
|
+ BeagleQuery *current_query;
|
|||
|
+ char *current_query_uri_prefix;
|
|||
|
+ gboolean query_finished;
|
|||
|
+};
|
|||
|
+
|
|||
|
+
|
|||
|
+G_DEFINE_TYPE (GtkSearchEngineBeagle, _gtk_search_engine_beagle, GTK_TYPE_SEARCH_ENGINE);
|
|||
|
+
|
|||
|
+static void
|
|||
|
+finalize (GObject *object)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineBeagle *beagle;
|
|||
|
+
|
|||
|
+ beagle = GTK_SEARCH_ENGINE_BEAGLE (object);
|
|||
|
+
|
|||
|
+ if (beagle->priv->current_query)
|
|||
|
+ {
|
|||
|
+ g_object_unref (beagle->priv->current_query);
|
|||
|
+ beagle->priv->current_query = NULL;
|
|||
|
+ g_free (beagle->priv->current_query_uri_prefix);
|
|||
|
+ beagle->priv->current_query_uri_prefix = NULL;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ if (beagle->priv->query)
|
|||
|
+ {
|
|||
|
+ g_object_unref (beagle->priv->query);
|
|||
|
+ beagle->priv->query = NULL;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ if (beagle->priv->client)
|
|||
|
+ {
|
|||
|
+ g_object_unref (beagle->priv->client);
|
|||
|
+ beagle->priv->client = NULL;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ G_OBJECT_CLASS (_gtk_search_engine_beagle_parent_class)->finalize (object);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+beagle_hits_added (BeagleQuery *query,
|
|||
|
+ BeagleHitsAddedResponse *response,
|
|||
|
+ GtkSearchEngineBeagle *engine)
|
|||
|
+{
|
|||
|
+ GSList *hits, *list;
|
|||
|
+ GList *hit_uris;
|
|||
|
+ const gchar *uri;
|
|||
|
+
|
|||
|
+ hit_uris = NULL;
|
|||
|
+
|
|||
|
+ hits = beagle_hits_added_response_get_hits (response);
|
|||
|
+
|
|||
|
+ for (list = hits; list != NULL; list = list->next)
|
|||
|
+ {
|
|||
|
+ BeagleHit *hit = BEAGLE_HIT (list->data);
|
|||
|
+
|
|||
|
+ uri = beagle_hit_get_uri (hit);
|
|||
|
+
|
|||
|
+ if (engine->priv->current_query_uri_prefix &&
|
|||
|
+ !g_str_has_prefix (uri, engine->priv->current_query_uri_prefix))
|
|||
|
+ continue;
|
|||
|
+
|
|||
|
+ hit_uris = g_list_prepend (hit_uris, (char *)uri);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ _gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (engine), hit_uris);
|
|||
|
+ g_list_free (hit_uris);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+beagle_hits_subtracted (BeagleQuery *query,
|
|||
|
+ BeagleHitsSubtractedResponse *response,
|
|||
|
+ GtkSearchEngineBeagle *engine)
|
|||
|
+{
|
|||
|
+ GSList *uris, *list;
|
|||
|
+ GList *hit_uris;
|
|||
|
+
|
|||
|
+ hit_uris = NULL;
|
|||
|
+
|
|||
|
+ uris = beagle_hits_subtracted_response_get_uris (response);
|
|||
|
+
|
|||
|
+ for (list = uris; list != NULL; list = list->next)
|
|||
|
+ {
|
|||
|
+ hit_uris = g_list_prepend (hit_uris, (char *)list->data);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ _gtk_search_engine_hits_subtracted (GTK_SEARCH_ENGINE (engine), hit_uris);
|
|||
|
+ g_list_free (hit_uris);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+beagle_finished (BeagleQuery *query,
|
|||
|
+ BeagleFinishedResponse *response,
|
|||
|
+ GtkSearchEngineBeagle *engine)
|
|||
|
+{
|
|||
|
+ /* For some reason we keep getting finished events,
|
|||
|
+ * only emit finished once */
|
|||
|
+ if (engine->priv->query_finished)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
+ engine->priv->query_finished = TRUE;
|
|||
|
+ _gtk_search_engine_finished (GTK_SEARCH_ENGINE (engine));
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+beagle_error (BeagleQuery *query,
|
|||
|
+ GError *error,
|
|||
|
+ GtkSearchEngineBeagle *engine)
|
|||
|
+{
|
|||
|
+ _gtk_search_engine_error (GTK_SEARCH_ENGINE (engine), error->message);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gtk_search_engine_beagle_start (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineBeagle *beagle;
|
|||
|
+ GError *error;
|
|||
|
+ GList *mimetypes, *l;
|
|||
|
+ gchar *text, *mimetype;
|
|||
|
+
|
|||
|
+ error = NULL;
|
|||
|
+ beagle = GTK_SEARCH_ENGINE_BEAGLE (engine);
|
|||
|
+
|
|||
|
+ if (beagle->priv->current_query)
|
|||
|
+ return;
|
|||
|
+
|
|||
|
+ beagle->priv->query_finished = FALSE;
|
|||
|
+ beagle->priv->current_query = beagle_query_new ();
|
|||
|
+ g_signal_connect (beagle->priv->current_query,
|
|||
|
+ "hits-added", G_CALLBACK (beagle_hits_added), engine);
|
|||
|
+ g_signal_connect (beagle->priv->current_query,
|
|||
|
+ "hits-subtracted", G_CALLBACK (beagle_hits_subtracted), engine);
|
|||
|
+ g_signal_connect (beagle->priv->current_query,
|
|||
|
+ "finished", G_CALLBACK (beagle_finished), engine);
|
|||
|
+ g_signal_connect (beagle->priv->current_query,
|
|||
|
+ "error", G_CALLBACK (beagle_error), engine);
|
|||
|
+
|
|||
|
+ /* We only want files */
|
|||
|
+ beagle_query_add_hit_type (beagle->priv->current_query,
|
|||
|
+ "File");
|
|||
|
+ beagle_query_set_max_hits (beagle->priv->current_query,
|
|||
|
+ 1000);
|
|||
|
+
|
|||
|
+ text = _gtk_query_get_text (beagle->priv->query);
|
|||
|
+ beagle_query_add_text (beagle->priv->current_query,
|
|||
|
+ text);
|
|||
|
+
|
|||
|
+ mimetypes = _gtk_query_get_mime_types (beagle->priv->query);
|
|||
|
+ for (l = mimetypes; l != NULL; l = l->next)
|
|||
|
+ {
|
|||
|
+ mimetype = l->data;
|
|||
|
+ beagle_query_add_mime_type (beagle->priv->current_query, mimetype);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ beagle->priv->current_query_uri_prefix = _gtk_query_get_location (beagle->priv->query);
|
|||
|
+
|
|||
|
+ if (!beagle_client_send_request_async (beagle->priv->client,
|
|||
|
+ BEAGLE_REQUEST (beagle->priv->current_query), &error))
|
|||
|
+ {
|
|||
|
+ _gtk_search_engine_error (engine, error->message);
|
|||
|
+ g_error_free (error);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ /* These must live during the lifetime of the query */
|
|||
|
+ g_free (text);
|
|||
|
+ g_list_foreach (mimetypes, (GFunc)g_free, NULL);
|
|||
|
+ g_list_free (mimetypes);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gtk_search_engine_beagle_stop (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineBeagle *beagle;
|
|||
|
+
|
|||
|
+ beagle = GTK_SEARCH_ENGINE_BEAGLE (engine);
|
|||
|
+
|
|||
|
+ if (beagle->priv->current_query)
|
|||
|
+ {
|
|||
|
+ g_object_unref (beagle->priv->current_query);
|
|||
|
+ beagle->priv->current_query = NULL;
|
|||
|
+ g_free (beagle->priv->current_query_uri_prefix);
|
|||
|
+ beagle->priv->current_query_uri_prefix = NULL;
|
|||
|
+ }
|
|||
|
+}
|
|||
|
+
|
|||
|
+static gboolean
|
|||
|
+gtk_search_engine_beagle_is_indexed (GtkSearchEngine *engine)
|
|||
|
+{
|
|||
|
+ return TRUE;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gtk_search_engine_beagle_set_query (GtkSearchEngine *engine,
|
|||
|
+ GtkQuery *query)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineBeagle *beagle;
|
|||
|
+
|
|||
|
+ beagle = GTK_SEARCH_ENGINE_BEAGLE (engine);
|
|||
|
+
|
|||
|
+ if (query)
|
|||
|
+ g_object_ref (query);
|
|||
|
+
|
|||
|
+ if (beagle->priv->query)
|
|||
|
+ g_object_unref (beagle->priv->query);
|
|||
|
+
|
|||
|
+ beagle->priv->query = query;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+_gtk_search_engine_beagle_class_init (GtkSearchEngineBeagleClass *class)
|
|||
|
+{
|
|||
|
+ GObjectClass *gobject_class;
|
|||
|
+ GtkSearchEngineClass *engine_class;
|
|||
|
+
|
|||
|
+ gobject_class = G_OBJECT_CLASS (class);
|
|||
|
+ gobject_class->finalize = finalize;
|
|||
|
+
|
|||
|
+ engine_class = GTK_SEARCH_ENGINE_CLASS (class);
|
|||
|
+ engine_class->set_query = gtk_search_engine_beagle_set_query;
|
|||
|
+ engine_class->start = gtk_search_engine_beagle_start;
|
|||
|
+ engine_class->stop = gtk_search_engine_beagle_stop;
|
|||
|
+ engine_class->is_indexed = gtk_search_engine_beagle_is_indexed;
|
|||
|
+
|
|||
|
+ g_type_class_add_private (gobject_class, sizeof (GtkSearchEngineBeaglePrivate));
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+_gtk_search_engine_beagle_init (GtkSearchEngineBeagle *engine)
|
|||
|
+{
|
|||
|
+ engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine, GTK_TYPE_SEARCH_ENGINE_BEAGLE, GtkSearchEngineBeaglePrivate);
|
|||
|
+}
|
|||
|
+
|
|||
|
+
|
|||
|
+GtkSearchEngine *
|
|||
|
+_gtk_search_engine_beagle_new (void)
|
|||
|
+{
|
|||
|
+ GtkSearchEngineBeagle *engine;
|
|||
|
+ BeagleClient *client;
|
|||
|
+
|
|||
|
+ open_libbeagle ();
|
|||
|
+
|
|||
|
+ if (!beagle_util_daemon_is_running)
|
|||
|
+ return NULL;
|
|||
|
+
|
|||
|
+ /* check whether daemon is running as beagle_client_new
|
|||
|
+ * doesn't fail when a stale socket file exists */
|
|||
|
+ if (!beagle_util_daemon_is_running ())
|
|||
|
+ return NULL;
|
|||
|
+
|
|||
|
+ client = beagle_client_new (NULL);
|
|||
|
+
|
|||
|
+ if (client == NULL)
|
|||
|
+ return NULL;
|
|||
|
+
|
|||
|
+ engine = g_object_new (GTK_TYPE_SEARCH_ENGINE_BEAGLE, NULL);
|
|||
|
+
|
|||
|
+ engine->priv->client = client;
|
|||
|
+
|
|||
|
+ return GTK_SEARCH_ENGINE (engine);
|
|||
|
+}
|
|||
|
--- /dev/null 2007-01-16 08:16:47.736226048 -0500
|
|||
|
+++ gtk+-2.10.8/gtk/gtkquery.c 2007-01-17 01:21:08.000000000 -0500
|
|||
|
@@ -0,0 +1,142 @@
|
|||
|
+/*
|
|||
|
+ * Copyright (C) 2005 Novell, Inc.
|
|||
|
+ *
|
|||
|
+ * This library is free software; you can redistribute it and/or
|
|||
|
+ * modify it under the terms of the GNU Lesser General Public
|
|||
|
+ * License as published by the Free Software Foundation; either
|
|||
|
+ * version 2 of the License, or (at your option) any later version.
|
|||
|
+ *
|
|||
|
+ * This library 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
|
|||
|
+ * Lesser General Public License for more details.
|
|||
|
+ *
|
|||
|
+ * You should have received a copy of the GNU Lesser General Public
|
|||
|
+ * License along with this library; if not, write to the
|
|||
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|||
|
+ *
|
|||
|
+ * Author: Anders Carlsson <andersca@imendio.com>
|
|||
|
+ *
|
|||
|
+ * Based on nautilus-query.c
|
|||
|
+ */
|
|||
|
+
|
|||
|
+#include <config.h>
|
|||
|
+#include <string.h>
|
|||
|
+
|
|||
|
+#include "gtkquery.h"
|
|||
|
+
|
|||
|
+struct _GtkQueryPrivate
|
|||
|
+{
|
|||
|
+ gchar *text;
|
|||
|
+ gchar *location_uri;
|
|||
|
+ GList *mime_types;
|
|||
|
+};
|
|||
|
+
|
|||
|
+G_DEFINE_TYPE (GtkQuery, _gtk_query, G_TYPE_OBJECT);
|
|||
|
+
|
|||
|
+static void
|
|||
|
+finalize (GObject *object)
|
|||
|
+{
|
|||
|
+ GtkQuery *query;
|
|||
|
+
|
|||
|
+ query = GTK_QUERY (object);
|
|||
|
+
|
|||
|
+ g_free (query->priv->text);
|
|||
|
+
|
|||
|
+ G_OBJECT_CLASS (_gtk_query_parent_class)->finalize (object);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+_gtk_query_class_init (GtkQueryClass *class)
|
|||
|
+{
|
|||
|
+ GObjectClass *gobject_class;
|
|||
|
+
|
|||
|
+ gobject_class = G_OBJECT_CLASS (class);
|
|||
|
+ gobject_class->finalize = finalize;
|
|||
|
+
|
|||
|
+ g_type_class_add_private (gobject_class, sizeof (GtkQueryPrivate));
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+_gtk_query_init (GtkQuery *query)
|
|||
|
+{
|
|||
|
+ query->priv = G_TYPE_INSTANCE_GET_PRIVATE (query, GTK_TYPE_QUERY, GtkQueryPrivate);
|
|||
|
+}
|
|||
|
+
|
|||
|
+GtkQuery *
|
|||
|
+_gtk_query_new (void)
|
|||
|
+{
|
|||
|
+ return g_object_new (GTK_TYPE_QUERY, NULL);
|
|||
|
+}
|
|||
|
+
|
|||
|
+
|
|||
|
+gchar *
|
|||
|
+_gtk_query_get_text (GtkQuery *query)
|
|||
|
+{
|
|||
|
+ return g_strdup (query->priv->text);
|
|||
|
+}
|
|||
|
+
|
|||
|
+void
|
|||
|
+_gtk_query_set_text (GtkQuery *query,
|
|||
|
+ const gchar *text)
|
|||
|
+{
|
|||
|
+ g_free (query->priv->text);
|
|||
|
+ query->priv->text = g_strdup (text);
|
|||
|
+}
|
|||
|
+
|
|||
|
+gchar *
|
|||
|
+_gtk_query_get_location (GtkQuery *query)
|
|||
|
+{
|
|||
|
+ return g_strdup (query->priv->location_uri);
|
|||
|
+}
|
|||
|
+
|
|||
|
+void
|
|||
|
+_gtk_query_set_location (GtkQuery *query,
|
|||
|
+ const gchar *uri)
|
|||
|
+{
|
|||
|
+ g_free (query->priv->location_uri);
|
|||
|
+ query->priv->location_uri = g_strdup (uri);
|
|||
|
+}
|
|||
|
+
|
|||
|
+GList *
|
|||
|
+_gtk_query_get_mime_types (GtkQuery *query)
|
|||
|
+{
|
|||
|
+ GList *list, *l;
|
|||
|
+ gchar *mime_type;
|
|||
|
+
|
|||
|
+ list = NULL;
|
|||
|
+ for (l = query->priv->mime_types; l; l = l->next)
|
|||
|
+ {
|
|||
|
+ mime_type = (gchar*)l->data;
|
|||
|
+ list = g_list_prepend (list, g_strdup (mime_type));
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ return list;
|
|||
|
+}
|
|||
|
+
|
|||
|
+void
|
|||
|
+_gtk_query_set_mime_types (GtkQuery *query,
|
|||
|
+ GList *mime_types)
|
|||
|
+{
|
|||
|
+ GList *l;
|
|||
|
+ gchar *mime_type;
|
|||
|
+
|
|||
|
+ g_list_foreach (query->priv->mime_types, (GFunc)g_free, NULL);
|
|||
|
+ g_list_free (query->priv->mime_types);
|
|||
|
+ query->priv->mime_types = NULL;
|
|||
|
+
|
|||
|
+ for (l = mime_types; l; l = l->next)
|
|||
|
+ {
|
|||
|
+ mime_type = (gchar*)l->data;
|
|||
|
+ query->priv->mime_types = g_list_prepend (query->priv->mime_types, g_strdup (mime_type));
|
|||
|
+ }
|
|||
|
+}
|
|||
|
+
|
|||
|
+void
|
|||
|
+_gtk_query_add_mime_type (GtkQuery *query,
|
|||
|
+ const gchar *mime_type)
|
|||
|
+{
|
|||
|
+ query->priv->mime_types = g_list_prepend (query->priv->mime_types,
|
|||
|
+ g_strdup (mime_type));
|
|||
|
+}
|
|||
|
+
|
|||
|
--- /dev/null 2007-01-16 08:16:47.736226048 -0500
|
|||
|
+++ gtk+-2.10.8/gtk/gtkquery.h 2007-01-17 01:21:08.000000000 -0500
|
|||
|
@@ -0,0 +1,74 @@
|
|||
|
+/*
|
|||
|
+ * Copyright (C) 2005 Novell, Inc.
|
|||
|
+ *
|
|||
|
+ * This library is free software; you can redistribute it and/or
|
|||
|
+ * modify it under the terms of the GNU Lesser General Public
|
|||
|
+ * License as published by the Free Software Foundation; either
|
|||
|
+ * version 2 of the License, or (at your option) any later version.
|
|||
|
+ *
|
|||
|
+ * This library 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
|
|||
|
+ * Lesser General Public License for more details.
|
|||
|
+ *
|
|||
|
+ * You should have received a copy of the GNU Lesser General Public
|
|||
|
+ * License along with this library; if not, write to the
|
|||
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|||
|
+ *
|
|||
|
+ * Author: Anders Carlsson <andersca@imendio.com>
|
|||
|
+ *
|
|||
|
+ * Based on nautilus-query.h
|
|||
|
+ */
|
|||
|
+
|
|||
|
+#ifndef __GTK_QUERY_H__
|
|||
|
+#define __GTK_QUERY_H__
|
|||
|
+
|
|||
|
+#include <glib-object.h>
|
|||
|
+
|
|||
|
+G_BEGIN_DECLS
|
|||
|
+
|
|||
|
+#define GTK_TYPE_QUERY (_gtk_query_get_type ())
|
|||
|
+#define GTK_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_QUERY, GtkQuery))
|
|||
|
+#define GTK_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_QUERY, GtkQueryClass))
|
|||
|
+#define GTK_IS_QUERY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_QUERY))
|
|||
|
+#define GTK_IS_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_QUERY))
|
|||
|
+#define GTK_QUERY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_QUERY, GtkQueryClass))
|
|||
|
+
|
|||
|
+typedef struct _GtkQuery GtkQuery;
|
|||
|
+typedef struct _GtkQueryClass GtkQueryClass;
|
|||
|
+typedef struct _GtkQueryPrivate GtkQueryPrivate;
|
|||
|
+
|
|||
|
+struct _GtkQuery
|
|||
|
+{
|
|||
|
+ GObject parent;
|
|||
|
+
|
|||
|
+ GtkQueryPrivate *priv;
|
|||
|
+};
|
|||
|
+
|
|||
|
+struct _GtkQueryClass
|
|||
|
+{
|
|||
|
+ GObjectClass parent_class;
|
|||
|
+};
|
|||
|
+
|
|||
|
+GType _gtk_query_get_type (void);
|
|||
|
+gboolean _gtk_query_enabled (void);
|
|||
|
+
|
|||
|
+GtkQuery* _gtk_query_new (void);
|
|||
|
+
|
|||
|
+gchar* _gtk_query_get_text (GtkQuery *query);
|
|||
|
+void _gtk_query_set_text (GtkQuery *query,
|
|||
|
+ const gchar *text);
|
|||
|
+
|
|||
|
+gchar* _gtk_query_get_location (GtkQuery *query);
|
|||
|
+void _gtk_query_set_location (GtkQuery *query,
|
|||
|
+ const gchar *uri);
|
|||
|
+
|
|||
|
+GList* _gtk_query_get_mime_types (GtkQuery *query);
|
|||
|
+void _gtk_query_set_mime_types (GtkQuery *query,
|
|||
|
+ GList *mime_types);
|
|||
|
+void _gtk_query_add_mime_type (GtkQuery *query,
|
|||
|
+ const gchar *mime_type);
|
|||
|
+
|
|||
|
+G_END_DECLS
|
|||
|
+
|
|||
|
+#endif /* __GTK_QUERY_H__ */
|