case FILEDATA_CHANGE_WRITE_METADATA:
break;
}
+}
+
+static gint collection_manager_sort_cb(gconstpointer a, gconstpointer b)
+{
+ const gchar *char_a = a;
+ const gchar *char_b = b;
+
+ return g_strcmp0(char_a, char_b);
+}
+
+/* Creates sorted list of collections
+ * Inputs: none
+ * Outputs: list of type gchar
+ * sorted list of collections names excluding extension
+ * sorted list of collections names including extension
+ * sorted list of collection paths
+ * Return: none
+ * Used lists must be freed with string_list_free()
+ */
+void collect_manager_list(GList **names_exc, GList **names_inc, GList **paths)
+{
+ FileData *dir_fd;
+ GList *list = NULL;
+ gchar *name;
+ FileData *fd;
+ gchar *filename;
+
+ if (names_exc == NULL && names_inc == NULL && paths == NULL)
+ {
+ return;
+ }
+
+ dir_fd = file_data_new_dir((get_collections_dir()));
+
+ filelist_read(dir_fd, &list, NULL);
+
+ while (list)
+ {
+ fd = list->data;
+ filename = g_strdup(filename_from_path((gchar *)fd->path));
+
+ if (file_extension_match(filename, GQ_COLLECTION_EXT))
+ {
+ name = remove_extension_from_path(filename);
+ if (names_exc != NULL)
+ {
+ *names_exc = g_list_insert_sorted(*names_exc, g_strdup(name),
+ collection_manager_sort_cb);
+ *names_exc = g_list_first(*names_exc);
+ }
+ if (names_inc != NULL)
+ {
+ *names_inc = g_list_insert_sorted(*names_inc,filename,
+ collection_manager_sort_cb);
+ *names_inc = g_list_first(*names_inc);
+ }
+ if (paths != NULL)
+ {
+ *paths = g_list_insert_sorted(*paths,fd->path,
+ collection_manager_sort_cb);
+ *paths = g_list_first(*paths);
+ }
+ g_free(name);
+ }
+ list = list->next;
+ g_free(filename);
+ }
+
+ filelist_free(list);
}
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
void collect_manager_flush(void);
void collect_manager_notify_cb(FileData *fd, NotifyType type, gpointer data);
-
+void collect_manager_list(GList **names_exc, GList **names_inc, GList **paths);
#endif
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
g_list_free(list);
}
-static void collection_table_popup_add_filelist_cb(GtkWidget *widget, gpointer data)
-{
- CollectTable *ct = data;
- GList *list;
-
- list = layout_list(NULL);
-
- if (list)
- {
- collection_table_add_filelist(ct, list);
- filelist_free(list);
- }
-}
-
static void collection_table_popup_add_file_selection_cb(GtkWidget *widget, gpointer data)
{
CollectTable *ct = data;
menu_item_add_stock(menu, _("Append from file selection"), GTK_STOCK_ADD,
G_CALLBACK(collection_table_popup_add_file_selection_cb), ct);
- menu_item_add_stock(menu, _("Append from file list"), GTK_STOCK_ADD,
- G_CALLBACK(collection_table_popup_add_filelist_cb), ct);
menu_item_add_stock(menu, _("Append from collection..."), GTK_STOCK_OPEN,
G_CALLBACK(collection_table_popup_add_collection_cb), ct);
menu_item_add_divider(menu);
#define COLLECT_DEF_WIDTH 440
#define COLLECT_DEF_HEIGHT 450
-static GList *collection_list = NULL;
-static GList *collection_window_list = NULL;
+/* list of paths to collections */
+
+/* List of currently open Collections*/
+static GList *collection_list = NULL; /* type CollectionData */
+/* List of currently open Collection windows*/
+static GList *collection_window_list = NULL; /* type CollectWindow */
static void collection_window_get_geometry(CollectWindow *cw);
static void collection_window_refresh(CollectWindow *cw);
return NULL;
}
+/* Checks string for existence of Collection.
+ * The parameter is the 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(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;
+}
+
+/* Checks input string for existence of Collection.
+ * The parameter is the filename
+ * with or without extension of any collection
+ *
+ * Returns TRUE if found
+ */
+gboolean is_collection(gchar *param)
+{
+ gchar *name = NULL;
+
+ name = collection_path(param);
+ if (name)
+ {
+ g_free(name);
+ return TRUE;
+ }
+ return FALSE;
+}
+
/*
*-------------------------------------------------------------------
* please use these to actually add/remove stuff
CollectWindow *collection_window_find_by_path(const gchar *path);
gboolean collection_window_modified_exists(void);
-
+gboolean is_collection(gchar *param);
+gchar *collection_path(gchar *param);
#endif
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
return list;
}
+/* Add file selection list to a collection
+ * Called from a right-click menu
+ * Inputs:
+ * data: index to the collection list menu item selected, or -1 for new collection
+ */
+static void dupe_pop_menu_collections_cb(GtkWidget *widget, gpointer data)
+{
+ DupeWindow *dw;
+ GList *selection_list;
+
+ dw = submenu_item_get_data(widget);
+ selection_list = dupe_listview_get_selection(dw, dw->listview);
+ pop_menu_collections(selection_list, data);
+
+ filelist_free(selection_list);
+}
+
static GtkWidget *dupe_menu_popup_main(DupeWindow *dw, DupeItem *di)
{
GtkWidget *menu;
GtkWidget *item;
gint on_row;
GList *editmenu_fd_list;
+ GtkWidget *submenu;
on_row = (di != NULL);
G_CALLBACK(dupe_menu_popup_destroy_cb), editmenu_fd_list);
submenu_add_edit(menu, &item, G_CALLBACK(dupe_menu_edit_cb), dw, editmenu_fd_list);
if (!on_row) gtk_widget_set_sensitive(item, FALSE);
- menu_item_add_stock_sensitive(menu, _("Add to new collection"), GTK_STOCK_INDEX, on_row,
- G_CALLBACK(dupe_menu_collection_cb), dw);
+
+ submenu = submenu_add_collections(menu, &item,
+ G_CALLBACK(dupe_pop_menu_collections_cb), dw);
+ gtk_widget_set_sensitive(item, on_row);
+
menu_item_add_stock_sensitive(menu, _("Print..."), GTK_STOCK_PRINT, on_row,
G_CALLBACK(dupe_menu_print_cb), dw);
menu_item_add_divider(menu);
return list;
}
+/* Add file selection list to a collection
+ * Called from a right-click submenu
+ * Inputs:
+ * data: index to the collection list menu item selected, or -1 for new collection
+ */
+static void image_pop_menu_collections_cb(GtkWidget *widget, gpointer data)
+{
+ ViewWindow *vw;
+ ImageWindow *imd;
+ FileData *fd;
+ GList *selection_list = NULL;
+
+ vw = submenu_item_get_data(widget);
+ imd = view_window_active_image(vw);
+ fd = image_get_fd(imd);
+ selection_list = g_list_append(selection_list, fd);
+ pop_menu_collections(selection_list, data);
+
+ filelist_free(selection_list);
+}
+
static GtkWidget *view_popup_menu(ViewWindow *vw)
{
GtkWidget *menu;
+ GtkWidget *submenu;
GtkWidget *item;
GList *editmenu_fd_list;
menu_item_add_divider(menu);
+ submenu = submenu_add_collections(menu, &item,
+ G_CALLBACK(image_pop_menu_collections_cb), vw);
+ gtk_widget_set_sensitive(item, TRUE);
+ menu_item_add_divider(menu);
+
if (vw->ss)
{
menu_item_add(menu, _("_Stop slideshow"), G_CALLBACK(view_slideshow_stop_cb), vw);
return list;
}
+/* Add file selection list to a collection
+ * Called from a right-click submenu
+ * Inputs:
+ * data: index to the collection list menu item selected, or -1 for new collection
+ */
+static void layout_pop_menu_collections_cb(GtkWidget *widget, gpointer data)
+{
+ LayoutWindow *lw;
+ GList *selection_list = NULL;
+
+ lw = submenu_item_get_data(widget);
+ selection_list = g_list_append(selection_list, layout_image_get_fd(lw));
+ pop_menu_collections(selection_list, data);
+
+ filelist_free(selection_list);
+}
+
static GtkWidget *layout_image_pop_menu(LayoutWindow *lw)
{
GtkWidget *menu;
if (!path) gtk_widget_set_sensitive(item, FALSE);
item = menu_item_add_stock(menu, _("_Delete..."), GTK_STOCK_DELETE, G_CALLBACK(li_pop_menu_delete_cb), lw);
if (!path) gtk_widget_set_sensitive(item, FALSE);
+ menu_item_add_divider(menu);
+ submenu = submenu_add_collections(menu, &item,
+ G_CALLBACK(layout_pop_menu_collections_cb), lw);
+ gtk_widget_set_sensitive(item, TRUE);
menu_item_add_divider(menu);
if (layout_image_slideshow_active(lw))
parse_command_line_add_file(file_path, path, file, list, collection_list);
}
-static gboolean is_collection(gchar *cmd_param)
-{
- gchar *path = NULL;
- gchar *full_name = NULL;
- gboolean result = FALSE;
-
- if (file_extension_match(cmd_param, GQ_COLLECTION_EXT))
- {
- path = g_build_filename(get_collections_dir(), cmd_param, NULL);
- }
- else if (file_extension_match(cmd_param, NULL))
- {
- full_name = g_strconcat(cmd_param, GQ_COLLECTION_EXT, NULL);
- path = g_build_filename(get_collections_dir(), full_name, NULL);
- }
-
- if (isfile(path))
- {
- result = TRUE;
- }
-
- g_free(path);
- g_free(full_name);
- return result;
-}
-
static void parse_command_line(gint argc, gchar *argv[])
{
GList *list = NULL;
else if (is_collection(cmd_line))
{
gchar *path = NULL;
- gchar *full_name = NULL;
- if (file_extension_match(cmd_line, GQ_COLLECTION_EXT))
- {
- path = g_build_filename(get_collections_dir(), cmd_line, NULL);
- }
- else
- {
- full_name = g_strconcat(cmd_line, GQ_COLLECTION_EXT, NULL);
- path = g_build_filename(get_collections_dir(), full_name, NULL);
- }
+ path = collection_path(cmd_line);
parse_command_line_process_file(path, &command_line->path, &command_line->file,
&list, &command_line->collection_list, &first_dir);
g_free(path);
- g_free(full_name);
}
else if (strncmp(cmd_line, "--debug", 7) == 0 && (cmd_line[7] == '\0' || cmd_line[7] == '='))
{
#include "cache_maint.h"
#include "collect.h"
#include "collect-dlg.h"
+#include "collect-io.h"
+#include "collect-table.h"
#include "dupe.h"
#include "editors.h"
#include "filedata.h"
{
return real_submenu_add_alter(menu, func, data, NULL);
}
+
+/*
+ *-----------------------------------------------------------------------------
+ * collections
+ *-----------------------------------------------------------------------------
+ */
+
+/* Add submenu consisting of "New collection", and list of existing collections
+ * to a right-click menu.
+ * Used by image windows
+ */
+static void add_collection_list(GtkWidget *menu, GCallback func,
+ GList *collection_list, gpointer data)
+{
+ GList *work;
+ gint index = 0; /* index to existing collection list menu item selected */
+ GtkWidget *item;
+
+ work = collection_list;
+ while (work)
+ {
+ const gchar *collection_name = work->data;
+
+ item = menu_item_add(menu, collection_name, func,
+ GINT_TO_POINTER(index));
+ work = work->next;
+ index++;
+ }
+}
+
+GtkWidget *submenu_add_collections(GtkWidget *menu, GtkWidget **menu_item,
+ GCallback func, gpointer data)
+{
+ GtkWidget *item;
+ GtkWidget *submenu;
+ GList *collection_list = NULL;
+
+ item = menu_item_add(menu, _("_Add to Collection"), NULL, NULL);
+
+ submenu = gtk_menu_new();
+ g_object_set_data(G_OBJECT(submenu), "submenu_data", data);
+
+ menu_item_add_stock_sensitive(submenu, _("New collection"),
+ GTK_STOCK_INDEX, TRUE, G_CALLBACK(func), GINT_TO_POINTER(-1));
+ menu_item_add_divider(submenu);
+
+ collect_manager_list(&collection_list,NULL,NULL);
+ add_collection_list(submenu, func, collection_list, data);
+
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
+ if (menu_item) *menu_item = item;
+
+ g_list_free(collection_list);
+
+ return submenu;
+}
+
+/* Add file selection list to a collection
+ * Called from a right-click submenu
+ * Inputs:
+ * selection_list: GList of FileData
+ * data: index to the collection list menu item selected, or -1 for new collection
+ */
+void pop_menu_collections(GList *selection_list, gpointer data)
+{
+ CollectWindow *cw;
+ gchar *collection_name;
+ GList *collection_list = NULL;
+ gchar *name;
+ const gint index = GPOINTER_TO_INT(data);
+
+ if (index >= 0)
+ {
+ collect_manager_list(&collection_list, NULL, NULL);
+ collection_name = g_list_nth_data(collection_list, index);
+ name = collection_path(collection_name);
+ cw = collection_window_new(name);
+ g_free(name);
+ string_list_free(collection_list);
+ }
+ else
+ {
+ cw = collection_window_new(NULL);
+ }
+
+ collection_table_add_filelist(cw->table, selection_list);
+}
+
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
gchar *alter_type_get_text(AlterType type);
GtkWidget *submenu_add_alter(GtkWidget *menu, GCallback func, gpointer data);
-
+GtkWidget *submenu_add_collections(GtkWidget *menu, GtkWidget **menu_item,
+ GCallback func, gpointer data);
+void pop_menu_collections(GList *selection_list, gpointer data);
#endif
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
return list;
}
+/* Add file selection list to a collection
+ * Called from a right-click submenu
+ * Inputs:
+ * data: index to the collection list menu item selected, or -1 for new collection
+ */
+static void pan_pop_menu_collections_cb(GtkWidget *widget, gpointer data)
+{
+ PanWindow *pw;
+ GList *selection_list = NULL;
+
+ pw = submenu_item_get_data(widget);
+ selection_list = g_list_append(selection_list, pan_menu_click_fd(pw));
+ pop_menu_collections(selection_list, data);
+
+ filelist_free(selection_list);
+}
+
static GtkWidget *pan_popup_menu(PanWindow *pw)
{
GtkWidget *menu;
G_CALLBACK(pan_delete_cb), pw);
menu_item_add_divider(menu);
+
+ submenu = submenu_add_collections(menu, &item,
+ G_CALLBACK(pan_pop_menu_collections_cb), pw);
+ gtk_widget_set_sensitive(item, TRUE);
+ menu_item_add_divider(menu);
+
+
item = menu_item_add_check(menu, _("Sort by E_xif date"), pw->exif_date_enable,
G_CALLBACK(pan_exif_date_toggle_cb), pw);
gtk_widget_set_sensitive(item, (pw->layout == PAN_LAYOUT_TIMELINE || pw->layout == PAN_LAYOUT_CALENDAR));
filelist_free(editmenu_fd_list);
}
+/* Add file selection list to a collection
+ * Called from a right-click submenu
+ * Inputs:
+ * data: index to the collection list menu item selected, or -1 for new collection
+ */
+static void search_pop_menu_collections_cb(GtkWidget *widget, gpointer data)
+{
+ SearchData *sd;
+ GList *selection_list;
+
+ sd = submenu_item_get_data(widget);
+ selection_list = search_result_selection_list(sd);
+ pop_menu_collections(selection_list, data);
+
+ filelist_free(selection_list);
+}
+
static GtkWidget *search_result_menu(SearchData *sd, gboolean on_row, gboolean empty)
{
GtkWidget *menu;
GtkWidget *item;
GList *editmenu_fd_list;
+ GtkWidget *submenu;
menu = popup_menu_short_lived();
G_CALLBACK(search_result_menu_destroy_cb), editmenu_fd_list);
submenu_add_edit(menu, &item, G_CALLBACK(sr_menu_edit_cb), sd, editmenu_fd_list);
if (!on_row) gtk_widget_set_sensitive(item, FALSE);
- menu_item_add_stock_sensitive(menu, _("Add to new collection"), GTK_STOCK_INDEX, on_row,
- G_CALLBACK(sr_menu_collection_cb), sd);
+
+ submenu = submenu_add_collections(menu, &item,
+ G_CALLBACK(search_pop_menu_collections_cb), sd);
+ gtk_widget_set_sensitive(item, on_row);
+
menu_item_add_stock_sensitive(menu, _("Print..."), GTK_STOCK_PRINT, on_row,
G_CALLBACK(sr_menu_print_cb), sd);
menu_item_add_divider(menu);
GtkWidget *window;
CollectTable *table;
GtkWidget *status_box;
- GList *list;
GtkWidget *close_dialog;
vf->editmenu_fd_list = NULL;
}
+/* Add file selection list to a collection
+ * Called from a right-click menu
+ * Inputs:
+ * data: index to the collection list menu item selected, or -1 for new collection
+ */
+static void vf_pop_menu_collections_cb(GtkWidget *widget, gpointer data)
+{
+ ViewFile *vf;
+ GList *selection_list;
+
+ vf = submenu_item_get_data(widget);
+ selection_list = vf_selection_get_list(vf);
+ pop_menu_collections(selection_list, data);
+
+ filelist_free(selection_list);
+}
+
GtkWidget *vf_pop_menu(ViewFile *vf)
{
GtkWidget *menu;
menu_item_add_stock_sensitive(menu, _("_Find duplicates..."), GTK_STOCK_FIND, active,
G_CALLBACK(vf_pop_menu_duplicates_cb), vf);
menu_item_add_divider(menu);
- menu_item_add_stock_sensitive(menu, _("Add to new collection"), GTK_STOCK_INDEX, active,
- G_CALLBACK(vf_pop_menu_add_collection_cb), vf);
+
+ submenu = submenu_add_collections(menu, &item,
+ G_CALLBACK(vf_pop_menu_collections_cb), vf);
+ gtk_widget_set_sensitive(item, active);
menu_item_add_divider(menu);
submenu = submenu_add_sort(NULL, G_CALLBACK(vf_pop_menu_sort_cb), vf,