#include "secure_save.h"
#include "exif.h"
+#include "misc.h"
#include <errno.h>
+#include <grp.h>
#ifdef DEBUG_FILEDATA
gint global_file_data_count = 0;
}
if (size < (gint64)1048576)
{
- return g_strdup_printf(_("%.1f K"), (gdouble)size / 1024.0);
+ return g_strdup_printf(_("%.1f KiB"), (gdouble)size / 1024.0);
}
if (size < (gint64)1073741824)
{
- return g_strdup_printf(_("%.1f MB"), (gdouble)size / 1048576.0);
+ return g_strdup_printf(_("%.1f MiB"), (gdouble)size / 1048576.0);
}
/* to avoid overflowing the gdouble, do division in two steps */
size /= 1048576;
- return g_strdup_printf(_("%.1f GB"), (gdouble)size / 1024.0);
+ return g_strdup_printf(_("%.1f GiB"), (gdouble)size / 1024.0);
}
/* note: returned string is valid until next call to text_from_time() */
static FileData *file_data_new(const gchar *path_utf8, struct stat *st, gboolean disable_sidecars)
{
FileData *fd;
+ struct passwd *user;
+ struct group *group;
DEBUG_2("file_data_new: '%s' %d", path_utf8, disable_sidecars);
fd->ref = 1;
fd->magick = FD_MAGICK;
fd->exifdate = 0;
- fd->rating = 0;
+ fd->rating = STAR_RATING_NOT_READ;
fd->format_class = filter_file_get_class(path_utf8);
+ fd->page_num = 0;
+ fd->page_total = 0;
+
+ user = getpwuid(st->st_uid);
+ if (!user)
+ {
+ fd->owner = g_strdup_printf("%u", st->st_uid);
+ }
+ else
+ {
+ fd->owner = g_strdup(user->pw_name);
+ }
+
+ group = getgrgid(st->st_gid);
+ if (!group)
+ {
+ fd->group = g_strdup_printf("%u", st->st_gid);
+ }
+ else
+ {
+ fd->group = g_strdup(group->gr_name);
+ }
+
+ fd->sym_link = get_symbolic_link(path_utf8);
if (disable_sidecars) fd->disable_grouping = TRUE;
return;
}
- file->exif = exif_read_fd(file);
+ if (!file->exif)
+ {
+ exif_read_fd(file);
+ }
if (file->exif)
{
return;
}
- file->exif = exif_read_fd(file);
+ if (!file->exif)
+ {
+ exif_read_fd(file);
+ }
if (file->exif)
{
}
}
+void read_rating_data(FileData *file)
+{
+ gchar *rating_str;
+
+ rating_str = metadata_read_string(file, RATING_KEY, METADATA_PLAIN);
+ if (rating_str)
+ {
+ file->rating = atoi(rating_str);
+ g_free(rating_str);
+ }
+ else
+ {
+ file->rating = 0;
+ }
+}
+
void set_exif_time_data(GList *files)
{
DEBUG_1("%s set_exif_time_data: ...", get_exec_time());
g_free(fd->extended_extension);
if (fd->thumb_pixbuf) g_object_unref(fd->thumb_pixbuf);
histmap_free(fd->histmap);
-
+ g_free(fd->owner);
+ g_free(fd->group);
+ g_free(fd->sym_link);
g_assert(fd->sidecar_files == NULL); /* sidecar files must be freed before calling this */
file_data_change_info_free(NULL, fd);
}
/**
- * \brief Checks if the FileData is referenced
+ * @brief Checks if the FileData is referenced
*
* Checks the refcount and whether the FileData is locked.
*/
}
/**
- * \brief Consider freeing a FileData.
+ * @brief Consider freeing a FileData.
*
* This function will free a FileData and its children provided that neither its parent nor it has
* a positive refcount, and provided that neither is locked.
}
/**
- * \brief Lock the FileData in memory.
+ * @brief Lock the FileData in memory.
*
* This allows the caller to prevent a FileData from being freed, even after its refcount is zero.
* This is intended to be used in cases where a FileData _should_ stay in memory as an optimization,
}
/**
- * \brief Reset the maintain-FileData-in-memory lock
+ * @brief Reset the maintain-FileData-in-memory lock
*
* This again allows the FileData to be freed when its refcount drops to zero. Automatically frees
* the FileData if its refcount is already zero (which will happen if the lock is the only thing
}
/**
- * \brief Lock all of the FileDatas in the provided list
+ * @brief Lock all of the FileDatas in the provided list
*
- * \see file_data_lock(FileData)
+ * @see file_data_lock(#FileData)
*/
void file_data_lock_list(GList *list)
{
}
/**
- * \brief Unlock all of the FileDatas in the provided list
+ * @brief Unlock all of the FileDatas in the provided list
*
- * \see file_data_unlock(FileData)
+ * @see #file_data_unlock(#FileData)
*/
void file_data_unlock_list(GList *list)
{
GList *filelist_sort(GList *list, SortType method, gboolean ascend)
{
- if (method == SORT_EXIFTIME)
- {
- set_exif_time_data(list);
- }
- if (method == SORT_EXIFTIMEDIGITIZED)
- {
- set_exif_time_digitized_data(list);
- }
- if (method == SORT_RATING)
- {
- set_rating_data(list);
- }
return filelist_sort_full(list, method, ascend, (GCompareFunc) filelist_sort_file_cb);
}
}
}
+static void filelist_recursive_append_full(GList **list, GList *dirs, SortType method, gboolean ascend)
+{
+ GList *work;
+
+ work = dirs;
+ while (work)
+ {
+ FileData *fd = (FileData *)(work->data);
+ GList *f;
+ GList *d;
+
+ if (filelist_read(fd, &f, &d))
+ {
+ f = filelist_filter(f, FALSE);
+ f = filelist_sort_full(f, method, ascend, (GCompareFunc) filelist_sort_file_cb);
+ *list = g_list_concat(*list, f);
+
+ d = filelist_filter(d, TRUE);
+ d = filelist_sort_path(d);
+ filelist_recursive_append_full(list, d, method, ascend);
+ filelist_free(d);
+ }
+
+ work = work->next;
+ }
+}
+
GList *filelist_recursive(FileData *dir_fd)
{
GList *list;
return list;
}
+GList *filelist_recursive_full(FileData *dir_fd, SortType method, gboolean ascend)
+{
+ GList *list;
+ GList *d;
+
+ if (!filelist_read(dir_fd, &list, &d)) return NULL;
+ list = filelist_filter(list, FALSE);
+ list = filelist_sort_full(list, method, ascend, (GCompareFunc) filelist_sort_file_cb);
+
+ d = filelist_filter(d, TRUE);
+ d = filelist_sort_path(d);
+ filelist_recursive_append_full(&list, d, method, ascend);
+ filelist_free(d);
+
+ return list;
+}
+
/*
*-----------------------------------------------------------------------------
* file modification support
return list;
}
+gboolean file_data_filter_file_filter(FileData *fd, GRegex *filter)
+{
+ return g_regex_match(filter, fd->name, 0, NULL);
+}
+
+GList *file_data_filter_file_filter_list(GList *list, GRegex *filter)
+{
+ GList *work;
+
+ work = list;
+ while (work)
+ {
+ FileData *fd = work->data;
+ GList *link = work;
+ work = work->next;
+
+ if (!file_data_filter_file_filter(fd, filter))
+ {
+ list = g_list_remove_link(list, link);
+ file_data_unref(fd);
+ g_list_free(link);
+ }
+ }
+
+ return list;
+}
+
+static gboolean file_data_filter_class(FileData *fd, guint filter)
+{
+ gint i;
+
+ for (i = 0; i < FILE_FORMAT_CLASSES; i++)
+ {
+ if (filter & (1 << i))
+ {
+ if ((FileFormatClass)i == filter_file_get_class(fd->path))
+ {
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+GList *file_data_filter_class_list(GList *list, guint filter)
+{
+ GList *work;
+
+ work = list;
+ while (work)
+ {
+ FileData *fd = work->data;
+ GList *link = work;
+ work = work->next;
+
+ if (!file_data_filter_class(fd, filter))
+ {
+ list = g_list_remove_link(list, link);
+ file_data_unref(fd);
+ g_list_free(link);
+ }
+ }
+
+ return list;
+}
+
static void file_data_notify_mark_func(gpointer key, gpointer value, gpointer user_data)
{
FileData *fd = value;
COPY
MOVE - path is changed, name may be changed too
RENAME - path remains unchanged, name is changed
- extension should remain (FIXME should we allow editing extension? it will make problems wth grouping)
+ extension should remain (FIXME should we allow editing extension? it will make problems with grouping)
sidecar names are changed too, extensions are not changed
DELETE
UPDATE - file size, date or grouping has been changed
}
else
{
- if (fd->change->type != FILEDATA_CHANGE_UNSPECIFIED) /* FIXME this is now needed for running editors */
+ if (fd->change->type != FILEDATA_CHANGE_UNSPECIFIED) /** @FIXME this is now needed for running editors */
{
ret |= CHANGE_WARN_SAME;
DEBUG_1("Change checked: source and destination are the same: %s -> %s", fd->path, fd->change->dest);
{
FileDataChangeType type = fd->change->type;
- /* FIXME delete ?*/
+ /** @FIXME delete ?*/
if (type == FILEDATA_CHANGE_MOVE || type == FILEDATA_CHANGE_RENAME)
{
DEBUG_1("planned change: applying %s -> %s", fd->change->dest, fd->path);
/* this change overwrites another file which is already known to other modules
renaming fd would create duplicate FileData structure
the best thing we can do is nothing
- FIXME: maybe we could copy stuff like marks
+ */
+ /** @FIXME maybe we could copy stuff like marks
*/
DEBUG_1("can't rename fd, target exists %s -> %s", fd->change->dest, fd->path);
}
}
/* remove sidecars from the list,
- they can be still acessed via main_fd->sidecar_files */
+ they can be still accessed via main_fd->sidecar_files */
work = list;
while (work)
{
* notify other modules about the change described by FileDataChangeInfo
*/
-/* might use file_maint_ functions for now, later it should be changed to a system of callbacks
- FIXME do we need the ignore_list? It looks like a workaround for ineffective
+/* might use file_maint_ functions for now, later it should be changed to a system of callbacks */
+/** @FIXME do we need the ignore_list? It looks like a workaround for ineffective
implementation in view_file_list.c */
marks_value = strtok(NULL, ",");
if (isfile(file_path))
{
- FileData *fd = file_data_new_group(file_path);
+ FileData *fd = file_data_new_no_grouping(file_path);
file_data_ref(fd);
gint n = 0;
while (n <= 9)
{
g_hash_table_foreach(file_data_pool, marks_clear, NULL);
}
+
+void file_data_set_page_num(FileData *fd, gint page_num)
+{
+ if (fd->page_total > 1 && page_num < 0)
+ {
+ fd->page_num = fd->page_total - 1;
+ }
+ else if (fd->page_total > 1 && page_num <= fd->page_total)
+ {
+ fd->page_num = page_num - 1;
+ }
+ else
+ {
+ fd->page_num = 0;
+ }
+ file_data_send_notification(fd, NOTIFY_REREAD);
+}
+
+void file_data_inc_page_num(FileData *fd)
+{
+ if (fd->page_total > 0 && fd->page_num < fd->page_total - 1)
+ {
+ fd->page_num = fd->page_num + 1;
+ }
+ else if (fd->page_total == 0)
+ {
+ fd->page_num = fd->page_num + 1;
+ }
+ file_data_send_notification(fd, NOTIFY_REREAD);
+}
+
+void file_data_dec_page_num(FileData *fd)
+{
+ if (fd->page_num > 0)
+ {
+ fd->page_num = fd->page_num - 1;
+ }
+ file_data_send_notification(fd, NOTIFY_REREAD);
+}
+
+void file_data_set_page_total(FileData *fd, gint page_total)
+{
+ fd->page_total = page_total;
+}
+
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */