Skip to content

Commit

Permalink
Fix #323: Rating system
Browse files Browse the repository at this point in the history
#323

Initial implementation.
Set values either by Edit menu, or Alt+Keypad+n: n is 0 to 5
Alt+keypad+minus sets the value to -1.
  • Loading branch information
caclark committed Jun 8, 2017
1 parent ca8f5ce commit cb2fa6a
Show file tree
Hide file tree
Showing 14 changed files with 330 additions and 2 deletions.
75 changes: 75 additions & 0 deletions doc/docbook/GuideMainWindowMenus.xml
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,81 @@
</warning>
</listitem>
</varlistentry>
<varlistentry>
<term>
<menuchoice>
<shortcut>
<keycombo>
<keycap>[</keycap>
</keycombo>
</shortcut>
<guimenu>Orientation</guimenu>
<guimenuitem>Rotate counterclockwise</guimenuitem>
</menuchoice>
</term>
<listitem>
<para>Rotates the current image counterclockwise 90 degrees, does not modify the file on disk.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<menuchoice>
<shortcut>
<keycombo>
<keycap>Shift</keycap>
<keycap>R</keycap>
</keycombo>
</shortcut>
<guimenu>Orientation</guimenu>
<guimenuitem>Rotate 180</guimenuitem>
</menuchoice>
</term>
<listitem>
<para>Rotates the current image 180 degrees, does not modify the file on disk.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<menuchoice>
<guimenu>Rating</guimenu>
</menuchoice>
</term>
<listitem>
<para>Set a Rating value for each image.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<menuchoice>
<shortcut>
<keycombo>
<keycap>Alt+Keypad+n</keycap>
</keycombo>
</shortcut>
<guimenu>Rating</guimenu>
<guimenuitem>n</guimenuitem>
</menuchoice>
</term>
<listitem>
<para>"n" is in the range 0 to 5. Sets the Rating value for the image.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<menuchoice>
<shortcut>
<keycombo>
<keycap>Alt+Keypad+Minus</keycap>
</keycombo>
</shortcut>
<guimenu>Rating</guimenu>
<guimenuitem>-1</guimenuitem>
</menuchoice>
</term>
<listitem>
<para>Sets the Rating value to -1 for the image.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<menuchoice>
Expand Down
8 changes: 8 additions & 0 deletions doc/docbook/GuideReferenceTags.xml
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,14 @@
<para>Title</para>
</entry>
</row>
<row>
<entry>
<para>Xmp.xmp.Rating</para>
</entry>
<entry>
<para>Rating</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
Expand Down
11 changes: 10 additions & 1 deletion src/bar.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ static const gchar default_config_comment[] =
" </bar>"
" </layout>"
"</gq>";
static const gchar default_config_rating[] =
"<gq>"
" <layout id = '_current_'>"
" <bar>"
" <pane_comment id = 'rating' expanded = 'true' key = '" RATING_KEY "' height = '10' />"
" </bar>"
" </layout>"
"</gq>";

static const gchar default_config_exif[] =
"<gq>"
Expand Down Expand Up @@ -176,6 +184,7 @@ static const KnownPanes known_panes[] = {
{PANE_COMMENT, "title", N_("Title"), default_config_title},
{PANE_KEYWORDS, "keywords", N_("Keywords"), default_config_keywords},
{PANE_COMMENT, "comment", N_("Comment"), default_config_comment},
{PANE_COMMENT, "rating", N_("Rating"), default_config_rating},
{PANE_EXIF, "exif", N_("Exif"), default_config_exif},
/* other pre-configured panes */
{PANE_EXIF, "file_info", N_("File info"), default_config_file_info},
Expand Down Expand Up @@ -567,7 +576,7 @@ void bar_add(GtkWidget *bar, GtkWidget *pane)

void bar_populate_default(GtkWidget *bar)
{
const gchar *populate_id[] = {"histogram", "title", "keywords", "comment", "exif", NULL};
const gchar *populate_id[] = {"histogram", "title", "keywords", "comment", "rating", "exif", NULL};
const gchar **id = populate_id;

while (*id)
Expand Down
8 changes: 8 additions & 0 deletions src/bar_comment.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ static void bar_pane_comment_write_config(GtkWidget *pane, GString *outstr, gint
{
pcd->height = options->info_comment.height;
}
if (!g_strcmp0(pcd->pane.id, "rating"))
{
pcd->height = options->info_rating.height;
}

WRITE_NL(); WRITE_STRING("<pane_comment ");
write_char_option(outstr, indent, "id", pcd->pane.id);
Expand Down Expand Up @@ -311,6 +315,10 @@ GtkWidget *bar_pane_comment_new_from_config(const gchar **attribute_names, const
{
options->info_comment.height = height;
}
if (!g_strcmp0(id, "rating"))
{
options->info_rating.height = height;
}

bar_pane_translate_title(PANE_COMMENT, id, &title);
ret = bar_pane_comment_new(id, title, key, expanded, height);
Expand Down
28 changes: 28 additions & 0 deletions src/filedata.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ static FileData *file_data_new(const gchar *path_utf8, struct stat *st, gboolean
fd->ref = 1;
fd->magick = FD_MAGICK;
fd->exifdate = 0;
fd->rating = 0;

if (disable_sidecars) fd->disable_grouping = TRUE;

Expand Down Expand Up @@ -514,6 +515,24 @@ void set_exif_time_data(GList *files)
}
}

void set_rating_data(GList *files)
{
gchar *rating_str;
DEBUG_1("%s set_rating_data: ...", get_exec_time());

while (files)
{
FileData *file = files->data;
rating_str = metadata_read_string(file, RATING_KEY, METADATA_PLAIN);
if (rating_str )
{
file->rating = atoi(rating_str);
g_free(rating_str);
}
files = files->next;
}
}

FileData *file_data_new_no_grouping(const gchar *path_utf8)
{
struct stat st;
Expand Down Expand Up @@ -1026,6 +1045,11 @@ gint filelist_sort_compare_filedata(FileData *fa, FileData *fb)
if (fa->exifdate > fb->exifdate) return 1;
/* fall back to name */
break;
case SORT_RATING:
if (fa->rating < fb->rating) return -1;
if (fa->rating > fb->rating) return 1;
/* fall back to name */
break;
#ifdef HAVE_STRVERSCMP
case SORT_NUMBER:
ret = strverscmp(fa->name, fb->name);
Expand Down Expand Up @@ -1081,6 +1105,10 @@ GList *filelist_sort(GList *list, SortType method, gboolean ascend)
{
set_exif_time_data(list);
}
if (method == SORT_RATING)
{
set_rating_data(list);
}
return filelist_sort_full(list, method, ascend, (GCompareFunc) filelist_sort_file_cb);
}

Expand Down
50 changes: 50 additions & 0 deletions src/layout_image.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,56 @@ void layout_image_alter_orientation(LayoutWindow *lw, AlterType type)
}
}

static void image_alter_rating(FileData *fd_n, const gchar *rating)
{
metadata_write_string(fd_n, RATING_KEY, rating);
}

void layout_image_rating(LayoutWindow *lw, const gchar *rating)
{
if (!layout_valid(&lw)) return;

GtkTreeModel *store;
GList *work;
GtkTreeSelection *selection;
GtkTreePath *tpath;
FileData *fd_n;
GtkTreeIter iter;
IconData *id;

if (!lw || !lw->vf) return;

if (lw->vf->type == FILEVIEW_ICON)
{
if (!VFICON(lw->vf)->selection) return;
work = VFICON(lw->vf)->selection;
}
else
{
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lw->vf->listview));
work = gtk_tree_selection_get_selected_rows(selection, &store);
}

while (work)
{
if (lw->vf->type == FILEVIEW_ICON)
{
id = work->data;
fd_n = id->fd;
work = work->next;
}
else
{
tpath = work->data;
gtk_tree_model_get_iter(store, &iter, tpath);
gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd_n, -1);
work = work->next;
}

image_alter_rating(fd_n, rating);
}
}

