Fix build with LTO
[geeqie.git] / src / ui-bookmark.cc
index f8ef298..ed4fb82 100644 (file)
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <string.h>
-
-#include "main.h"
 #include "ui-bookmark.h"
 
+#include <cstdlib>
+#include <cstring>
+#include <memory>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk/gdk.h>
+#include <glib-object.h>
+#include <pango/pango.h>
+
+#include "compat.h"
+#include "debug.h"
 #include "history-list.h"
+#include "intl.h"
+#include "main-defines.h"
+#include "misc.h"
+#include "pixbuf-util.h"
+#include "typedefs.h"
 #include "ui-fileops.h"
 #include "ui-menu.h"
 #include "ui-misc.h"
-#include "ui-utildlg.h"
 #include "ui-tabcomp.h"
+#include "ui-utildlg.h"
 #include "uri-utils.h"
 
-
-
 /*
  *-----------------------------------------------------------------------------
  * bookmarks
 #define MARKER_PATH "[path]"
 #define MARKER_ICON "[icon]"
 
-typedef struct _BookMarkData BookMarkData;
-typedef struct _BookButtonData BookButtonData;
-typedef struct _BookPropData BookPropData;
+struct BookButtonData;
 
-struct _BookMarkData
+struct BookMarkData
 {
        GtkWidget *widget;
        GtkWidget *box;
-       gchar *key;
+       const gchar *key;
 
        void (*select_func)(const gchar *path, gpointer data);
        gpointer select_data;
@@ -64,7 +73,7 @@ struct _BookMarkData
        BookButtonData *active_button;
 };
 
-struct _BookButtonData
+struct BookButtonData
 {
        GtkWidget *button;
        GtkWidget *image;
@@ -77,7 +86,7 @@ struct _BookButtonData
        gchar *parent;
 };
 
-struct _BookPropData
+struct BookPropData
 {
        GtkWidget *name_entry;
        GtkWidget *path_entry;
@@ -94,20 +103,24 @@ enum {
 
 static GtkTargetEntry bookmark_drop_types[] = {
        { const_cast<gchar *>("text/uri-list"), 0, TARGET_URI_LIST },
-       { "x-url/http",    0, TARGET_X_URL },
-       { "_NETSCAPE_URL", 0, TARGET_X_URL }
+       { const_cast<gchar *>("x-url/http"),    0, TARGET_X_URL },
+       { const_cast<gchar *>("_NETSCAPE_URL"), 0, TARGET_X_URL }
+};
+enum {
+       bookmark_drop_types_n = 3
 };
-#define bookmark_drop_types_n 3
 
 static GtkTargetEntry bookmark_drag_types[] = {
        { const_cast<gchar *>("text/uri-list"), 0, TARGET_URI_LIST },
        { const_cast<gchar *>("text/plain"),    0, TARGET_TEXT_PLAIN }
 };
-#define bookmark_drag_types_n 2
+enum {
+       bookmark_drag_types_n = 2
+};
 
 
-static GList *bookmark_widget_list = NULL;
-static GList *bookmark_default_list = NULL;
+static GList *bookmark_widget_list = nullptr;
+static GList *bookmark_default_list = nullptr;
 
 
 static void bookmark_populate_all(const gchar *key);
@@ -125,7 +138,7 @@ static BookButtonData *bookmark_from_string(const gchar *text)
                {
                b->name = g_strdup(_("New Bookmark"));
                b->path = g_strdup(homedir());
-               b->key = NULL;
+               b->key = nullptr;
                return b;
                }
 
@@ -137,7 +150,7 @@ static BookButtonData *bookmark_from_string(const gchar *text)
        if (path_ptr && icon_ptr && icon_ptr < path_ptr)
                {
                log_printf("warning, bookmark icon must be after path\n");
-               return NULL;
+               return nullptr;
                }
 
        if (path_ptr)
@@ -187,19 +200,18 @@ static void bookmark_free(BookButtonData *b)
 static gchar *bookmark_string(const gchar *name, const gchar *path, const gchar *icon)
 {
        if (!name) name = _("New Bookmark");
-       if (icon && strncmp(icon, G_DIR_SEPARATOR_S, 1) != 0) icon = NULL;
 
        if (icon)
                {
-               return g_strdup_printf("%s"MARKER_PATH"%s"MARKER_ICON"%s", name, path, icon);
+               return g_strdup_printf("%s" MARKER_PATH "%s" MARKER_ICON "%s", name, path, icon);
                }
 
-       return g_strdup_printf("%s"MARKER_PATH"%s", name, path);
+       return g_strdup_printf("%s" MARKER_PATH "%s", name, path);
 }
 
 static void bookmark_select_cb(GtkWidget *button, gpointer data)
 {
-       BookMarkData *bm = static_cast<BookMarkData *>(data);
+       auto bm = static_cast<BookMarkData *>(data);
        BookButtonData *b;
 
        b = static_cast<BookButtonData *>(g_object_get_data(G_OBJECT(button), "bookbuttondata"));
@@ -208,29 +220,29 @@ static void bookmark_select_cb(GtkWidget *button, gpointer data)
        if (bm->select_func) bm->select_func(b->path, bm->select_data);
 }
 
-static void bookmark_edit_destroy_cb(GtkWidget *UNUSED(widget), gpointer data)
+static void bookmark_edit_destroy_cb(GtkWidget *, gpointer data)
 {
-       BookPropData *p = static_cast<BookPropData *>(data);
+       auto p = static_cast<BookPropData *>(data);
 
        bookmark_free(p->bb);
        g_free(p);
 }
 
-static void bookmark_edit_cancel_cb(GenericDialog *UNUSED(gd), gpointer UNUSED(data))
+static void bookmark_edit_cancel_cb(GenericDialog *, gpointer)
 {
 }
 
-static void bookmark_edit_ok_cb(GenericDialog *UNUSED(gd), gpointer data)
+static void bookmark_edit_ok_cb(GenericDialog *, gpointer data)
 {
-       BookPropData *p = static_cast<BookPropData *>(data);
+       auto p = static_cast<BookPropData *>(data);
        const gchar *name;
        gchar *path;
        const gchar *icon;
        gchar *new_string;
 
-       name = gtk_entry_get_text(GTK_ENTRY(p->name_entry));
-       path = remove_trailing_slash(gtk_entry_get_text(GTK_ENTRY(p->path_entry)));
-       icon = gtk_entry_get_text(GTK_ENTRY(p->icon_entry));
+       name = gq_gtk_entry_get_text(GTK_ENTRY(p->name_entry));
+       path = remove_trailing_slash(gq_gtk_entry_get_text(GTK_ENTRY(p->path_entry)));
+       icon = gq_gtk_entry_get_text(GTK_ENTRY(p->icon_entry));
 
        new_string = bookmark_string(name, path, icon);
 
@@ -275,38 +287,38 @@ static void bookmark_edit(const gchar *key, const gchar *text, GtkWidget *parent
        g_signal_connect(G_OBJECT(gd->dialog), "destroy",
                         G_CALLBACK(bookmark_edit_destroy_cb), p);
 
-       generic_dialog_add_message(gd, NULL, _("Edit Bookmark"), NULL, FALSE);
+       generic_dialog_add_message(gd, nullptr, _("Edit Bookmark"), nullptr, FALSE);
 
-       generic_dialog_add_button(gd, GTK_STOCK_OK, NULL,
+       generic_dialog_add_button(gd, GQ_ICON_OK, "OK",
                                  bookmark_edit_ok_cb, TRUE);
 
        table = pref_table_new(gd->vbox, 3, 2, FALSE, TRUE);
-       pref_table_label(table, 0, 0, _("Name:"), 1.0);
+       pref_table_label(table, 0, 0, _("Name:"), GTK_ALIGN_END);
 
        p->name_entry = gtk_entry_new();
        gtk_widget_set_size_request(p->name_entry, 300, -1);
-       if (p->bb->name) gtk_entry_set_text(GTK_ENTRY(p->name_entry), p->bb->name);
-       gtk_table_attach_defaults(GTK_TABLE(table), p->name_entry, 1, 2, 0, 1);
+       if (p->bb->name) gq_gtk_entry_set_text(GTK_ENTRY(p->name_entry), p->bb->name);
+       gq_gtk_grid_attach_default(GTK_GRID(table), p->name_entry, 1, 2, 0, 1);
        generic_dialog_attach_default(gd, p->name_entry);
        gtk_widget_show(p->name_entry);
 
-       pref_table_label(table, 0, 1, _("Path:"), 1.0);
+       pref_table_label(table, 0, 1, _("Path:"), GTK_ALIGN_END);
 
        label = tab_completion_new_with_history(&p->path_entry, p->bb->path,
-                                               "bookmark_path", -1, NULL, NULL);
-       tab_completion_add_select_button(p->path_entry, NULL, TRUE);
-       gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 1, 2);
+                                               "bookmark_path", -1, nullptr, nullptr);
+       tab_completion_add_select_button(p->path_entry, nullptr, TRUE);
+       gq_gtk_grid_attach_default(GTK_GRID(table), label, 1, 2, 1, 2);
        generic_dialog_attach_default(gd, p->path_entry);
        gtk_widget_show(label);
 
-       pref_table_label(table, 0, 2, _("Icon:"), 1.0);
+       pref_table_label(table, 0, 2, _("Icon:"), GTK_ALIGN_END);
 
        icon = p->bb->icon;
        if (!icon) icon = "";
        label = tab_completion_new_with_history(&p->icon_entry, icon,
-                                               "bookmark_icons", -1, NULL, NULL);
+                                               "bookmark_icons", -1, nullptr, nullptr);
        tab_completion_add_select_button(p->icon_entry, _("Select icon"), FALSE);
-       gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 2, 3);
+       gq_gtk_grid_attach_default(GTK_GRID(table), label, 1, 2, 2, 3);
        generic_dialog_attach_default(gd, p->icon_entry);
        gtk_widget_show(label);
 
@@ -318,7 +330,7 @@ static void bookmark_move(BookMarkData *bm, GtkWidget *button, gint direction)
        BookButtonData *b;
        gint p;
        GList *list;
-       gchar *key_holder;
+       const gchar *key_holder;
 
        if (!bm->editable) return;
 
@@ -342,7 +354,7 @@ static void bookmark_move(BookMarkData *bm, GtkWidget *button, gint direction)
 
 static void bookmark_menu_prop_cb(GtkWidget *widget, gpointer data)
 {
-       BookMarkData *bm = static_cast<BookMarkData *>(data);
+       auto bm = static_cast<BookMarkData *>(data);
 
        if (!bm->active_button) return;
 
@@ -356,19 +368,19 @@ static void bookmark_menu_move(BookMarkData *bm, gint direction)
        bookmark_move(bm, bm->active_button->button, direction);
 }
 
-static void bookmark_menu_up_cb(GtkWidget *UNUSED(widget), gpointer data)
+static void bookmark_menu_up_cb(GtkWidget *, gpointer data)
 {
-       bookmark_menu_move(data, -1);
+       bookmark_menu_move(static_cast<BookMarkData *>(data), -1);
 }
 
-static void bookmark_menu_down_cb(GtkWidget *UNUSED(widget), gpointer data)
+static void bookmark_menu_down_cb(GtkWidget *, gpointer data)
 {
-       bookmark_menu_move(data, 1);
+       bookmark_menu_move(static_cast<BookMarkData *>(data), 1);
 }
 
-static void bookmark_menu_remove_cb(GtkWidget *UNUSED(widget), gpointer data)
+static void bookmark_menu_remove_cb(GtkWidget *, gpointer data)
 {
-       BookMarkData *bm = static_cast<BookMarkData *>(data);
+       auto bm = static_cast<BookMarkData *>(data);
 
        if (!bm->active_button) return;
 
@@ -376,8 +388,7 @@ static void bookmark_menu_remove_cb(GtkWidget *UNUSED(widget), gpointer data)
        bookmark_populate_all(bm->key);
 }
 
-static void bookmark_menu_popup(BookMarkData *bm, GtkWidget *button,
-                               gint UNUSED(button_n), guint32 UNUSED(time), gboolean local)
+static void bookmark_menu_popup(BookMarkData *bm, GtkWidget *button, gint, guint32, gboolean local)
 {
        GtkWidget *menu;
        BookButtonData *b;
@@ -388,28 +399,28 @@ static void bookmark_menu_popup(BookMarkData *bm, GtkWidget *button,
        bm->active_button = b;
 
        menu = popup_menu_short_lived();
-       menu_item_add_stock_sensitive(menu, _("_Properties..."), GTK_STOCK_PROPERTIES, bm->editable,
+       menu_item_add_icon_sensitive(menu, _("_Properties..."), PIXBUF_INLINE_ICON_PROPERTIES, bm->editable,
                      G_CALLBACK(bookmark_menu_prop_cb), bm);
-       menu_item_add_stock_sensitive(menu, _("Move _up"), GTK_STOCK_GO_UP, bm->editable,
+       menu_item_add_icon_sensitive(menu, _("Move _up"), GQ_ICON_GO_UP, bm->editable,
                      G_CALLBACK(bookmark_menu_up_cb), bm);
-       menu_item_add_stock_sensitive(menu, _("Move _down"), GTK_STOCK_GO_DOWN, bm->editable,
+       menu_item_add_icon_sensitive(menu, _("Move _down"), GQ_ICON_GO_DOWN, bm->editable,
                      G_CALLBACK(bookmark_menu_down_cb), bm);
-       menu_item_add_stock_sensitive(menu, _("_Remove"), GTK_STOCK_REMOVE, bm->editable,
+       menu_item_add_icon_sensitive(menu, _("_Remove"), GQ_ICON_REMOVE, bm->editable,
                      G_CALLBACK(bookmark_menu_remove_cb), bm);
 
        if (local)
                {
-               gtk_menu_popup_at_widget(GTK_MENU(menu), button, GDK_GRAVITY_NORTH_EAST, GDK_GRAVITY_CENTER, NULL);
+               gtk_menu_popup_at_widget(GTK_MENU(menu), button, GDK_GRAVITY_NORTH_EAST, GDK_GRAVITY_CENTER, nullptr);
                }
        else
                {
-               gtk_menu_popup_at_pointer(GTK_MENU(menu), NULL);
+               gtk_menu_popup_at_pointer(GTK_MENU(menu), nullptr);
                }
 }
 
 static gboolean bookmark_press_cb(GtkWidget *button, GdkEventButton *event, gpointer data)
 {
-       BookMarkData *bm = static_cast<BookMarkData *>(data);
+       auto bm = static_cast<BookMarkData *>(data);
 
        if (event->button != MOUSE_BUTTON_RIGHT) return FALSE;
 
@@ -420,7 +431,7 @@ static gboolean bookmark_press_cb(GtkWidget *button, GdkEventButton *event, gpoi
 
 static gboolean bookmark_keypress_cb(GtkWidget *button, GdkEventKey *event, gpointer data)
 {
-       BookMarkData *bm = static_cast<BookMarkData *>(data);
+       auto bm = static_cast<BookMarkData *>(data);
 
        switch (event->keyval)
                {
@@ -452,11 +463,11 @@ static gboolean bookmark_keypress_cb(GtkWidget *button, GdkEventKey *event, gpoi
 
 static void bookmark_drag_set_data(GtkWidget *button,
                                   GdkDragContext *context, GtkSelectionData *selection_data,
-                                  guint UNUSED(info), guint UNUSED(time), gpointer data)
+                                  guint, guint, gpointer data)
 {
-       BookMarkData *bm = static_cast<BookMarkData *>(data);
+       auto bm = static_cast<BookMarkData *>(data);
        BookButtonData *b;
-       GList *list = NULL;
+       GList *list = nullptr;
 
        return;
        if (gdk_drag_context_get_dest_window(context) == gtk_widget_get_window(bm->widget)) return;
@@ -479,11 +490,12 @@ static void bookmark_drag_set_data(GtkWidget *button,
        g_list_free(list);
 }
 
-static void bookmark_drag_begin(GtkWidget *button, GdkDragContext *context, gpointer UNUSED(data))
+static void bookmark_drag_begin(GtkWidget *button, GdkDragContext *context, gpointer)
 {
        GdkPixbuf *pixbuf;
        GdkModifierType mask;
-       gint x, y;
+       gint x;
+       gint y;
        GtkAllocation allocation;
        GdkSeat *seat;
        GdkDevice *device;
@@ -502,7 +514,7 @@ static void bookmark_drag_begin(GtkWidget *button, GdkDragContext *context, gpoi
        g_object_unref(pixbuf);
 }
 
-static gboolean bookmark_path_tooltip_cb(GtkWidget *button, gpointer UNUSED(data))
+static gboolean bookmark_path_tooltip_cb(GtkWidget *button, gpointer)
 {
        BookButtonData *b;
 
@@ -525,7 +537,7 @@ static void bookmark_populate(BookMarkData *bm)
                {
                GtkWidget *widget = GTK_WIDGET(work->data);
                work = work->next;
-               gtk_widget_destroy(widget);
+               gq_gtk_widget_destroy(widget);
                }
 
        if (!bm->no_defaults && !history_list_get_by_key(bm->key))
@@ -535,18 +547,21 @@ static void bookmark_populate(BookMarkData *bm)
 
                if (!bookmark_default_list)
                        {
-                       buf = bookmark_string(_("Home"), homedir(), NULL);
+                       buf = bookmark_string(_("Home"), homedir(), nullptr);
                        history_list_add_to_key(bm->key, buf, 0);
                        g_free(buf);
 
-                       buf = bookmark_string(".", g_strdup(history_list_find_last_path_by_key("path_list")), NULL);
-                       history_list_add_to_key(bm->key, buf, 0);
-                       g_free(buf);
+                       if (g_strcmp0(bm->key, "shortcuts") != 0)
+                               {
+                               buf = bookmark_string(".", g_strdup(history_list_find_last_path_by_key("path_list")), nullptr);
+                               history_list_add_to_key(bm->key, buf, 0);
+                               g_free(buf);
+                               }
 
                        path = g_build_filename(homedir(), "Desktop", NULL);
                        if (isname(path))
                                {
-                               buf = bookmark_string(_("Desktop"), path, NULL);
+                               buf = bookmark_string(_("Desktop"), path, nullptr);
                                history_list_add_to_key(bm->key, buf, 0);
                                g_free(buf);
                                }
@@ -565,11 +580,18 @@ static void bookmark_populate(BookMarkData *bm)
 
                        if (strcmp(name, ".") == 0)
                                {
-                               buf = bookmark_string(name, g_strdup(history_list_find_last_path_by_key("path_list")), NULL);
+                               if (g_strcmp0(bm->key, "shortcuts") != 0)
+                                       {
+                                       buf = bookmark_string(name, g_strdup(history_list_find_last_path_by_key("path_list")), nullptr);
+                                       }
+                               else
+                                       {
+                                       continue;
+                                       }
                                }
                        else
                                {
-                               buf = bookmark_string(name, path, NULL);
+                               buf = bookmark_string(name, path, nullptr);
                                }
                        history_list_add_to_key(bm->key, buf, 0);
                        g_free(buf);
@@ -599,28 +621,45 @@ static void bookmark_populate(BookMarkData *bm)
 
                        b->button = gtk_button_new();
                        gtk_button_set_relief(GTK_BUTTON(b->button), GTK_RELIEF_NONE);
-                       gtk_box_pack_start(GTK_BOX(bm->box), b->button, FALSE, FALSE, 0);
+                       gq_gtk_box_pack_start(GTK_BOX(bm->box), b->button, FALSE, FALSE, 0);
                        gtk_widget_show(b->button);
 
                        g_object_set_data_full(G_OBJECT(b->button), "bookbuttondata",
-                                              b, (GDestroyNotify)bookmark_free);
+                                              b, reinterpret_cast<GDestroyNotify>(bookmark_free));
 
                        box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
-                       gtk_container_add(GTK_CONTAINER(b->button), box);
+                       gq_gtk_container_add(GTK_WIDGET(b->button), box);
                        gtk_widget_show(box);
 
                        if (b->icon)
                                {
-                               GdkPixbuf *pixbuf;
+                               GdkPixbuf *pixbuf = nullptr;
                                gchar *iconl;
 
                                iconl = path_from_utf8(b->icon);
-                               pixbuf = gdk_pixbuf_new_from_file(iconl, NULL);
+                               pixbuf = gdk_pixbuf_new_from_file(iconl, nullptr);
+
+                               if (isfile(b->icon))
+                                       {
+                                       pixbuf = gdk_pixbuf_new_from_file(iconl, nullptr);
+                                       }
+                               else
+                                       {
+                                       gint w;
+                                       gint h;
+
+                                       w = h = 16;
+                                       gtk_icon_size_lookup(GTK_ICON_SIZE_BUTTON, &w, &h);
+
+                                       pixbuf = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), b->icon, w, GTK_ICON_LOOKUP_NO_SVG, nullptr);
+                                       }
+
                                g_free(iconl);
                                if (pixbuf)
                                        {
                                        GdkPixbuf *scaled;
-                                       gint w, h;
+                                       gint w;
+                                       gint h;
 
                                        w = h = 16;
                                        gtk_icon_size_lookup(GTK_ICON_SIZE_BUTTON, &w, &h);
@@ -633,19 +672,18 @@ static void bookmark_populate(BookMarkData *bm)
                                        }
                                else
                                        {
-                                       b->image = gtk_image_new_from_stock(GTK_STOCK_MISSING_IMAGE,
-                                                                           GTK_ICON_SIZE_BUTTON);
+                                       b->image = gtk_image_new_from_icon_name(GQ_ICON_DIRECTORY, GTK_ICON_SIZE_BUTTON);
                                        }
                                }
                        else
                                {
-                               b->image = gtk_image_new_from_stock(GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_BUTTON);
+                               b->image = gtk_image_new_from_icon_name(GQ_ICON_DIRECTORY, GTK_ICON_SIZE_BUTTON);
                                }
-                       gtk_box_pack_start(GTK_BOX(box), b->image, FALSE, FALSE, 0);
+                       gq_gtk_box_pack_start(GTK_BOX(box), b->image, FALSE, FALSE, 0);
                        gtk_widget_show(b->image);
 
                        b->label = gtk_label_new(b->name);
-                       gtk_box_pack_start(GTK_BOX(box), b->label, FALSE, FALSE, 0);
+                       gq_gtk_box_pack_start(GTK_BOX(box), b->label, FALSE, FALSE, 0);
                        gtk_widget_show(b->label);
 
                        g_signal_connect(G_OBJECT(b->button), "clicked",
@@ -657,7 +695,7 @@ static void bookmark_populate(BookMarkData *bm)
 
                        gtk_drag_source_set(b->button, GDK_BUTTON1_MASK,
                                            bookmark_drag_types, bookmark_drag_types_n,
-                                           GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
+                                           static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK));
                        g_signal_connect(G_OBJECT(b->button), "drag_data_get",
                                         G_CALLBACK(bookmark_drag_set_data), bm);
                        g_signal_connect(G_OBJECT(b->button), "drag_begin",
@@ -692,15 +730,16 @@ static void bookmark_populate_all(const gchar *key)
                }
 }
 
-static void bookmark_dnd_get_data(GtkWidget *UNUSED(widget),
-                                 GdkDragContext *UNUSED(context), gint UNUSED(x), gint UNUSED(y),
-                                 GtkSelectionData *selection_data, guint UNUSED(info),
-                                 guint UNUSED(time), gpointer data)
+static void bookmark_dnd_get_data(GtkWidget *, GdkDragContext *,
+                                 gint, gint,
+                                 GtkSelectionData *selection_data, guint,
+                                 guint, gpointer data)
 {
-       BookMarkData *bm = static_cast<BookMarkData *>(data);
-       GList *list = NULL;
-       GList *errors = NULL;
+       auto bm = static_cast<BookMarkData *>(data);
+       GList *list = nullptr;
+       GList *errors = nullptr;
        GList *work;
+       gchar *real_path;
        gchar **uris;
 
        if (!bm->editable) return;
@@ -712,37 +751,52 @@ static void bookmark_dnd_get_data(GtkWidget *UNUSED(widget),
                if(errors)
                        {
                        warning_dialog_dnd_uri_error(errors);
-                       string_list_free(errors);
+                       g_list_free_full(errors, g_free);
                        }
                g_strfreev(uris);
 
                work = list;
                while (work)
                        {
-                       gchar *path = static_cast<gchar *>(work->data);
+                       auto path = static_cast<gchar *>(work->data);
                        gchar *buf;
 
                        work = work->next;
 
                        if (bm->only_directories && !isdir(path)) continue;
-                       buf = bookmark_string(filename_from_path(path), path, NULL);
+
+                       real_path = realpath(path, nullptr);
+
+                       if (strstr(real_path, get_collections_dir()) && isfile(path))
+                               {
+                               buf = bookmark_string(filename_from_path(path), path, "gq-icon-collection");
+                               }
+                       else if (isfile(path))
+                               {
+                               buf = bookmark_string(filename_from_path(path), path, GQ_ICON_FILE);
+                               }
+                       else
+                               {
+                               buf = bookmark_string(filename_from_path(path), path, nullptr);
+                               }
                        history_list_add_to_key(bm->key, buf, 0);
                        g_free(buf);
+                       g_free(real_path);
                        }
 
-               string_list_free(list);
+               g_list_free_full(list, g_free);
 
                bookmark_populate_all(bm->key);
                }
 }
 
-static void bookmark_list_destroy(GtkWidget *UNUSED(widget), gpointer data)
+static void bookmark_list_destroy(GtkWidget *, gpointer data)
 {
-       BookMarkData *bm = static_cast<BookMarkData *>(data);
+       auto bm = static_cast<BookMarkData *>(data);
 
        bookmark_widget_list = g_list_remove(bookmark_widget_list, bm);
 
-       g_free(bm->key);
+       g_free(const_cast<gchar *>(bm->key));
        g_free(bm);
 }
 
@@ -764,10 +818,11 @@ GtkWidget *bookmark_list_new(const gchar *key,
        bm->editable = TRUE;
        bm->only_directories = FALSE;
 
-       scrolled = gtk_scrolled_window_new(NULL, NULL);
+       scrolled = gq_gtk_scrolled_window_new(nullptr, nullptr);
 
        PangoLayout *layout;
-       gint width, height;
+       gint width;
+       gint height;
 
        layout = gtk_widget_create_pango_layout(GTK_WIDGET(scrolled), "reasonable width");
        pango_layout_get_pixel_size(layout, &width, &height);
@@ -777,7 +832,7 @@ GtkWidget *bookmark_list_new(const gchar *key,
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
        bm->box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
-       gtk_container_add(GTK_CONTAINER(scrolled), bm->box);
+       gq_gtk_container_add(GTK_WIDGET(scrolled), bm->box);
        gtk_widget_show(bm->box);
 
        bookmark_populate(bm);
@@ -789,9 +844,9 @@ GtkWidget *bookmark_list_new(const gchar *key,
        bm->widget = scrolled;
 
        gtk_drag_dest_set(scrolled,
-                         GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
+                         static_cast<GtkDestDefaults>(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP),
                          bookmark_drop_types, bookmark_drop_types_n,
-                         GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
+                         static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK));
        g_signal_connect(G_OBJECT(scrolled), "drag_data_received",
                         G_CALLBACK(bookmark_dnd_get_data), bm);
 
@@ -811,7 +866,7 @@ void bookmark_list_set_key(GtkWidget *list, const gchar *key)
 
        if (bm->key && strcmp(bm->key, key) == 0) return;
 
-       g_free(bm->key);
+       g_free(const_cast<gchar *>(bm->key));
        bm->key = g_strdup(key);
 
        bookmark_populate(bm);
@@ -850,14 +905,32 @@ void bookmark_list_set_only_directories(GtkWidget *list, gboolean only_directori
 void bookmark_list_add(GtkWidget *list, const gchar *name, const gchar *path)
 {
        BookMarkData *bm;
-       gchar *buf;
+       gchar *real_path;
 
        bm = static_cast<BookMarkData *>(g_object_get_data(G_OBJECT(list), BOOKMARK_DATA_KEY));
        if (!bm) return;
 
-       buf = bookmark_string(name, path, NULL);
-       history_list_add_to_key(bm->key, buf, 0);
-       g_free(buf);
+       std::unique_ptr<gchar, decltype(&g_free)> buf(bookmark_string(name, path, nullptr), g_free);
+       real_path = realpath(path, nullptr);
+
+       if (strstr(real_path, get_collections_dir()) && isfile(path))
+               {
+               buf.reset(bookmark_string(name, path, "gq-icon-collection"));
+               }
+       else
+               {
+               if (isfile(path))
+                       {
+                       buf.reset(bookmark_string(name, path, GQ_ICON_FILE));
+                       }
+               else
+                       {
+                       buf.reset(bookmark_string(name, path, nullptr));
+                       }
+               }
+
+       history_list_add_to_key(bm->key, buf.get(), 0);
+       g_free(real_path);
 
        bookmark_populate_all(bm->key);
 }
@@ -875,8 +948,7 @@ void bookmark_add_default(const gchar *name, const gchar *path)
  *-----------------------------------------------------------------------------
  */
 
