/src/pan-view/.deps
/src/pan-view/.dirstamp
+# /src/view_file/
+/src/view_file/.deps
+/src/view_file/.dirstamp
+
/build-stamp
/debian/geeqie*
/debian/files
$(extra_ICONS)
include $(srcdir)/pan-view/Makefile.am
+include $(srcdir)/view_file/Makefile.am
bin_PROGRAMS = geeqie
geeqie_SOURCES = \
$(module_SLIK) \
$(module_pan_view) \
+ $(module_view_file) \
ClayRGB1998.icc \
ClayRGB1998_icc.h \
advanced_exif.c \
view_dir_tree.h \
view_file.c \
view_file.h \
- view_file_list.c \
- view_file_list.h \
- view_file_icon.c \
- view_file_icon.h \
window.c \
window.h \
lua.c \
GtkTreePath *tpath;
FileData *fd_n;
GtkTreeIter iter;
- IconData *id;
if (!lw || !lw->vf) return;
{
if (lw->vf->type == FILEVIEW_ICON)
{
- id = work->data;
- fd_n = id->fd;
+ fd_n = work->data;
work = work->next;
}
else
GtkTreePath *tpath;
FileData *fd_n;
GtkTreeIter iter;
- IconData *id;
if (!lw || !lw->vf) return;
{
if (lw->vf->type == FILEVIEW_ICON)
{
- id = work->data;
- fd_n = id->fd;
+ fd_n = work->data;
work = work->next;
}
else
GtkTreePath *tpath;
FileData *fd_n;
GtkTreeIter iter;
- IconData *id;
gchar *rotation;
gchar *command;
gint run_result;
{
if (lw->vf->type == FILEVIEW_ICON)
{
- id = work->data;
- fd_n = id->fd;
+ fd_n = work->data;
work = work->next;
}
else
%D%/pan-util.c \
%D%/pan-util.h \
%D%/pan-view.c \
- %D%/pan-view.h
+ %D%/pan-view.h \
+ %D%/pan-view-filter.c \
+ %D%/pan-view-filter.h \
+ %D%/pan-view-search.c \
+ %D%/pan-view-search.h
+
#include "pan-util.h"
#include "pan-view.h"
+#include "pan-view-filter.h"
#include "pixbuf_util.h"
#define PAN_CAL_POPUP_COLOR 220, 220, 220
gint end_month = 0;
list = pan_list_tree(dir_fd, SORT_NONE, TRUE, pw->ignore_symlinks);
+ pan_filter_fd_list(&list, pw->filter_ui->filter_elements);
if (pw->cache_list && pw->exif_date_enable)
{
#include "pan-item.h"
#include "pan-util.h"
+#include "pan-view-filter.h"
static void pan_flower_size(PanWindow *pw, gint *width, gint *height)
{
f = filelist_sort(f, SORT_NAME, TRUE);
d = filelist_sort(d, SORT_NAME, TRUE);
+ pan_filter_fd_list(&f, pw->filter_ui->filter_elements);
+
pi_box = pan_item_text_new(pw, x, y, dir_fd->path, PAN_TEXT_ATTR_NONE,
PAN_TEXT_BORDER_SIZE,
PAN_TEXT_COLOR, 255);
f = filelist_sort(f, SORT_NAME, TRUE);
d = filelist_sort(d, SORT_NAME, TRUE);
+ pan_filter_fd_list(&f, pw->filter_ui->filter_elements);
+
*x = PAN_BOX_BORDER + ((*level) * MAX(PAN_BOX_BORDER, PAN_THUMB_GAP));
pi_box = pan_item_text_new(pw, *x, *y, dir_fd->path, PAN_TEXT_ATTR_NONE,
#include "pan-item.h"
#include "pan-util.h"
+#include "pan-view-filter.h"
void pan_grid_compute(PanWindow *pw, FileData *dir_fd, gint *width, gint *height)
{
gint next_y;
list = pan_list_tree(dir_fd, SORT_NAME, TRUE, pw->ignore_symlinks);
+ pan_filter_fd_list(&list, pw->filter_ui->filter_elements);
grid_size = (gint)sqrt((gdouble)g_list_length(list));
if (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE)
#include "pan-item.h"
#include "pan-util.h"
#include "pan-view.h"
+#include "pan-view-filter.h"
void pan_timeline_compute(PanWindow *pw, FileData *dir_fd, gint *width, gint *height)
{
GList *list;
GList *work;
gint x, y;
- time_t tc;
+ time_t group_start_date;
gint total;
gint count;
PanItem *pi_month = NULL;
gint y_height;
list = pan_list_tree(dir_fd, SORT_NONE, TRUE, pw->ignore_symlinks);
+ pan_filter_fd_list(&list, pw->filter_ui->filter_elements);
if (pw->cache_list && pw->exif_date_enable)
{
day_start = month_start;
x_width = 0;
y_height = 0;
- tc = 0;
+ group_start_date = 0;
+ // total and count are used to enforce a stride of PAN_GROUP_MAX thumbs.
total = 0;
count = 0;
work = list;
fd = work->data;
work = work->next;
- if (!pan_date_compare(fd->date, tc, PAN_DATE_LENGTH_DAY))
+ if (!pan_date_compare(fd->date, group_start_date, PAN_DATE_LENGTH_DAY))
{
+ // FD starts a new day group.
GList *needle;
gchar *buf;
- if (!pan_date_compare(fd->date, tc, PAN_DATE_LENGTH_MONTH))
+ if (!pan_date_compare(fd->date, group_start_date, PAN_DATE_LENGTH_MONTH))
{
+ // FD starts a new month group.
pi_day = NULL;
if (pi_month)
if (pi_day) x = pi_day->x + pi_day->width + PAN_BOX_BORDER;
- tc = fd->date;
+ group_start_date = fd->date;
total = 1;
count = 0;
FileData *nfd;
nfd = needle->data;
- if (pan_date_compare(nfd->date, tc, PAN_DATE_LENGTH_DAY))
+ if (pan_date_compare(nfd->date, group_start_date, PAN_DATE_LENGTH_DAY))
{
needle = needle->next;
total++;
gboolean queued;
};
+typedef struct _PanViewSearchUi PanViewSearchUi;
+struct _PanViewSearchUi
+{
+ GtkWidget *search_box;
+ GtkWidget *search_entry;
+ GtkWidget *search_label;
+ GtkWidget *search_button;
+ GtkWidget *search_button_arrow;
+};
+
+// Defined in pan-view-filter.h
+typedef struct _PanViewFilterUi PanViewFilterUi;
+
typedef struct _PanWindow PanWindow;
struct _PanWindow
{
GtkWidget *label_message;
GtkWidget *label_zoom;
- GtkWidget *search_box;
- GtkWidget *search_entry;
- GtkWidget *search_label;
- GtkWidget *search_button;
- GtkWidget *search_button_arrow;
+ PanViewSearchUi *search_ui;
+ PanViewFilterUi *filter_ui;
GtkWidget *date_button;
--- /dev/null
+/*
+ * Copyright (C) 2006 John Ellis
+ * Copyright (C) 2008 - 2016 The Geeqie Team
+ *
+ * Author: John Ellis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "pan-view-filter.h"
+
+#include "image.h"
+#include "metadata.h"
+#include "pan-item.h"
+#include "pan-util.h"
+#include "pan-view.h"
+#include "ui_fileops.h"
+#include "ui_tabcomp.h"
+#include "ui_misc.h"
+
+PanViewFilterUi *pan_filter_ui_new(PanWindow *pw)
+{
+ PanViewFilterUi *ui = g_new0(PanViewFilterUi, 1);
+ GtkWidget *combo;
+ GtkWidget *hbox;
+
+ /* Since we're using the GHashTable as a HashSet (in which key and value pointers
+ * are always identical), specifying key _and_ value destructor callbacks will
+ * cause a double-free.
+ */
+ {
+ GtkTreeIter iter;
+ ui->filter_mode_model = gtk_list_store_new(3, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING);
+ gtk_list_store_append(ui->filter_mode_model, &iter);
+ gtk_list_store_set(ui->filter_mode_model, &iter,
+ 0, PAN_VIEW_FILTER_REQUIRE, 1, _("Require"), 2, _("R"), -1);
+ gtk_list_store_append(ui->filter_mode_model, &iter);
+ gtk_list_store_set(ui->filter_mode_model, &iter,
+ 0, PAN_VIEW_FILTER_EXCLUDE, 1, _("Exclude"), 2, _("E"), -1);
+ gtk_list_store_append(ui->filter_mode_model, &iter);
+ gtk_list_store_set(ui->filter_mode_model, &iter,
+ 0, PAN_VIEW_FILTER_INCLUDE, 1, _("Include"), 2, _("I"), -1);
+ gtk_list_store_append(ui->filter_mode_model, &iter);
+ gtk_list_store_set(ui->filter_mode_model, &iter,
+ 0, PAN_VIEW_FILTER_GROUP, 1, _("Group"), 2, _("G"), -1);
+
+ ui->filter_mode_combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(ui->filter_mode_model));
+ gtk_combo_box_set_focus_on_click(GTK_COMBO_BOX(ui->filter_mode_combo), FALSE);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(ui->filter_mode_combo), 0);
+
+ GtkCellRenderer *render = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(ui->filter_mode_combo), render, TRUE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(ui->filter_mode_combo), render, "text", 1, NULL);
+ }
+
+ // Build the actual filter UI.
+ ui->filter_box = gtk_hbox_new(FALSE, PREF_PAD_SPACE);
+ pref_spacer(ui->filter_box, 0);
+ pref_label_new(ui->filter_box, _("Keyword Filter:"));
+
+ gtk_box_pack_start(GTK_BOX(ui->filter_box), ui->filter_mode_combo, TRUE, TRUE, 0);
+ gtk_widget_show(ui->filter_mode_combo);
+
+ hbox = gtk_hbox_new(TRUE, PREF_PAD_SPACE);
+ gtk_box_pack_start(GTK_BOX(ui->filter_box), hbox, TRUE, TRUE, 0);
+ gtk_widget_show(hbox);
+
+ combo = tab_completion_new_with_history(&ui->filter_entry, "", "pan_view_filter", -1,
+ pan_filter_activate_cb, pw);
+ gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, TRUE, 0);
+ gtk_widget_show(combo);
+
+ // TODO(xsdg): Figure out whether it's useful to keep this label around.
+ ui->filter_label = gtk_label_new("");
+ //gtk_box_pack_start(GTK_BOX(hbox), ui->filter_label, FALSE, FALSE, 0);
+ //gtk_widget_show(ui->filter_label);
+
+ ui->filter_kw_hbox = gtk_hbox_new(FALSE, PREF_PAD_SPACE);
+ gtk_box_pack_start(GTK_BOX(hbox), ui->filter_kw_hbox, TRUE, TRUE, 0);
+ gtk_widget_show(ui->filter_kw_hbox);
+
+ // Build the spin-button to show/hide the filter UI.
+ ui->filter_button = gtk_toggle_button_new();
+ gtk_button_set_relief(GTK_BUTTON(ui->filter_button), GTK_RELIEF_NONE);
+ gtk_button_set_focus_on_click(GTK_BUTTON(ui->filter_button), FALSE);
+ hbox = gtk_hbox_new(FALSE, PREF_PAD_GAP);
+ gtk_container_add(GTK_CONTAINER(ui->filter_button), hbox);
+ gtk_widget_show(hbox);
+ ui->filter_button_arrow = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_NONE);
+ gtk_box_pack_start(GTK_BOX(hbox), ui->filter_button_arrow, FALSE, FALSE, 0);
+ gtk_widget_show(ui->filter_button_arrow);
+ pref_label_new(hbox, _("Filter"));
+
+ g_signal_connect(G_OBJECT(ui->filter_button), "clicked",
+ G_CALLBACK(pan_filter_toggle_cb), pw);
+
+ return ui;
+}
+
+void pan_filter_ui_destroy(PanViewFilterUi **ui_ptr)
+{
+ if (ui_ptr == NULL || *ui_ptr == NULL) return;
+
+ // Note that g_clear_pointer handles already-NULL pointers.
+ //g_clear_pointer(&(*ui_ptr)->filter_kw_table, g_hash_table_destroy);
+
+ g_free(*ui_ptr);
+ *ui_ptr = NULL;
+}
+
+static void pan_filter_status(PanWindow *pw, const gchar *text)
+{
+ gtk_label_set_text(GTK_LABEL(pw->filter_ui->filter_label), (text) ? text : "");
+}
+
+static void pan_filter_kw_button_cb(GtkButton *widget, gpointer data)
+{
+ PanFilterCallbackState *cb_state = data;
+ PanWindow *pw = cb_state->pw;
+ PanViewFilterUi *ui = pw->filter_ui;
+
+ // TODO(xsdg): Fix filter element pointed object memory leak.
+ ui->filter_elements = g_list_delete_link(ui->filter_elements, cb_state->filter_element);
+ gtk_widget_destroy(GTK_WIDGET(widget));
+ g_free(cb_state);
+
+ pan_filter_status(pw, _("Removed keyword…"));
+ pan_layout_update(pw);
+}
+
+void pan_filter_activate_cb(const gchar *text, gpointer data)
+{
+ GtkWidget *kw_button;
+ PanWindow *pw = data;
+ PanViewFilterUi *ui = pw->filter_ui;
+ GtkTreeIter iter;
+
+ if (!text) return;
+
+ // Get all relevant state and reset UI.
+ gtk_combo_box_get_active_iter(GTK_COMBO_BOX(ui->filter_mode_combo), &iter);
+ gtk_entry_set_text(GTK_ENTRY(ui->filter_entry), "");
+ tab_completion_append_to_history(ui->filter_entry, text);
+
+ // Add new filter element.
+ PanViewFilterElement *element = g_new0(PanViewFilterElement, 1);
+ gtk_tree_model_get(GTK_TREE_MODEL(ui->filter_mode_model), &iter, 0, &element->mode, -1);
+ element->keyword = g_strdup(text);
+ if (g_strcmp0(text, g_regex_escape_string(text, -1)))
+ {
+ // It's an actual regex, so compile
+ element->kw_regex = g_regex_new(text, G_REGEX_ANCHORED | G_REGEX_OPTIMIZE, G_REGEX_MATCH_ANCHORED, NULL);
+ }
+ ui->filter_elements = g_list_append(ui->filter_elements, element);
+
+ // Get the short version of the mode value.
+ gchar *short_mode;
+ gtk_tree_model_get(GTK_TREE_MODEL(ui->filter_mode_model), &iter, 2, &short_mode, -1);
+
+ // Create the button.
+ // TODO(xsdg): Use MVC so that the button list is an actual representation of the GList
+ gchar *label = g_strdup_printf("(%s) %s", short_mode, text);
+ kw_button = gtk_button_new_with_label(label);
+ g_clear_pointer(&label, g_free);
+
+ gtk_box_pack_start(GTK_BOX(ui->filter_kw_hbox), kw_button, FALSE, FALSE, 0);
+ gtk_widget_show(kw_button);
+
+ PanFilterCallbackState *cb_state = g_new0(PanFilterCallbackState, 1);
+ cb_state->pw = pw;
+ cb_state->filter_element = g_list_last(ui->filter_elements);
+
+ g_signal_connect(G_OBJECT(kw_button), "clicked",
+ G_CALLBACK(pan_filter_kw_button_cb), cb_state);
+
+ pan_layout_update(pw);
+}
+
+void pan_filter_activate(PanWindow *pw)
+{
+ gchar *text;
+
+ text = g_strdup(gtk_entry_get_text(GTK_ENTRY(pw->filter_ui->filter_entry)));
+ pan_filter_activate_cb(text, pw);
+ g_free(text);
+}
+
+void pan_filter_toggle_cb(GtkWidget *button, gpointer data)
+{
+ PanWindow *pw = data;
+ PanViewFilterUi *ui = pw->filter_ui;
+ gboolean visible;
+
+ visible = gtk_widget_get_visible(ui->filter_box);
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)) == visible) return;
+
+ if (visible)
+ {
+ gtk_widget_hide(ui->filter_box);
+ gtk_arrow_set(GTK_ARROW(ui->filter_button_arrow), GTK_ARROW_UP, GTK_SHADOW_NONE);
+ }
+ else
+ {
+ gtk_widget_show(ui->filter_box);
+ gtk_arrow_set(GTK_ARROW(ui->filter_button_arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
+ gtk_widget_grab_focus(ui->filter_entry);
+ }
+}
+
+void pan_filter_toggle_visible(PanWindow *pw, gboolean enable)
+{
+ PanViewFilterUi *ui = pw->filter_ui;
+ if (pw->fs) return;
+
+ if (enable)
+ {
+ if (gtk_widget_get_visible(ui->filter_box))
+ {
+ gtk_widget_grab_focus(ui->filter_entry);
+ }
+ else
+ {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->filter_button), TRUE);
+ }
+ }
+ else
+ {
+ if (gtk_widget_get_visible(ui->filter_entry))
+ {
+ if (gtk_widget_has_focus(ui->filter_entry))
+ {
+ gtk_widget_grab_focus(GTK_WIDGET(pw->imd->widget));
+ }
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->filter_button), FALSE);
+ }
+ }
+}
+
+static gboolean pan_view_list_contains_kw_pattern(GList *haystack, PanViewFilterElement *filter, gchar **found_kw)
+{
+ if (filter->kw_regex)
+ {
+ // regex compile succeeded; attempt regex match.
+ GList *work = g_list_first(haystack);
+ while (work)
+ {
+ gchar *keyword = work->data;
+ work = work->next;
+ if (g_regex_match(filter->kw_regex, keyword, 0x0, NULL))
+ {
+ if (found_kw) *found_kw = keyword;
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+ else
+ {
+ // regex compile failed; fall back to exact string match.
+ GList *found_elem = g_list_find_custom(haystack, filter->keyword, (GCompareFunc)g_strcmp0);
+ if (found_elem && found_kw) *found_kw = found_elem->data;
+ return !!found_elem;
+ }
+}
+
+gboolean pan_filter_fd_list(GList **fd_list, GList *filter_elements)
+{
+ GList *work;
+ gboolean modified = FALSE;
+ GHashTable *seen_kw_table = NULL;
+
+ if (!fd_list || !*fd_list || !filter_elements) return modified;
+
+ // seen_kw_table is only valid in this scope, so don't take ownership of any strings.
+ seen_kw_table = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
+
+ work = *fd_list;
+ while (work)
+ {
+ FileData *fd = work->data;
+ GList *last_work = work;
+ work = work->next;
+
+ // TODO(xsdg): OPTIMIZATION Do the search inside of metadata.c to avoid a
+ // bunch of string list copies.
+ GList *img_keywords = metadata_read_list(fd, KEYWORD_KEY, METADATA_PLAIN);
+
+ // TODO(xsdg): OPTIMIZATION Determine a heuristic for when to linear-search the
+ // keywords list, and when to build a hash table for the image's keywords.
+ gboolean should_reject = FALSE;
+ gchar *group_kw = NULL;
+ GList *filter_element = filter_elements;
+ while (filter_element)
+ {
+ PanViewFilterElement *filter = filter_element->data;
+ filter_element = filter_element->next;
+ gchar *found_kw = NULL;
+ gboolean has_kw = pan_view_list_contains_kw_pattern(img_keywords, filter, &found_kw);
+
+ switch (filter->mode)
+ {
+ case PAN_VIEW_FILTER_REQUIRE:
+ should_reject |= !has_kw;
+ break;
+ case PAN_VIEW_FILTER_EXCLUDE:
+ should_reject |= has_kw;
+ break;
+ case PAN_VIEW_FILTER_INCLUDE:
+ if (has_kw) should_reject = FALSE;
+ break;
+ case PAN_VIEW_FILTER_GROUP:
+ if (has_kw)
+ {
+ if (g_hash_table_contains(seen_kw_table, found_kw))
+ {
+ should_reject = TRUE;
+ }
+ else if (group_kw == NULL)
+ {
+ group_kw = found_kw;
+ }
+ }
+ break;
+ }
+ }
+
+ if (!should_reject && group_kw != NULL) g_hash_table_add(seen_kw_table, group_kw);
+
+ group_kw = NULL; // group_kw references an item from img_keywords.
+ string_list_free(img_keywords);
+
+ if (should_reject)
+ {
+ *fd_list = g_list_delete_link(*fd_list, last_work);
+ modified = TRUE;
+ }
+ }
+
+ g_hash_table_destroy(seen_kw_table);
+ return modified;
+}
--- /dev/null
+/*
+ * Copyright (C) 2006 John Ellis
+ * Copyright (C) 2008 - 2016 The Geeqie Team
+ *
+ * Author: John Ellis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef PAN_VIEW_PAN_VIEW_FILTER_H
+#define PAN_VIEW_PAN_VIEW_FILTER_H
+
+#include "main.h"
+#include "pan-types.h"
+
+typedef enum {
+ PAN_VIEW_FILTER_REQUIRE,
+ PAN_VIEW_FILTER_EXCLUDE,
+ PAN_VIEW_FILTER_INCLUDE,
+ PAN_VIEW_FILTER_GROUP
+} PanViewFilterMode;
+
+typedef struct _PanViewFilterElement PanViewFilterElement;
+struct _PanViewFilterElement
+{
+ PanViewFilterMode mode;
+ gchar *keyword;
+ GRegex *kw_regex;
+};
+
+typedef struct _PanFilterCallbackState PanFilterCallbackState;
+struct _PanFilterCallbackState
+{
+ PanWindow *pw;
+ GList *filter_element;
+};
+
+struct _PanViewFilterUi
+{
+ GtkWidget *filter_box;
+ GtkWidget *filter_entry;
+ GtkWidget *filter_label;
+ GtkWidget *filter_button;
+ GtkWidget *filter_button_arrow;
+ GtkWidget *filter_kw_hbox;
+ GtkListStore *filter_mode_model;
+ GtkWidget *filter_mode_combo;
+ GList *filter_elements; // List of PanViewFilterElement.
+};
+
+void pan_filter_toggle_visible(PanWindow *pw, gboolean enable);
+void pan_filter_activate(PanWindow *pw);
+void pan_filter_activate_cb(const gchar *text, gpointer data);
+void pan_filter_toggle_cb(GtkWidget *button, gpointer data);
+
+// Creates a new PanViewFilterUi instance and returns it.
+PanViewFilterUi *pan_filter_ui_new(PanWindow *pw);
+
+// Destroys the specified PanViewFilterUi and sets the pointer to NULL.
+void pan_filter_ui_destroy(PanViewFilterUi **ui);
+
+gboolean pan_filter_fd_list(GList **fd_list, GList *filter_elements);
+
+#endif
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
--- /dev/null
+/*
+ * Copyright (C) 2006 John Ellis
+ * Copyright (C) 2008 - 2016 The Geeqie Team
+ *
+ * Author: John Ellis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "pan-view-search.h"
+
+#include "image.h"
+#include "pan-calendar.h"
+#include "pan-item.h"
+#include "pan-util.h"
+#include "pan-view.h"
+#include "ui_tabcomp.h"
+#include "ui_misc.h"
+
+PanViewSearchUi *pan_search_ui_new(PanWindow *pw)
+{
+ PanViewSearchUi *ui = g_new0(PanViewSearchUi, 1);
+ GtkWidget *combo;
+ GtkWidget *hbox;
+
+ // Build the actual search UI.
+ ui->search_box = gtk_hbox_new(FALSE, PREF_PAD_SPACE);
+ pref_spacer(ui->search_box, 0);
+ pref_label_new(ui->search_box, _("Find:"));
+
+ hbox = gtk_hbox_new(TRUE, PREF_PAD_SPACE);
+ gtk_box_pack_start(GTK_BOX(ui->search_box), hbox, TRUE, TRUE, 0);
+ gtk_widget_show(hbox);
+
+ combo = tab_completion_new_with_history(&ui->search_entry, "", "pan_view_search", -1,
+ pan_search_activate_cb, pw);
+ gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, TRUE, 0);
+ gtk_widget_show(combo);
+
+ ui->search_label = gtk_label_new("");
+ gtk_box_pack_start(GTK_BOX(hbox), ui->search_label, TRUE, TRUE, 0);
+ gtk_widget_show(ui->search_label);
+
+ // Build the spin-button to show/hide the search UI.
+ ui->search_button = gtk_toggle_button_new();
+ gtk_button_set_relief(GTK_BUTTON(ui->search_button), GTK_RELIEF_NONE);
+ gtk_button_set_focus_on_click(GTK_BUTTON(ui->search_button), FALSE);
+ hbox = gtk_hbox_new(FALSE, PREF_PAD_GAP);
+ gtk_container_add(GTK_CONTAINER(ui->search_button), hbox);
+ gtk_widget_show(hbox);
+ ui->search_button_arrow = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_NONE);
+ gtk_box_pack_start(GTK_BOX(hbox), ui->search_button_arrow, FALSE, FALSE, 0);
+ gtk_widget_show(ui->search_button_arrow);
+ pref_label_new(hbox, _("Find"));
+
+ g_signal_connect(G_OBJECT(ui->search_button), "clicked",
+ G_CALLBACK(pan_search_toggle_cb), pw);
+
+ return ui;
+}
+
+void pan_search_ui_destroy(PanViewSearchUi **ui_ptr)
+{
+ if (ui_ptr == NULL || *ui_ptr == NULL) return;
+
+ g_free(*ui_ptr);
+ *ui_ptr = NULL;
+}
+
+static void pan_search_status(PanWindow *pw, const gchar *text)
+{
+ gtk_label_set_text(GTK_LABEL(pw->search_ui->search_label), (text) ? text : "");
+}
+
+static gint pan_search_by_path(PanWindow *pw, const gchar *path)
+{
+ PanItem *pi;
+ GList *list;
+ GList *found;
+ PanItemType type;
+ gchar *buf;
+
+ type = (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE) ? PAN_ITEM_IMAGE : PAN_ITEM_THUMB;
+
+ list = pan_item_find_by_path(pw, type, path, FALSE, FALSE);
+ if (!list) return FALSE;
+
+ found = g_list_find(list, pw->click_pi);
+ if (found && found->next)
+ {
+ found = found->next;
+ pi = found->data;
+ }
+ else
+ {
+ pi = list->data;
+ }
+
+ pan_info_update(pw, pi);
+ image_scroll_to_point(pw->imd, pi->x + pi->width / 2, pi->y + pi->height / 2, 0.5, 0.5);
+
+ buf = g_strdup_printf("%s ( %d / %d )",
+ (path[0] == G_DIR_SEPARATOR) ? _("path found") : _("filename found"),
+ g_list_index(list, pi) + 1,
+ g_list_length(list));
+ pan_search_status(pw, buf);
+ g_free(buf);
+
+ g_list_free(list);
+
+ return TRUE;
+}
+
+static gboolean pan_search_by_partial(PanWindow *pw, const gchar *text)
+{
+ PanItem *pi;
+ GList *list;
+ GList *found;
+ PanItemType type;
+ gchar *buf;
+
+ type = (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE) ? PAN_ITEM_IMAGE : PAN_ITEM_THUMB;
+
+ list = pan_item_find_by_path(pw, type, text, TRUE, FALSE);
+ if (!list) list = pan_item_find_by_path(pw, type, text, FALSE, TRUE);
+ if (!list)
+ {
+ gchar *needle;
+
+ needle = g_utf8_strdown(text, -1);
+ list = pan_item_find_by_path(pw, type, needle, TRUE, TRUE);
+ g_free(needle);
+ }
+ if (!list) return FALSE;
+
+ found = g_list_find(list, pw->click_pi);
+ if (found && found->next)
+ {
+ found = found->next;
+ pi = found->data;
+ }
+ else
+ {
+ pi = list->data;
+ }
+
+ pan_info_update(pw, pi);
+ image_scroll_to_point(pw->imd, pi->x + pi->width / 2, pi->y + pi->height / 2, 0.5, 0.5);
+
+ buf = g_strdup_printf("%s ( %d / %d )",
+ _("partial match"),
+ g_list_index(list, pi) + 1,
+ g_list_length(list));
+ pan_search_status(pw, buf);
+ g_free(buf);
+
+ g_list_free(list);
+
+ return TRUE;
+}
+
+static gboolean valid_date_separator(gchar c)
+{
+ return (c == '/' || c == '-' || c == ' ' || c == '.' || c == ',');
+}
+
+static GList *pan_search_by_date_val(PanWindow *pw, PanItemType type,
+ gint year, gint month, gint day,
+ const gchar *key)
+{
+ GList *list = NULL;
+ GList *work;
+
+ work = g_list_last(pw->list_static);
+ while (work)
+ {
+ PanItem *pi;
+
+ pi = work->data;
+ work = work->prev;
+
+ if (pi->fd && (pi->type == type || type == PAN_ITEM_NONE) &&
+ ((!key && !pi->key) || (key && pi->key && strcmp(key, pi->key) == 0)))
+ {
+ struct tm *tl;
+
+ tl = localtime(&pi->fd->date);
+ if (tl)
+ {
+ gint match;
+
+ match = (tl->tm_year == year - 1900);
+ if (match && month >= 0) match = (tl->tm_mon == month - 1);
+ if (match && day > 0) match = (tl->tm_mday == day);
+
+ if (match) list = g_list_prepend(list, pi);
+ }
+ }
+ }
+
+ return g_list_reverse(list);
+}
+
+static gboolean pan_search_by_date(PanWindow *pw, const gchar *text)
+{
+ PanItem *pi = NULL;
+ GList *list = NULL;
+ GList *found;
+ gint year;
+ gint month = -1;
+ gint day = -1;
+ gchar *ptr;
+ gchar *mptr;
+ struct tm *lt;
+ time_t t;
+ gchar *message;
+ gchar *buf;
+ gchar *buf_count;
+
+ if (!text) return FALSE;
+
+ ptr = (gchar *)text;
+ while (*ptr != '\0')
+ {
+ if (!g_unichar_isdigit(*ptr) && !valid_date_separator(*ptr)) return FALSE;
+ ptr++;
+ }
+
+ t = time(NULL);
+ if (t == -1) return FALSE;
+ lt = localtime(&t);
+ if (!lt) return FALSE;
+
+ if (valid_date_separator(*text))
+ {
+ year = -1;
+ mptr = (gchar *)text;
+ }
+ else
+ {
+ year = (gint)strtol(text, &mptr, 10);
+ if (mptr == text) return FALSE;
+ }
+
+ if (*mptr != '\0' && valid_date_separator(*mptr))
+ {
+ gchar *dptr;
+
+ mptr++;
+ month = strtol(mptr, &dptr, 10);
+ if (dptr == mptr)
+ {
+ if (valid_date_separator(*dptr))
+ {
+ month = lt->tm_mon + 1;
+ dptr++;
+ }
+ else
+ {
+ month = -1;
+ }
+ }
+ if (dptr != mptr && *dptr != '\0' && valid_date_separator(*dptr))
+ {
+ gchar *eptr;
+ dptr++;
+ day = strtol(dptr, &eptr, 10);
+ if (dptr == eptr)
+ {
+ day = lt->tm_mday;
+ }
+ }
+ }
+
+ if (year == -1)
+ {
+ year = lt->tm_year + 1900;
+ }
+ else if (year < 100)
+ {
+ if (year > 70)
+ year+= 1900;
+ else
+ year+= 2000;
+ }
+
+ if (year < 1970 ||
+ month < -1 || month == 0 || month > 12 ||
+ day < -1 || day == 0 || day > 31) return FALSE;
+
+ t = pan_date_to_time(year, month, day);
+ if (t < 0) return FALSE;
+
+ if (pw->layout == PAN_LAYOUT_CALENDAR)
+ {
+ list = pan_search_by_date_val(pw, PAN_ITEM_BOX, year, month, day, "day");
+ }
+ else
+ {
+ PanItemType type;
+
+ type = (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE) ? PAN_ITEM_IMAGE : PAN_ITEM_THUMB;
+ list = pan_search_by_date_val(pw, type, year, month, day, NULL);
+ }
+
+ if (list)
+ {
+ found = g_list_find(list, pw->search_pi);
+ if (found && found->next)
+ {
+ found = found->next;
+ pi = found->data;
+ }
+ else
+ {
+ pi = list->data;
+ }
+ }
+
+ pw->search_pi = pi;
+
+ if (pw->layout == PAN_LAYOUT_CALENDAR && pi && pi->type == PAN_ITEM_BOX)
+ {
+ pan_info_update(pw, NULL);
+ pan_calendar_update(pw, pi);
+ image_scroll_to_point(pw->imd,
+ pi->x + pi->width / 2,
+ pi->y + pi->height / 2, 0.5, 0.5);
+ }
+ else if (pi)
+ {
+ pan_info_update(pw, pi);
+ image_scroll_to_point(pw->imd,
+ pi->x - PAN_BOX_BORDER * 5 / 2,
+ pi->y, 0.0, 0.5);
+ }
+
+ if (month > 0)
+ {
+ buf = pan_date_value_string(t, PAN_DATE_LENGTH_MONTH);
+ if (day > 0)
+ {
+ gchar *tmp;
+ tmp = buf;
+ buf = g_strdup_printf("%d %s", day, tmp);
+ g_free(tmp);
+ }
+ }
+ else
+ {
+ buf = pan_date_value_string(t, PAN_DATE_LENGTH_YEAR);
+ }
+
+ if (pi)
+ {
+ buf_count = g_strdup_printf("( %d / %d )",
+ g_list_index(list, pi) + 1,
+ g_list_length(list));
+ }
+ else
+ {
+ buf_count = g_strdup_printf("(%s)", _("no match"));
+ }
+
+ message = g_strdup_printf("%s %s %s", _("Date:"), buf, buf_count);
+ g_free(buf);
+ g_free(buf_count);
+ pan_search_status(pw, message);
+ g_free(message);
+
+ g_list_free(list);
+
+ return TRUE;
+}
+
+void pan_search_activate_cb(const gchar *text, gpointer data)
+{
+ PanWindow *pw = data;
+
+ if (!text) return;
+
+ tab_completion_append_to_history(pw->search_ui->search_entry, text);
+
+ if (pan_search_by_path(pw, text)) return;
+
+ if ((pw->layout == PAN_LAYOUT_TIMELINE ||
+ pw->layout == PAN_LAYOUT_CALENDAR) &&
+ pan_search_by_date(pw, text))
+ {
+ return;
+ }
+
+ if (pan_search_by_partial(pw, text)) return;
+
+ pan_search_status(pw, _("no match"));
+}
+
+void pan_search_activate(PanWindow *pw)
+{
+ gchar *text;
+
+ text = g_strdup(gtk_entry_get_text(GTK_ENTRY(pw->search_ui->search_entry)));
+ pan_search_activate_cb(text, pw);
+ g_free(text);
+}
+
+void pan_search_toggle_cb(GtkWidget *button, gpointer data)
+{
+ PanWindow *pw = data;
+ PanViewSearchUi *ui = pw->search_ui;
+ gboolean visible;
+
+ visible = gtk_widget_get_visible(ui->search_box);
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)) == visible) return;
+
+ if (visible)
+ {
+ gtk_widget_hide(ui->search_box);
+ gtk_arrow_set(GTK_ARROW(ui->search_button_arrow), GTK_ARROW_UP, GTK_SHADOW_NONE);
+ }
+ else
+ {
+ gtk_widget_show(ui->search_box);
+ gtk_arrow_set(GTK_ARROW(ui->search_button_arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
+ gtk_widget_grab_focus(ui->search_entry);
+ }
+}
+
+void pan_search_toggle_visible(PanWindow *pw, gboolean enable)
+{
+ PanViewSearchUi *ui = pw->search_ui;
+ if (pw->fs) return;
+
+ if (enable)
+ {
+ if (gtk_widget_get_visible(ui->search_box))
+ {
+ gtk_widget_grab_focus(ui->search_entry);
+ }
+ else
+ {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->search_button), TRUE);
+ }
+ }
+ else
+ {
+ if (gtk_widget_get_visible(ui->search_entry))
+ {
+ if (gtk_widget_has_focus(ui->search_entry))
+ {
+ gtk_widget_grab_focus(GTK_WIDGET(pw->imd->widget));
+ }
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->search_button), FALSE);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2006 John Ellis
+ * Copyright (C) 2008 - 2016 The Geeqie Team
+ *
+ * Author: John Ellis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef PAN_VIEW_PAN_VIEW_SEARCH_H
+#define PAN_VIEW_PAN_VIEW_SEARCH_H
+
+#include "main.h"
+#include "pan-types.h"
+
+void pan_search_toggle_visible(PanWindow *pw, gboolean enable);
+void pan_search_activate(PanWindow *pw);
+void pan_search_activate_cb(const gchar *text, gpointer data);
+void pan_search_toggle_cb(GtkWidget *button, gpointer data);
+
+// Creates a new PanViewSearchUi instance and returns it.
+PanViewSearchUi *pan_search_ui_new(PanWindow *pw);
+
+// Destroys the specified PanViewSearchUi and sets the pointer to NULL.
+void pan_search_ui_destroy(PanViewSearchUi **ui);
+
+#endif
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
#include "pan-item.h"
#include "pan-timeline.h"
#include "pan-util.h"
+#include "pan-view-filter.h"
+#include "pan-view-search.h"
#include "pixbuf-renderer.h"
#include "pixbuf_util.h"
#include "thumb.h"
static void pan_fullscreen_toggle(PanWindow *pw, gboolean force_off);
-static void pan_search_toggle_visible(PanWindow *pw, gboolean enable);
-static void pan_search_activate(PanWindow *pw);
-
static void pan_window_close(PanWindow *pw);
static GtkWidget *pan_popup_menu(PanWindow *pw);
}
}
-static void pan_layout_update(PanWindow *pw)
+void pan_layout_update(PanWindow *pw)
{
pan_window_message(pw, _("Sorting images..."));
pan_layout_update_idle(pw);
imd_widget = gtk_container_get_focus_child(GTK_CONTAINER(pw->imd->widget));
focused = (pw->fs || (imd_widget && gtk_widget_has_focus(imd_widget)));
on_entry = (gtk_widget_has_focus(pw->path_entry) ||
- gtk_widget_has_focus(pw->search_entry));
+ gtk_widget_has_focus(pw->search_ui->search_entry) ||
+ gtk_widget_has_focus(pw->filter_ui->filter_entry));
if (focused)
{
if (stop_signal) return stop_signal;
+ // Don't steal characters from entry boxes.
if (!on_entry)
{
stop_signal = TRUE;
}
-static void pan_info_update(PanWindow *pw, PanItem *pi)
+void pan_info_update(PanWindow *pw, PanItem *pi)
{
PanTextAlignment *ta;
PanItem *pbox;
}
-/*
- *-----------------------------------------------------------------------------
- * search
- *-----------------------------------------------------------------------------
- */
-
-static void pan_search_status(PanWindow *pw, const gchar *text)
-{
- gtk_label_set_text(GTK_LABEL(pw->search_label), (text) ? text : "");
-}
-
-static gint pan_search_by_path(PanWindow *pw, const gchar *path)
-{
- PanItem *pi;
- GList *list;
- GList *found;
- PanItemType type;
- gchar *buf;
-
- type = (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE) ? PAN_ITEM_IMAGE : PAN_ITEM_THUMB;
-
- list = pan_item_find_by_path(pw, type, path, FALSE, FALSE);
- if (!list) return FALSE;
-
- found = g_list_find(list, pw->click_pi);
- if (found && found->next)
- {
- found = found->next;
- pi = found->data;
- }
- else
- {
- pi = list->data;
- }
-
- pan_info_update(pw, pi);
- image_scroll_to_point(pw->imd, pi->x + pi->width / 2, pi->y + pi->height / 2, 0.5, 0.5);
-
- buf = g_strdup_printf("%s ( %d / %d )",
- (path[0] == G_DIR_SEPARATOR) ? _("path found") : _("filename found"),
- g_list_index(list, pi) + 1,
- g_list_length(list));
- pan_search_status(pw, buf);
- g_free(buf);
-
- g_list_free(list);
-
- return TRUE;
-}
-
-static gboolean pan_search_by_partial(PanWindow *pw, const gchar *text)
-{
- PanItem *pi;
- GList *list;
- GList *found;
- PanItemType type;
- gchar *buf;
-
- type = (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE) ? PAN_ITEM_IMAGE : PAN_ITEM_THUMB;
-
- list = pan_item_find_by_path(pw, type, text, TRUE, FALSE);
- if (!list) list = pan_item_find_by_path(pw, type, text, FALSE, TRUE);
- if (!list)
- {
- gchar *needle;
-
- needle = g_utf8_strdown(text, -1);
- list = pan_item_find_by_path(pw, type, needle, TRUE, TRUE);
- g_free(needle);
- }
- if (!list) return FALSE;
-
- found = g_list_find(list, pw->click_pi);
- if (found && found->next)
- {
- found = found->next;
- pi = found->data;
- }
- else
- {
- pi = list->data;
- }
-
- pan_info_update(pw, pi);
- image_scroll_to_point(pw->imd, pi->x + pi->width / 2, pi->y + pi->height / 2, 0.5, 0.5);
-
- buf = g_strdup_printf("%s ( %d / %d )",
- _("partial match"),
- g_list_index(list, pi) + 1,
- g_list_length(list));
- pan_search_status(pw, buf);
- g_free(buf);
-
- g_list_free(list);
-
- return TRUE;
-}
-
-static gboolean valid_date_separator(gchar c)
-{
- return (c == '/' || c == '-' || c == ' ' || c == '.' || c == ',');
-}
-
-static GList *pan_search_by_date_val(PanWindow *pw, PanItemType type,
- gint year, gint month, gint day,
- const gchar *key)
-{
- GList *list = NULL;
- GList *work;
-
- work = g_list_last(pw->list_static);
- while (work)
- {
- PanItem *pi;
-
- pi = work->data;
- work = work->prev;
-
- if (pi->fd && (pi->type == type || type == PAN_ITEM_NONE) &&
- ((!key && !pi->key) || (key && pi->key && strcmp(key, pi->key) == 0)))
- {
- struct tm *tl;
-
- tl = localtime(&pi->fd->date);
- if (tl)
- {
- gint match;
-
- match = (tl->tm_year == year - 1900);
- if (match && month >= 0) match = (tl->tm_mon == month - 1);
- if (match && day > 0) match = (tl->tm_mday == day);
-
- if (match) list = g_list_prepend(list, pi);
- }
- }
- }
-
- return g_list_reverse(list);
-}
-
-static gboolean pan_search_by_date(PanWindow *pw, const gchar *text)
-{
- PanItem *pi = NULL;
- GList *list = NULL;
- GList *found;
- gint year;
- gint month = -1;
- gint day = -1;
- gchar *ptr;
- gchar *mptr;
- struct tm *lt;
- time_t t;
- gchar *message;
- gchar *buf;
- gchar *buf_count;
-
- if (!text) return FALSE;
-
- ptr = (gchar *)text;
- while (*ptr != '\0')
- {
- if (!g_unichar_isdigit(*ptr) && !valid_date_separator(*ptr)) return FALSE;
- ptr++;
- }
-
- t = time(NULL);
- if (t == -1) return FALSE;
- lt = localtime(&t);
- if (!lt) return FALSE;
-
- if (valid_date_separator(*text))
- {
- year = -1;
- mptr = (gchar *)text;
- }
- else
- {
- year = (gint)strtol(text, &mptr, 10);
- if (mptr == text) return FALSE;
- }
-
- if (*mptr != '\0' && valid_date_separator(*mptr))
- {
- gchar *dptr;
-
- mptr++;
- month = strtol(mptr, &dptr, 10);
- if (dptr == mptr)
- {
- if (valid_date_separator(*dptr))
- {
- month = lt->tm_mon + 1;
- dptr++;
- }
- else
- {
- month = -1;
- }
- }
- if (dptr != mptr && *dptr != '\0' && valid_date_separator(*dptr))
- {
- gchar *eptr;
- dptr++;
- day = strtol(dptr, &eptr, 10);
- if (dptr == eptr)
- {
- day = lt->tm_mday;
- }
- }
- }
-
- if (year == -1)
- {
- year = lt->tm_year + 1900;
- }
- else if (year < 100)
- {
- if (year > 70)
- year+= 1900;
- else
- year+= 2000;
- }
-
- if (year < 1970 ||
- month < -1 || month == 0 || month > 12 ||
- day < -1 || day == 0 || day > 31) return FALSE;
-
- t = pan_date_to_time(year, month, day);
- if (t < 0) return FALSE;
-
- if (pw->layout == PAN_LAYOUT_CALENDAR)
- {
- list = pan_search_by_date_val(pw, PAN_ITEM_BOX, year, month, day, "day");
- }
- else
- {
- PanItemType type;
-
- type = (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE) ? PAN_ITEM_IMAGE : PAN_ITEM_THUMB;
- list = pan_search_by_date_val(pw, type, year, month, day, NULL);
- }
-
- if (list)
- {
- found = g_list_find(list, pw->search_pi);
- if (found && found->next)
- {
- found = found->next;
- pi = found->data;
- }
- else
- {
- pi = list->data;
- }
- }
-
- pw->search_pi = pi;
-
- if (pw->layout == PAN_LAYOUT_CALENDAR && pi && pi->type == PAN_ITEM_BOX)
- {
- pan_info_update(pw, NULL);
- pan_calendar_update(pw, pi);
- image_scroll_to_point(pw->imd,
- pi->x + pi->width / 2,
- pi->y + pi->height / 2, 0.5, 0.5);
- }
- else if (pi)
- {
- pan_info_update(pw, pi);
- image_scroll_to_point(pw->imd,
- pi->x - PAN_BOX_BORDER * 5 / 2,
- pi->y, 0.0, 0.5);
- }
-
- if (month > 0)
- {
- buf = pan_date_value_string(t, PAN_DATE_LENGTH_MONTH);
- if (day > 0)
- {
- gchar *tmp;
- tmp = buf;
- buf = g_strdup_printf("%d %s", day, tmp);
- g_free(tmp);
- }
- }
- else
- {
- buf = pan_date_value_string(t, PAN_DATE_LENGTH_YEAR);
- }
-
- if (pi)
- {
- buf_count = g_strdup_printf("( %d / %d )",
- g_list_index(list, pi) + 1,
- g_list_length(list));
- }
- else
- {
- buf_count = g_strdup_printf("(%s)", _("no match"));
- }
-
- message = g_strdup_printf("%s %s %s", _("Date:"), buf, buf_count);
- g_free(buf);
- g_free(buf_count);
- pan_search_status(pw, message);
- g_free(message);
-
- g_list_free(list);
-
- return TRUE;
-}
-
-static void pan_search_activate_cb(const gchar *text, gpointer data)
-{
- PanWindow *pw = data;
-
- if (!text) return;
-
- tab_completion_append_to_history(pw->search_entry, text);
-
- if (pan_search_by_path(pw, text)) return;
-
- if ((pw->layout == PAN_LAYOUT_TIMELINE ||
- pw->layout == PAN_LAYOUT_CALENDAR) &&
- pan_search_by_date(pw, text))
- {
- return;
- }
-
- if (pan_search_by_partial(pw, text)) return;
-
- pan_search_status(pw, _("no match"));
-}
-
-static void pan_search_activate(PanWindow *pw)
-{
- gchar *text;
-
- text = g_strdup(gtk_entry_get_text(GTK_ENTRY(pw->search_entry)));
- pan_search_activate_cb(text, pw);
- g_free(text);
-}
-
-static void pan_search_toggle_cb(GtkWidget *button, gpointer data)
-{
- PanWindow *pw = data;
- gboolean visible;
-
- visible = gtk_widget_get_visible(pw->search_box);
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)) == visible) return;
-
- if (visible)
- {
- gtk_widget_hide(pw->search_box);
- gtk_arrow_set(GTK_ARROW(pw->search_button_arrow), GTK_ARROW_UP, GTK_SHADOW_NONE);
- }
- else
- {
- gtk_widget_show(pw->search_box);
- gtk_arrow_set(GTK_ARROW(pw->search_button_arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
- gtk_widget_grab_focus(pw->search_entry);
- }
-}
-
-static void pan_search_toggle_visible(PanWindow *pw, gboolean enable)
-{
- if (pw->fs) return;
-
- if (enable)
- {
- if (gtk_widget_get_visible(pw->search_box))
- {
- gtk_widget_grab_focus(pw->search_entry);
- }
- else
- {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pw->search_button), TRUE);
- }
- }
- else
- {
- if (gtk_widget_get_visible(pw->search_entry))
- {
- if (gtk_widget_has_focus(pw->search_entry))
- {
- gtk_widget_grab_focus(GTK_WIDGET(pw->imd->widget));
- }
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pw->search_button), FALSE);
- }
- }
-}
-
-
/*
*-----------------------------------------------------------------------------
* main window
}
pan_fullscreen_toggle(pw, TRUE);
+ pan_search_ui_destroy(&pw->search_ui);
+ pan_filter_ui_destroy(&pw->filter_ui);
gtk_widget_destroy(pw->window);
pan_window_items_free(pw);
/* find bar */
- pw->search_box = gtk_hbox_new(FALSE, PREF_PAD_SPACE);
- gtk_box_pack_start(GTK_BOX(vbox), pw->search_box, FALSE, FALSE, 2);
+ pw->search_ui = pan_search_ui_new(pw);
+ gtk_box_pack_start(GTK_BOX(vbox), pw->search_ui->search_box, FALSE, FALSE, 2);
- pref_spacer(pw->search_box, 0);
- pref_label_new(pw->search_box, _("Find:"));
-
- hbox = gtk_hbox_new(TRUE, PREF_PAD_SPACE);
- gtk_box_pack_start(GTK_BOX(pw->search_box), hbox, TRUE, TRUE, 0);
- gtk_widget_show(hbox);
-
- combo = tab_completion_new_with_history(&pw->search_entry, "", "pan_view_search", -1,
- pan_search_activate_cb, pw);
- gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, TRUE, 0);
- gtk_widget_show(combo);
-
- pw->search_label = gtk_label_new("");
- gtk_box_pack_start(GTK_BOX(hbox), pw->search_label, TRUE, TRUE, 0);
- gtk_widget_show(pw->search_label);
+ /* filter bar */
+ pw->filter_ui = pan_filter_ui_new(pw);
+ gtk_box_pack_start(GTK_BOX(vbox), pw->filter_ui->filter_box, FALSE, FALSE, 2);
/* status bar */
gtk_container_add(GTK_CONTAINER(frame), pw->label_zoom);
gtk_widget_show(pw->label_zoom);
- pw->search_button = gtk_toggle_button_new();
- gtk_button_set_relief(GTK_BUTTON(pw->search_button), GTK_RELIEF_NONE);
- gtk_button_set_focus_on_click(GTK_BUTTON(pw->search_button), FALSE);
- hbox = gtk_hbox_new(FALSE, PREF_PAD_GAP);
- gtk_container_add(GTK_CONTAINER(pw->search_button), hbox);
- gtk_widget_show(hbox);
- pw->search_button_arrow = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_NONE);
- gtk_box_pack_start(GTK_BOX(hbox), pw->search_button_arrow, FALSE, FALSE, 0);
- gtk_widget_show(pw->search_button_arrow);
- pref_label_new(hbox, _("Find"));
-
- gtk_box_pack_end(GTK_BOX(box), pw->search_button, FALSE, FALSE, 0);
- gtk_widget_show(pw->search_button);
- g_signal_connect(G_OBJECT(pw->search_button), "clicked",
- G_CALLBACK(pan_search_toggle_cb), pw);
+ // Add the "Find" button to the status bar area.
+ gtk_box_pack_end(GTK_BOX(box), pw->search_ui->search_button, FALSE, FALSE, 0);
+ gtk_widget_show(pw->search_ui->search_button);
+
+ // Add the "Filter" button to the status bar area.
+ gtk_box_pack_end(GTK_BOX(box), pw->filter_ui->filter_button, FALSE, FALSE, 0);
+ gtk_widget_show(pw->filter_ui->filter_button);
g_signal_connect(G_OBJECT(pw->window), "delete_event",
G_CALLBACK(pan_window_delete_cb), pw);
#include "main.h"
#include "pan-types.h"
+void pan_layout_update(PanWindow *pw);
GList *pan_layout_intersect(PanWindow *pw, gint x, gint y, gint width, gint height);
void pan_layout_resize(PanWindow *pw);
GList *pan_cache_sort(GList *list, SortType method, gboolean ascend);
+void pan_info_update(PanWindow *pw, PanItem *pi);
#endif
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
#define MAX_SPLIT_IMAGES 4
+typedef enum {
+ SELECTION_NONE = 0,
+ SELECTION_SELECTED = 1 << 0,
+ SELECTION_PRELIGHT = 1 << 1,
+ SELECTION_FOCUS = 1 << 2
+} SelectionType;
+
typedef struct _ImageLoader ImageLoader;
typedef struct _ThumbLoader ThumbLoader;
GHashTable *modified_xmp; // hash table which contains unwritten xmp metadata in format: key->list of string values
GList *cached_metadata;
gint rating;
+
+ SelectionType selected; // Used by view_file_icon.
};
struct _LayoutOptions
struct _ViewFile
{
FileViewType type;
+ // TODO(xsdg): Turn this into a union (see VFLIST and VFICON from view_file.h).
gpointer info;
GtkWidget *widget;
guint select_idle_id; /* event source id */
};
-typedef enum {
- SELECTION_NONE = 0,
- SELECTION_SELECTED = 1 << 0,
- SELECTION_PRELIGHT = 1 << 1,
- SELECTION_FOCUS = 1 << 2
-} SelectionType;
-
-typedef struct _IconData IconData;
-struct _IconData
-{
- SelectionType selected;
- FileData *fd;
-};
-
struct _ViewFileInfoIcon
{
/* table stuff */
gint rows;
GList *selection;
- struct _IconData *prev_selection;
+ FileData *prev_selection;
GtkWidget *tip_window;
guint tip_delay_id; /* event source id */
- struct _IconData *tip_id;
+ FileData *tip_fd;
- struct _IconData *click_id;
+ FileData *click_fd;
- struct _IconData *focus_id;
+ FileData *focus_fd;
gint focus_row;
gint focus_column;
#include "ui_menu.h"
#include "ui_fileops.h"
#include "utilops.h"
-#include "view_file_list.h"
-#include "view_file_icon.h"
+#include "view_file/view_file_list.h"
+#include "view_file/view_file_icon.h"
/*
*-----------------------------------------------------------------------------
active = (VFLIST(vf)->click_fd != NULL);
break;
case FILEVIEW_ICON:
- active = (VFICON(vf)->click_id != NULL);
+ active = (VFICON(vf)->click_fd != NULL);
break;
}
--- /dev/null
+module_view_file = \
+ %D%/view_file_icon.c \
+ %D%/view_file_icon.h \
+ %D%/view_file_list.c \
+ %D%/view_file_list.h
--- /dev/null
+/*
+ * This file is a part of Geeqie project (http://www.geeqie.org/).
+ * Copyright (C) 2008 - 2016 The Geeqie Team
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+guint vfcommon_count(ViewFile *vf, gint64 *bytes)
+{
+ if (bytes)
+ {
+ gint64 b = 0;
+ GList *work;
+
+ work = vf->list;
+ while (work)
+ {
+ FileData *fd = work->data;
+ work = work->next;
+
+ b += fd->size;
+ }
+
+ *bytes = b;
+ }
+
+ return g_list_length(vf->list);
+}
+
FILE_COLUMN_COUNT
};
-static gint vficon_index_by_id(ViewFile *vf, IconData *in_id);
-
-static IconData *vficon_icon_data(ViewFile *vf, FileData *fd)
-{
- IconData *id = NULL;
- GList *work;
-
- if (!fd) return NULL;
- work = vf->list;
- while (work && !id)
- {
- IconData *chk = work->data;
- work = work->next;
- if (chk->fd == fd) id = chk;
- }
- return id;
-}
-
-static void iconlist_free(GList *list)
-{
- GList *work = list;
- while (work)
- {
- IconData *id = work->data;
- file_data_unref(id->fd);
- g_free(id);
- work = work->next;
- }
-
- g_list_free(list);
-
-}
-
-gint iconlist_sort_file_cb(gpointer a, gpointer b)
-{
- IconData *ida = a;
- IconData *idb = b;
- return filelist_sort_compare_filedata(ida->fd, idb->fd);
-}
-
-GList *iconlist_sort(GList *list, SortType method, gboolean ascend)
-{
- return filelist_sort_full(list, method, ascend, (GCompareFunc) iconlist_sort_file_cb);
-}
-
-GList *iconlist_insert_sort(GList *list, IconData *id, SortType method, gboolean ascend)
-{
- return filelist_insert_sort_full(list, id, method, ascend, (GCompareFunc) iconlist_sort_file_cb);
-}
-
-
static void vficon_toggle_filenames(ViewFile *vf);
-static void vficon_selection_remove(ViewFile *vf, IconData *id, SelectionType mask, GtkTreeIter *iter);
+static void vficon_selection_remove(ViewFile *vf, FileData *id, SelectionType mask, GtkTreeIter *iter);
static void vficon_move_focus(ViewFile *vf, gint row, gint col, gboolean relative);
-static void vficon_set_focus(ViewFile *vf, IconData *id);
+static void vficon_set_focus(ViewFile *vf, FileData *fd);
static void vficon_populate_at_new_size(ViewFile *vf, gint w, gint h, gboolean force);
GList *vficon_pop_menu_file_list(ViewFile *vf)
{
- if (!VFICON(vf)->click_id) return NULL;
+ if (!VFICON(vf)->click_fd) return NULL;
- if (VFICON(vf)->click_id->selected & SELECTION_SELECTED)
+ if (VFICON(vf)->click_fd->selected & SELECTION_SELECTED)
{
return vf_selection_get_list(vf);
}
- return vficon_selection_get_one(vf, VFICON(vf)->click_id->fd);
+ return vficon_selection_get_one(vf, VFICON(vf)->click_fd);
}
void vficon_pop_menu_view_cb(GtkWidget *widget, gpointer data)
{
ViewFile *vf = data;
- if (!VFICON(vf)->click_id) return;
+ if (!VFICON(vf)->click_fd) return;
- if (VFICON(vf)->click_id->selected & SELECTION_SELECTED)
+ if (VFICON(vf)->click_fd->selected & SELECTION_SELECTED)
{
GList *list;
}
else
{
- view_window_new(VFICON(vf)->click_id->fd);
+ view_window_new(VFICON(vf)->click_fd);
}
}
void vficon_popup_destroy_cb(GtkWidget *widget, gpointer data)
{
ViewFile *vf = data;
- vficon_selection_remove(vf, VFICON(vf)->click_id, SELECTION_PRELIGHT, NULL);
- VFICON(vf)->click_id = NULL;
+ vficon_selection_remove(vf, VFICON(vf)->click_fd, SELECTION_PRELIGHT, NULL);
+ VFICON(vf)->click_fd = NULL;
vf->popup = NULL;
}
*-------------------------------------------------------------------
*/
-static void vficon_send_layout_select(ViewFile *vf, IconData *id)
+static void vficon_send_layout_select(ViewFile *vf, FileData *fd)
{
FileData *read_ahead_fd = NULL;
FileData *sel_fd;
FileData *cur_fd;
- if (!vf->layout || !id || !id->fd) return;
+ if (!vf->layout || !fd) return;
- sel_fd = id->fd;
+ sel_fd = fd;
cur_fd = layout_image_get_fd(vf->layout);
if (sel_fd == cur_fd) return; /* no change */
{
gint row;
- row = g_list_index(vf->list, id);
+ row = g_list_index(vf->list, fd);
if (row > vficon_index_by_fd(vf, cur_fd) &&
(guint) (row + 1) < vf_count(vf, NULL))
{
*-------------------------------------------------------------------
*/
-static gboolean vficon_find_position(ViewFile *vf, IconData *id, gint *row, gint *col)
+static gboolean vficon_find_position(ViewFile *vf, FileData *fd, gint *row, gint *col)
{
gint n;
- n = g_list_index(vf->list, id);
+ n = g_list_index(vf->list, fd);
if (n < 0) return FALSE;
return TRUE;
}
-static gboolean vficon_find_iter(ViewFile *vf, IconData *id, GtkTreeIter *iter, gint *column)
+static gboolean vficon_find_iter(ViewFile *vf, FileData *fd, GtkTreeIter *iter, gint *column)
{
GtkTreeModel *store;
gint row, col;
store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview));
- if (!vficon_find_position(vf, id, &row, &col)) return FALSE;
+ if (!vficon_find_position(vf, fd, &row, &col)) return FALSE;
if (!gtk_tree_model_iter_nth_child(store, iter, NULL, row)) return FALSE;
if (column) *column = col;
return TRUE;
}
-static IconData *vficon_find_data(ViewFile *vf, gint row, gint col, GtkTreeIter *iter)
+static FileData *vficon_find_data(ViewFile *vf, gint row, gint col, GtkTreeIter *iter)
{
GtkTreeModel *store;
GtkTreeIter p;
return NULL;
}
-static IconData *vficon_find_data_by_coord(ViewFile *vf, gint x, gint y, GtkTreeIter *iter)
+static FileData *vficon_find_data_by_coord(ViewFile *vf, gint x, gint y, GtkTreeIter *iter)
{
GtkTreePath *tpath;
GtkTreeViewColumn *column;
gint column;
GList *list;
guint toggled_mark;
- IconData *id;
+ FileData *fd;
store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview));
- if (!path || !gtk_tree_model_get_iter(store, &row, path))
- return;
+ if (!path || !gtk_tree_model_get_iter(store, &row, path)) return;
gtk_tree_model_get(store, &row, FILE_COLUMN_POINTER, &list, -1);
column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell), "column_number"));
g_object_get(G_OBJECT(cell), "toggled_mark", &toggled_mark, NULL);
- id = g_list_nth_data(list, column);
- if (id)
+ fd = g_list_nth_data(list, column);
+ if (fd)
{
- FileData *fd = id->fd;
file_data_set_mark(fd, toggled_mark, !file_data_get_mark(fd, toggled_mark));
}
}
gdk_window_get_pointer(gtk_tree_view_get_bin_window(GTK_TREE_VIEW(vf->listview)), &x, &y, NULL);
#endif
- VFICON(vf)->tip_id = vficon_find_data_by_coord(vf, x, y, NULL);
- if (!VFICON(vf)->tip_id) return;
+ VFICON(vf)->tip_fd = vficon_find_data_by_coord(vf, x, y, NULL);
+ if (!VFICON(vf)->tip_fd) return;
VFICON(vf)->tip_window = gtk_window_new(GTK_WINDOW_POPUP);
gtk_window_set_resizable(GTK_WINDOW(VFICON(vf)->tip_window), FALSE);
gtk_container_set_border_width(GTK_CONTAINER(VFICON(vf)->tip_window), 2);
- label = gtk_label_new(VFICON(vf)->tip_id->fd->name);
+ label = gtk_label_new(VFICON(vf)->tip_fd->name);
g_object_set_data(G_OBJECT(VFICON(vf)->tip_window), "tip_label", label);
gtk_container_add(GTK_CONTAINER(VFICON(vf)->tip_window), label);
}
}
-static void tip_update(ViewFile *vf, IconData *id)
+static void tip_update(ViewFile *vf, FileData *fd)
{
#if GTK_CHECK_VERSION(3,0,0)
GdkDisplay *display = gdk_display_get_default();
#endif
gtk_window_move(GTK_WINDOW(VFICON(vf)->tip_window), x + 16, y + 16);
- if (id != VFICON(vf)->tip_id)
+ if (fd != VFICON(vf)->tip_fd)
{
GtkWidget *label;
- VFICON(vf)->tip_id = id;
+ VFICON(vf)->tip_fd = fd;
- if (!VFICON(vf)->tip_id)
+ if (!VFICON(vf)->tip_fd)
{
tip_hide(vf);
tip_schedule(vf);
}
label = g_object_get_data(G_OBJECT(VFICON(vf)->tip_window), "tip_label");
- gtk_label_set_text(GTK_LABEL(label), VFICON(vf)->tip_id->fd->name);
+ gtk_label_set_text(GTK_LABEL(label), VFICON(vf)->tip_fd->name);
}
}
else
ViewFile *vf = data;
GList *list = NULL;
- if (!VFICON(vf)->click_id) return;
+ if (!VFICON(vf)->click_fd) return;
- if (VFICON(vf)->click_id->selected & SELECTION_SELECTED)
+ if (VFICON(vf)->click_fd->selected & SELECTION_SELECTED)
{
list = vf_selection_get_list(vf);
}
else
{
- list = g_list_append(NULL, file_data_ref(VFICON(vf)->click_id->fd));
+ list = g_list_append(NULL, file_data_ref(VFICON(vf)->click_fd));
}
if (!list) return;
ViewFile *vf = data;
if (info == TARGET_TEXT_PLAIN) {
- IconData *id = vficon_find_data_by_coord(vf, x, y, NULL);
+ FileData *fd = vficon_find_data_by_coord(vf, x, y, NULL);
- if (id && id->fd) {
+ if (fd) {
/* Add keywords to file */
- FileData *fd = id->fd;
gchar *str = (gchar *) gtk_selection_data_get_text(selection);
GList *kw_list = string_to_keywords_list(str);
tip_unschedule(vf);
- if (VFICON(vf)->click_id && VFICON(vf)->click_id->fd->thumb_pixbuf)
+ if (VFICON(vf)->click_fd && VFICON(vf)->click_fd->thumb_pixbuf)
{
gint items;
- if (VFICON(vf)->click_id->selected & SELECTION_SELECTED)
+ if (VFICON(vf)->click_fd->selected & SELECTION_SELECTED)
items = g_list_length(VFICON(vf)->selection);
else
items = 1;
- dnd_set_drag_icon(widget, context, VFICON(vf)->click_id->fd->thumb_pixbuf, items);
+ dnd_set_drag_icon(widget, context, VFICON(vf)->click_fd->thumb_pixbuf, items);
}
}
{
ViewFile *vf = data;
- vficon_selection_remove(vf, VFICON(vf)->click_id, SELECTION_PRELIGHT, NULL);
+ vficon_selection_remove(vf, VFICON(vf)->click_fd, SELECTION_PRELIGHT, NULL);
if (gdk_drag_context_get_selected_action(context) == GDK_ACTION_MOVE)
{
*-------------------------------------------------------------------
*/
-static void vficon_selection_set(ViewFile *vf, IconData *id, SelectionType value, GtkTreeIter *iter)
+static void vficon_selection_set(ViewFile *vf, FileData *fd, SelectionType value, GtkTreeIter *iter)
{
GtkTreeModel *store;
GList *list;
- if (!id) return;
-
+ if (!fd) return;
- if (id->selected == value) return;
- id->selected = value;
+ if (fd->selected == value) return;
+ fd->selected = value;
store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview));
if (iter)
{
GtkTreeIter row;
- if (vficon_find_iter(vf, id, &row, NULL))
+ if (vficon_find_iter(vf, fd, &row, NULL))
{
gtk_tree_model_get(store, &row, FILE_COLUMN_POINTER, &list, -1);
if (list) gtk_list_store_set(GTK_LIST_STORE(store), &row, FILE_COLUMN_POINTER, list, -1);
}
}
-static void vficon_selection_add(ViewFile *vf, IconData *id, SelectionType mask, GtkTreeIter *iter)
+static void vficon_selection_add(ViewFile *vf, FileData *fd, SelectionType mask, GtkTreeIter *iter)
{
- if (!id) return;
+ if (!fd) return;
- vficon_selection_set(vf, id, id->selected | mask, iter);
+ vficon_selection_set(vf, fd, fd->selected | mask, iter);
}
-static void vficon_selection_remove(ViewFile *vf, IconData *id, SelectionType mask, GtkTreeIter *iter)
+static void vficon_selection_remove(ViewFile *vf, FileData *fd, SelectionType mask, GtkTreeIter *iter)
{
- if (!id) return;
+ if (!fd) return;
- vficon_selection_set(vf, id, id->selected & ~mask, iter);
+ vficon_selection_set(vf, fd, fd->selected & ~mask, iter);
}
void vficon_marks_set(ViewFile *vf, gint enable)
work = VFICON(vf)->selection;
while (work)
{
- IconData *id = work->data;
+ FileData *fd = work->data;
work = work->next;
- if (vficon_index_by_id(vf, id) >= 0) continue;
+ if (vficon_index_by_fd(vf, fd) >= 0) continue;
- VFICON(vf)->selection = g_list_remove(VFICON(vf)->selection, id);
+ VFICON(vf)->selection = g_list_remove(VFICON(vf)->selection, fd);
}
}
work = vf->list;
while (work)
{
- IconData *id = work->data;
+ FileData *fd = work->data;
work = work->next;
- VFICON(vf)->selection = g_list_append(VFICON(vf)->selection, id);
- vficon_selection_add(vf, id, SELECTION_SELECTED, NULL);
+ VFICON(vf)->selection = g_list_append(VFICON(vf)->selection, fd);
+ vficon_selection_add(vf, fd, SELECTION_SELECTED, NULL);
}
vf_send_update(vf);
work = VFICON(vf)->selection;
while (work)
{
- IconData *id = work->data;
+ FileData *fd = work->data;
work = work->next;
- vficon_selection_remove(vf, id, SELECTION_SELECTED, NULL);
+ vficon_selection_remove(vf, fd, SELECTION_SELECTED, NULL);
}
g_list_free(VFICON(vf)->selection);
work = vf->list;
while (work)
{
- IconData *id = work->data;
+ FileData *fd = work->data;
work = work->next;
- if (id->selected & SELECTION_SELECTED)
+ if (fd->selected & SELECTION_SELECTED)
{
- VFICON(vf)->selection = g_list_remove(VFICON(vf)->selection, id);
- vficon_selection_remove(vf, id, SELECTION_SELECTED, NULL);
+ VFICON(vf)->selection = g_list_remove(VFICON(vf)->selection, fd);
+ vficon_selection_remove(vf, fd, SELECTION_SELECTED, NULL);
}
else
{
- VFICON(vf)->selection = g_list_append(VFICON(vf)->selection, id);
- vficon_selection_add(vf, id, SELECTION_SELECTED, NULL);
+ VFICON(vf)->selection = g_list_append(VFICON(vf)->selection, fd);
+ vficon_selection_add(vf, fd, SELECTION_SELECTED, NULL);
}
}
vf_send_update(vf);
}
-static void vficon_select(ViewFile *vf, IconData *id)
+static void vficon_select(ViewFile *vf, FileData *fd)
{
- VFICON(vf)->prev_selection = id;
+ VFICON(vf)->prev_selection = fd;
- if (!id || id->selected & SELECTION_SELECTED) return;
+ if (!fd || fd->selected & SELECTION_SELECTED) return;
- VFICON(vf)->selection = g_list_append(VFICON(vf)->selection, id);
- vficon_selection_add(vf, id, SELECTION_SELECTED, NULL);
+ VFICON(vf)->selection = g_list_append(VFICON(vf)->selection, fd);
+ vficon_selection_add(vf, fd, SELECTION_SELECTED, NULL);
vf_send_update(vf);
}
-static void vficon_unselect(ViewFile *vf, IconData *id)
+static void vficon_unselect(ViewFile *vf, FileData *fd)
{
- VFICON(vf)->prev_selection = id;
+ VFICON(vf)->prev_selection = fd;
- if (!id || !(id->selected & SELECTION_SELECTED) ) return;
+ if (!fd || !(fd->selected & SELECTION_SELECTED) ) return;
- VFICON(vf)->selection = g_list_remove(VFICON(vf)->selection, id);
- vficon_selection_remove(vf, id, SELECTION_SELECTED, NULL);
+ VFICON(vf)->selection = g_list_remove(VFICON(vf)->selection, fd);
+ vficon_selection_remove(vf, fd, SELECTION_SELECTED, NULL);
vf_send_update(vf);
}
-static void vficon_select_util(ViewFile *vf, IconData *id, gboolean select)
+static void vficon_select_util(ViewFile *vf, FileData *fd, gboolean select)
{
if (select)
{
- vficon_select(vf, id);
+ vficon_select(vf, fd);
}
else
{
- vficon_unselect(vf, id);
+ vficon_unselect(vf, fd);
}
}
-static void vficon_select_region_util(ViewFile *vf, IconData *start, IconData *end, gboolean select)
+static void vficon_select_region_util(ViewFile *vf, FileData *start, FileData *end, gboolean select)
{
gint row1, col1;
gint row2, col2;
if (!options->collections.rectangular_selection)
{
GList *work;
- IconData *id;
if (g_list_index(vf->list, start) > g_list_index(vf->list, end))
{
- id = start;
+ FileData *tmp = start;
start = end;
- end = id;
+ end = tmp;
}
work = g_list_find(vf->list, start);
while (work)
{
- id = work->data;
- vficon_select_util(vf, id, select);
+ FileData *fd = work->data;
+ vficon_select_util(vf, fd, select);
if (work->data != end)
work = work->next;
return;
}
+ // rectangular_selection==true.
if (row2 < row1)
{
t = row1;
{
for (j = col1; j <= col2; j++)
{
- IconData *id = vficon_find_data(vf, i, j, NULL);
- if (id) vficon_select_util(vf, id, select);
+ FileData *fd = vficon_find_data(vf, i, j, NULL);
+ if (fd) vficon_select_util(vf, fd, select);
}
}
}
gboolean vficon_index_is_selected(ViewFile *vf, gint row)
{
- IconData *id = g_list_nth_data(vf->list, row);
+ FileData *fd = g_list_nth_data(vf->list, row);
- if (!id) return FALSE;
+ if (!fd) return FALSE;
- return (id->selected & SELECTION_SELECTED);
+ return (fd->selected & SELECTION_SELECTED);
}
guint vficon_selection_count(ViewFile *vf, gint64 *bytes)
work = VFICON(vf)->selection;
while (work)
{
- IconData *id = work->data;
- FileData *fd = id->fd;
+ FileData *fd = work->data;
g_assert(fd->magick == FD_MAGICK);
b += fd->size;
work = VFICON(vf)->selection;
while (work)
{
- IconData *id = work->data;
- FileData *fd = id->fd;
+ FileData *fd = work->data;
g_assert(fd->magick == FD_MAGICK);
list = g_list_prepend(list, file_data_ref(fd));
return g_list_reverse(list);
}
-static void vficon_select_by_id(ViewFile *vf, IconData *id)
+void vficon_select_by_fd(ViewFile *vf, FileData *fd)
{
- if (!id) return;
+ if (!fd) return;
+ if (!g_list_find(vf->list, fd)) return;
- if (!(id->selected & SELECTION_SELECTED))
+ if (!(fd->selected & SELECTION_SELECTED))
{
vf_select_none(vf);
- vficon_select(vf, id);
+ vficon_select(vf, fd);
}
- vficon_set_focus(vf, id);
-}
-
-void vficon_select_by_fd(ViewFile *vf, FileData *fd)
-{
- IconData *id = NULL;
- GList *work;
-
- if (!fd) return;
- work = vf->list;
- while (work && !id)
- {
- IconData *chk = work->data;
- work = work->next;
- if (chk->fd == fd) id = chk;
- }
- vficon_select_by_id(vf, id);
+ vficon_set_focus(vf, fd);
}
void vficon_mark_to_selection(ViewFile *vf, gint mark, MarkToSelectionMode mode)
work = vf->list;
while (work)
{
- IconData *id = work->data;
- FileData *fd = id->fd;
+ FileData *fd = work->data;
gboolean mark_val, selected;
g_assert(fd->magick == FD_MAGICK);
mark_val = file_data_get_mark(fd, n);
- selected = (id->selected & SELECTION_SELECTED);
+ selected = fd->selected & SELECTION_SELECTED;
switch (mode)
{
break;
}
- vficon_select_util(vf, id, selected);
+ vficon_select_util(vf, fd, selected);
work = work->next;
}
static void vficon_select_closest(ViewFile *vf, FileData *sel_fd)
{
GList *work;
- IconData *id = NULL;
+ FileData *fd = NULL;
if (sel_fd->parent) sel_fd = sel_fd->parent;
work = vf->list;
while (work)
{
gint match;
- FileData *fd;
- id = work->data;
- fd = id->fd;
+ fd = work->data;
work = work->next;
match = filelist_sort_compare_filedata_full(fd, sel_fd, vf->sort_method, vf->sort_ascend);
if (match >= 0) break;
}
- if (id)
+ if (fd)
{
- vficon_select(vf, id);
- vficon_send_layout_select(vf, id);
+ vficon_select(vf, fd);
+ vficon_send_layout_select(vf, fd);
}
}
vficon_set_focus(vf, vficon_find_data(vf, new_row, new_col, NULL));
}
-static void vficon_set_focus(ViewFile *vf, IconData *id)
+static void vficon_set_focus(ViewFile *vf, FileData *fd)
{
GtkTreeIter iter;
gint row, col;
- if (g_list_find(vf->list, VFICON(vf)->focus_id))
+ if (g_list_find(vf->list, VFICON(vf)->focus_fd))
{
- if (id == VFICON(vf)->focus_id)
+ if (fd == VFICON(vf)->focus_fd)
{
/* ensure focus row col are correct */
- vficon_find_position(vf, VFICON(vf)->focus_id, &VFICON(vf)->focus_row, &VFICON(vf)->focus_column);
+ 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
* preserved when the icon view is refreshed. Caused by an unknown call from
* the idle loop. This patch hides the problem.
*/
- if (vficon_find_iter(vf, VFICON(vf)->focus_id, &iter, NULL))
+ if (vficon_find_iter(vf, VFICON(vf)->focus_fd, &iter, NULL))
{
tree_view_row_make_visible(GTK_TREE_VIEW(vf->listview), &iter, FALSE);
}
#endif
return;
}
- vficon_selection_remove(vf, VFICON(vf)->focus_id, SELECTION_FOCUS, NULL);
+ vficon_selection_remove(vf, VFICON(vf)->focus_fd, SELECTION_FOCUS, NULL);
}
- if (!vficon_find_position(vf, id, &row, &col))
+ if (!vficon_find_position(vf, fd, &row, &col))
{
- VFICON(vf)->focus_id = NULL;
+ VFICON(vf)->focus_fd = NULL;
VFICON(vf)->focus_row = -1;
VFICON(vf)->focus_column = -1;
return;
}
- VFICON(vf)->focus_id = id;
+ VFICON(vf)->focus_fd = fd;
VFICON(vf)->focus_row = row;
VFICON(vf)->focus_column = col;
- vficon_selection_add(vf, VFICON(vf)->focus_id, SELECTION_FOCUS, NULL);
+ vficon_selection_add(vf, VFICON(vf)->focus_fd, SELECTION_FOCUS, NULL);
- if (vficon_find_iter(vf, VFICON(vf)->focus_id, &iter, NULL))
+ if (vficon_find_iter(vf, VFICON(vf)->focus_fd, &iter, NULL))
{
GtkTreePath *tpath;
GtkTreeViewColumn *column;
GtkTreePath *tpath;
gint cw, ch;
- if (!vficon_find_iter(vf, VFICON(vf)->click_id, &iter, &column)) return;
+ if (!vficon_find_iter(vf, VFICON(vf)->click_fd, &iter, &column)) return;
store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview));
tpath = gtk_tree_model_get_path(store, &iter);
tree_view_get_cell_clamped(GTK_TREE_VIEW(vf->listview), tpath, column, FALSE, x, y, &cw, &ch);
ViewFile *vf = data;
gint focus_row = 0;
gint focus_col = 0;
- IconData *id;
+ FileData *fd;
gboolean stop_signal;
stop_signal = TRUE;
focus_col = VFICON(vf)->columns - 1 - VFICON(vf)->focus_column;
break;
case GDK_KEY_space:
- id = vficon_find_data(vf, VFICON(vf)->focus_row, VFICON(vf)->focus_column, NULL);
- if (id)
+ fd = vficon_find_data(vf, VFICON(vf)->focus_row, VFICON(vf)->focus_column, NULL);
+ if (fd)
{
- VFICON(vf)->click_id = id;
+ VFICON(vf)->click_fd = fd;
if (event->state & GDK_CONTROL_MASK)
{
gint selected;
- selected = id->selected & SELECTION_SELECTED;
+ selected = fd->selected & SELECTION_SELECTED;
if (selected)
{
- vficon_unselect(vf, id);
+ vficon_unselect(vf, fd);
}
else
{
- vficon_select(vf, id);
- vficon_send_layout_select(vf, id);
+ vficon_select(vf, fd);
+ vficon_send_layout_select(vf, fd);
}
}
else
{
vf_select_none(vf);
- vficon_select(vf, id);
- vficon_send_layout_select(vf, id);
+ vficon_select(vf, fd);
+ vficon_send_layout_select(vf, fd);
}
}
break;
case GDK_KEY_Menu:
- id = vficon_find_data(vf, VFICON(vf)->focus_row, VFICON(vf)->focus_column, NULL);
- VFICON(vf)->click_id = id;
+ fd = vficon_find_data(vf, VFICON(vf)->focus_row, VFICON(vf)->focus_column, NULL);
+ VFICON(vf)->click_fd = fd;
- vficon_selection_add(vf, VFICON(vf)->click_id, SELECTION_PRELIGHT, NULL);
+ vficon_selection_add(vf, VFICON(vf)->click_fd, SELECTION_PRELIGHT, NULL);
tip_unschedule(vf);
vf->popup = vf_pop_menu(vf);
if (focus_row != 0 || focus_col != 0)
{
- IconData *new_id;
- IconData *old_id;
+ FileData *new_fd;
+ FileData *old_fd;
- old_id = vficon_find_data(vf, VFICON(vf)->focus_row, VFICON(vf)->focus_column, NULL);
+ old_fd = vficon_find_data(vf, VFICON(vf)->focus_row, VFICON(vf)->focus_column, NULL);
vficon_move_focus(vf, focus_row, focus_col, TRUE);
- new_id = vficon_find_data(vf, VFICON(vf)->focus_row, VFICON(vf)->focus_column, NULL);
+ new_fd = vficon_find_data(vf, VFICON(vf)->focus_row, VFICON(vf)->focus_column, NULL);
- if (new_id != old_id)
+ if (new_fd != old_fd)
{
if (event->state & GDK_SHIFT_MASK)
{
if (!options->collections.rectangular_selection)
{
- vficon_select_region_util(vf, old_id, new_id, FALSE);
+ vficon_select_region_util(vf, old_fd, new_fd, FALSE);
}
else
{
- vficon_select_region_util(vf, VFICON(vf)->click_id, old_id, FALSE);
+ vficon_select_region_util(vf, VFICON(vf)->click_fd, old_fd, FALSE);
}
- vficon_select_region_util(vf, VFICON(vf)->click_id, new_id, TRUE);
- vficon_send_layout_select(vf, new_id);
+ vficon_select_region_util(vf, VFICON(vf)->click_fd, new_fd, TRUE);
+ vficon_send_layout_select(vf, new_fd);
}
else if (event->state & GDK_CONTROL_MASK)
{
- VFICON(vf)->click_id = new_id;
+ VFICON(vf)->click_fd = new_fd;
}
else
{
- VFICON(vf)->click_id = new_id;
+ VFICON(vf)->click_fd = new_fd;
vf_select_none(vf);
- vficon_select(vf, new_id);
- vficon_send_layout_select(vf, new_id);
+ vficon_select(vf, new_fd);
+ vficon_send_layout_select(vf, new_fd);
}
}
}
static gboolean vficon_motion_cb(GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
ViewFile *vf = data;
- IconData *id;
+ FileData *fd;
- id = vficon_find_data_by_coord(vf, (gint)event->x, (gint)event->y, NULL);
- tip_update(vf, id);
+ fd = vficon_find_data_by_coord(vf, (gint)event->x, (gint)event->y, NULL);
+ tip_update(vf, fd);
return FALSE;
}
{
ViewFile *vf = data;
GtkTreeIter iter;
- IconData *id;
+ FileData *fd;
tip_unschedule(vf);
- id = vficon_find_data_by_coord(vf, (gint)bevent->x, (gint)bevent->y, &iter);
+ fd = vficon_find_data_by_coord(vf, (gint)bevent->x, (gint)bevent->y, &iter);
- VFICON(vf)->click_id = id;
- vficon_selection_add(vf, VFICON(vf)->click_id, SELECTION_PRELIGHT, &iter);
+ VFICON(vf)->click_fd = fd;
+ vficon_selection_add(vf, VFICON(vf)->click_fd, SELECTION_PRELIGHT, &iter);
switch (bevent->button)
{
gtk_widget_grab_focus(vf->listview);
}
- if (bevent->type == GDK_2BUTTON_PRESS &&
- vf->layout)
+ if (bevent->type == GDK_2BUTTON_PRESS && vf->layout)
{
- vficon_selection_remove(vf, VFICON(vf)->click_id, SELECTION_PRELIGHT, &iter);
+ vficon_selection_remove(vf, VFICON(vf)->click_fd, SELECTION_PRELIGHT, &iter);
layout_image_full_screen_start(vf->layout);
}
break;
{
ViewFile *vf = data;
GtkTreeIter iter;
- IconData *id = NULL;
+ FileData *fd = NULL;
gboolean was_selected;
tip_schedule(vf);
if ((gint)bevent->x != 0 || (gint)bevent->y != 0)
{
- id = vficon_find_data_by_coord(vf, (gint)bevent->x, (gint)bevent->y, &iter);
+ fd = vficon_find_data_by_coord(vf, (gint)bevent->x, (gint)bevent->y, &iter);
}
- if (VFICON(vf)->click_id)
+ if (VFICON(vf)->click_fd)
{
- vficon_selection_remove(vf, VFICON(vf)->click_id, SELECTION_PRELIGHT, NULL);
+ vficon_selection_remove(vf, VFICON(vf)->click_fd, SELECTION_PRELIGHT, NULL);
}
- if (!id || VFICON(vf)->click_id != id) return TRUE;
+ if (!fd || VFICON(vf)->click_fd != fd) return TRUE;
- was_selected = !!(id->selected & SELECTION_SELECTED);
+ was_selected = !!(fd->selected & SELECTION_SELECTED);
switch (bevent->button)
{
case MOUSE_BUTTON_LEFT:
{
- vficon_set_focus(vf, id);
+ vficon_set_focus(vf, fd);
if (bevent->state & GDK_CONTROL_MASK)
{
gboolean select;
- select = !(id->selected & SELECTION_SELECTED);
+ select = !(fd->selected & SELECTION_SELECTED);
if ((bevent->state & GDK_SHIFT_MASK) && VFICON(vf)->prev_selection)
{
- vficon_select_region_util(vf, VFICON(vf)->prev_selection, id, select);
+ vficon_select_region_util(vf, VFICON(vf)->prev_selection, fd, select);
}
else
{
- vficon_select_util(vf, id, select);
+ vficon_select_util(vf, fd, select);
}
}
else
if ((bevent->state & GDK_SHIFT_MASK) && VFICON(vf)->prev_selection)
{
- vficon_select_region_util(vf, VFICON(vf)->prev_selection, id, TRUE);
+ vficon_select_region_util(vf, VFICON(vf)->prev_selection, fd, TRUE);
}
else
{
- vficon_select_util(vf, id, TRUE);
+ vficon_select_util(vf, fd, TRUE);
was_selected = FALSE;
}
}
break;
case MOUSE_BUTTON_MIDDLE:
{
- vficon_select_util(vf, id, !(id->selected & SELECTION_SELECTED));
+ vficon_select_util(vf, fd, !(fd->selected & SELECTION_SELECTED));
}
break;
default:
break;
}
- if (!was_selected && (id->selected & SELECTION_SELECTED))
+ if (!was_selected && (fd->selected & SELECTION_SELECTED))
{
- vficon_send_layout_select(vf, id);
+ vficon_send_layout_select(vf, fd);
}
return TRUE;
GtkTreeModel *store;
GtkTreePath *tpath;
GList *work;
- IconData *visible_id = NULL;
+ FileData *visible_fd = NULL;
gint r, c;
gboolean valid;
GtkTreeIter iter;
gtk_tree_path_free(tpath);
gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &list, -1);
- if (list) visible_id = list->data;
+ if (list) visible_fd = list->data;
}
while (list)
{
- IconData *id;
+ FileData *fd;
if (work)
{
- id = work->data;
+ fd = work->data;
work = work->next;
c++;
}
else
{
- id = NULL;
+ fd = NULL;
}
- list->data = id;
+ list->data = fd;
list = list->next;
}
if (valid) valid = gtk_tree_model_iter_next(store, &iter);
VFICON(vf)->rows = r;
- if (visible_id &&
+ if (visible_fd &&
gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vf->listview), 0, 0, &tpath, NULL, NULL, NULL))
{
GtkTreeIter iter;
gtk_tree_path_free(tpath);
gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &list, -1);
- if (g_list_find(list, visible_id) == NULL &&
- vficon_find_iter(vf, visible_id, &iter, NULL))
+ if (g_list_find(list, visible_fd) == NULL &&
+ vficon_find_iter(vf, visible_fd, &iter, NULL))
{
tree_view_row_make_visible(GTK_TREE_VIEW(vf->listview), &iter, FALSE);
}
GList *work = list;
while (work)
{
- IconData *id = work->data;
- FileData *fd = id->fd;
+ FileData *fd = work->data;
work = work->next;
if (fd->thumb_pixbuf) (*done)++;
GtkTreeIter iter;
GList *list;
- if (!vficon_find_iter(vf, vficon_icon_data(vf, fd), &iter, NULL)) return;
+ 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));
gtk_list_store_set(GTK_LIST_STORE(store), &iter, FILE_COLUMN_POINTER, list, -1);
}
-
+/* Returns the next fd without a loaded pixbuf, so the thumb-loader can load the pixbuf for it. */
FileData *vficon_thumb_next_fd(ViewFile *vf)
{
GtkTreePath *tpath;
- FileData *fd = NULL;
+ /* First see if there are visible files that don't have a loaded thumb... */
if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vf->listview), 0, 0, &tpath, NULL, NULL, NULL))
{
GtkTreeModel *store;
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;
- while (!fd && valid && tree_view_row_get_visibility(GTK_TREE_VIEW(vf->listview), &iter, FALSE) == 0)
+ 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);
- while (!fd && list)
+ // TODO(xsdg): for loop here.
+ for (; list; list = list->next)
{
- IconData *id = list->data;
- if (id && !id->fd->thumb_pixbuf) fd = id->fd;
- list = list->next;
+ FileData *fd = list->data;
+ if (fd && !fd->thumb_pixbuf) return fd;
}
valid = gtk_tree_model_iter_next(store, &iter);
}
}
- /* then find first undone */
-
- if (!fd)
+ /* Then iterate through the entire list to load all of them. */
+ GList *work;
+ for (work = vf->list; work; work = work->next)
{
- GList *work = vf->list;
- while (work && !fd)
- {
- IconData *id = work->data;
- FileData *fd_p = id->fd;
- work = work->next;
+ FileData *fd = work->data;
- if (!fd_p->thumb_pixbuf) fd = fd_p;
- }
+ // Note: This implementation differs from view_file_list.c because sidecar files are not
+ // distinct list elements here, as they are in the list view.
+ if (!fd->thumb_pixbuf) return fd;
}
- return fd;
+ return NULL;
}
void vficon_thumb_reset_all(ViewFile *vf)
while (work)
{
- IconData *id = work->data;
- FileData *fd = id->fd;
+ FileData *fd = work->data;
if (fd->thumb_pixbuf)
{
g_object_unref(fd->thumb_pixbuf);
FileData *vficon_index_get_data(ViewFile *vf, gint row)
{
- IconData *id;
+ FileData *fd;
- id = g_list_nth_data(vf->list, row);
- return id ? id->fd : NULL;
+ fd = g_list_nth_data(vf->list, row);
+ return fd ? fd : NULL;
}
work = vf->list;
while (work)
{
- IconData *id = work->data;
- FileData *fd = id->fd;
+ FileData *fd = work->data;
if (fd == in_fd) return p;
work = work->next;
p++;
return -1;
}
-static gint vficon_index_by_id(ViewFile *vf, IconData *in_id)
-{
- gint p = 0;
- GList *work;
-
- if (!in_id) return -1;
-
- work = vf->list;
- while (work)
- {
- IconData *id = work->data;
- if (id == in_id) return p;
- work = work->next;
- p++;
- }
-
- return -1;
-}
-
guint vficon_count(ViewFile *vf, gint64 *bytes)
{
if (bytes)
work = vf->list;
while (work)
{
- IconData *id = work->data;
- FileData *fd = id->fd;
+ FileData *fd = work->data;
work = work->next;
b += fd->size;
work = vf->list;
while (work)
{
- IconData *id = work->data;
- FileData *fd = id->fd;
+ FileData *fd = work->data;
work = work->next;
list = g_list_prepend(list, file_data_ref(fd));
static gboolean vficon_refresh_real(ViewFile *vf, gboolean keep_position)
{
gboolean ret = TRUE;
- GList *work, *work_fd;
- IconData *focus_id;
- GList *new_filelist = NULL;
+ GList *work, *new_work;
+ FileData *focus_fd;
FileData *first_selected = NULL;
- GList *new_iconlist = NULL;
+ GList *new_filelist = NULL;
+ GList *new_fd_list = NULL;
- focus_id = VFICON(vf)->focus_id;
+ focus_fd = VFICON(vf)->focus_fd;
if (vf->dir_fd)
{
new_filelist = file_data_filter_marks_list(new_filelist, vf_marks_get_filter(vf));
}
- vf->list = iconlist_sort(vf->list, vf->sort_method, vf->sort_ascend); /* the list might not be sorted if there were renames */
+ vf->list = filelist_sort(vf->list, vf->sort_method, vf->sort_ascend); /* the list might not be sorted if there were renames */
new_filelist = filelist_sort(new_filelist, vf->sort_method, vf->sort_ascend);
if (VFICON(vf)->selection)
{
- first_selected = ((IconData *)(VFICON(vf)->selection->data))->fd;
+ first_selected = VFICON(vf)->selection->data;
file_data_ref(first_selected);
g_list_free(VFICON(vf)->selection);
VFICON(vf)->selection = NULL;
-
-
}
- /* check for same files from old_list */
+ /* iterate old list and new list, looking for differences */
work = vf->list;
- work_fd = new_filelist;
- while (work || work_fd)
+ new_work = new_filelist;
+ while (work || new_work)
{
- IconData *id = NULL;
FileData *fd = NULL;
FileData *new_fd = NULL;
gint match;
- if (work && work_fd)
+ if (work && new_work)
{
- id = work->data;
- fd = id->fd;
-
- new_fd = work_fd->data;
+ fd = work->data;
+ new_fd = new_work->data;
if (fd == new_fd)
{
/* not changed, go to next */
work = work->next;
- work_fd = work_fd->next;
- if (id->selected & SELECTION_SELECTED)
+ new_work = new_work->next;
+ if (fd->selected & SELECTION_SELECTED)
{
- VFICON(vf)->selection = g_list_prepend(VFICON(vf)->selection, id);
+ VFICON(vf)->selection = g_list_prepend(VFICON(vf)->selection, fd);
}
continue;
}
}
else if (work)
{
- id = work->data;
- fd = id->fd;
+ /* old item was deleted */
+ fd = work->data;
match = -1;
}
- else /* work_fd */
+ else
{
- new_fd = work_fd->data;
+ /* new item was added */
+ new_fd = new_work->data;
match = 1;
}
/* file no longer exists, delete from vf->list */
GList *to_delete = work;
work = work->next;
- if (id == VFICON(vf)->prev_selection) VFICON(vf)->prev_selection = NULL;
- if (id == VFICON(vf)->click_id) VFICON(vf)->click_id = NULL;
+ if (fd == VFICON(vf)->prev_selection) VFICON(vf)->prev_selection = NULL;
+ if (fd == VFICON(vf)->click_fd) VFICON(vf)->click_fd = NULL;
file_data_unref(fd);
- g_free(id);
vf->list = g_list_delete_link(vf->list, to_delete);
}
else
{
/* new file, add to vf->list */
- id = g_new0(IconData, 1);
-
- id->selected = SELECTION_NONE;
- id->fd = file_data_ref(new_fd);
+ file_data_ref(new_fd);
+ new_fd->selected = SELECTION_NONE;
if (work)
- vf->list = g_list_insert_before(vf->list, work, id);
+ {
+ vf->list = g_list_insert_before(vf->list, work, new_fd);
+ }
else
- new_iconlist = g_list_prepend(new_iconlist, id); /* it is faster to append all new entries together later */
+ {
+ /* it is faster to append all new entries together later */
+ new_fd_list = g_list_prepend(new_fd_list, new_fd);
+ }
- work_fd = work_fd->next;
+ new_work = new_work->next;
}
-
}
- if (new_iconlist)
+ if (new_fd_list)
{
- vf->list = g_list_concat(vf->list, g_list_reverse(new_iconlist));
+ vf->list = g_list_concat(vf->list, g_list_reverse(new_fd_list));
}
VFICON(vf)->selection = g_list_reverse(VFICON(vf)->selection);
file_data_unref(first_selected);
/* attempt to keep focus on same icon when refreshing */
- if (focus_id && g_list_find(vf->list, focus_id))
+ if (focus_fd && g_list_find(vf->list, focus_fd))
{
- vficon_set_focus(vf, focus_id);
+ vficon_set_focus(vf, focus_fd);
}
return ret;
GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
{
GList *list;
- IconData *id;
+ FileData *fd;
ColumnData *cd = data;
ViewFile *vf = cd->vf;
gtk_tree_model_get(tree_model, iter, FILE_COLUMN_POINTER, &list, -1);
- id = g_list_nth_data(list, cd->number);
+ fd = g_list_nth_data(list, cd->number);
- if (id)
+ if (fd)
{
GdkColor color_fg;
GdkColor color_bg;
gchar *link;
GtkStateType state = GTK_STATE_NORMAL;
- g_assert(id->fd->magick == FD_MAGICK);
+ g_assert(fd->magick == FD_MAGICK);
- link = islink(id->fd->path) ? GQ_LINK_STR : "";
- if (id->fd->sidecar_files)
+ link = islink(fd->path) ? GQ_LINK_STR : "";
+ if (fd->sidecar_files)
{
- gchar *sidecars = file_data_sc_list_to_string(id->fd);
- name_sidecars = g_strdup_printf("%s%s %s", link, id->fd->name, sidecars);
+ gchar *sidecars = file_data_sc_list_to_string(fd);
+ name_sidecars = g_strdup_printf("%s%s %s", link, fd->name, sidecars);
g_free(sidecars);
}
else
{
- gchar *disabled_grouping = id->fd->disable_grouping ? _(" [NO GROUPING]") : "";
- name_sidecars = g_strdup_printf("%s%s%s", link, id->fd->name, disabled_grouping);
+ gchar *disabled_grouping = fd->disable_grouping ? _(" [NO GROUPING]") : "";
+ name_sidecars = g_strdup_printf("%s%s%s", link, fd->name, disabled_grouping);
}
style = gtk_widget_get_style(vf->listview);
- if (id->selected & SELECTION_SELECTED)
+ if (fd->selected & SELECTION_SELECTED)
{
state = GTK_STATE_SELECTED;
}
memcpy(&color_fg, &style->text[state], sizeof(color_fg));
memcpy(&color_bg, &style->base[state], sizeof(color_bg));
- if (id->selected & SELECTION_PRELIGHT)
+ if (fd->selected & SELECTION_PRELIGHT)
{
shift_color(&color_bg, -1, 0);
}
- g_object_set(cell, "pixbuf", id->fd->thumb_pixbuf,
+ g_object_set(cell, "pixbuf", fd->thumb_pixbuf,
"text", name_sidecars,
- "marks", file_data_get_marks(id->fd),
+ "marks", file_data_get_marks(fd),
"show_marks", vf->marks_enabled,
"cell-background-gdk", &color_bg,
"cell-background-set", TRUE,
"foreground-gdk", &color_fg,
"foreground-set", TRUE,
- "has-focus", (VFICON(vf)->focus_id == id), NULL);
+ "has-focus", (VFICON(vf)->focus_fd == fd), NULL);
g_free(name_sidecars);
}
else
g_list_free(VFICON(vf)->selection);
VFICON(vf)->selection = NULL;
- iconlist_free(vf->list);
+ g_list_free(vf->list);
vf->list = NULL;
/* NOTE: populate will clear the store for us */
ret = vficon_refresh_real(vf, FALSE);
- VFICON(vf)->focus_id = NULL;
+ VFICON(vf)->focus_fd = NULL;
vficon_move_focus(vf, 0, 0, FALSE);
return ret;
vf_thumb_cleanup(vf);
- iconlist_free(vf->list);
+ g_list_free(vf->list);
g_list_free(VFICON(vf)->selection);
}
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef VIEW_FILE_ICON_H
-#define VIEW_FILE_ICON_H
+#ifndef VIEW_FILE_VIEW_FILE_ICON_H
+#define VIEW_FILE_VIEW_FILE_ICON_H
+
+#include "filedata.h"
gboolean vficon_press_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer data);
gboolean vficon_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data);
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;
while (!fd && valid && tree_view_row_get_visibility(GTK_TREE_VIEW(vf->listview), &iter, FALSE) == 0)
{
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef VIEW_FILE_LIST_H
-#define VIEW_FILE_LIST_H
-
+#ifndef VIEW_FILE_VIEW_FILE_LIST_H
+#define VIEW_FILE_VIEW_FILE_LIST_H
#include "filedata.h"