From caabfd977c23c65296e736ad38d1eb5c7e340609 Mon Sep 17 00:00:00 2001 From: Colin Clark Date: Wed, 3 Jan 2018 17:49:15 +0000 Subject: [PATCH] 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. --- doc/docbook/GuideImageSearchSearch.xml | 15 +++++ doc/docbook/GuideMainWindowStatusBar.xml | 27 +++++++- src/collect.c | 4 ++ src/filedata.c | 5 ++ src/menu.c | 4 ++ src/search.c | 78 ++++++++++++++++++++++++ src/typedefs.h | 3 +- web/help/GuideImageSearchSearch.html | 13 ++++ web/help/GuideMainWindowStatusBar.html | 23 ++++++- 9 files changed, 167 insertions(+), 5 deletions(-) diff --git a/doc/docbook/GuideImageSearchSearch.xml b/doc/docbook/GuideImageSearchSearch.xml index f1719ea8..55a70822 100644 --- a/doc/docbook/GuideImageSearchSearch.xml +++ b/doc/docbook/GuideImageSearchSearch.xml @@ -161,6 +161,21 @@ + + + Class + + + The search will match if the file's class is, or is not, one of the following types. + + Unknown + Image + Raw Image + Video + Metadata + + + diff --git a/doc/docbook/GuideMainWindowStatusBar.xml b/doc/docbook/GuideMainWindowStatusBar.xml index d749b37c..6c327032 100644 --- a/doc/docbook/GuideMainWindowStatusBar.xml +++ b/doc/docbook/GuideMainWindowStatusBar.xml @@ -58,7 +58,30 @@ Size - Image are sorted by file size on disk. + Images are sorted by file size on disk. + + + + + Rating + + + Image are sorted by Xmp.xmp.Rating. + + + + + Class + + + Image are sorted by class. The class types, and sort order, is: + + Unknown + Image + Raw Image + Video + Metadata + @@ -70,7 +93,7 @@ - + When images have equal rank, for example in rating or class sorts, within each section images will be sorted by filename.
File list diff --git a/src/collect.c b/src/collect.c index 33d5285c..cc2dd6e6 100644 --- a/src/collect.c +++ b/src/collect.c @@ -172,6 +172,10 @@ static gint collection_list_sort_cb(gconstpointer a, gconstpointer b) 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); diff --git a/src/filedata.c b/src/filedata.c index 38622779..301f448d 100644 --- a/src/filedata.c +++ b/src/filedata.c @@ -1051,6 +1051,11 @@ gint filelist_sort_compare_filedata(FileData *fa, FileData *fb) 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); diff --git a/src/menu.c b/src/menu.c index d5a0c7ae..8fc69956 100644 --- a/src/menu.c +++ b/src/menu.c @@ -163,6 +163,9 @@ gchar *sort_type_get_text(SortType method) 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 @@ GtkWidget *submenu_add_sort(GtkWidget *menu, GCallback func, gpointer data, 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); diff --git a/src/search.c b/src/search.c index 257b0acf..f0463022 100644 --- a/src/search.c +++ b/src/search.c @@ -144,6 +144,10 @@ struct _SearchData 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 @@ struct _SearchData MatchType match_comment; MatchType match_rating; MatchType match_gps; + MatchType match_class; gboolean match_name_enable; gboolean match_size_enable; @@ -189,6 +194,7 @@ struct _SearchData 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 @@ static const MatchList text_search_menu_gps[] = { { 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 @@ static gboolean search_file_next(SearchData *sd) } } + 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 @@ static void menu_choice_rating_cb(GtkWidget *combo, gpointer data) (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 @@ void search_new(FileData *dir_fd, FileData *example_file) 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 @@ void search_new(FileData *dir_fd, FileData *example_file) 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); diff --git a/src/typedefs.h b/src/typedefs.h index 8e55ea4d..6f250271 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -74,7 +74,8 @@ typedef enum { SORT_PATH, SORT_NUMBER, SORT_EXIFTIME, - SORT_RATING + SORT_RATING, + SORT_CLASS } SortType; typedef enum { diff --git a/web/help/GuideImageSearchSearch.html b/web/help/GuideImageSearchSearch.html index 1ede40fd..30180097 100644 --- a/web/help/GuideImageSearchSearch.html +++ b/web/help/GuideImageSearchSearch.html @@ -606,6 +606,19 @@ dd.answer div.label { float: left; } for details on how to create this file. +
+ Class +
+
+ The search will match if the file's class is, or is not, one of the following types. +
    +
  • Unknown
  • +
  • Image
  • +
  • Raw Image
  • +
  • Video
  • +
  • Metadata
  • +
+

diff --git a/web/help/GuideMainWindowStatusBar.html b/web/help/GuideMainWindowStatusBar.html index bbc8246e..5a1e458f 100644 --- a/web/help/GuideMainWindowStatusBar.html +++ b/web/help/GuideMainWindowStatusBar.html @@ -516,7 +516,26 @@ dd.answer div.label { float: left; } Size
-

Image are sorted by file size on disk.

+

Images are sorted by file size on disk.

+
+
+ Rating +
+
+

Image are sorted by Xmp.xmp.Rating.

+
+
+ Class +
+
+

Image are sorted by class. The class types, and sort order, is:

+
    +
  • Unknown
  • +
  • Image
  • +
  • Raw Image
  • +
  • Video
  • +
  • Metadata
  • +
Ascending @@ -525,7 +544,7 @@ dd.answer div.label { float: left; }

Toggles between increasing and decreasing sort order. A check will appear next to this entry to indicate ascending sort order.

-

+
When images have equal rank, for example in rating or class sorts, within each section images will be sorted by filename.

2.6.3. File list

-- 2.20.1