changeset 2771:3aa4c31b93ff

Show star rating in files pane Accessed via a right-click menu
author Colin Clark <colin.clark@cclark.uk>
date Mon, 18 Jun 2018 19:17:19 +0100
parents 2e819f4a7a41
children 6645d929ffba
files doc/docbook/GuideMainWindowFilePane.xml src/exif-common.c src/metadata.c src/metadata.h src/misc.c src/misc.h src/options.c src/options.h src/view_file.h src/view_file/view_file.c src/view_file/view_file_icon.c src/view_file/view_file_icon.h src/view_file/view_file_list.c src/view_file/view_file_list.h web/help/GuideMainWindowFilePane.html
diffstat 15 files changed, 284 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/doc/docbook/GuideMainWindowFilePane.xml	Mon Jun 18 18:53:46 2018 +0100
+++ b/doc/docbook/GuideMainWindowFilePane.xml	Mon Jun 18 19:17:19 2018 +0100
@@ -166,6 +166,14 @@
           <para>Toggles display of file names in the icon view display mode.</para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>
+          <emphasis role="bold">Show star rating</emphasis>
+        </term>
+        <listitem>
+          <para>Toggles display of the "star rating" (Xmp.xmp.Rating).</para>
+        </listitem>
+      </varlistentry>
     </variablelist>
     <para />
   </section>
--- a/src/exif-common.c	Mon Jun 18 18:53:46 2018 +0100
+++ b/src/exif-common.c	Mon Jun 18 19:17:19 2018 +0100
@@ -56,6 +56,7 @@
 #include "ui_fileops.h"
 #include "cache.h"
 #include "jpeg_parser.h"
+#include "misc.h"
 #include "zonedetect.h"
 
 
@@ -855,27 +856,10 @@
 static gchar *exif_build_formatted_star_rating(ExifData *exif)
 {
 	gint n;
-	gchar *ret = NULL;
-	GString *str = g_string_new(NULL);
 
 	exif_get_integer(exif, "Xmp.xmp.Rating", &n);
 
-	if (n == -1)
-		{
-		ret = g_strdup("⨷");
-		}
-	else if (n > 0 && n < 6)
-		{
-		while (n > 0)
-			{
-			str = g_string_append(str, "🟊");
-			n = n - 1;
-			}
-		ret = g_strdup(str->str);
-		g_string_free(str, TRUE);
-		}
-
-	return ret;
+	return convert_rating_to_stars(n);
 }
 
 /* List of custom formatted pseudo-exif tags */
--- a/src/metadata.c	Mon Jun 18 18:53:46 2018 +0100
+++ b/src/metadata.c	Mon Jun 18 19:17:19 2018 +0100
@@ -749,6 +749,16 @@
 	return ret;
 }
 
+gchar *metadata_read_rating_stars(FileData *fd)
+{
+	gchar *ret;
+	gint n = metadata_read_int(fd, RATING_KEY, METADATA_PLAIN);
+
+	ret = convert_rating_to_stars(n);
+
+	return ret;
+}
+
 gdouble metadata_read_GPS_coord(FileData *fd, const gchar *key, gdouble fallback)
 {
 	gdouble coord;
--- a/src/metadata.h	Mon Jun 18 18:53:46 2018 +0100
+++ b/src/metadata.h	Mon Jun 18 19:17:19 2018 +0100
@@ -112,5 +112,6 @@
 GtkTreeIter *keyword_add_from_config(GtkTreeStore *keyword_tree, GtkTreeIter *parent, const gchar **attribute_names, const gchar **attribute_values);
 
 void keyword_tree_disconnect_marks();
+gchar *metadata_read_rating_stars(FileData *fd);
 #endif
 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
--- a/src/misc.c	Mon Jun 18 18:53:46 2018 +0100
+++ b/src/misc.c	Mon Jun 18 19:17:19 2018 +0100
@@ -294,4 +294,31 @@
 	return abday;
 }
 