-typedef struct _HistoryComboData HistoryComboData;
-struct _HistoryComboData
+struct HistoryComboData
 {
        GtkWidget *combo;
        GtkWidget *entry;
@@ -884,9 +956,9 @@ struct _HistoryComboData
        gint history_levels;
 };
 
-static void history_combo_destroy(GtkWidget *UNUSED(widget), gpointer data)
+static void history_combo_destroy(GtkWidget *, gpointer data)
 {
-       HistoryComboData *hc = static_cast<HistoryComboData *>(data);
+       auto hc = static_cast<HistoryComboData *>(data);
 
        g_free(hc->history_key);
        g_free(data);
@@ -916,14 +988,14 @@ GtkWidget *history_combo_new(GtkWidget **entry, const gchar *text,
        work = history_list_get_by_key(hc->history_key);
        while (work)
                {
-               gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(hc->combo), (gchar *)work->data);
+               gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(hc->combo), static_cast<gchar *>(work->data));
                work = work->next;
                n++;
                }
 
        if (text)
                {
-               gtk_entry_set_text(GTK_ENTRY(hc->entry), text);
+               gq_gtk_entry_set_text(GTK_ENTRY(hc->entry), text);
                }
        else if (n > 0)
                {
@@ -955,7 +1027,7 @@ void history_combo_append_history(GtkWidget *widget, const gchar *text)
                }
        else
                {
-               new_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(hc->entry)));
+               new_text = g_strdup(gq_gtk_entry_get_text(GTK_ENTRY(hc->entry)));
                }
 
        if (new_text && strlen(new_text) > 0)
@@ -973,7 +1045,7 @@ void history_combo_append_history(GtkWidget *widget, const gchar *text)
                work = history_list_get_by_key(hc->history_key);
                while (work)
                        {
-                       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(hc->combo), (gchar *)work->data);
+                       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(hc->combo), static_cast<gchar *>(work->data));
                        work = work->next;
                        }
                }