summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2005-12-07 15:03:12 +0000
committerAlexander Larsson <alexl@src.gnome.org>2005-12-07 15:03:12 +0000
commit5d38be40b9465993590918106ae41d32cfdc58c3 (patch)
treee7f47becf02cf1f07ca9c207dcfffad59a0297ef
parentbb0f3df3aef06040ab7154d8d67161a0cf1a6a0f (diff)
downloadnautilus-5d38be40b9465993590918106ae41d32cfdc58c3.tar.gz
Mime API needs gnome-vfs-module. Unfortunate...
2005-12-07 Alexander Larsson <alexl@redhat.com> * configure.in: Mime API needs gnome-vfs-module. Unfortunate... * libnautilus-private/nautilus-query.c: Parse queries fully * libnautilus-private/nautilus-search-engine-beagle.c: Look at mime types and location. * src/nautilus-query-editor.c: Add mime type and location to query editor
-rw-r--r--ChangeLog14
-rw-r--r--configure.in3
-rw-r--r--libnautilus-private/nautilus-query.c107
-rw-r--r--libnautilus-private/nautilus-search-engine-beagle.c41
-rw-r--r--src/nautilus-query-editor.c755
5 files changed, 858 insertions, 62 deletions
diff --git a/ChangeLog b/ChangeLog
index 5318f5aa3..6afde1f6b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2005-12-07 Alexander Larsson <alexl@redhat.com>
+
+ * configure.in:
+ Mime API needs gnome-vfs-module. Unfortunate...
+
+ * libnautilus-private/nautilus-query.c:
+ Parse queries fully
+
+ * libnautilus-private/nautilus-search-engine-beagle.c:
+ Look at mime types and location.
+
+ * src/nautilus-query-editor.c:
+ Add mime type and location to query editor
+
2005-12-06 Alexander Larsson <alexl@redhat.com>
* libnautilus-private/nautilus-query.[ch]:
diff --git a/configure.in b/configure.in
index a77523940..704566b7a 100644
--- a/configure.in
+++ b/configure.in
@@ -86,6 +86,7 @@ PKG_CHECK_MODULES(ALL, [
glib-2.0 >= glib_minver
gnome-desktop-2.0 >= gnome_desktop_minver
gnome-vfs-2.0 >= gnome_vfs_minver
+ gnome-vfs-module-2.0 >= gnome_vfs_minver
ORBit-2.0 >= orbit_minver
pango >= pango_minver
gtk+-2.0 >= gtk_minver
@@ -308,7 +309,7 @@ LIBNAUTILUS_EXTENSION_LIBS="`$PKG_CONFIG --libs $LIBNAUTILUS_EXTENSION_MODULES`"
AC_SUBST(LIBNAUTILUS_EXTENSION_LIBS)
dnl core nautilus (must list bonobo-activation and libbonobo because idldir does not respect "requires")
-CORE_MODULES="eel-2.0 librsvg-2.0 bonobo-activation-2.0 libbonobo-2.0 esound gnome-desktop-2.0 $EXTRA_CORE_MODULES"
+CORE_MODULES="eel-2.0 librsvg-2.0 bonobo-activation-2.0 libbonobo-2.0 esound gnome-desktop-2.0 gnome-vfs-module-2.0 $EXTRA_CORE_MODULES"
CORE_CFLAGS="`$PKG_CONFIG --cflags $CORE_MODULES` $x_cflags"
AC_SUBST(CORE_CFLAGS)
CORE_LIBS="`$PKG_CONFIG --libs $CORE_MODULES` $CDDA_LIBS $LIBJPEG $x_libs"
diff --git a/libnautilus-private/nautilus-query.c b/libnautilus-private/nautilus-query.c
index f7ef23c88..b8e761a63 100644
--- a/libnautilus-private/nautilus-query.c
+++ b/libnautilus-private/nautilus-query.c
@@ -123,8 +123,8 @@ nautilus_query_set_mime_types (NautilusQuery *query, GList *mime_types)
void
nautilus_query_add_mime_type (NautilusQuery *query, const char *mime_type)
{
- query->details->mime_types = g_list_prepend (query->details->mime_types,
- g_strdup (mime_type));
+ query->details->mime_types = g_list_append (query->details->mime_types,
+ g_strdup (mime_type));
}
char *
@@ -137,9 +137,54 @@ nautilus_query_to_readable_string (NautilusQuery *query)
return g_strdup_printf ("Search for \"%s\"", query->details->text);
}
+static char *
+encode_home_uri (const char *uri)
+{
+ char *home_uri;
+ const char *encoded_uri;
+
+ home_uri = gnome_vfs_get_uri_from_local_path (g_get_home_dir ());
+
+ if (g_str_has_prefix (uri, home_uri)) {
+ encoded_uri = uri + strlen (home_uri);
+ if (*encoded_uri == '/') {
+ encoded_uri++;
+ }
+ } else {
+ encoded_uri = uri;
+ }
+
+ g_free (home_uri);
+
+ return g_markup_escape_text (encoded_uri, -1);
+}
+
+static char *
+decode_home_uri (const char *uri)
+{
+ char *home_uri;
+ char *decoded_uri;
+
+ if (g_str_has_prefix (uri, "file:")) {
+ decoded_uri = g_strdup (uri);
+ } else {
+ home_uri = gnome_vfs_get_uri_from_local_path (g_get_home_dir ());
+
+ decoded_uri = g_strconcat (home_uri, "/", uri, NULL);
+
+ g_free (home_uri);
+ }
+
+ return decoded_uri;
+}
+
+
typedef struct {
NautilusQuery *query;
gboolean in_text;
+ gboolean in_location;
+ gboolean in_mimetypes;
+ gboolean in_mimetype;
} ParserInfo;
static void
@@ -156,6 +201,12 @@ start_element_cb (GMarkupParseContext *ctx,
if (strcmp (element_name, "text") == 0)
info->in_text = TRUE;
+ else if (strcmp (element_name, "location") == 0)
+ info->in_location = TRUE;
+ else if (strcmp (element_name, "mimetypes") == 0)
+ info->in_mimetypes = TRUE;
+ else if (strcmp (element_name, "mimetype") == 0)
+ info->in_mimetype = TRUE;
}
static void
@@ -170,6 +221,12 @@ end_element_cb (GMarkupParseContext *ctx,
if (strcmp (element_name, "text") == 0)
info->in_text = FALSE;
+ else if (strcmp (element_name, "location") == 0)
+ info->in_location = FALSE;
+ else if (strcmp (element_name, "mimetypes") == 0)
+ info->in_mimetypes = FALSE;
+ else if (strcmp (element_name, "mimetype") == 0)
+ info->in_mimetype = FALSE;
}
static void
@@ -180,22 +237,24 @@ text_cb (GMarkupParseContext *ctx,
GError **err)
{
ParserInfo *info;
- char *t;
- NautilusQuery *query;
+ char *t, *uri;
info = (ParserInfo *) user_data;
- if (!info->in_text) {
- return;
- }
-
t = g_strndup (text, text_len);
- query = nautilus_query_new ();
- nautilus_query_set_text (query, t);
+ if (info->in_text) {
+ nautilus_query_set_text (info->query, t);
+ } else if (info->in_location) {
+ uri = decode_home_uri (t);
+ nautilus_query_set_location (info->query, uri);
+ g_free (uri);
+ } else if (info->in_mimetypes && info->in_mimetype) {
+ nautilus_query_add_mime_type (info->query, t);
+ }
+
g_free (t);
- info->query = query;
}
static void
@@ -217,14 +276,14 @@ static GMarkupParser parser = {
static NautilusQuery *
nautilus_query_parse_xml (char *xml, gsize xml_len)
{
- ParserInfo info;
+ ParserInfo info = { NULL };
GMarkupParseContext *ctx;
if (xml_len == -1) {
xml_len = strlen (xml);
}
- info.query = NULL;
+ info.query = nautilus_query_new ();
info.in_text = FALSE;
ctx = g_markup_parse_context_new (&parser, 0, &info, NULL);
@@ -254,28 +313,6 @@ nautilus_query_load (char *file)
}
static char *
-encode_home_uri (const char *uri)
-{
- char *home_uri;
- const char *encoded_uri;
-
- home_uri = gnome_vfs_get_uri_from_local_path (g_get_home_dir ());
-
- if (g_str_has_prefix (uri, home_uri)) {
- encoded_uri = uri + strlen (home_uri);
- if (*encoded_uri == '/') {
- encoded_uri++;
- }
- } else {
- encoded_uri = uri;
- }
-
- g_free (home_uri);
-
- return g_markup_escape_text (encoded_uri, -1);
-}
-
-static char *
nautilus_query_to_xml (NautilusQuery *query)
{
GString *xml;
diff --git a/libnautilus-private/nautilus-search-engine-beagle.c b/libnautilus-private/nautilus-search-engine-beagle.c
index d9a974ac9..84df7a6ad 100644
--- a/libnautilus-private/nautilus-search-engine-beagle.c
+++ b/libnautilus-private/nautilus-search-engine-beagle.c
@@ -26,12 +26,14 @@
#include <beagle/beagle.h>
#include <eel/eel-gtk-macros.h>
+#include <eel/eel-glib-extensions.h>
struct NautilusSearchEngineBeagleDetails {
BeagleClient *client;
NautilusQuery *query;
BeagleQuery *current_query;
+ char *current_query_uri_prefix;
gboolean query_finished;
};
@@ -55,6 +57,8 @@ finalize (GObject *object)
if (beagle->details->current_query) {
g_object_unref (beagle->details->current_query);
beagle->details->current_query = NULL;
+ g_free (beagle->details->current_query_uri_prefix);
+ beagle->details->current_query_uri_prefix = NULL;
}
if (beagle->details->query) {
@@ -79,6 +83,7 @@ beagle_hits_added (BeagleQuery *query,
{
GSList *hits, *list;
GList *hit_uris;
+ const char *uri;
hit_uris = NULL;
@@ -87,7 +92,14 @@ beagle_hits_added (BeagleQuery *query,
for (list = hits; list != NULL; list = list->next) {
BeagleHit *hit = BEAGLE_HIT (list->data);
- hit_uris = g_list_prepend (hit_uris, (char *)beagle_hit_get_uri (hit));
+ uri = beagle_hit_get_uri (hit);
+
+ if (engine->details->current_query_uri_prefix &&
+ !g_str_has_prefix (uri, engine->details->current_query_uri_prefix)) {
+ continue;
+ }
+
+ hit_uris = g_list_prepend (hit_uris, (char *)uri);
}
nautilus_search_engine_hits_added (NAUTILUS_SEARCH_ENGINE (engine), hit_uris);
@@ -142,6 +154,9 @@ nautilus_search_engine_beagle_start (NautilusSearchEngine *engine)
{
NautilusSearchEngineBeagle *beagle;
GError *error;
+ GList *mimetypes, *l;
+ char *text, **words, *mimetype;
+ int i;
error = NULL;
beagle = NAUTILUS_SEARCH_ENGINE_BEAGLE (engine);
@@ -171,13 +186,31 @@ nautilus_search_engine_beagle_start (NautilusSearchEngine *engine)
g_signal_connect (beagle->details->current_query,
"error", G_CALLBACK (beagle_error), engine);
- beagle_query_add_text (beagle->details->current_query,
- nautilus_query_get_text (beagle->details->query));
/* We only want files */
beagle_query_add_hit_type (beagle->details->current_query,
"File");
beagle_query_set_max_hits (beagle->details->current_query,
1000);
+
+ text = nautilus_query_get_text (beagle->details->query);
+ words = g_strsplit (text, " \n\t", -1);
+ for (i = 0; words[i] != NULL; i++) {
+ beagle_query_add_text (beagle->details->current_query,
+ words[i]);
+ }
+ g_free (text);
+ g_strdupv (words);
+
+ mimetypes = nautilus_query_get_mime_types (beagle->details->query);
+ for (l = mimetypes; l != NULL; l = l->next) {
+ mimetype = l->data;
+ beagle_query_add_mime_type (beagle->details->current_query,
+ mimetype);
+ }
+ eel_g_list_free_deep (mimetypes);
+
+ beagle->details->current_query_uri_prefix = nautilus_query_get_location (beagle->details->query);
+
if (!beagle_client_send_request_async (beagle->details->client,
BEAGLE_REQUEST (beagle->details->current_query), &error)) {
nautilus_search_engine_error (engine, error->message);
@@ -195,6 +228,8 @@ nautilus_search_engine_beagle_stop (NautilusSearchEngine *engine)
if (beagle->details->current_query) {
g_object_unref (beagle->details->current_query);
beagle->details->current_query = NULL;
+ g_free (beagle->details->current_query_uri_prefix);
+ beagle->details->current_query_uri_prefix = NULL;
}
}
diff --git a/src/nautilus-query-editor.c b/src/nautilus-query-editor.c
index 28cf9d22e..626cc12dd 100644
--- a/src/nautilus-query-editor.c
+++ b/src/nautilus-query-editor.c
@@ -24,6 +24,7 @@
#include <config.h>
#include "nautilus-query-editor.h"
+#include <string.h>
#include <glib/gi18n.h>
#include <eel/eel-gtk-macros.h>
#include <eel/eel-glib-extensions.h>
@@ -34,6 +35,43 @@
#include <gtk/gtkframe.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtklabel.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtkcombobox.h>
+#include "gtk/gtkliststore.h"
+#include <gtk/gtkfilechooserbutton.h>
+#include "gtk/gtkcelllayout.h"
+#include "gtk/gtkcellrenderertext.h"
+#include <libgnomevfs/gnome-vfs-utils.h>
+#include <libgnomevfs/gnome-vfs-mime-info.h>
+
+typedef enum {
+ NAUTILUS_QUERY_EDITOR_ROW_LOCATION,
+ NAUTILUS_QUERY_EDITOR_ROW_TYPE,
+
+ NAUTILUS_QUERY_EDITOR_ROW_LAST
+} NautilusQueryEditorRowType;
+
+typedef struct {
+ NautilusQueryEditorRowType type;
+ NautilusQueryEditor *editor;
+ GtkWidget *hbox;
+ GtkWidget *combo;
+
+ GtkWidget *type_widget;
+
+ void *data;
+} NautilusQueryEditorRow;
+
+
+typedef struct {
+ const char *name;
+ GtkWidget * (*create_widgets) (NautilusQueryEditorRow *row);
+ void (*add_to_query) (NautilusQueryEditorRow *row,
+ NautilusQuery *query);
+ void (*free_data) (NautilusQueryEditorRow *row);
+ void (*add_rows_from_query) (NautilusQueryEditor *editor,
+ NautilusQuery *query);
+} NautilusQueryEditorRowOps;
struct NautilusQueryEditorDetails {
GtkWidget *entry;
@@ -42,6 +80,8 @@ struct NautilusQueryEditorDetails {
gboolean is_visible;
GtkWidget *invisible_vbox;
GtkWidget *visible_vbox;
+
+ GList *rows;
NautilusSearchBar *bar;
};
@@ -59,6 +99,39 @@ static void nautilus_query_editor_init (NautilusQueryEditor *e
static void entry_activate_cb (GtkWidget *entry, NautilusQueryEditor *editor);
static void entry_changed_cb (GtkWidget *entry, NautilusQueryEditor *editor);
+static void nautilus_query_editor_changed (NautilusQueryEditor *editor);
+static NautilusQueryEditorRow * nautilus_query_editor_add_row (NautilusQueryEditor *editor,
+ NautilusQueryEditorRowType type);
+
+static GtkWidget *location_row_create_widgets (NautilusQueryEditorRow *row);
+static void location_row_add_to_query (NautilusQueryEditorRow *row,
+ NautilusQuery *query);
+static void location_row_free_data (NautilusQueryEditorRow *row);
+static void location_add_rows_from_query (NautilusQueryEditor *editor,
+ NautilusQuery *query);
+static GtkWidget *type_row_create_widgets (NautilusQueryEditorRow *row);
+static void type_row_add_to_query (NautilusQueryEditorRow *row,
+ NautilusQuery *query);
+static void type_row_free_data (NautilusQueryEditorRow *row);
+static void type_add_rows_from_query (NautilusQueryEditor *editor,
+ NautilusQuery *query);
+
+
+
+static NautilusQueryEditorRowOps row_type[] = {
+ { N_("Location"),
+ location_row_create_widgets,
+ location_row_add_to_query,
+ location_row_free_data,
+ location_add_rows_from_query
+ },
+ { N_("File Type"),
+ type_row_create_widgets,
+ type_row_add_to_query,
+ type_row_free_data,
+ type_add_rows_from_query
+ },
+};
EEL_CLASS_BOILERPLATE (NautilusQueryEditor,
nautilus_query_editor,
@@ -131,46 +204,25 @@ nautilus_query_editor_class_init (NautilusQueryEditorClass *class)
gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0, "cancel", 0);
}
-static gboolean
-query_is_valid (NautilusQueryEditor *editor)
-{
- const char *text;
-
- text = gtk_entry_get_text (GTK_ENTRY (editor->details->entry));
-
- return text != NULL && text[0] != '\0';
-}
-
static void
entry_activate_cb (GtkWidget *entry, NautilusQueryEditor *editor)
{
- NautilusQuery *query;
-
if (editor->details->typing_timeout_id) {
g_source_remove (editor->details->typing_timeout_id);
editor->details->typing_timeout_id = 0;
}
- if (query_is_valid (editor)) {
- query = nautilus_query_editor_get_query (editor);
- g_signal_emit (editor, signals[ACTIVATE], 0, query);
- g_object_unref (query);
- }
+ nautilus_query_editor_changed (editor);
}
static gboolean
typing_timeout_cb (gpointer user_data)
{
NautilusQueryEditor *editor;
- NautilusQuery *query;
editor = NAUTILUS_QUERY_EDITOR (user_data);
- if (query_is_valid (editor)) {
- query = nautilus_query_editor_get_query (editor);
- g_signal_emit (editor, signals[ACTIVATE], 0, query);
- g_object_unref (query);
- }
+ nautilus_query_editor_changed (editor);
editor->details->typing_timeout_id = 0;
@@ -202,6 +254,598 @@ edit_clicked (GtkButton *button, NautilusQueryEditor *editor)
nautilus_query_editor_set_visible (editor, TRUE);
}
+/* Location */
+
+static GtkWidget *
+location_row_create_widgets (NautilusQueryEditorRow *row)
+{
+ GtkWidget *chooser;
+
+ chooser = gtk_file_chooser_button_new (_("Select folder search in"),
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+ gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), TRUE);
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser),
+ g_get_home_dir ());
+ gtk_widget_show (chooser);
+
+ g_signal_connect_swapped (chooser, "current-folder-changed",
+ G_CALLBACK (nautilus_query_editor_changed),
+ row->editor);
+
+ gtk_box_pack_start (GTK_BOX (row->hbox), chooser, FALSE, FALSE, 0);
+
+ return chooser;
+}
+
+static void
+location_row_add_to_query (NautilusQueryEditorRow *row,
+ NautilusQuery *query)
+{
+ char *folder, *uri;
+
+ folder = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (row->type_widget));
+ uri = gnome_vfs_get_uri_from_local_path (folder);
+ g_free (folder);
+
+ nautilus_query_set_location (query, uri);
+ g_free (uri);
+}
+
+static void
+location_row_free_data (NautilusQueryEditorRow *row)
+{
+}
+
+static void
+location_add_rows_from_query (NautilusQueryEditor *editor,
+ NautilusQuery *query)
+{
+ NautilusQueryEditorRow *row;
+ char *uri, *folder;
+
+ uri = nautilus_query_get_location (query);
+
+ if (uri == NULL) {
+ return;
+ }
+ folder = gnome_vfs_get_local_path_from_uri (uri);
+ g_free (uri);
+ if (folder == NULL) {
+ return;
+ }
+
+ row = nautilus_query_editor_add_row (editor,
+ NAUTILUS_QUERY_EDITOR_ROW_LOCATION);
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (row->type_widget),
+ folder);
+
+ g_free (folder);
+}
+
+
+/* Type */
+
+static gboolean
+type_separator_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ char *text;
+ gboolean res;
+
+ gtk_tree_model_get (model, iter, 0, &text, -1);
+
+ res = strcmp (text, "---") == 0;
+
+ g_free (text);
+ return res;
+}
+
+struct {
+ char *name;
+ char *mimetypes[20];
+} mime_type_groups[] = {
+ { N_("Documents"),
+ { "application/rtf",
+ "application/msword",
+ "application/vnd.sun.xml.writer",
+ "application/vnd.sun.xml.writer.global",
+ "application/vnd.sun.xml.writer.template",
+ "application/vnd.oasis.opendocument.text",
+ "application/vnd.oasis.opendocument.text-template",
+ "application/x-abiword",
+ "application/x-applix-word",
+ "application/x-mswrite",
+ "application/docbook+xml",
+ "application/x-kword",
+ "application/x-kword-crypt",
+ "application/x-lyx",
+ NULL
+ }
+ },
+ { N_("Music"),
+ { "application/ogg",
+ "audio/ac3",
+ "audio/basic",
+ "audio/midi",
+ "audio/x-flac",
+ "audio/mp4",
+ "audio/mpeg",
+ "audio/x-mpeg",
+ "audio/x-ms-asx",
+ "audio/x-pn-realaudio",
+ NULL
+ }
+ },
+ { N_("Video"),
+ { "video/mp4",
+ "video/3gpp",
+ "video/mpeg",
+ "video/quicktime",
+ "video/vivo",
+ "video/x-avi",
+ "video/x-mng",
+ "video/x-ms-asf",
+ "video/x-ms-wmv",
+ "video/x-msvideo",
+ "video/x-nsv",
+ "video/x-real-video",
+ NULL
+ }
+ },
+ { N_("Picture"),
+ { "application/vnd.oasis.opendocument.image",
+ "application/x-krita",
+ "image/bmp",
+ "image/cgm",
+ "image/gif",
+ "image/jpeg",
+ "image/jpeg2000",
+ "image/png",
+ "image/svg+xml",
+ "image/tiff",
+ "image/x-compressed-xcf",
+ "image/x-pcx",
+ "image/x-photo-cd",
+ "image/x-psd",
+ "image/x-tga",
+ "image/x-xcf",
+ NULL
+ }
+ },
+ { N_("Illustration"),
+ { "application/illustrator",
+ "application/vnd.corel-draw",
+ "application/vnd.stardivision.draw",
+ "application/vnd.oasis.opendocument.graphics",
+ "application/x-dia-diagram",
+ "application/x-karbon",
+ "application/x-killustrator",
+ "application/x-kivio",
+ "application/x-kontour",
+ "application/x-wpg",
+ NULL
+ }
+ },
+ { N_("Spreadsheet"),
+ { "application/vnd.lotus-1-2-3",
+ "application/vnd.ms-excel",
+ "application/vnd.stardivision.calc",
+ "application/vnd.sun.xml.calc",
+ "application/vnd.oasis.opendocument.spreadsheet",
+ "application/x-applix-spreadsheet",
+ "application/x-gnumeric",
+ "application/x-kspread",
+ "application/x-kspread-crypt",
+ "application/x-quattropro",
+ "application/x-sc",
+ "application/x-siag",
+ NULL
+ }
+ },
+ { N_("Presentation"),
+ { "application/vnd.ms-powerpoint",
+ "application/vnd.sun.xml.impress",
+ "application/vnd.oasis.opendocument.presentation",
+ "application/x-magicpoint",
+ "application/x-kpresenter",
+ NULL
+ }
+ },
+ { N_("Pdf / Postscript"),
+ { "application/pdf",
+ "application/postscript",
+ "application/x-dvi",
+ "image/x-eps",
+ NULL
+ }
+ },
+ { N_("Text File"),
+ { "text/plain",
+ NULL
+ }
+ }
+};
+
+static void
+type_combo_changed (GtkComboBox *combo_box, NautilusQueryEditorRow *row)
+{
+ GtkTreeIter iter;
+ gboolean other;
+ GtkTreeModel *model;
+
+ if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (row->type_widget),
+ &iter)) {
+ return;
+ }
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (row->type_widget));
+ gtk_tree_model_get (model, &iter, 3, &other, -1);
+
+ if (other) {
+ /* TODO: Ask for other mimetype and add it to list + select it */
+ /* But can't read list of mimetypes atm */
+ }
+
+ nautilus_query_editor_changed (row->editor);
+}
+
+static void
+type_add_custom_type (NautilusQueryEditorRow *row,
+ const char *mime_type,
+ const char *description,
+ GtkTreeIter *iter)
+{
+ GtkTreeModel *model;
+ GtkListStore *store;
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (row->type_widget));
+ store = GTK_LIST_STORE (model);
+
+ gtk_list_store_append (store, iter);
+ gtk_list_store_set (store, iter,
+ 0, description,
+ 2, mime_type,
+ -1);
+}
+
+
+static GtkWidget *
+type_row_create_widgets (NautilusQueryEditorRow *row)
+{
+ GtkWidget *combo;
+ GtkCellRenderer *cell;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ int i;
+
+ store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_BOOLEAN);
+ combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
+ g_object_unref (store);
+
+ cell = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
+ "text", 0,
+ NULL);
+ gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo),
+ type_separator_func,
+ NULL, NULL);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _("Any"), -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, "---", -1);
+
+ for (i = 0; i < G_N_ELEMENTS (mime_type_groups); i++) {
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, gettext (mime_type_groups[i].name),
+ 1, mime_type_groups[i].mimetypes,
+ -1);
+ }
+
+#if 0 /* Disable this for now, as there is no way to read list of mimetypes */
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, "---", -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _("Other Type..."), 3, TRUE, -1);
+#endif
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+
+ g_signal_connect (combo, "changed",
+ G_CALLBACK (type_combo_changed),
+ row);
+
+ gtk_widget_show (combo);
+
+ gtk_box_pack_start (GTK_BOX (row->hbox), combo, FALSE, FALSE, 0);
+
+ return combo;
+}
+
+static void
+type_row_add_to_query (NautilusQueryEditorRow *row,
+ NautilusQuery *query)
+{
+ GtkTreeIter iter;
+ char **mimetypes;
+ char *mimetype;
+ GtkTreeModel *model;
+
+ if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (row->type_widget),
+ &iter)) {
+ return;
+ }
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (row->type_widget));
+ gtk_tree_model_get (model, &iter, 1, &mimetypes, 2, &mimetype, -1);
+
+ if (mimetypes != NULL) {
+ while (*mimetypes != NULL) {
+ nautilus_query_add_mime_type (query, *mimetypes);
+ mimetypes++;
+ }
+ }
+ if (mimetype) {
+ nautilus_query_add_mime_type (query, mimetype);
+ g_free (mimetype);
+ }
+}
+
+static void
+type_row_free_data (NautilusQueryEditorRow *row)
+{
+}
+
+static gboolean
+all_group_types_in_list (char **group_types, GList *mime_types)
+{
+ GList *l;
+ char **group_type;
+ char *mime_type;
+ gboolean found;
+
+ group_type = group_types;
+ while (*group_type != NULL) {
+ found = FALSE;
+
+ for (l = mime_types; l != NULL; l = l->next) {
+ mime_type = l->data;
+
+ if (strcmp (mime_type, *group_type) == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found) {
+ return FALSE;
+ }
+ group_type++;
+ }
+ return TRUE;
+}
+
+static GList *
+remove_group_types_from_list (char **group_types, GList *mime_types)
+{
+ GList *l, *next;
+ char **group_type;
+ char *mime_type;
+ gboolean found;
+
+ group_type = group_types;
+ while (*group_type != NULL) {
+ found = FALSE;
+
+ for (l = mime_types; l != NULL; l = next) {
+ mime_type = l->data;
+ next = l->next;
+
+ if (strcmp (mime_type, *group_type) == 0) {
+ mime_types = g_list_remove_link (mime_types, l);
+ g_free (mime_type);
+ break;
+ }
+ }
+
+ group_type++;
+ }
+ return mime_types;
+}
+
+
+static void
+type_add_rows_from_query (NautilusQueryEditor *editor,
+ NautilusQuery *query)
+{
+ GList *mime_types;
+ char *mime_type;
+ const char *desc;
+ NautilusQueryEditorRow *row;
+ GtkTreeIter iter;
+ int i;
+ GtkTreeModel *model;
+ GList *l;
+
+ mime_types = nautilus_query_get_mime_types (query);
+
+ if (mime_types == NULL) {
+ return;
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (mime_type_groups); i++) {
+ if (all_group_types_in_list (mime_type_groups[i].mimetypes,
+ mime_types)) {
+ mime_types = remove_group_types_from_list (mime_type_groups[i].mimetypes,
+ mime_types);
+
+ row = nautilus_query_editor_add_row (editor,
+ NAUTILUS_QUERY_EDITOR_ROW_TYPE);
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (row->type_widget));
+
+ gtk_tree_model_iter_nth_child (model, &iter, NULL, i + 2);
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (row->type_widget),
+ &iter);
+ }
+ }
+
+ for (l = mime_types; l != NULL; l = l->next) {
+ mime_type = l->data;
+
+ desc = gnome_vfs_mime_get_value (mime_type, "description");
+ if (desc == NULL) {
+ desc = mime_type;
+ }
+
+ row = nautilus_query_editor_add_row (editor,
+ NAUTILUS_QUERY_EDITOR_ROW_TYPE);
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (row->type_widget));
+
+ type_add_custom_type (row, mime_type, desc, &iter);
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (row->type_widget),
+ &iter);
+ }
+
+ eel_g_list_free_deep (mime_types);
+
+}
+
+/* End of row types */
+
+static NautilusQueryEditorRowType
+get_next_free_type (NautilusQueryEditor *editor)
+{
+ NautilusQueryEditorRow *row;
+ NautilusQueryEditorRowType type;
+ gboolean found;
+ GList *l;
+
+
+ for (type = 0; type < NAUTILUS_QUERY_EDITOR_ROW_LAST; type++) {
+ found = FALSE;
+ for (l = editor->details->rows; l != NULL; l = l->next) {
+ row = l->data;
+ if (row->type == type) {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found) {
+ return type;
+ }
+ }
+ return NAUTILUS_QUERY_EDITOR_ROW_TYPE;
+}
+
+static void
+remove_row_cb (GtkButton *clicked_button, NautilusQueryEditorRow *row)
+{
+ NautilusQueryEditor *editor;
+
+ editor = row->editor;
+ gtk_container_remove (GTK_CONTAINER (editor->details->visible_vbox),
+ row->hbox);
+
+ editor->details->rows = g_list_remove (editor->details->rows, row);
+
+ row_type[row->type].free_data (row);
+ g_free (row);
+
+ nautilus_query_editor_changed (editor);
+}
+
+static void
+create_type_widgets (NautilusQueryEditorRow *row)
+{
+ row->type_widget = row_type[row->type].create_widgets (row);
+}
+
+static void
+row_type_combo_changed_cb (GtkComboBox *combo_box, NautilusQueryEditorRow *row)
+{
+ NautilusQueryEditorRowType type;
+
+ type = gtk_combo_box_get_active (combo_box);
+
+ if (type == row->type) {
+ return;
+ }
+
+ if (row->type_widget != NULL) {
+ gtk_widget_destroy (row->type_widget);
+ row->type_widget = NULL;
+ }
+
+ row_type[row->type].free_data (row);
+ row->data = NULL;
+
+ row->type = type;
+
+ create_type_widgets (row);
+
+ nautilus_query_editor_changed (row->editor);
+}
+
+static NautilusQueryEditorRow *
+nautilus_query_editor_add_row (NautilusQueryEditor *editor,
+ NautilusQueryEditorRowType type)
+{
+ GtkWidget *hbox, *button, *image, *combo;
+ NautilusQueryEditorRow *row;
+ int i;
+
+ row = g_new0 (NautilusQueryEditorRow, 1);
+ row->editor = editor;
+ row->type = type;
+
+ hbox = gtk_hbox_new (FALSE, 6);
+ row->hbox = hbox;
+ gtk_widget_show (hbox);
+ gtk_box_pack_start (GTK_BOX (editor->details->visible_vbox), hbox, FALSE, FALSE, 0);
+
+ combo = gtk_combo_box_new_text ();
+ row->combo = combo;
+ for (i = 0; i < NAUTILUS_QUERY_EDITOR_ROW_LAST; i++) {
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), gettext (row_type[i].name));
+ }
+ gtk_widget_show (combo);
+ gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), row->type);
+
+ editor->details->rows = g_list_append (editor->details->rows, row);
+
+ g_signal_connect (combo, "changed",
+ G_CALLBACK (row_type_combo_changed_cb), row);
+
+ create_type_widgets (row);
+
+ button = gtk_button_new ();
+ image = gtk_image_new_from_stock (GTK_STOCK_CLOSE,
+ GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_container_add (GTK_CONTAINER (button), image);
+ gtk_widget_show (image);
+ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+ gtk_widget_show (button);
+
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (remove_row_cb), row);
+
+ gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+
+ return row;
+}
+
+static void
+add_new_row_cb (GtkButton *clicked_button, NautilusQueryEditor *editor)
+{
+ nautilus_query_editor_add_row (editor, get_next_free_type (editor));
+ nautilus_query_editor_changed (editor);
+}
static void
nautilus_query_editor_init (NautilusQueryEditor *editor)
@@ -237,7 +881,25 @@ nautilus_query_editor_init (NautilusQueryEditor *editor)
g_signal_connect (button, "clicked",
G_CALLBACK (edit_clicked), editor);
+}
+
+static void
+finish_first_line (NautilusQueryEditor *editor, GtkWidget *hbox)
+{
+ GtkWidget *button, *image;
+
+ button = gtk_button_new ();
+ image = gtk_image_new_from_stock (GTK_STOCK_ADD,
+ GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_container_add (GTK_CONTAINER (button), image);
+ gtk_widget_show (image);
+ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+ gtk_widget_show (button);
+
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (add_new_row_cb), editor);
+ gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
}
static void
@@ -263,6 +925,8 @@ setup_internal_entry (NautilusQueryEditor *editor)
g_signal_connect (editor->details->entry, "changed",
G_CALLBACK (entry_changed_cb), editor);
gtk_widget_show (editor->details->entry);
+
+ finish_first_line (editor, hbox);
}
static void
@@ -284,6 +948,9 @@ setup_external_entry (NautilusQueryEditor *editor, GtkWidget *entry)
G_CALLBACK (entry_activate_cb), editor);
g_signal_connect (editor->details->entry, "changed",
G_CALLBACK (entry_changed_cb), editor);
+
+ finish_first_line (editor, hbox);
+
}
void
@@ -300,6 +967,34 @@ nautilus_query_editor_set_visible (NautilusQueryEditor *editor,
}
}
+static gboolean
+query_is_valid (NautilusQueryEditor *editor)
+{
+ const char *text;
+
+ text = gtk_entry_get_text (GTK_ENTRY (editor->details->entry));
+
+ return text != NULL && text[0] != '\0';
+}
+
+
+static void
+nautilus_query_editor_changed (NautilusQueryEditor *editor)
+{
+ NautilusQuery *query;
+
+ if (editor->details->change_frozen) {
+ return;
+ }
+
+ if (query_is_valid (editor)) {
+ query = nautilus_query_editor_get_query (editor);
+ g_signal_emit (editor, signals[ACTIVATE], 0, query);
+ g_object_unref (query);
+ }
+}
+
+
void
nautilus_query_editor_grab_focus (NautilusQueryEditor *editor)
{
@@ -311,6 +1006,8 @@ nautilus_query_editor_get_query (NautilusQueryEditor *editor)
{
const char *query_text;
NautilusQuery *query;
+ GList *l;
+ NautilusQueryEditorRow *row;
query_text = gtk_entry_get_text (GTK_ENTRY (editor->details->entry));
@@ -322,6 +1019,12 @@ nautilus_query_editor_get_query (NautilusQueryEditor *editor)
query = nautilus_query_new ();
nautilus_query_set_text (query, query_text);
+ for (l = editor->details->rows; l != NULL; l = l->next) {
+ row = l->data;
+
+ row_type[row->type].add_to_query (row, query);
+ }
+
return query;
}
@@ -371,6 +1074,7 @@ nautilus_query_editor_new_with_bar (gboolean start_hidden,
void
nautilus_query_editor_set_query (NautilusQueryEditor *editor, NautilusQuery *query)
{
+ NautilusQueryEditorRowType type;
const char *text;
if (!query) {
@@ -385,5 +1089,10 @@ nautilus_query_editor_set_query (NautilusQueryEditor *editor, NautilusQuery *que
editor->details->change_frozen = TRUE;
gtk_entry_set_text (GTK_ENTRY (editor->details->entry), text);
+
+ for (type = 0; type < NAUTILUS_QUERY_EDITOR_ROW_LAST; type++) {
+ row_type[type].add_rows_from_query (editor, query);
+ }
+
editor->details->change_frozen = FALSE;
}