#include "img-view.h"
#include "layout.h"
#include "layout_image.h"
+#include "layout_util.h"
#include "misc.h"
#include "pixbuf_util.h"
#include "print.h"
#define COLLECT_DEF_WIDTH 440
#define COLLECT_DEF_HEIGHT 450
+/**
+ * list of paths to collections */
+
+/**
+ * @brief List of currently open Collections.
+ *
+ * Type ::_CollectionData
+ */
static GList *collection_list = NULL;
+
+/**
+ * @brief List of currently open Collection windows.
+ *
+ * Type ::_CollectWindow
+ */
static GList *collection_window_list = NULL;
static void collection_window_get_geometry(CollectWindow *cw);
if (cia->fd->cdate > cib->fd->cdate) return 1;
return 0;
break;
+ case SORT_EXIFTIME:
+ if (cia->fd->exifdate < cib->fd->exifdate) return -1;
+ if (cia->fd->exifdate > cib->fd->exifdate) return 1;
+ break;
+ case SORT_EXIFTIMEDIGITIZED:
+ if (cia->fd->exifdate_digitized < cib->fd->exifdate_digitized) return -1;
+ if (cia->fd->exifdate_digitized > cib->fd->exifdate_digitized) return 1;
+ break;
+ case SORT_RATING:
+ if (cia->fd->rating < cib->fd->rating) return -1;
+ if (cia->fd->rating > cib->fd->rating) return 1;
+ break;
case SORT_PATH:
return utf8_compare(cia->fd->path, cib->fd->path, options->file_sort.case_sensitive);
break;
+ case SORT_CLASS:
+ if (cia->fd->format_class < cib->fd->format_class) return -1;
+ if (cia->fd->format_class > cib->fd->format_class) return 1;
+ break;
#ifdef HAVE_STRVERSCMP
case SORT_NUMBER:
return strverscmp(cia->fd->name, cib->fd->name);
return NULL;
}
+/**
+ * @brief Checks string for existence of Collection.
+ * @param[in] param Filename, with or without extension of any collection
+ * @returns full pathname if found or NULL
+ *
+ * Return value must be freed with g_free()
+ */
+gchar *collection_path(const gchar *param)
+{
+ gchar *path = NULL;
+ gchar *full_name = NULL;
+
+ if (file_extension_match(param, GQ_COLLECTION_EXT))
+ {
+ path = g_build_filename(get_collections_dir(), param, NULL);
+ }
+ else if (file_extension_match(param, NULL))
+ {
+ full_name = g_strconcat(param, GQ_COLLECTION_EXT, NULL);
+ path = g_build_filename(get_collections_dir(), full_name, NULL);
+ }
+
+ if (!isfile(path))
+ {
+ g_free(path);
+ path = NULL;
+ }
+
+ g_free(full_name);
+ return path;
+}
+
+/**
+ * @brief Checks input string for existence of Collection.
+ * @param[in] param Filename with or without extension of any collection
+ * @returns TRUE if found
+ *
+ *
+ */
+gboolean is_collection(const gchar *param)
+{
+ gchar *name = NULL;
+
+ name = collection_path(param);
+ if (name)
+ {
+ g_free(name);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * @brief Creates a text list of the image paths of the contents of a Collection
+ * @param[in] name The name of the collection, with or without extension
+ * @param[inout] contents A GString to which the image paths are appended
+ *
+ *
+ */
+void collection_contents(const gchar *name, GString **contents)
+{
+ gchar *path;
+ CollectionData *cd;
+ CollectInfo *ci;
+ GList *work;
+ FileData *fd;
+
+ if (is_collection(name))
+ {
+ path = collection_path(name);
+ cd = collection_new("");
+ collection_load(cd, path, COLLECTION_LOAD_APPEND);
+ work = cd->list;
+ while (work)
+ {
+ ci = work->data;
+ fd = ci->fd;
+ *contents = g_string_append(*contents, g_strdup(fd->path));
+ *contents = g_string_append(*contents, "\n");
+
+ work = work->next;
+ }
+ g_free(path);
+ collection_free(cd);
+ }
+}
+
+/**
+ * @brief Returns a list of filedatas of the contents of a Collection
+ * @param[in] name The name of the collection, with or without extension
+ *
+ *
+ */
+GList *collection_contents_fd(const gchar *name)
+{
+ gchar *path;
+ CollectionData *cd;
+ CollectInfo *ci;
+ GList *work;
+ FileData *fd;
+ GList *list = NULL;
+
+ if (is_collection(name))
+ {
+ path = collection_path(name);
+ cd = collection_new("");
+ collection_load(cd, path, COLLECTION_LOAD_APPEND);
+ work = cd->list;
+ while (work)
+ {
+ ci = work->data;
+ fd = ci->fd;
+ list = g_list_append(list, ci->fd);
+
+ work = work->next;
+ }
+ g_free(path);
+ collection_free(cd);
+ }
+
+ return list;
+}
+
/*
*-------------------------------------------------------------------
* please use these to actually add/remove stuff
file_util_rename(NULL, collection_table_selection_get_list(cw->table), cw->window);
break;
case 'D': case 'd':
+ options->file_ops.safe_delete_enable = TRUE;
file_util_delete(NULL, collection_table_selection_get_list(cw->table), cw->window);
break;
case 'S': case 's':
collection_remove_by_info(cw->cd, collection_table_get_focus_info(cw->table));
}
break;
- case GDK_KEY_F1:
- help_window_show("GuideReferenceKeyboardShortcuts.html#CollectionsKeyboardShortcuts");
- break;
default:
stop_signal = FALSE;
break;
}
}
+ if (!stop_signal && is_help_key(event))
+ {
+ help_window_show("GuideCollections.html");
+ stop_signal = TRUE;
+ }
+
return stop_signal;
}
collection_close_cancel_cb, cw);
generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION,
_("Close collection"),
- _("Collection has been modified.\nSave first?"));
+ _("Collection has been modified.\nSave first?"), TRUE);
generic_dialog_add_button(gd, GTK_STOCK_SAVE, NULL, collection_close_save_cb, TRUE);
generic_dialog_add_button(gd, GTK_STOCK_DELETE, _("_Discard"), collection_close_close_cb, FALSE);
if (cw) collection_window_close_final(cw);
}
+/**
+ * @brief Check if any Collection windows have unsaved data
+ * @returns TRUE if unsaved data exists
+ *
+ * Also saves window geometry for Collection windows that have
+ * no unsaved data
+ */
gboolean collection_window_modified_exists(void)
{
GList *work;
+ gboolean ret;
+
+ ret = FALSE;
work = collection_window_list;
while (work)
{
CollectWindow *cw = work->data;
- if (cw->cd->changed) return TRUE;
+ if (cw->cd->changed)
+ {
+ ret = TRUE;
+ }
+ else
+ {
+ if (!collection_save(cw->table->cd, cw->table->cd->path))
+ {
+ log_printf("failed saving to collection path: %s\n", cw->table->cd->path);
+ }
+ }
work = work->next;
}
- return FALSE;
+ return ret;
}
static gboolean collection_window_delete(GtkWidget *widget, GdkEvent *event, gpointer data)
GtkWidget *extra_label;
GdkGeometry geometry;
+ /* If the collection is already opened in another window, return that one */
+ cw = collection_window_find_by_path(path);
+ if (cw)
+ {
+ return cw;
+ }
+
cw = g_new0(CollectWindow, 1);
collection_window_list = g_list_append(collection_window_list, cw);
cw->cd = collection_new(path);
cw->window = window_new(GTK_WINDOW_TOPLEVEL, "collection", PIXBUF_INLINE_ICON_BOOK, NULL, NULL);
+ DEBUG_NAME(cw->window);
geometry.min_width = DEFAULT_MINIMAL_WINDOW_SIZE;
geometry.min_height = DEFAULT_MINIMAL_WINDOW_SIZE;
gtk_window_set_geometry_hints(GTK_WINDOW(cw->window), NULL, &geometry,
GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE);
+ if (options->collections_on_top)
+ {
+ gtk_window_set_keep_above(GTK_WINDOW(cw->window), TRUE);
+ }
if (options->save_window_positions && path && collection_load_only_geometry(cw->cd, path))
{
- /* FIXME: x, y is not implemented */
gtk_window_set_default_size(GTK_WINDOW(cw->window), cw->cd->window_w, cw->cd->window_h);
+ gtk_window_move(GTK_WINDOW(cw->window), cw->cd->window_x, cw->cd->window_y);
}
else
{
gtk_widget_show(cw->status_box);
frame = gtk_frame_new(NULL);
+ DEBUG_NAME(frame);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
gtk_box_pack_start(GTK_BOX(cw->status_box), frame, TRUE, TRUE, 0);
gtk_widget_show(frame);