+gchar *convert_rating_to_stars(gint rating)
+{
+	gchar *ret;
+	GString *str = g_string_new(NULL);
+
+	if (rating == -1)
+		{
+		ret = g_strdup("⨷");
+		}
+	else if (rating > 0 && rating < 6)
+		{
+		while (rating > 0)
+			{
+			str = g_string_append(str, "🟊");
+			rating = rating - 1;
+			}
+		ret = g_strdup(str->str);
+		g_string_free(str, TRUE);
+		}
+	else
+		{
+		ret = g_strdup("");
+		}
+
+	return ret;
+}
+
 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
--- a/src/misc.h	Mon Jun 18 18:53:46 2018 +0100
+++ b/src/misc.h	Mon Jun 18 19:17:19 2018 +0100
@@ -29,5 +29,6 @@
 gchar *decode_geo_parameters(const gchar *input_text);
 gint date_get_first_day_of_week();
 gchar *date_get_abbreviated_day_name(gint day);
+gchar *convert_rating_to_stars(gint rating);
 #endif /* MISC_H */
 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
--- a/src/options.c	Mon Jun 18 18:53:46 2018 +0100
+++ b/src/options.c	Mon Jun 18 19:17:19 2018 +0100
@@ -154,6 +154,7 @@
 	options->metadata.sidecar_extended_name = FALSE;
 
 	options->show_icon_names = TRUE;
+	options->show_star_rating = FALSE;
 
 	options->slideshow.delay = 50;
 	options->slideshow.random = FALSE;
--- a/src/options.h	Mon Jun 18 18:53:46 2018 +0100
+++ b/src/options.h	Mon Jun 18 19:17:19 2018 +0100
@@ -34,6 +34,7 @@
 	gboolean image_l_click_video;
 	gchar *image_l_click_video_editor;
 	gboolean show_icon_names;
+	gboolean show_star_rating;
 
 	/* various */
 	gboolean tree_descend_subdirs;
--- a/src/view_file.h	Mon Jun 18 18:53:46 2018 +0100
+++ b/src/view_file.h	Mon Jun 18 19:17:19 2018 +0100
@@ -39,6 +39,7 @@
 
 void vf_thumb_set(ViewFile *vf, gboolean enable);
 void vf_marks_set(ViewFile *vf, gboolean enable);
+void vf_star_rating_set(ViewFile *vf, gboolean enable);
 void vf_sort_set(ViewFile *vf, SortType type, gboolean ascend);
 
 guint vf_marks_get_filter(ViewFile *vf);
--- a/src/view_file/view_file.c	Mon Jun 18 18:53:46 2018 +0100
+++ b/src/view_file/view_file.c	Mon Jun 18 19:17:19 2018 +0100
@@ -484,6 +484,23 @@
 	layout_views_set(vf->layout, vf->layout->options.dir_view_type, new_type);
 }
 
+static void vf_pop_menu_toggle_star_rating(ViewFile *vf)
+{
+	GtkAllocation allocation;
+
+	options->show_star_rating = !options->show_star_rating;
+
+	gtk_widget_get_allocation(vf->listview, &allocation);
+	vf_star_rating_set(vf, options->show_star_rating);
+}
+
+static void vf_pop_menu_show_star_rating_cb(GtkWidget *widget, gpointer data)
+{
+	ViewFile *vf = data;
+
+	vf_pop_menu_toggle_star_rating(vf);
+}
+
 static void vf_pop_menu_refresh_cb(GtkWidget *widget, gpointer data)
 {
 	ViewFile *vf = data;
@@ -662,6 +679,18 @@
 		break;
 	}
 
