/*
- * Geeqie
- * (C) 2004 John Ellis
- * Copyright (C) 2008 - 2012 The Geeqie Team
+ * Copyright (C) 2004 John Ellis
+ * Copyright (C) 2008 - 2016 The Geeqie Team
*
* Author: John Ellis
*
- * This software is released under the GNU General Public License (GNU GPL).
- * Please read the included file COPYING for more information.
- * This software comes with no warranty of any kind, use at your own risk!
+ * 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 "main.h"
#include "collect-io.h"
guint flush = !!(flags & COLLECTION_LOAD_FLUSH);
guint append = !!(flags & COLLECTION_LOAD_APPEND);
guint only_geometry = !!(flags & COLLECTION_LOAD_GEOMETRY);
+ gboolean reading_extended_filename = FALSE;
+ GString *extended_filename_buffer = g_string_new(NULL);
+ gchar *buffer2;
if (!only_geometry)
{
gchar *buf;
gchar *p = s_buf;
- /* Skip whitespaces and empty lines */
- while (*p && g_ascii_isspace(*p)) p++;
- if (*p == '\n' || *p == '\r') continue;
+ if (!reading_extended_filename)
+ {
+ /* Skip whitespaces and empty lines */
+ while (*p && g_ascii_isspace(*p)) p++;
+ if (*p == '\n' || *p == '\r') continue;
+
+ /* Parse comments */
+ if (*p == '#')
+ {
+ if (!need_header) continue;
+ if (g_ascii_strncasecmp(p, GQ_COLLECTION_MARKER, strlen(GQ_COLLECTION_MARKER)) == 0)
+ {
+ /* Looks like an official collection, allow unchecked input.
+ * All this does is allow adding files that may not exist,
+ * which is needed for the collection manager to work.
+ * Also unofficial files abort after too many invalid entries.
+ */
+ has_official_header = TRUE;
+ limit_failures = FALSE;
+ }
+ else if (strncmp(p, "#geometry:", 10 ) == 0 &&
+ scan_geometry(p + 10, &cd->window_x, &cd->window_y, &cd->window_w, &cd->window_h))
+ {
+ has_geometry_header = TRUE;
+ cd->window_read = TRUE;
+ if (only_geometry) break;
+ }
+ else if (g_ascii_strncasecmp(p, "#GQview collection", strlen("#GQview collection")) == 0)
+ {
+ /* As 2008/04/15 there is no difference between our collection file format
+ * and GQview 2.1.5 collection file format so ignore failures as well. */
+ has_gqview_header = TRUE;
+ limit_failures = FALSE;
+ }
+ need_header = (!has_official_header && !has_gqview_header) || !has_geometry_header;
+ continue;
+ }
+
+ if (only_geometry) continue;
+ }
- /* Parse comments */
- if (*p == '#')
+ /* Read filenames */
+ /** @todo This is not safe! */
+ /* Updated: anything within double quotes is considered a filename */
+ if (!reading_extended_filename)
{
- if (!need_header) continue;
- if (g_ascii_strncasecmp(p, GQ_COLLECTION_MARKER, strlen(GQ_COLLECTION_MARKER)) == 0)
+ /* not yet reading filename */
+ while (*p && *p != '"') p++;
+ if (*p) p++;
+ /* start of filename read */
+ buf = p;
+ while (*p && *p != '"') p++;
+ if (p[0] != '"')
{
- /* Looks like an official collection, allow unchecked input.
- * All this does is allow adding files that may not exist,
- * which is needed for the collection manager to work.
- * Also unofficial files abort after too many invalid entries.
- */
- has_official_header = TRUE;
- limit_failures = FALSE;
+ /* first part of extended filename */
+ g_string_append(extended_filename_buffer, buf);
+ reading_extended_filename = TRUE;
+ continue;
}
- else if (strncmp(p, "#geometry:", 10 ) == 0 &&
- scan_geometry(p + 10, &cd->window_x, &cd->window_y, &cd->window_w, &cd->window_h))
+ }
+ else
+ {
+ buf = p;
+ while (*p && *p != '"') p++;
+ if (p[0] != '"')
{
- has_geometry_header = TRUE;
- cd->window_read = TRUE;
- if (only_geometry) break;
+ /* end of extended filename still not found */
+ g_string_append(extended_filename_buffer, buf);
+ continue;
}
- else if (g_ascii_strncasecmp(p, "#GQview collection", strlen("#GQview collection")) == 0)
+ else
{
- /* As 2008/04/15 there is no difference between our collection file format
- * and GQview 2.1.5 collection file format so ignore failures as well. */
- has_gqview_header = TRUE;
- limit_failures = FALSE;
+ /* end of extended filename found */
+ g_string_append_len(extended_filename_buffer, buf, p - buf);
+ reading_extended_filename = FALSE;
}
- need_header = (!has_official_header && !has_gqview_header) || !has_geometry_header;
- continue;
}
- if (only_geometry) continue;
+ if (strlen(extended_filename_buffer->str) > 0)
+ {
+ buffer2 = g_strdup(extended_filename_buffer->str);
+ g_string_erase(extended_filename_buffer, 0, -1);
+ }
+ else
+ {
+ *p = 0;
+ buffer2 = g_strdup(buf);
+ }
- /* Read filenames */
- /* TODO: This is not safe! */
- while (*p && *p != '"') p++;
- if (*p) p++;
- buf = p;
- while (*p && *p != '"') p++;
- *p = 0;
- if (*buf)
+ if (*buffer2)
{
gboolean valid;
if (!flush)
- changed |= collect_manager_process_action(entry, &buf);
+ changed |= collect_manager_process_action(entry, &buffer2);
- valid = (buf[0] == G_DIR_SEPARATOR && collection_add_check(cd, file_data_new_simple(buf), FALSE, TRUE));
- if (!valid) DEBUG_1("collection invalid file: %s", buf);
+ valid = (buffer2[0] == G_DIR_SEPARATOR && collection_add_check(cd, file_data_new_simple(buffer2), FALSE, TRUE));
+ if (!valid) DEBUG_1("collection invalid file: %s", buffer2);
total++;
if (!valid)
}
}
}
+ g_free(buffer2);
}
+ g_string_free(extended_filename_buffer, TRUE);
+
DEBUG_1("collection files: total = %d fail = %d official=%d gqview=%d geometry=%d",
total, fail, has_official_header, has_gqview_header, has_geometry_header);
if (action)
{
- g_free(path);
- path = g_strdup(action->newpath);
- *path_ptr = path;
+ strcpy(*path_ptr, action->newpath);
return TRUE;
}
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);
+}
+
+/**
+ * @brief Creates sorted list of collections
+ * @param[out] names_exc sorted list of collections names excluding extension
+ * @param[out] names_inc sorted list of collections names including extension
+ * @param[out] paths sorted list of collection paths
+ *
+ * Lists of type gchar.
+ * 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: */