2 * Copyright (C) 2006 John Ellis
3 * Copyright (C) 2008 - 2016 The Geeqie Team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "pan-view-search.h"
25 #include "pan-calendar.h"
29 #include "ui_tabcomp.h"
31 static void pan_search_status(PanWindow *pw, const gchar *text)
33 gtk_label_set_text(GTK_LABEL(pw->search_label), (text) ? text : "");
36 static gint pan_search_by_path(PanWindow *pw, const gchar *path)
44 type = (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE) ? PAN_ITEM_IMAGE : PAN_ITEM_THUMB;
46 list = pan_item_find_by_path(pw, type, path, FALSE, FALSE);
47 if (!list) return FALSE;
49 found = g_list_find(list, pw->click_pi);
50 if (found && found->next)
60 pan_info_update(pw, pi);
61 image_scroll_to_point(pw->imd, pi->x + pi->width / 2, pi->y + pi->height / 2, 0.5, 0.5);
63 buf = g_strdup_printf("%s ( %d / %d )",
64 (path[0] == G_DIR_SEPARATOR) ? _("path found") : _("filename found"),
65 g_list_index(list, pi) + 1,
67 pan_search_status(pw, buf);
75 static gboolean pan_search_by_partial(PanWindow *pw, const gchar *text)
83 type = (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE) ? PAN_ITEM_IMAGE : PAN_ITEM_THUMB;
85 list = pan_item_find_by_path(pw, type, text, TRUE, FALSE);
86 if (!list) list = pan_item_find_by_path(pw, type, text, FALSE, TRUE);
91 needle = g_utf8_strdown(text, -1);
92 list = pan_item_find_by_path(pw, type, needle, TRUE, TRUE);
95 if (!list) return FALSE;
97 found = g_list_find(list, pw->click_pi);
98 if (found && found->next)
108 pan_info_update(pw, pi);
109 image_scroll_to_point(pw->imd, pi->x + pi->width / 2, pi->y + pi->height / 2, 0.5, 0.5);
111 buf = g_strdup_printf("%s ( %d / %d )",
113 g_list_index(list, pi) + 1,
114 g_list_length(list));
115 pan_search_status(pw, buf);
123 static gboolean valid_date_separator(gchar c)
125 return (c == '/' || c == '-' || c == ' ' || c == '.' || c == ',');
128 static GList *pan_search_by_date_val(PanWindow *pw, PanItemType type,
129 gint year, gint month, gint day,
135 work = g_list_last(pw->list_static);
143 if (pi->fd && (pi->type == type || type == PAN_ITEM_NONE) &&
144 ((!key && !pi->key) || (key && pi->key && strcmp(key, pi->key) == 0)))
148 tl = localtime(&pi->fd->date);
153 match = (tl->tm_year == year - 1900);
154 if (match && month >= 0) match = (tl->tm_mon == month - 1);
155 if (match && day > 0) match = (tl->tm_mday == day);
157 if (match) list = g_list_prepend(list, pi);
162 return g_list_reverse(list);
165 static gboolean pan_search_by_date(PanWindow *pw, const gchar *text)
181 if (!text) return FALSE;
186 if (!g_unichar_isdigit(*ptr) && !valid_date_separator(*ptr)) return FALSE;
191 if (t == -1) return FALSE;
193 if (!lt) return FALSE;
195 if (valid_date_separator(*text))
198 mptr = (gchar *)text;
202 year = (gint)strtol(text, &mptr, 10);
203 if (mptr == text) return FALSE;
206 if (*mptr != '\0' && valid_date_separator(*mptr))
211 month = strtol(mptr, &dptr, 10);
214 if (valid_date_separator(*dptr))
216 month = lt->tm_mon + 1;
224 if (dptr != mptr && *dptr != '\0' && valid_date_separator(*dptr))
228 day = strtol(dptr, &eptr, 10);
238 year = lt->tm_year + 1900;
249 month < -1 || month == 0 || month > 12 ||
250 day < -1 || day == 0 || day > 31) return FALSE;
252 t = pan_date_to_time(year, month, day);
253 if (t < 0) return FALSE;
255 if (pw->layout == PAN_LAYOUT_CALENDAR)
257 list = pan_search_by_date_val(pw, PAN_ITEM_BOX, year, month, day, "day");
263 type = (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE) ? PAN_ITEM_IMAGE : PAN_ITEM_THUMB;
264 list = pan_search_by_date_val(pw, type, year, month, day, NULL);
269 found = g_list_find(list, pw->search_pi);
270 if (found && found->next)
283 if (pw->layout == PAN_LAYOUT_CALENDAR && pi && pi->type == PAN_ITEM_BOX)
285 pan_info_update(pw, NULL);
286 pan_calendar_update(pw, pi);
287 image_scroll_to_point(pw->imd,
288 pi->x + pi->width / 2,
289 pi->y + pi->height / 2, 0.5, 0.5);
293 pan_info_update(pw, pi);
294 image_scroll_to_point(pw->imd,
295 pi->x - PAN_BOX_BORDER * 5 / 2,
301 buf = pan_date_value_string(t, PAN_DATE_LENGTH_MONTH);
306 buf = g_strdup_printf("%d %s", day, tmp);
312 buf = pan_date_value_string(t, PAN_DATE_LENGTH_YEAR);
317 buf_count = g_strdup_printf("( %d / %d )",
318 g_list_index(list, pi) + 1,
319 g_list_length(list));
323 buf_count = g_strdup_printf("(%s)", _("no match"));
326 message = g_strdup_printf("%s %s %s", _("Date:"), buf, buf_count);
329 pan_search_status(pw, message);
337 void pan_search_activate_cb(const gchar *text, gpointer data)
339 PanWindow *pw = data;
343 tab_completion_append_to_history(pw->search_entry, text);
345 if (pan_search_by_path(pw, text)) return;
347 if ((pw->layout == PAN_LAYOUT_TIMELINE ||
348 pw->layout == PAN_LAYOUT_CALENDAR) &&
349 pan_search_by_date(pw, text))
354 if (pan_search_by_partial(pw, text)) return;
356 pan_search_status(pw, _("no match"));
359 void pan_search_activate(PanWindow *pw)
363 text = g_strdup(gtk_entry_get_text(GTK_ENTRY(pw->search_entry)));
364 pan_search_activate_cb(text, pw);
368 void pan_search_toggle_cb(GtkWidget *button, gpointer data)
370 PanWindow *pw = data;
373 visible = gtk_widget_get_visible(pw->search_box);
374 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)) == visible) return;
378 gtk_widget_hide(pw->search_box);
379 gtk_arrow_set(GTK_ARROW(pw->search_button_arrow), GTK_ARROW_UP, GTK_SHADOW_NONE);
383 gtk_widget_show(pw->search_box);
384 gtk_arrow_set(GTK_ARROW(pw->search_button_arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
385 gtk_widget_grab_focus(pw->search_entry);
389 void pan_search_toggle_visible(PanWindow *pw, gboolean enable)
395 if (gtk_widget_get_visible(pw->search_box))
397 gtk_widget_grab_focus(pw->search_entry);
401 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pw->search_button), TRUE);
406 if (gtk_widget_get_visible(pw->search_entry))
408 if (gtk_widget_has_focus(pw->search_entry))
410 gtk_widget_grab_focus(GTK_WIDGET(pw->imd->widget));
412 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pw->search_button), FALSE);