+	switch (vf->type)
+	{
+	case FILEVIEW_LIST:
+		menu_item_add_check(menu, _("Show star rating"), options->show_star_rating,
+				    G_CALLBACK(vflist_pop_menu_show_star_rating_cb), vf);
+		break;
+	case FILEVIEW_ICON:
+		menu_item_add_check(menu, _("Show star rating"), options->show_star_rating,
+				    G_CALLBACK(vficon_pop_menu_show_star_rating_cb), vf);
+		break;
+	}
+
 	menu_item_add_stock(menu, _("Re_fresh"), GTK_STOCK_REFRESH, G_CALLBACK(vf_pop_menu_refresh_cb), vf);
 
 	return menu;
@@ -1113,6 +1142,19 @@
 	vf_refresh_idle(vf);
 }
 
+void vf_star_rating_set(ViewFile *vf, gboolean enable)
+{
+	if (options->show_star_rating == enable) return;
+	options->show_star_rating = enable;
+
+	switch (vf->type)
+		{
+		case FILEVIEW_LIST: vflist_star_rating_set(vf, enable); break;
+		case FILEVIEW_ICON: vficon_star_rating_set(vf, enable); break;
+		}
+	vf_refresh_idle(vf);
+}
+
 guint vf_marks_get_filter(ViewFile *vf)
 {
 	guint ret = 0;
--- a/src/view_file/view_file_icon.c	Mon Jun 18 18:53:46 2018 +0100
+++ b/src/view_file/view_file_icon.c	Mon Jun 18 19:17:19 2018 +0100
@@ -125,6 +125,23 @@
 	vficon_toggle_filenames(vf);
 }
 
+static void vficon_toggle_star_rating(ViewFile *vf)
+{
+	GtkAllocation allocation;
+
+	options->show_star_rating = !options->show_star_rating;
+
+	gtk_widget_get_allocation(vf->listview, &allocation);
+	vficon_populate_at_new_size(vf, allocation.width, allocation.height, TRUE);
+}
+
+void vficon_pop_menu_show_star_rating_cb(GtkWidget *widget, gpointer data)
+{
+	ViewFile *vf = data;
+
+	vficon_toggle_star_rating(vf);
+}
+
 void vficon_pop_menu_refresh_cb(GtkWidget *widget, gpointer data)
 {
 	ViewFile *vf = data;
@@ -621,6 +638,13 @@
 	vficon_populate_at_new_size(vf, allocation.width, allocation.height, TRUE);
 }
 
