diff options
author | Alexander Larsson <alexl@redhat.com> | 2005-12-07 15:03:12 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@src.gnome.org> | 2005-12-07 15:03:12 +0000 |
commit | 5d38be40b9465993590918106ae41d32cfdc58c3 (patch) | |
tree | e7f47becf02cf1f07ca9c207dcfffad59a0297ef | |
parent | bb0f3df3aef06040ab7154d8d67161a0cf1a6a0f (diff) | |
download | nautilus-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-- | ChangeLog | 14 | ||||
-rw-r--r-- | configure.in | 3 | ||||
-rw-r--r-- | libnautilus-private/nautilus-query.c | 107 | ||||
-rw-r--r-- | libnautilus-private/nautilus-search-engine-beagle.c | 41 | ||||
-rw-r--r-- | src/nautilus-query-editor.c | 755 |
5 files changed, 858 insertions, 62 deletions
@@ -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; } |