Fix #431: Bookmarks (shortcuts) to folders
authorColin Clark <cclark@mcb.net>
Fri, 24 Feb 2017 16:25:33 +0000 (16:25 +0000)
committerColin Clark <cclark@mcb.net>
Fri, 24 Feb 2017 16:25:33 +0000 (16:25 +0000)
Additional section in the folders pane to permit shortcuts (bookmarks)
to commonly used folders or images.

doc/docbook/GuideMainWindowFolderPane.xml
src/Makefile.am
src/layout.c
src/shortcuts.c [new file with mode: 0644]
src/shortcuts.h [new file with mode: 0644]
src/typedefs.h

index 0e22dcf..10e6fbc 100644 (file)
   </section>\r
   <section id="Folderlist">\r
     <title>Folder list</title>\r
-    <para>This displays a list of sub folders contained in the active folder, or a tree that includes all folders in the file system.</para>\r
-    <para>\r
-      A\r
-      <emphasis role="strong">context menu</emphasis>\r
-      can be displayed by clicking the right mouse button on the folder pane or pressing the menu key while the folder pane has the focus\r
-    </para>\r
-    <para />\r
+    <para>This pane consists of two sections: a folder pane and a shortcuts pane. The shortcuts pane may be hidden or revealed simply by moving the vertical divider to or from the extreme left.</para>\r
+    <section id="folders">\r
+      <title>Folders</title>\r
+      <para>This displays a list of sub folders contained in the active folder, or a tree that includes all folders in the file system.</para>\r
+      <para>\r
+        A\r
+        <emphasis role="strong">context menu</emphasis>\r
+        can be displayed by clicking the right mouse button on the folder pane or pressing the menu key while the folder pane has the focus\r
+      </para>\r
+    </section>\r
+    <section id="Shortcutslist">\r
+      <title>Shortcuts</title>\r
+      <para>This is a list of shortcuts (bookmarks) to commonly used folders or images. A context menu will appear by right clicking on an item, or pressing the menu key when the item has the focus.</para>\r
+      <para>Folders or images can be added to the list by activating the Add button at the bottom of the pane, or dragging a folder or image onto the list.</para>\r
+      <para>\r
+        To edit an item select\r
+        <emphasis role="bold">Properties</emphasis>\r
+        from its context menu. A dialog will appear allowing the Name, Path, and Icon for the item to be changed. Select OK to close the dialog and apply the changes, or Cancel to close the dialog and discard the changes.\r
+      </para>\r
+      <para>\r
+        To change the order of the list, select\r
+        <emphasis role="bold">Move up</emphasis>\r
+        or\r
+        <emphasis role="bold">Move down</emphasis>\r
+        from the item's context menu. To move an item with the keyboard move the focus to that item, then press\r
+        <keycombo>\r
+          <keycap>Shift</keycap>\r
+          <keycap>Up</keycap>\r
+        </keycombo>\r
+        or\r
+        <keycombo>\r
+          <keycap>Shift</keycap>\r
+          <keycap>Down</keycap>\r
+        </keycombo>\r
+        to move the item.\r
+      </para>\r
+      <para>\r
+        To remove an item from the list select\r
+        <emphasis role="bold">Remove</emphasis>\r
+        from it's context menu.\r
+      </para>\r
+      <para />\r
+    </section>\r
   </section>\r
   <section id="Listview">\r
     <title>List view</title>\r
index 151c658..3900a39 100644 (file)
@@ -226,6 +226,8 @@ geeqie_SOURCES = \
        search.h        \
        secure_save.c   \
        secure_save.h   \
+       shortcuts.c     \
+       shortcuts.h     \
        similar.c       \
        similar.h       \
        slideshow.c     \
index 1e4347f..2ac8fa3 100644 (file)
@@ -46,7 +46,7 @@
 #include "bar.h"
 #include "bar_sort.h"
 #include "preferences.h"
-
+#include "shortcuts.h"
 #ifdef HAVE_LIRC
 #include "lirc.h"
 #endif
@@ -183,6 +183,21 @@ static gboolean layout_set_current_cb(GtkWidget *widget, GdkEventFocus *event, g
        return FALSE;
 }
 