+void vficon_star_rating_set(ViewFile *vf, gint enable)
+{
+	GtkAllocation allocation;
+	gtk_widget_get_allocation(vf->listview, &allocation);
+	vficon_populate_at_new_size(vf, allocation.width, allocation.height, TRUE);
+}
+
 /*
  *-------------------------------------------------------------------
  * selections
@@ -1542,7 +1566,7 @@
 				{
 				g_object_set(G_OBJECT(cell), "fixed_width", thumb_width,
 							     "fixed_height", options->thumbnails.max_height,
-							     "show_text", VFICON(vf)->show_text,
+							     "show_text", VFICON(vf)->show_text || options->show_star_rating,
 							     "show_marks", vf->marks_enabled,
 							     "num_marks", FILEDATA_MARKS_SIZE,
 							     NULL);
@@ -1947,6 +1971,7 @@
 	FileData *fd;
 	ColumnData *cd = data;
 	ViewFile *vf = cd->vf;
+	gchar *star_rating;
 
 	if (!GQV_IS_CELL_RENDERER_ICON(cell)) return;
 
@@ -1959,24 +1984,56 @@
 		GdkColor color_fg;
 		GdkColor color_bg;
 		GtkStyle *style;
-		gchar *name_sidecars;
+		gchar *name_sidecars = NULL;
 		gchar *link;
 		GtkStateType state = GTK_STATE_NORMAL;
 
 		g_assert(fd->magick == FD_MAGICK);
 
+		if (options->show_star_rating)
+			{
+			star_rating = metadata_read_rating_stars(fd);
+			}
+		else
+			{
+			star_rating = NULL;
+			}
+
 		link = islink(fd->path) ? GQ_LINK_STR : "";
 		if (fd->sidecar_files)
 			{
 			gchar *sidecars = file_data_sc_list_to_string(fd);
-			name_sidecars = g_strdup_printf("%s%s %s", link, fd->name, sidecars);
+			if (options->show_star_rating && VFICON(vf)->show_text)
+				{
+				name_sidecars = g_strdup_printf("%s%s %s\n%s", link, fd->name, sidecars, star_rating);
+				}
+			else if (options->show_star_rating)
+				{
+				name_sidecars = g_strdup_printf("%s", star_rating);
+				}
+			else if (VFICON(vf)->show_text)
+				{
+				name_sidecars = g_strdup_printf("%s%s %s", link, fd->name, sidecars);
+				}
 			g_free(sidecars);
 			}
 		else
 			{
 			gchar *disabled_grouping = fd->disable_grouping ? _(" [NO GROUPING]") : "";
-			name_sidecars = g_strdup_printf("%s%s%s", link, fd->name, disabled_grouping);
+			if (options->show_star_rating && VFICON(vf)->show_text)
+				{
+				name_sidecars = g_strdup_printf("%s%s%s\n%s", link, fd->name, disabled_grouping, star_rating);
+				}
+			else if (options->show_star_rating)
+				{
+				name_sidecars = g_strdup_printf("%s", star_rating);
+				}
+			else if (VFICON(vf)->show_text)
+				{
+				name_sidecars = g_strdup_printf("%s%s%s", link, fd->name, disabled_grouping);
+				}
 			}
+		g_free(star_rating);
 
 		style = gtk_widget_get_style(vf->listview);
 		if (fd->selected & SELECTION_SELECTED)
--- a/src/view_file/view_file_icon.h	Mon Jun 18 18:53:46 2018 +0100
+++ b/src/view_file/view_file_icon.h	Mon Jun 18 19:17:19 2018 +0100
@@ -39,6 +39,7 @@
 void vficon_sort_set(ViewFile *vf, SortType type, gboolean ascend);
 
 void vficon_marks_set(ViewFile *vf, gboolean enable);
+void vficon_star_rating_set(ViewFile *vf, gboolean enable);
 
 GList *vficon_selection_get_one(ViewFile *vf, FileData *fd);
 GList *vficon_pop_menu_file_list(ViewFile *vf);
@@ -47,6 +48,7 @@
 void vficon_pop_menu_refresh_cb(GtkWidget *widget, gpointer data);
 void vficon_popup_destroy_cb(GtkWidget *widget, gpointer data);
 void vficon_pop_menu_show_names_cb(GtkWidget *widget, gpointer data);
+void vficon_pop_menu_show_star_rating_cb(GtkWidget *widget, gpointer data);
 
 FileData *vficon_index_get_data(ViewFile *vf, gint row);
 gint vficon_index_by_fd(ViewFile *vf, FileData *in_fd);
--- a/src/view_file/view_file_list.c	Mon Jun 18 18:53:46 2018 +0100
+++ b/src/view_file/view_file_list.c	Mon Jun 18 19:17:19 2018 +0100
@@ -47,8 +47,10 @@
 	FILE_COLUMN_VERSION,
 	FILE_COLUMN_THUMB,
 	FILE_COLUMN_FORMATTED,
+	FILE_COLUMN_FORMATTED_WITH_STARS,
 	FILE_COLUMN_NAME,
 	FILE_COLUMN_SIDECARS,
+	FILE_COLUMN_STAR_RATING,
 	FILE_COLUMN_SIZE,
 	FILE_COLUMN_DATE,
 	FILE_COLUMN_EXPANDED,
@@ -65,6 +67,8 @@
 	FILE_VIEW_COLUMN_MARKS_LAST = FILE_VIEW_COLUMN_MARKS + FILEDATA_MARKS_SIZE - 1,
 	FILE_VIEW_COLUMN_THUMB,
 	FILE_VIEW_COLUMN_FORMATTED,
+	FILE_VIEW_COLUMN_FORMATTED_WITH_STARS,
+	FILE_VIEW_COLUMN_STAR_RATING,
 	FILE_VIEW_COLUMN_SIZE,
 	FILE_VIEW_COLUMN_DATE,
 	FILE_VIEW_COLUMN_COUNT
@@ -422,6 +426,53 @@
 		}
 }
 
+void vflist_star_rating_set(ViewFile *vf, gboolean enable)
+{
+	GList *columns, *work;
+
+	columns = gtk_tree_view_get_columns(GTK_TREE_VIEW(vf->listview));
+
+	work = columns;
+	while (work)
+		{
+		GtkTreeViewColumn *column = work->data;
+		gint col_idx = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(column), "column_store_idx"));
+		work = work->next;
+
+		if (vflist_is_multiline(vf))
+			{
+			if (col_idx == FILE_COLUMN_FORMATTED_WITH_STARS)
+				{
+				gtk_tree_view_column_set_visible(column, enable);
+				}
+			if (col_idx == FILE_COLUMN_FORMATTED)
+				{
+				gtk_tree_view_column_set_visible(column, !enable);
+				}
+			}
+		else
+			{
+			if (col_idx == FILE_COLUMN_STAR_RATING)
+				{
+				gtk_tree_view_column_set_visible(column, enable);
+				}
+			}
+		}
+	g_list_free(columns);
+}
+
+void vflist_pop_menu_show_star_rating_cb(GtkWidget *widget, gpointer data)
+{
+	ViewFile *vf = data;
+
+	options->show_star_rating = !options->show_star_rating;
+
+	vflist_populate_view(vf, TRUE);
+
+	vflist_color_set(vf, VFLIST(vf)->click_fd, FALSE);
+	vflist_star_rating_set(vf, options->show_star_rating);
+}
+
 void vflist_pop_menu_refresh_cb(GtkWidget *widget, gpointer data)
 {
 	ViewFile *vf = data;
@@ -768,14 +819,21 @@
  */
 
 
-static gchar* vflist_get_formatted(ViewFile *vf, const gchar *name, const gchar *sidecars, const gchar *size, const gchar *time, gboolean expanded)
+static gchar* vflist_get_formatted(ViewFile *vf, const gchar *name, const gchar *sidecars, const gchar *size, const gchar *time, gboolean expanded, gboolean with_stars, const gchar *star_rating)
  {
 	gboolean multiline = vflist_is_multiline(vf);
 	gchar *text;
 
 	if (multiline)
 		{
-		text = g_strdup_printf("%s %s\n%s\n%s", name, expanded ? "" : sidecars, size, time);
+		if (with_stars)
+			{
+					text = g_strdup_printf("%s %s\n%s\n%s\n%s", name, expanded ? "" : sidecars, size, time, star_rating);
+			}
+		else
+			{
+			text = g_strdup_printf("%s %s\n%s\n%s", name, expanded ? "" : sidecars, size, time);
+			}
 		}
 	else
 		{
@@ -792,7 +850,8 @@
 	gchar *size;
 	gchar *time;
 	gchar *formatted;
-
+	gchar *formatted_with_stars;
+	gchar *star_rating;
 	store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview)));
 
 	gtk_tree_model_get(GTK_TREE_MODEL(store), iter,
@@ -800,12 +859,18 @@
 					FILE_COLUMN_SIDECARS, &sidecars,
 					FILE_COLUMN_SIZE, &size,
 					FILE_COLUMN_DATE, &time,
+					FILE_COLUMN_STAR_RATING, &star_rating,
 					-1);
-	formatted = vflist_get_formatted(vf, name, sidecars, size, time, expanded);
+
+	formatted = vflist_get_formatted(vf, name, sidecars, size, time, expanded, FALSE, NULL);
+	formatted_with_stars = vflist_get_formatted(vf, name, sidecars, size, time, expanded, TRUE, star_rating);
 
 	gtk_tree_store_set(store, iter, FILE_COLUMN_FORMATTED, formatted,
 					FILE_COLUMN_EXPANDED, expanded,
 					-1);