void layout_image_reset_orientation(LayoutWindow *lw)
{
ImageWindow *imd= lw->image;
Expand Down
2 changes: 2 additions & 0 deletions src/layout_image.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ void layout_image_alter_orientation(LayoutWindow *lw, AlterType type);
void layout_image_set_desaturate(LayoutWindow *lw, gboolean desaturate);
gboolean layout_image_get_desaturate(LayoutWindow *lw);

void layout_image_rating(LayoutWindow *lw, const gchar *rating);

/*
gint layout_image_stereo_get(LayoutWindow *lw);
void layout_image_stereo_set(LayoutWindow *lw, gint stereo_mode);
Expand Down
67 changes: 67 additions & 0 deletions src/layout_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,55 @@ static void layout_menu_alter_90_cb(GtkAction *action, gpointer data)
layout_image_alter_orientation(lw, ALTER_ROTATE_90);
}

static void layout_menu_rating_0_cb(GtkAction *action, gpointer data)
{
LayoutWindow *lw = data;

layout_image_rating(lw, "0");
}

static void layout_menu_rating_1_cb(GtkAction *action, gpointer data)
{
LayoutWindow *lw = data;

layout_image_rating(lw, "1");
}

static void layout_menu_rating_2_cb(GtkAction *action, gpointer data)
{
LayoutWindow *lw = data;

layout_image_rating(lw, "2");
}

static void layout_menu_rating_3_cb(GtkAction *action, gpointer data)
{
LayoutWindow *lw = data;

layout_image_rating(lw, "3");
}

static void layout_menu_rating_4_cb(GtkAction *action, gpointer data)
{
LayoutWindow *lw = data;

layout_image_rating(lw, "4");
}

static void layout_menu_rating_5_cb(GtkAction *action, gpointer data)
{
LayoutWindow *lw = data;

layout_image_rating(lw, "5");
}

static void layout_menu_rating_m1_cb(GtkAction *action, gpointer data)
{
LayoutWindow *lw = data;

layout_image_rating(lw, "-1");
}

static void layout_menu_alter_90cc_cb(GtkAction *action, gpointer data)
{
LayoutWindow *lw = data;
Expand Down Expand Up @@ -1524,6 +1573,7 @@ static GtkActionEntry menu_entries[] = {
{ "EditMenu", NULL, N_("_Edit"), NULL, NULL, NULL },
{ "SelectMenu", NULL, N_("_Select"), NULL, NULL, NULL },
{ "OrientationMenu", NULL, N_("_Orientation"), NULL, NULL, NULL },
{ "RatingMenu", NULL, N_("_Rating"), NULL, NULL, NULL },
{ "ExternalMenu", NULL, N_("E_xternal Editors"), NULL, NULL, NULL },
{ "PreferencesMenu", NULL, N_("P_references"), NULL, NULL, NULL },
{ "ViewMenu", NULL, N_("_View"), NULL, NULL, NULL },
Expand Down Expand Up @@ -1569,6 +1619,13 @@ static GtkActionEntry menu_entries[] = {
{ "CloseWindow", GTK_STOCK_CLOSE, N_("C_lose window"), "<control>W", N_("Close window"), CB(layout_menu_close_cb) },
{ "Quit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q", N_("Quit"), CB(layout_menu_exit_cb) },
{ "RotateCW", NULL, N_("_Rotate clockwise"), "bracketright", N_("Rotate clockwise"), CB(layout_menu_alter_90_cb) },
{ "Rating0", NULL, N_("_Rating 0"), "<alt>KP_0", N_("Rating 0"), CB(layout_menu_rating_0_cb) },
{ "Rating1", NULL, N_("_Rating 1"), "<alt>KP_1", N_("Rating 1"), CB(layout_menu_rating_1_cb) },
{ "Rating2", NULL, N_("_Rating 2"), "<alt>KP_2", N_("Rating 2"), CB(layout_menu_rating_2_cb) },
{ "Rating3", NULL, N_("_Rating 3"), "<alt>KP_3", N_("Rating 3"), CB(layout_menu_rating_3_cb) },
{ "Rating4", NULL, N_("_Rating 4"), "<alt>KP_4", N_("Rating 4"), CB(layout_menu_rating_4_cb) },
{ "Rating5", NULL, N_("_Rating 5"), "<alt>KP_5", N_("Rating 5"), CB(layout_menu_rating_5_cb) },
{ "RatingM1", NULL, N_("_Rating -1"), "<alt>KP_Subtract", N_("Rating -1"), CB(layout_menu_rating_m1_cb) },
{ "RotateCCW", NULL, N_("Rotate _counterclockwise"), "bracketleft", N_("Rotate counterclockwise"), CB(layout_menu_alter_90cc_cb) },
{ "Rotate180", NULL, N_("Rotate 1_80"), "<shift>R", N_("Rotate 180"), CB(layout_menu_alter_180_cb) },
{ "Mirror", NULL, N_("_Mirror"), "<shift>M", N_("Mirror"), CB(layout_menu_alter_mirror_cb) },
Expand Down Expand Up @@ -1777,6 +1834,16 @@ static const gchar *menu_ui_description =
" <menuitem action='ExifRotate'/>"
" <separator/>"
" </menu>"
" <menu action='RatingMenu'>"
" <menuitem action='Rating0'/>"
" <menuitem action='Rating1'/>"
" <menuitem action='Rating2'/>"
" <menuitem action='Rating3'/>"
" <menuitem action='Rating4'/>"
" <menuitem action='Rating5'/>"
" <menuitem action='RatingM1'/>"
" <separator/>"
" </menu>"
" <menuitem action='SaveMetadata'/>"
" <placeholder name='PropertiesSection'/>"
" <separator/>"
Expand Down
4 changes: 4 additions & 0 deletions src/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ gchar *sort_type_get_text(SortType method)
case SORT_NUMBER:
return _("Sort by number");
break;
case SORT_RATING:
return _("Sort by rating");
break;
case SORT_NAME:
default:
return _("Sort by name");
Expand Down Expand Up @@ -205,6 +208,7 @@ GtkWidget *submenu_add_sort(GtkWidget *menu, GCallback func, gpointer data,
submenu_add_sort_item(submenu, func, SORT_CTIME, show_current, type);
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);
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);

Expand Down
1 change: 1 addition & 0 deletions src/metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define COMMENT_KEY "Xmp.dc.description"
#define KEYWORD_KEY "Xmp.dc.subject"
#define ORIENTATION_KEY "Xmp.tiff.Orientation"
#define RATING_KEY "Xmp.xmp.Rating"

void metadata_cache_free(FileData *fd);

Expand Down
Loading

0 comments on commit cb2fa6a

Please sign in to comment.