+static void layout_box_folders_changed_cb(GtkWidget *widget, gpointer data)
+{
+       LayoutWindow *lw;
+       GList *work;
+
+/* FIXME: this is probably not the correct way to implement this */
+       work = layout_window_list;
+       while (work)
+               {
+               lw = work->data;
+               lw->options.folder_window.vdivider_pos = gtk_paned_get_position(GTK_PANED(widget));
+               work = work->next;
+               }
+}
+
 /*
  *-----------------------------------------------------------------------------
  * menu, toolbar, and dir view
@@ -272,6 +287,8 @@ static void layout_path_entry_tab_append_cb(const gchar *path, gpointer data, gi
 static GtkWidget *layout_tool_setup(LayoutWindow *lw)
 {
        GtkWidget *box;
+       GtkWidget *box_folders;
+       GtkWidget *scd;
        GtkWidget *menu_bar;
        GtkWidget *tabcomp;
        GtkWidget *toolbar;
@@ -300,15 +317,26 @@ static GtkWidget *layout_tool_setup(LayoutWindow *lw)
                         G_CALLBACK(layout_path_entry_changed_cb), lw);
 #endif
 
+       box_folders = GTK_WIDGET(gtk_hpaned_new());
+       gtk_box_pack_start(GTK_BOX(box), box_folders, TRUE, TRUE, 0);
+
        lw->vd = vd_new(lw->options.dir_view_type, lw->dir_fd);
        vd_set_layout(lw->vd, lw);
        vd_set_select_func(lw->vd, layout_vd_select_cb, lw);
 
        lw->dir_view = lw->vd->widget;
-
-       gtk_box_pack_start(GTK_BOX(box), lw->dir_view, TRUE, TRUE, 0);
+       gtk_paned_add2(GTK_PANED(box_folders), lw->dir_view);
        gtk_widget_show(lw->dir_view);
 
+       scd = shortcuts_new_default(lw);
+       gtk_paned_add1(GTK_PANED(box_folders), scd);
+       gtk_paned_set_position(GTK_PANED(box_folders), lw->options.folder_window.vdivider_pos);
+
+       gtk_widget_show(box_folders);
+
+       g_signal_connect(G_OBJECT(box_folders), "notify::position",
+                        G_CALLBACK(layout_box_folders_changed_cb), lw);
+
        gtk_widget_show(box);
 
        return box;
@@ -2277,6 +2305,9 @@ void layout_write_attributes(LayoutOptions *layout, GString *outstr, gint indent
        WRITE_NL(); WRITE_INT(*layout, main_window.vdivider_pos);
        WRITE_SEPARATOR();
 
+       WRITE_NL(); WRITE_INT(*layout, folder_window.vdivider_pos);
+       WRITE_SEPARATOR();
+
        WRITE_NL(); WRITE_INT(*layout, float_window.x);
        WRITE_NL(); WRITE_INT(*layout, float_window.y);
        WRITE_NL(); WRITE_INT(*layout, float_window.w);
@@ -2351,6 +2382,8 @@ void layout_load_attributes(LayoutOptions *layout, const gchar **attribute_names
                if (READ_INT(*layout, main_window.hdivider_pos)) continue;
                if (READ_INT(*layout, main_window.vdivider_pos)) continue;
 
+               if (READ_INT_CLAMP(*layout, folder_window.vdivider_pos, 1, 1000)) continue;
+
                if (READ_INT(*layout, float_window.x)) continue;
                if (READ_INT(*layout, float_window.y)) continue;
                if (READ_INT(*layout, float_window.w)) continue;
diff --git a/src/shortcuts.c b/src/shortcuts.c
new file mode 100644 (file)
index 0000000..c801fc8
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2004 John Ellis
+ * Copyright (C) 2008 - 2016 The Geeqie Team
+ *
+ * Author: John Ellis
+ *
+ * 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 "shortcuts.h"
+
+#include "layout.h"
+#include "utilops.h"
+#include "ui_bookmark.h"
+#include "ui_fileops.h"
+#include "ui_misc.h"
+
+typedef struct _ShortcutsData ShortcutsData;
+struct _ShortcutsData
+{
+       GtkWidget *vbox;
+       GtkWidget *bookmarks;
+       LayoutWindow *lw;
+
+       FileDialog *dialog;
+       GtkWidget *dialog_name_entry;
+
+       GtkWidget *add_button;
+};
+
+#define SHORTCUTS     "shortcuts"
+
+static void shortcuts_bookmark_select(const gchar *path, gpointer data)
+{
+       ShortcutsData *scd = data;
+
+       layout_set_path(scd->lw, path);
+}
+
+static void shortcuts_add_close(ShortcutsData *scd)
+{
+       if (scd->dialog) file_dialog_close(scd->dialog);
+       scd->dialog_name_entry = NULL;
+       scd->dialog = NULL;
+}
+
+static void shortcuts_add_ok_cb(FileDialog *fd, gpointer data)
+{
+       ShortcutsData *scd = data;
+       const gchar *name = gtk_entry_get_text(GTK_ENTRY(scd->dialog_name_entry));
+       gboolean empty_name = (name[0] == '\0');
+
+       name = gtk_entry_get_text(GTK_ENTRY(scd->dialog_name_entry));
+
+       if (empty_name)
+               {
+               name = filename_from_path(fd->dest_path);
+               }
+
+       bookmark_list_add(scd->bookmarks, name, fd->dest_path);
+
+       shortcuts_add_close(scd);
+}
+
+static void shortcuts_add_cancel_cb(FileDialog *fd, gpointer data)
+{
+       ShortcutsData *scd = data;
+
+       shortcuts_add_close(scd);
+}
+
+static void shortcuts_add_cb(GtkWidget *button, gpointer data)
+{
+       ShortcutsData *scd = data;
+       GtkWidget *hbox;
+       const gchar *title;
+
+       if (scd->dialog)
+               {
+               gtk_window_present(GTK_WINDOW(GENERIC_DIALOG(scd->dialog)->dialog));
+               return;
+               }
+
+       title = _("Add Shortcut");
+       scd->dialog = file_util_file_dlg(title,
+                                       "add_shortcuts", button,
+                                       shortcuts_add_cancel_cb, scd);
+       file_dialog_add_button(scd->dialog, GTK_STOCK_OK, NULL, shortcuts_add_ok_cb, TRUE);
+
+       generic_dialog_add_message(GENERIC_DIALOG(scd->dialog), NULL, title, NULL);
+
+       file_dialog_add_path_widgets(scd->dialog, NULL, NULL, "add_shortcuts", NULL, NULL);
+
+       hbox = pref_box_new(GENERIC_DIALOG(scd->dialog)->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP);
+
+       pref_label_new(hbox, _("Name:"));
+
+       scd->dialog_name_entry = gtk_entry_new();
+       gtk_box_pack_start(GTK_BOX(hbox), scd->dialog_name_entry, TRUE, TRUE, 0);
+       generic_dialog_attach_default(GENERIC_DIALOG(scd->dialog), scd->dialog_name_entry);
+       gtk_widget_show(scd->dialog_name_entry);
+
+       gtk_widget_show(GENERIC_DIALOG(scd->dialog)->dialog);
+}
+
+static void shortcuts_destroy(GtkWidget *widget, gpointer data)
+{
+       ShortcutsData *scd = data;
+
+       shortcuts_add_close(scd);
+
+       g_free(scd);
+}
+
+static GtkWidget *shortcuts_new(LayoutWindow *lw)
+{
+       ShortcutsData *scd;
+       GtkWidget *tbar;
+
+       if (!lw) return NULL;
+
+       scd = g_new0(ShortcutsData, 1);
+
+       scd->lw = lw;
+
+       scd->vbox = gtk_vbox_new(FALSE, PREF_PAD_GAP);
+       g_object_set_data(G_OBJECT(scd->vbox), "shortcuts_data", scd);
+       g_signal_connect(G_OBJECT(scd->vbox), "destroy",
+                       G_CALLBACK(shortcuts_destroy), scd);
+
+       scd->bookmarks = bookmark_list_new(SHORTCUTS, shortcuts_bookmark_select, scd);
+       gtk_box_pack_start(GTK_BOX(scd->vbox), scd->bookmarks, TRUE, TRUE, 0);
+       gtk_widget_show(scd->bookmarks);
+
+       tbar = pref_toolbar_new(scd->vbox, GTK_TOOLBAR_ICONS);
+
+       scd->add_button = pref_toolbar_button(tbar, GTK_STOCK_ADD, NULL, FALSE,
+                                       _("Add Shortcut"),
+                                       G_CALLBACK(shortcuts_add_cb), scd);
+
+       return scd->vbox;
+}
+
+GtkWidget *shortcuts_new_from_config(LayoutWindow *lw, const gchar **attribute_names, const gchar **attribute_values)
+{
+       GtkWidget *shortcuts_bar;
+
+       shortcuts_bar = shortcuts_new(lw);
+       gtk_widget_show(shortcuts_bar);
+
+       return shortcuts_bar;
+}
+
+GtkWidget *shortcuts_new_default(LayoutWindow *lw)
+{
+       return shortcuts_new_from_config(lw, NULL, NULL);
+}
+
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
diff --git a/src/shortcuts.h b/src/shortcuts.h
new file mode 100644 (file)
index 0000000..3176905
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2004 John Ellis
+ * Copyright (C) 2008 - 2016 The Geeqie Team
+ *
+ * Author: John Ellis
+ *
+ * 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.
+ */
+
+#ifndef SHORTCUTS_H
+#define SHORTCUTS_H
+
+GtkWidget *shortcuts_new_default(LayoutWindow *lw);
+
+#endif
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
index 07dd8fd..6016faf 100644 (file)
@@ -605,6 +605,10 @@ struct _LayoutOptions
                gint vdivider_pos;
        } float_window;
 
+       struct {
+               gint vdivider_pos;
+       } folder_window;
+
        struct {
                gint w;
                gint h;