gint thumb_gap;
gint image_size;
+ gint ignore_symlinks;
+
GList *list;
GList *list_static;
GList *list_grid;
static GList *pan_window_list = NULL;
-static GList *pan_window_layout_list(const gchar *path, SortType sort, gint ascend);
+static GList *pan_window_layout_list(const gchar *path, SortType sort, gint ascend,
+ gint ignore_symlinks);
static GList *pan_layout_intersect(PanWindow *pw, gint x, gint y, gint width, gint height);
pan_cache_free(pw);
- list = pan_window_layout_list(path, SORT_NAME, TRUE);
+ list = pan_window_layout_list(path, SORT_NAME, TRUE, pw->ignore_symlinks);
pw->cache_todo = g_list_reverse(list);
pw->cache_total = g_list_length(pw->cache_todo);
*-----------------------------------------------------------------------------
*/
-static GList *pan_window_layout_list(const gchar *path, SortType sort, gint ascend)
+static gint islink_loop(const gchar *s)
+{
+ gchar *sl;
+ struct stat st;
+ gint ret = FALSE;
+
+ sl = path_from_utf8(s);
+
+ if (lstat(sl, &st) == 0 && S_ISLNK(st.st_mode))
+ {
+ gchar *buf;
+ gint l;
+
+ buf = g_malloc(st.st_size + 1);
+ l = readlink(sl, buf, st.st_size);
+ if (l == st.st_size)
+ {
+ buf[l] = '\0';
+
+ parse_out_relatives(buf);
+ l = strlen(buf);
+
+ parse_out_relatives(sl);
+
+ if (buf[0] == '/')
+ {
+ if (strncmp(sl, buf, l) == 0 &&
+ (sl[l] == '\0' || sl[l] == '/' || l == 1)) ret = TRUE;
+ }
+ else
+ {
+ gchar *link_path;
+
+ link_path = concat_dir_and_file(sl, buf);
+ parse_out_relatives(link_path);
+
+ if (strncmp(sl, link_path, l) == 0 &&
+ (sl[l] == '\0' || sl[l] == '/' || l == 1)) ret = TRUE;
+
+ g_free(link_path);
+ }
+ }
+
+ g_free(buf);
+ }
+
+ g_free(sl);
+
+ return ret;
+}
+
+static gint is_ignored(const gchar *s, gint ignore_symlinks)
+{
+ struct stat st;
+ const gchar *n;
+
+ if (!lstat_utf8(s, &st)) return TRUE;
+
+#if 0
+ /* normal filesystems have directories with some size or block allocation,
+ * special filesystems (like linux /proc) set both to zero.
+ * enable this check if you enable listing the root "/" folder
+ */
+ if (st.st_size == 0 && st.st_blocks == 0) return TRUE;
+#endif
+
+ if (S_ISLNK(st.st_mode) && (ignore_symlinks || islink_loop(s))) return TRUE;
+
+ n = filename_from_path(s);
+ if (n && strcmp(n, GQVIEW_RC_DIR) == 0) return TRUE;
+
+ return FALSE;
+}
+
+static GList *pan_window_layout_list(const gchar *path, SortType sort, gint ascend,
+ gint ignore_symlinks)
{
GList *flist = NULL;
GList *dlist = NULL;
fd = folders->data;
folders = g_list_remove(folders, fd);
- if (filelist_read(fd->path, &flist, &dlist))
+ if (!is_ignored(fd->path, ignore_symlinks) &&
+ filelist_read(fd->path, &flist, &dlist))
{
if (sort != SORT_NONE)
{
gint grid_size;
gint next_y;
- list = pan_window_layout_list(path, SORT_NAME, TRUE);
+ list = pan_window_layout_list(path, SORT_NAME, TRUE, pw->ignore_symlinks);
grid_size = (gint)sqrt((double)g_list_length(list));
if (pw->size > LAYOUT_SIZE_THUMB_LARGE)
pan_item_size_by_item(pi_box, pi, PAN_FOLDER_BOX_BORDER);
}
- g_list_free(f);
-
group = g_new0(FlowerGroup, 1);
group->items = pw->list;
pw->list = NULL;
fd = work->data;
work = work->next;
- child = pan_window_layout_compute_folders_flower_path(pw, fd->path, 0, 0);
- if (child) group->children = g_list_prepend(group->children, child);
+ if (!is_ignored(fd->path, pw->ignore_symlinks))
+ {
+ child = pan_window_layout_compute_folders_flower_path(pw, fd->path, 0, 0);
+ if (child) group->children = g_list_prepend(group->children, child);
+ }
+ }
+
+ if (!f && !group->children)
+ {
+ work = group->items;
+ while (work)
+ {
+ PanItem *pi;
+
+ pi = work->data;
+ work = work->next;
+
+ pan_item_free(pi);
+ }
+
+ g_list_free(group->items);
+ g_free(group);
+ group = NULL;
}
+ g_list_free(f);
filelist_free(d);
return group;
fd = work->data;
work = work->next;
- *level = *level + 1;
- pan_window_layout_compute_folders_linear_path(pw, fd->path, x, y, level,
- pi_box, width, height);
- *level = *level - 1;
+ if (!is_ignored(fd->path, pw->ignore_symlinks))
+ {
+ *level = *level + 1;
+ pan_window_layout_compute_folders_linear_path(pw, fd->path, x, y, level,
+ pi_box, width, height);
+ *level = *level - 1;
+ }
}
filelist_free(d);
gint end_year = 0;
gint end_month = 0;
- list = pan_window_layout_list(path, SORT_NONE, TRUE);
+ list = pan_window_layout_list(path, SORT_NONE, TRUE, pw->ignore_symlinks);
if (pw->cache_list && SORT_BY_EXIF_DATE)
{
gint x_width;
gint y_height;
- list = pan_window_layout_list(path, SORT_NONE, TRUE);
+ list = pan_window_layout_list(path, SORT_NONE, TRUE, pw->ignore_symlinks);
if (pw->cache_list && SORT_BY_EXIF_DATE)
{
g_free(buf);
}
+static void pan_warning_folder(const gchar *path, GtkWidget *parent)
+{
+ gchar *message;
+
+ message = g_strdup_printf(_("The pan view does not support the folder \"%s\"."), path);
+ warning_dialog(_("Folder not supported"), message,
+ GTK_STOCK_DIALOG_INFO, parent);
+ g_free(message);
+}
+
static void pan_window_zoom_limit(PanWindow *pw)
{
gdouble min;
pan_window_layout_update_idle(pw);
}
+static void pan_window_layout_set_path(PanWindow *pw, const gchar *path)
+{
+ if (!path) return;
+
+ if (strcmp(path, "/") == 0)
+ {
+ pan_warning_folder(path, pw->window);
+ return;
+ }
+
+ g_free(pw->path);
+ pw->path = g_strdup(path);
+
+ pan_window_layout_update(pw);
+}
+
/*
*-----------------------------------------------------------------------------
* pan window keyboard
{
tab_completion_append_to_history(pw->path_entry, path);
- g_free(pw->path);
- pw->path = g_strdup(path);
-
- pan_window_layout_update(pw);
+ pan_window_layout_set_path(pw, path);
}
g_free(path);
pw->thumb_size = PAN_THUMB_SIZE_NORMAL;
pw->thumb_gap = PAN_THUMB_GAP_NORMAL;
+ pw->ignore_symlinks = TRUE;
+
pw->list = NULL;
pw->list_static = NULL;
pw->list_grid = NULL;
GtkWidget *ct_button;
gint hide_dlg;
+ if (path && strcmp(path, "/") == 0)
+ {
+ pan_warning_folder(path, NULL);
+ return TRUE;
+ }
+
if (enable_thumb_caching &&
thumbnail_spec_standard) return FALSE;
{
gchar *path = list->data;
- g_free(pw->path);
- pw->path = g_strdup(path);
-
- pan_window_layout_update(pw);
+ pan_window_layout_set_path(pw, path);
}
path_list_free(list);
sw = gdk_pixbuf_get_width(pixbuf);
sh = gdk_pixbuf_get_height(pixbuf);
- if (tl->cache_enable && !tl->cache_hit &&
- (sw >= THUMB_SIZE_NORMAL || sh >= THUMB_SIZE_NORMAL || shrunk))
+ if (tl->cache_enable)
{
- gint cache_w, cache_h;
- gint thumb_w, thumb_h;
-
- if (tl->requested_width > THUMB_SIZE_NORMAL || tl->requested_height > THUMB_SIZE_NORMAL)
+ if (!tl->cache_hit)
{
- cache_w = cache_h = THUMB_SIZE_LARGE;
- }
- else
- {
- cache_w = cache_h = THUMB_SIZE_NORMAL;
- }
+ gint cache_w, cache_h;
- if (thumb_loader_std_scale_aspect(cache_w, cache_h, sw, sh,
- &thumb_w, &thumb_h))
- {
- pixbuf_thumb = gdk_pixbuf_scale_simple(pixbuf, thumb_w, thumb_h,
- (GdkInterpType)thumbnail_quality);
+ if (tl->requested_width > THUMB_SIZE_NORMAL || tl->requested_height > THUMB_SIZE_NORMAL)
+ {
+ cache_w = cache_h = THUMB_SIZE_LARGE;
+ }
+ else
+ {
+ cache_w = cache_h = THUMB_SIZE_NORMAL;
+ }
+
+ if (sw > cache_w || sh > cache_h || shrunk)
+ {
+ gint thumb_w, thumb_h;
+
+ if (thumb_loader_std_scale_aspect(cache_w, cache_h, sw, sh,
+ &thumb_w, &thumb_h))
+ {
+ pixbuf_thumb = gdk_pixbuf_scale_simple(pixbuf, thumb_w, thumb_h,
+ (GdkInterpType)thumbnail_quality);
+ }
+ else
+ {
+ pixbuf_thumb = pixbuf;
+ g_object_ref(G_OBJECT(pixbuf_thumb));
+ }
+
+ thumb_loader_std_save(tl, pixbuf_thumb);
+ }
}
- else
+ else if (tl->cache_hit &&
+ tl->cache_local && !tl->thumb_path_local)
{
- pixbuf_thumb = pixbuf;
- g_object_ref(G_OBJECT(pixbuf_thumb));
- }
-
- thumb_loader_std_save(tl, pixbuf_thumb);
- }
- else if (tl->cache_enable && tl->cache_local &&
- tl->cache_hit && !tl->thumb_path_local)
- {
- /* A local cache save was requested, but a valid thumb is in $HOME,
- * so specifically save as a local thumbnail.
- */
- g_free(tl->thumb_path);
- tl->thumb_path = NULL;
+ /* A local cache save was requested, but a valid thumb is in $HOME,
+ * so specifically save as a local thumbnail.
+ */
+ g_free(tl->thumb_path);
+ tl->thumb_path = NULL;
- tl->cache_hit = FALSE;
+ tl->cache_hit = FALSE;
- if (debug) printf("thumb copied: %s\n", tl->source_path);
+ if (debug) printf("thumb copied: %s\n", tl->source_path);
- thumb_loader_std_save(tl, pixbuf);
+ thumb_loader_std_save(tl, pixbuf);
+ }
}
if (sw <= tl->requested_width && sh <= tl->requested_height)