+	gtk_tree_store_set(store, iter, FILE_COLUMN_FORMATTED_WITH_STARS, formatted_with_stars,
+					FILE_COLUMN_EXPANDED, expanded,
+					-1);
 	g_free(time);
 	g_free(size);
 	g_free(sidecars);
@@ -822,7 +887,18 @@
 	gchar *link = islink(fd->path) ? GQ_LINK_STR : "";
 	const gchar *disabled_grouping;
 	gchar *formatted;
+	gchar *formatted_with_stars;
 	gboolean expanded = FALSE;
+	gchar *star_rating;
+
+	if (options->show_star_rating)
+		{
+		star_rating = metadata_read_rating_stars(fd);
+		}
+	else
+		{
+		star_rating = NULL;
+		}
 
 	if (fd->sidecar_files) /* expanded has no effect on files without sidecars */
 		{
@@ -835,14 +911,17 @@
 	name = g_strdup_printf("%s%s%s", link, fd->name, disabled_grouping);
 	size = text_from_size(fd->size);
 
-	formatted = vflist_get_formatted(vf, name, sidecars, size, time, expanded);
+	formatted = vflist_get_formatted(vf, name, sidecars, size, time, expanded, FALSE, NULL);
+	formatted_with_stars = vflist_get_formatted(vf, name, sidecars, size, time, expanded, TRUE, star_rating);
 
 	gtk_tree_store_set(store, iter, FILE_COLUMN_POINTER, fd,
 					FILE_COLUMN_VERSION, fd->version,
 					FILE_COLUMN_THUMB, fd->thumb_pixbuf,
 					FILE_COLUMN_FORMATTED, formatted,
+					FILE_COLUMN_FORMATTED_WITH_STARS, formatted_with_stars,
 					FILE_COLUMN_SIDECARS, sidecars,
 					FILE_COLUMN_NAME, name,
+					FILE_COLUMN_STAR_RATING, star_rating,
 					FILE_COLUMN_SIZE, size,
 					FILE_COLUMN_DATE, time,
 #define STORE_SET_IS_SLOW 1
@@ -1608,9 +1687,32 @@
 	g_object_set(G_OBJECT(cell), "height", options->thumbnails.max_height, NULL);
 	gtk_tree_view_column_set_visible(column, thumb);
 
-	column = gtk_tree_view_get_column(GTK_TREE_VIEW(listview), FILE_VIEW_COLUMN_FORMATTED);
+	if (options->show_star_rating)
+		{
+		column = gtk_tree_view_get_column(GTK_TREE_VIEW(listview), FILE_VIEW_COLUMN_FORMATTED_WITH_STARS);
+		if (!column) return;
+		gtk_tree_view_set_expander_column(GTK_TREE_VIEW(listview), column);
+		gtk_tree_view_column_set_visible(column, TRUE);
+
+		column = gtk_tree_view_get_column(GTK_TREE_VIEW(listview), FILE_VIEW_COLUMN_FORMATTED);
+		if (!column) return;
+		gtk_tree_view_column_set_visible(column, FALSE);
+		}
+	else
+		{
+		column = gtk_tree_view_get_column(GTK_TREE_VIEW(listview), FILE_VIEW_COLUMN_FORMATTED);
+		if (!column) return;
+		gtk_tree_view_set_expander_column(GTK_TREE_VIEW(listview), column);
+		gtk_tree_view_column_set_visible(column, TRUE);
+
+		column = gtk_tree_view_get_column(GTK_TREE_VIEW(listview), FILE_VIEW_COLUMN_FORMATTED_WITH_STARS);
+		if (!column) return;
+		gtk_tree_view_column_set_visible(column, FALSE);
+		}
+
+	column = gtk_tree_view_get_column(GTK_TREE_VIEW(listview), FILE_VIEW_COLUMN_STAR_RATING);
 	if (!column) return;
-	gtk_tree_view_set_expander_column(GTK_TREE_VIEW(listview), column);
+	gtk_tree_view_column_set_visible(column, !multiline && options->show_star_rating);
 
 	column = gtk_tree_view_get_column(GTK_TREE_VIEW(listview), FILE_VIEW_COLUMN_SIZE);
 	if (!column) return;
@@ -1910,7 +2012,9 @@
 	flist_types[FILE_COLUMN_VERSION] = G_TYPE_INT;
 	flist_types[FILE_COLUMN_THUMB] = GDK_TYPE_PIXBUF;
 	flist_types[FILE_COLUMN_FORMATTED] = G_TYPE_STRING;
+	flist_types[FILE_COLUMN_FORMATTED_WITH_STARS] = G_TYPE_STRING;
 	flist_types[FILE_COLUMN_NAME] = G_TYPE_STRING;
+	flist_types[FILE_COLUMN_STAR_RATING] = G_TYPE_STRING;
 	flist_types[FILE_COLUMN_SIDECARS] = G_TYPE_STRING;
 	flist_types[FILE_COLUMN_SIZE] = G_TYPE_STRING;
 	flist_types[FILE_COLUMN_DATE] = G_TYPE_STRING;
@@ -1954,6 +2058,14 @@
 	g_assert(column == FILE_VIEW_COLUMN_FORMATTED);
 	column++;
 
+	vflist_listview_add_column(vf, FILE_COLUMN_FORMATTED_WITH_STARS, _("NameStars"), FALSE, FALSE, TRUE);
+	g_assert(column == FILE_VIEW_COLUMN_FORMATTED_WITH_STARS);
+	column++;
+
+	vflist_listview_add_column(vf, FILE_COLUMN_STAR_RATING, _("Stars"), FALSE, FALSE, FALSE);
+	g_assert(column == FILE_VIEW_COLUMN_STAR_RATING);
+	column++;
+
 	vflist_listview_add_column(vf, FILE_COLUMN_SIZE, _("Size"), FALSE, TRUE, FALSE);
 	g_assert(column == FILE_VIEW_COLUMN_SIZE);
 	column++;
--- a/src/view_file/view_file_list.h	Mon Jun 18 18:53:46 2018 +0100
+++ b/src/view_file/view_file_list.h	Mon Jun 18 19:17:19 2018 +0100
@@ -38,6 +38,7 @@
 
 void vflist_thumb_set(ViewFile *vf, gboolean enable);
 void vflist_marks_set(ViewFile *vf, gboolean enable);
+void vflist_star_rating_set(ViewFile *vf, gboolean enable);
 void vflist_sort_set(ViewFile *vf, SortType type, gboolean ascend);
 
 GList *vflist_selection_get_one(ViewFile *vf, FileData *fd);
@@ -73,6 +74,6 @@
 void vflist_set_thumb_fd(ViewFile *vf, FileData *fd);
 FileData *vflist_thumb_next_fd(ViewFile *vf);
 void vflist_thumb_reset_all(ViewFile *vf);
-
+void vflist_pop_menu_show_star_rating_cb(GtkWidget *widget, gpointer data);
 #endif
 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
--- a/web/help/GuideMainWindowFilePane.html	Mon Jun 18 18:53:46 2018 +0100
+++ b/web/help/GuideMainWindowFilePane.html	Mon Jun 18 19:17:19 2018 +0100
@@ -636,6 +636,12 @@
 <dd>
           <p class="para block block-first">Toggles display of file names in the icon view display mode.</p>
         </dd>
+<dt class="term">
+          <span class="emphasis emphasis-bold">Show star rating</span>
+        </dt>
+<dd>
+          <p class="para block block-first">Toggles display of the "star rating" (Xmp.xmp.Rating).</p>
+        </dd>
 </dl></div>
 <p class="para block"></p>
 </div>