Mercurial > hg > forks > geeqie
changeset 2696:f090fbf9362f
Sort/search on file class
Implement sort and search on file class (raw image, video etc.)
Note that the sort order is set by an enumerated type in typedefs.h, but
cannot be easily changed because the class is saved in the filter
section of geeqierc.xml as an integer.
author | Colin Clark <colin.clark@cclark.uk> |
---|---|
date | Wed, 03 Jan 2018 17:49:15 +0000 |
parents | 226c02528774 |
children | 10ca4efb9d48 940f217da9ec |
files | doc/docbook/GuideImageSearchSearch.xml doc/docbook/GuideMainWindowStatusBar.xml src/collect.c src/filedata.c src/menu.c src/search.c src/typedefs.h web/help/GuideImageSearchSearch.html web/help/GuideMainWindowStatusBar.html |
diffstat | 9 files changed, 167 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/docbook/GuideImageSearchSearch.xml Wed Jan 03 16:10:35 2018 +0000 +++ b/doc/docbook/GuideImageSearchSearch.xml Wed Jan 03 17:49:15 2018 +0000 @@ -161,6 +161,21 @@ </note> </listitem> </varlistentry> + <varlistentry> + <term> + <guilabel>Class</guilabel> + </term> + <listitem> + The search will match if the file's class is, or is not, one of the following types. + <itemizedlist> + <listitem>Unknown</listitem> + <listitem>Image</listitem> + <listitem>Raw Image</listitem> + <listitem>Video</listitem> + <listitem>Metadata</listitem> + </itemizedlist> + </listitem> + </varlistentry> </variablelist> <para /> <para />
--- a/doc/docbook/GuideMainWindowStatusBar.xml Wed Jan 03 16:10:35 2018 +0000 +++ b/doc/docbook/GuideMainWindowStatusBar.xml Wed Jan 03 17:49:15 2018 +0000 @@ -58,7 +58,30 @@ <guilabel>Size</guilabel> </term> <listitem> - <para>Image are sorted by file size on disk.</para> + <para>Images are sorted by file size on disk.</para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <guilabel>Rating</guilabel> + </term> + <listitem> + <para>Image are sorted by Xmp.xmp.Rating.</para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <guilabel>Class</guilabel> + </term> + <listitem> + <para>Image are sorted by class. The class types, and sort order, is:</para> + <itemizedlist> + <listitem>Unknown</listitem> + <listitem>Image</listitem> + <listitem>Raw Image</listitem> + <listitem>Video</listitem> + <listitem>Metadata</listitem> + </itemizedlist> </listitem> </varlistentry> <varlistentry> @@ -70,7 +93,7 @@ </listitem> </varlistentry> </variablelist> - <para /> + <note>When images have equal rank, for example in rating or class sorts, within each section images will be sorted by filename.</note> </section> <section id="Filelist"> <title>File list</title>
--- a/src/collect.c Wed Jan 03 16:10:35 2018 +0000 +++ b/src/collect.c Wed Jan 03 17:49:15 2018 +0000 @@ -172,6 +172,10 @@ case SORT_PATH: return utf8_compare(cia->fd->path, cib->fd->path, options->file_sort.case_sensitive); break; + case SORT_CLASS: + if (cia->fd->format_class < cib->fd->format_class) return -1; + if (cia->fd->format_class > cib->fd->format_class) return 1; + break; #ifdef HAVE_STRVERSCMP case SORT_NUMBER: return strverscmp(cia->fd->name, cib->fd->name);
--- a/src/filedata.c Wed Jan 03 16:10:35 2018 +0000 +++ b/src/filedata.c Wed Jan 03 17:49:15 2018 +0000 @@ -1051,6 +1051,11 @@ if (fa->rating > fb->rating) return 1; /* fall back to name */ break; + case SORT_CLASS: + if (fa->format_class < fb->format_class) return -1; + if (fa->format_class > fb->format_class) return 1; + /* fall back to name */ + break; #ifdef HAVE_STRVERSCMP case SORT_NUMBER: ret = strverscmp(fa->name, fb->name);
--- a/src/menu.c Wed Jan 03 16:10:35 2018 +0000 +++ b/src/menu.c Wed Jan 03 17:49:15 2018 +0000 @@ -163,6 +163,9 @@ case SORT_RATING: return _("Sort by rating"); break; + case SORT_CLASS: + return _("Sort by class"); + break; case SORT_NAME: default: return _("Sort by name"); @@ -211,6 +214,7 @@ submenu_add_sort_item(submenu, func, SORT_EXIFTIME, show_current, type); submenu_add_sort_item(submenu, func, SORT_SIZE, show_current, type); submenu_add_sort_item(submenu, func, SORT_RATING, show_current, type); + submenu_add_sort_item(submenu, func, SORT_CLASS, show_current, type); if (include_path) submenu_add_sort_item(submenu, func, SORT_PATH, show_current, type); if (include_none) submenu_add_sort_item(submenu, func, SORT_NONE, show_current, type);
--- a/src/search.c Wed Jan 03 16:10:35 2018 +0000 +++ b/src/search.c Wed Jan 03 17:49:15 2018 +0000 @@ -144,6 +144,10 @@ GtkWidget *spin_rating; GtkWidget *spin_rating_end; + GtkWidget *check_class; + GtkWidget *menu_class; + GtkWidget *class_type; + FileData *search_dir_fd; gboolean search_path_recurse; gchar *search_name; @@ -180,6 +184,7 @@ MatchType match_comment; MatchType match_rating; MatchType match_gps; + MatchType match_class; gboolean match_name_enable; gboolean match_size_enable; @@ -189,6 +194,7 @@ gboolean match_keywords_enable; gboolean match_comment_enable; gboolean match_rating_enable; + gboolean match_class_enable; GList *search_folder_list; GList *search_done_list; @@ -290,6 +296,11 @@ { N_("greater than"), SEARCH_MATCH_OVER } }; +static const MatchList text_search_menu_class[] = { + { N_("is"), SEARCH_MATCH_EQUAL }, + { N_("is not"), SEARCH_MATCH_NONE } +}; + static GList *search_window_list = NULL; @@ -2032,6 +2043,49 @@ } } + if (match && sd->match_class_enable) + { + tested = TRUE; + match = FALSE; + gint class; + FileFormatClass search_class; + + if (g_strcmp0(gtk_combo_box_text_get_active_text( + GTK_COMBO_BOX_TEXT(sd->class_type)), _("Image")) == 0) + { + search_class = FORMAT_CLASS_IMAGE; + } + else if (g_strcmp0(gtk_combo_box_text_get_active_text( + GTK_COMBO_BOX_TEXT(sd->class_type)), _("Raw Image")) == 0) + { + search_class = FORMAT_CLASS_RAWIMAGE; + } + else if (g_strcmp0(gtk_combo_box_text_get_active_text( + GTK_COMBO_BOX_TEXT(sd->class_type)), _("Video")) == 0) + { + search_class = FORMAT_CLASS_VIDEO; + } + else if (g_strcmp0(gtk_combo_box_text_get_active_text( + GTK_COMBO_BOX_TEXT(sd->class_type)), _("Metadata")) == 0) + { + search_class = FORMAT_CLASS_META; + } + else + { + search_class = FORMAT_CLASS_UNKNOWN; + } + + class = fd->format_class; + if (sd->match_class == SEARCH_MATCH_EQUAL) + { + match = (class == search_class); + } + else if (sd->match_class == SEARCH_MATCH_NONE) + { + match = (class != search_class); + } + } + if (match && sd->match_gps_enable) { /* Calculate the distance the image is from the specified origin. @@ -2618,6 +2672,13 @@ (sd->match_rating == SEARCH_MATCH_BETWEEN)); } +static void menu_choice_class_cb(GtkWidget *combo, gpointer data) +{ + SearchData *sd = data; + + if (!menu_choice_get_match_type(combo, &sd->match_class)) return; +} + static void menu_choice_date_cb(GtkWidget *combo, gpointer data) { SearchData *sd = data; @@ -2847,6 +2908,7 @@ sd->match_keywords = SEARCH_MATCH_ALL; sd->match_comment = SEARCH_MATCH_CONTAINS; sd->match_rating = SEARCH_MATCH_EQUAL; + sd->match_class = SEARCH_MATCH_EQUAL; sd->match_name_enable = TRUE; @@ -3062,6 +3124,22 @@ gtk_widget_show(sd->entry_gps_coord); + /* Search for image class */ + hbox = menu_choice(sd->box_search, &sd->check_class, &sd->menu_class, + _("Image class"), &sd->match_class_enable, + text_search_menu_class, sizeof(text_search_menu_class) / sizeof(MatchList), + G_CALLBACK(menu_choice_class_cb), sd); + + sd->class_type = gtk_combo_box_text_new(); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(sd->class_type), _("Image")); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(sd->class_type), _("Raw Image")); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(sd->class_type), _("Video")); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(sd->class_type), _("Metadata")); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(sd->class_type), _("Unknown")); + gtk_box_pack_start(GTK_BOX(hbox), sd->class_type, FALSE, FALSE, 0); + gtk_combo_box_set_active(GTK_COMBO_BOX(sd->class_type), 0); + gtk_widget_show(sd->class_type); + /* Done the types of searches */ scrolled = gtk_scrolled_window_new(NULL, NULL);
--- a/src/typedefs.h Wed Jan 03 16:10:35 2018 +0000 +++ b/src/typedefs.h Wed Jan 03 17:49:15 2018 +0000 @@ -74,7 +74,8 @@ SORT_PATH, SORT_NUMBER, SORT_EXIFTIME, - SORT_RATING + SORT_RATING, + SORT_CLASS } SortType; typedef enum {
--- a/web/help/GuideImageSearchSearch.html Wed Jan 03 16:10:35 2018 +0000 +++ b/web/help/GuideImageSearchSearch.html Wed Jan 03 17:49:15 2018 +0000 @@ -606,6 +606,19 @@ for details on how to create this file. </div></div> </dd> +<dt class="term"> + <span class="guilabel">Class</span> + </dt> +<dd> + The search will match if the file's class is, or is not, one of the following types. + <div class="block list itemizedlist"><ul class="itemizedlist"> +<li class="li-first">Unknown</li> +<li>Image</li> +<li>Raw Image</li> +<li>Video</li> +<li>Metadata</li> +</ul></div> + </dd> </dl></div> <p class="para block"></p> <p class="para block"></p>
--- a/web/help/GuideMainWindowStatusBar.html Wed Jan 03 16:10:35 2018 +0000 +++ b/web/help/GuideMainWindowStatusBar.html Wed Jan 03 17:49:15 2018 +0000 @@ -516,7 +516,26 @@ <span class="guilabel">Size</span> </dt> <dd> - <p class="para block block-first">Image are sorted by file size on disk.</p> + <p class="para block block-first">Images are sorted by file size on disk.</p> + </dd> +<dt class="term"> + <span class="guilabel">Rating</span> + </dt> +<dd> + <p class="para block block-first">Image are sorted by Xmp.xmp.Rating.</p> + </dd> +<dt class="term"> + <span class="guilabel">Class</span> + </dt> +<dd> + <p class="para block block-first">Image are sorted by class. The class types, and sort order, is:</p> + <div class="block list itemizedlist"><ul class="itemizedlist"> +<li class="li-first">Unknown</li> +<li>Image</li> +<li>Raw Image</li> +<li>Video</li> +<li>Metadata</li> +</ul></div> </dd> <dt class="term"> <span class="guilabel">Ascending</span> @@ -525,7 +544,7 @@ <p class="para block block-first">Toggles between increasing and decreasing sort order. A check will appear next to this entry to indicate ascending sort order.</p> </dd> </dl></div> -<p class="para block"></p> +<div class="admonition block note block-indent"><div class="note-inner">When images have equal rank, for example in rating or class sorts, within each section images will be sorted by filename.</div></div> </div> <div class="division section"> <a name="Filelist"></a><div class="header"><h2 class="section title"><span class="title"><span class="label">2.6.3. </span>File list</span></h2></div>