#include "layout_image.h"
#include "menu.h"
#include "metadata.h"
+#include "misc.h"
#include "thumb.h"
#include "utilops.h"
#include "ui_fileops.h"
#include "ui_menu.h"
+#include "ui_misc.h"
#include "ui_tree_edit.h"
#include "uri_utils.h"
#include "view_file.h"
/* between these, the icon width is increased by thumb_max_width / 2 */
#define THUMB_MIN_ICON_WIDTH 128
-#define THUMB_MAX_ICON_WIDTH 150
+#define THUMB_MAX_ICON_WIDTH 160
+#define THUMB_MIN_ICON_WIDTH_WITH_MARKS TOGGLE_SPACING * FILEDATA_MARKS_SIZE
#define VFICON_MAX_COLUMNS 32
#define THUMB_BORDER_PADDING 2
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;
{
gint width;
- if (!VFICON(vf)->show_text) return options->thumbnails.max_width;
+ if (!VFICON(vf)->show_text && !vf->marks_enabled ) return options->thumbnails.max_width;
width = options->thumbnails.max_width + options->thumbnails.max_width / 2;
if (width < THUMB_MIN_ICON_WIDTH) width = THUMB_MIN_ICON_WIDTH;
if (width > THUMB_MAX_ICON_WIDTH) width = options->thumbnails.max_width;
+ if (vf->marks_enabled && width < THUMB_MIN_ICON_WIDTH_WITH_MARKS) width = THUMB_MIN_ICON_WIDTH_WITH_MARKS;
return width;
}
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
vficon_set_focus(vf, fd);
}
+void vficon_select_list(ViewFile *vf, GList *list)
+{
+ GList *work;
+ FileData *fd;
+
+ if (!list) return;
+
+ work = list;
+ while (work)
+ {
+ fd = work->data;
+ if (g_list_find(vf->list, fd))
+ {
+ VFICON(vf)->selection = g_list_append(VFICON(vf)->selection, fd);
+ vficon_selection_add(vf, fd, SELECTION_SELECTED, NULL);
+ }
+ work = work->next;
+ }
+}
+
void vficon_mark_to_selection(ViewFile *vf, gint mark, MarkToSelectionMode mode)
{
GList *work;
/* ensure focus row col are correct */
vficon_find_position(vf, VFICON(vf)->focus_fd, &VFICON(vf)->focus_row, &VFICON(vf)->focus_column);
#if GTK_CHECK_VERSION(3,0,0)
-/* FIXME: Refer to issue #467 on Github. The thumbnail position is not
+/** @FIXME Refer to issue #467 on Github. The thumbnail position is not
* preserved when the icon view is refreshed. Caused by an unknown call from
* the idle loop. This patch hides the problem.
*/
if (bevent->type == GDK_2BUTTON_PRESS && vf->layout)
{
- vficon_selection_remove(vf, VFICON(vf)->click_fd, SELECTION_PRELIGHT, &iter);
- layout_image_full_screen_start(vf->layout);
+ if (VFICON(vf)->click_fd->format_class == FORMAT_CLASS_COLLECTION)
+ {
+ collection_window_new(VFICON(vf)->click_fd->path);
+ }
+ else
+ {
+ vficon_selection_remove(vf, VFICON(vf)->click_fd, SELECTION_PRELIGHT, &iter);
+ layout_image_full_screen_start(vf->layout);
+ }
}
break;
case MOUSE_BUTTON_RIGHT:
tip_schedule(vf);
+ if (defined_mouse_buttons(widget, bevent, vf->layout))
+ {
+ return TRUE;
+ }
+
if ((gint)bevent->x != 0 || (gint)bevent->y != 0)
{
fd = vficon_find_data_by_coord(vf, (gint)bevent->x, (gint)bevent->y, &iter);
{
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);
vf_send_update(vf);
vf_thumb_update(vf);
+ vf_star_update(vf);
}
static void vficon_populate_at_new_size(ViewFile *vf, gint w, gint h, gboolean force)
}
}
+void vficon_read_metadata_progress_count(GList *list, gint *count, gint *done)
+{
+ GList *work = list;
+ while (work)
+ {
+ FileData *fd = work->data;
+ work = work->next;
+
+ if (fd->metadata_in_idle_loaded) (*done)++;
+ (*count)++;
+ }
+}
+
void vficon_set_thumb_fd(ViewFile *vf, FileData *fd)
{
GtkTreeModel *store;
GList *list;
gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &list, -1);
- // TODO(xsdg): for loop here.
+ /** @todo (xsdg): for loop here. */
for (; list; list = list->next)
{
FileData *fd = list->data;
return NULL;
}
-void vficon_thumb_reset_all(ViewFile *vf)
+void vficon_set_star_fd(ViewFile *vf, FileData *fd)
{
- GList *work = vf->list;
+ GtkTreeModel *store;
+ GtkTreeIter iter;
+ GList *list;
- while (work)
- {
- FileData *fd = work->data;
- if (fd->thumb_pixbuf)
- {
- g_object_unref(fd->thumb_pixbuf);
- fd->thumb_pixbuf = NULL;
- }
- work = work->next;
- }
-}
+ if (!g_list_find(vf->list, fd)) return;
+ if (!vficon_find_iter(vf, fd, &iter, NULL)) return;
+ store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview));
-/*
- *-----------------------------------------------------------------------------
- * row stuff
- *-----------------------------------------------------------------------------
- */
+ gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &list, -1);
+ gtk_list_store_set(GTK_LIST_STORE(store), &iter, FILE_COLUMN_POINTER, list, -1);
+}
-FileData *vficon_index_get_data(ViewFile *vf, gint row)
+FileData *vficon_star_next_fd(ViewFile *vf)
{
- FileData *fd;
+ GtkTreePath *tpath;
- fd = g_list_nth_data(vf->list, row);
- return fd ? fd : NULL;
-}
+ /* first check the visible files */
+ if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vf->listview), 0, 0, &tpath, NULL, NULL, NULL))
+ {
+ GtkTreeModel *store;
+ GtkTreeIter iter;
+ gboolean valid = TRUE;
-gint vficon_index_by_fd(ViewFile *vf, FileData *in_fd)
-{
- gint p = 0;
- GList *work;
+ store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview));
+ gtk_tree_model_get_iter(store, &iter, tpath);
+ gtk_tree_path_free(tpath);
+ tpath = NULL;
- if (!in_fd) return -1;
+ while (valid && tree_view_row_get_visibility(GTK_TREE_VIEW(vf->listview), &iter, FALSE) == 0)
+ {
+ GList *list;
+ gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &list, -1);
- work = vf->list;
- while (work)
- {
- FileData *fd = work->data;
- if (fd == in_fd) return p;
- work = work->next;
- p++;
+ for (; list; list = list->next)
+ {
+ FileData *fd = list->data;
+ if (fd && fd->rating == STAR_RATING_NOT_READ)
+ {
+ vf->stars_filedata = fd;
+
+ if (vf->stars_id == 0)
+ {
+ vf->stars_id = g_idle_add_full(G_PRIORITY_LOW, vf_stars_cb, vf, NULL);
+ }
+
+ return fd;
+ }
+ }
+
+ valid = gtk_tree_model_iter_next(store, &iter);
+ }
}
- return -1;
-}
+ /* Then iterate through the entire list to load all of them. */
-guint vficon_count(ViewFile *vf, gint64 *bytes)
-{
- if (bytes)
+ GList *work;
+ for (work = vf->list; work; work = work->next)
{
- gint64 b = 0;
- GList *work;
+ FileData *fd = work->data;
- work = vf->list;
- while (work)
+ if (fd && fd->rating == STAR_RATING_NOT_READ)
{
- FileData *fd = work->data;
- work = work->next;
+ vf->stars_filedata = fd;
- b += fd->size;
- }
+ if (vf->stars_id == 0)
+ {
+ vf->stars_id = g_idle_add_full(G_PRIORITY_LOW, vf_stars_cb, vf, NULL);
+ }
- *bytes = b;
+ return fd;
+ }
}
- return g_list_length(vf->list);
+ return NULL;
}
-GList *vficon_get_list(ViewFile *vf)
+/*
+ *-----------------------------------------------------------------------------
+ * row stuff
+ *-----------------------------------------------------------------------------
+ */
+
+gint vficon_index_by_fd(ViewFile *vf, FileData *in_fd)
{
- GList *list = NULL;
+ gint p = 0;
GList *work;
+ if (!in_fd) return -1;
+
work = vf->list;
while (work)
{
FileData *fd = work->data;
+ if (fd == in_fd) return p;
work = work->next;
-
- list = g_list_prepend(list, file_data_ref(fd));
+ p++;
}
- return g_list_reverse(list);
+ return -1;
}
/*
FileData *first_selected = NULL;
GList *new_filelist = NULL;
GList *new_fd_list = NULL;
+ GList *old_selected = NULL;
+ GtkTreePath *end_path = NULL;
+ GtkTreePath *start_path = NULL;
focus_fd = VFICON(vf)->focus_fd;
+ gtk_tree_view_get_visible_range(GTK_TREE_VIEW(vf->listview), &start_path, &end_path);
+
if (vf->dir_fd)
{
ret = filelist_read(vf->dir_fd, &new_filelist, NULL);
new_filelist = file_data_filter_marks_list(new_filelist, vf_marks_get_filter(vf));
+ new_filelist = g_list_first(new_filelist);
+ new_filelist = file_data_filter_file_filter_list(new_filelist, vf_file_filter_get_filter(vf));
+
+ new_filelist = g_list_first(new_filelist);
+ new_filelist = file_data_filter_class_list(new_filelist, vf_class_get_filter(vf));
+
}
vf->list = filelist_sort(vf->list, vf->sort_method, vf->sort_ascend); /* the list might not be sorted if there were renames */
if (VFICON(vf)->selection)
{
+ old_selected = g_list_copy(VFICON(vf)->selection);
first_selected = VFICON(vf)->selection->data;
file_data_ref(first_selected);
g_list_free(VFICON(vf)->selection);
VFICON(vf)->selection = g_list_reverse(VFICON(vf)->selection);
+ /* Preserve the original selection order */
+ if (old_selected)
+ {
+ GList *reversed_old_selected;
+
+ reversed_old_selected = g_list_reverse(old_selected);
+ while (reversed_old_selected)
+ {
+ GList *tmp;
+ tmp = g_list_find(VFICON(vf)->selection, reversed_old_selected->data);
+ if (tmp)
+ {
+ VFICON(vf)->selection = g_list_remove_link(VFICON(vf)->selection, tmp);
+ VFICON(vf)->selection = g_list_concat(tmp, VFICON(vf)->selection);
+ }
+ reversed_old_selected = reversed_old_selected->next;
+ }
+ g_list_free(old_selected);
+ }
+
filelist_free(new_filelist);
vficon_populate(vf, TRUE, keep_position);
}
file_data_unref(first_selected);
- /* attempt to keep focus on same icon when refreshing */
- if (focus_fd && g_list_find(vf->list, focus_fd))
+ if (start_path)
{
- vficon_set_focus(vf, focus_fd);
+ gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(vf->listview), start_path, NULL, FALSE, 0.0, 0.0);
}
+ gtk_tree_path_free(start_path);
+ gtk_tree_path_free(end_path);
+
return ret;
}
FileData *fd;
ColumnData *cd = data;
ViewFile *vf = cd->vf;
+ gchar *star_rating;
if (!GQV_IS_CELL_RENDERER_ICON(cell)) return;
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 && fd->rating != STAR_RATING_NOT_READ)
+ {
+ star_rating = convert_rating_to_stars(fd->rating);
+ }
+ 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)
tip_unschedule(vf);
vf_thumb_cleanup(vf);
+ vf_star_cleanup(vf);
g_list_free(vf->list);
g_list_free(VFICON(vf)->selection);