/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* * Caja * * Copyright (C) 1999, 2000 Red Hat, Inc. * Copyright (C) 2000, 2001 Eazel, Inc. * * This library 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 library 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Authors: Elliot Lee <sopwith@redhat.com> * Darin Adler <darin@bentspoon.com> * */ #include <config.h> #include <eel/eel-gtk-extensions.h> #include <gtk/gtk.h> #include <glib/gi18n.h> #include <libcaja-private/caja-bookmark.h> #include <libcaja-private/caja-global-preferences.h> #include <libcaja-private/caja-sidebar-provider.h> #include <libcaja-private/caja-module.h> #include <libcaja-private/caja-signaller.h> #include <libcaja-private/caja-window-info.h> #include <libcaja-private/caja-window-slot-info.h> #include "caja-history-sidebar.h" #define CAJA_HISTORY_SIDEBAR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), CAJA_TYPE_HISTORY_SIDEBAR, CajaHistorySidebarClass)) #define CAJA_IS_HISTORY_SIDEBAR(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CAJA_TYPE_HISTORY_SIDEBAR)) #define CAJA_IS_HISTORY_SIDEBAR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), CAJA_TYPE_HISTORY_SIDEBAR)) typedef struct { GtkScrolledWindowClass parent; } CajaHistorySidebarClass; typedef struct { GObject parent; } CajaHistorySidebarProvider; typedef struct { GObjectClass parent; } CajaHistorySidebarProviderClass; enum { HISTORY_SIDEBAR_COLUMN_ICON, HISTORY_SIDEBAR_COLUMN_NAME, HISTORY_SIDEBAR_COLUMN_BOOKMARK, HISTORY_SIDEBAR_COLUMN_COUNT }; static void caja_history_sidebar_iface_init (CajaSidebarIface *iface); static void sidebar_provider_iface_init (CajaSidebarProviderIface *iface); static GType caja_history_sidebar_provider_get_type (void); static void caja_history_sidebar_style_updated (GtkWidget *widget); G_DEFINE_TYPE_WITH_CODE (CajaHistorySidebar, caja_history_sidebar, GTK_TYPE_SCROLLED_WINDOW, G_IMPLEMENT_INTERFACE (CAJA_TYPE_SIDEBAR, caja_history_sidebar_iface_init)); G_DEFINE_TYPE_WITH_CODE (CajaHistorySidebarProvider, caja_history_sidebar_provider, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (CAJA_TYPE_SIDEBAR_PROVIDER, sidebar_provider_iface_init)); static void update_history (CajaHistorySidebar *sidebar) { GtkListStore *store; GtkTreeSelection *selection; CajaBookmark *bookmark; GdkPixbuf *pixbuf; GtkTreeIter iter; char *name; GList *l, *history; store = GTK_LIST_STORE (gtk_tree_view_get_model (sidebar->tree_view)); gtk_list_store_clear (store); history = caja_window_info_get_history (sidebar->window); for (l = history; l != NULL; l = l->next) { bookmark = caja_bookmark_copy (l->data); pixbuf = caja_bookmark_get_pixbuf (bookmark, GTK_ICON_SIZE_MENU); name = caja_bookmark_get_name (bookmark); gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, HISTORY_SIDEBAR_COLUMN_ICON, pixbuf, HISTORY_SIDEBAR_COLUMN_NAME, name, HISTORY_SIDEBAR_COLUMN_BOOKMARK, bookmark, -1); g_object_unref (bookmark); if (pixbuf != NULL) { g_object_unref (pixbuf); } g_free (name); } g_list_free_full (history, g_object_unref); selection = GTK_TREE_SELECTION (gtk_tree_view_get_selection (sidebar->tree_view)); if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { gtk_tree_selection_select_iter (selection, &iter); } } static void history_changed_callback (GObject *signaller, CajaHistorySidebar *sidebar) { update_history (sidebar); } static void open_selected_item (CajaHistorySidebar *sidebar, GtkTreePath *path, CajaWindowOpenFlags flags) { CajaWindowSlotInfo *slot; GtkTreeModel *model; GtkTreeIter iter; CajaBookmark *bookmark; GFile *location; model = gtk_tree_view_get_model (sidebar->tree_view); if (!gtk_tree_model_get_iter (model, &iter, path)) { return; } gtk_tree_model_get (model, &iter, HISTORY_SIDEBAR_COLUMN_BOOKMARK, &bookmark, -1); /* Navigate to the clicked location. */ location = caja_bookmark_get_location (CAJA_BOOKMARK (bookmark)); slot = caja_window_info_get_active_slot (sidebar->window); caja_window_slot_info_open_location (slot, location, CAJA_WINDOW_OPEN_ACCORDING_TO_MODE, flags, NULL); g_object_unref (location); } static void row_activated_callback (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data) { CajaHistorySidebar *sidebar; sidebar = CAJA_HISTORY_SIDEBAR (user_data); g_assert (sidebar->tree_view == tree_view); open_selected_item (sidebar, path, 0); } static gboolean button_press_event_callback (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { if (event->button == 2 && event->type == GDK_BUTTON_PRESS) { /* Open new tab on middle click. */ CajaHistorySidebar *sidebar; GtkTreePath *path; sidebar = CAJA_HISTORY_SIDEBAR (user_data); g_assert (sidebar->tree_view == GTK_TREE_VIEW (widget)); if (gtk_tree_view_get_path_at_pos (sidebar->tree_view, event->x, event->y, &path, NULL, NULL, NULL)) { open_selected_item (sidebar, path, CAJA_WINDOW_OPEN_FLAG_NEW_TAB); gtk_tree_path_free (path); } } return FALSE; } static void update_click_policy (CajaHistorySidebar *sidebar) { int policy; policy = g_settings_get_enum (caja_preferences, CAJA_PREFERENCES_CLICK_POLICY); eel_gtk_tree_view_set_activate_on_single_click (sidebar->tree_view, policy == CAJA_CLICK_POLICY_SINGLE); } static void click_policy_changed_callback (gpointer user_data) { CajaHistorySidebar *sidebar; sidebar = CAJA_HISTORY_SIDEBAR (user_data); update_click_policy (sidebar); } static void caja_history_sidebar_init (CajaHistorySidebar *sidebar) { GtkTreeView *tree_view; GtkTreeViewColumn *col; GtkCellRenderer *cell; GtkListStore *store; GtkTreeSelection *selection; tree_view = GTK_TREE_VIEW (gtk_tree_view_new ()); gtk_tree_view_set_headers_visible (tree_view, FALSE); gtk_widget_show (GTK_WIDGET (tree_view)); col = GTK_TREE_VIEW_COLUMN (gtk_tree_view_column_new ()); cell = gtk_cell_renderer_pixbuf_new (); gtk_tree_view_column_pack_start (col, cell, FALSE); gtk_tree_view_column_set_attributes (col, cell, "pixbuf", HISTORY_SIDEBAR_COLUMN_ICON, NULL); cell = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (col, cell, TRUE); gtk_tree_view_column_set_attributes (col, cell, "text", HISTORY_SIDEBAR_COLUMN_NAME, NULL); gtk_tree_view_column_set_fixed_width (col, CAJA_ICON_SIZE_SMALLER); gtk_tree_view_append_column (tree_view, col); store = gtk_list_store_new (HISTORY_SIDEBAR_COLUMN_COUNT, GDK_TYPE_PIXBUF, G_TYPE_STRING, CAJA_TYPE_BOOKMARK); gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (store)); g_object_unref (store); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sidebar), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (sidebar), NULL); gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (sidebar), NULL); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sidebar), GTK_SHADOW_IN); #if GTK_CHECK_VERSION (3, 16, 0) gtk_scrolled_window_set_overlay_scrolling (GTK_SCROLLED_WINDOW (sidebar), FALSE); #endif gtk_container_add (GTK_CONTAINER (sidebar), GTK_WIDGET (tree_view)); gtk_widget_show (GTK_WIDGET (sidebar)); sidebar->tree_view = tree_view; selection = gtk_tree_view_get_selection (tree_view); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); g_signal_connect_object (tree_view, "row_activated", G_CALLBACK (row_activated_callback), sidebar, 0); g_signal_connect_object (caja_signaller_get_current (), "history_list_changed", G_CALLBACK (history_changed_callback), sidebar, 0); g_signal_connect (tree_view, "button-press-event", G_CALLBACK (button_press_event_callback), sidebar); g_signal_connect_swapped (caja_preferences, "changed::" CAJA_PREFERENCES_CLICK_POLICY, G_CALLBACK(click_policy_changed_callback), sidebar); update_click_policy (sidebar); } static void caja_history_sidebar_finalize (GObject *object) { CajaHistorySidebar *sidebar; sidebar = CAJA_HISTORY_SIDEBAR (object); g_signal_handlers_disconnect_by_func (caja_preferences, click_policy_changed_callback, sidebar); G_OBJECT_CLASS (caja_history_sidebar_parent_class)->finalize (object); } static void caja_history_sidebar_class_init (CajaHistorySidebarClass *class) { G_OBJECT_CLASS (class)->finalize = caja_history_sidebar_finalize; GTK_WIDGET_CLASS (class)->style_updated = caja_history_sidebar_style_updated; } static const char * caja_history_sidebar_get_sidebar_id (CajaSidebar *sidebar) { return CAJA_HISTORY_SIDEBAR_ID; } static char * caja_history_sidebar_get_tab_label (CajaSidebar *sidebar) { return g_strdup (_("History")); } static char * caja_history_sidebar_get_tab_tooltip (CajaSidebar *sidebar) { return g_strdup (_("Show History")); } static GdkPixbuf * caja_history_sidebar_get_tab_icon (CajaSidebar *sidebar) { return NULL; } static void caja_history_sidebar_is_visible_changed (CajaSidebar *sidebar, gboolean is_visible) { /* Do nothing */ } static void caja_history_sidebar_iface_init (CajaSidebarIface *iface) { iface->get_sidebar_id = caja_history_sidebar_get_sidebar_id; iface->get_tab_label = caja_history_sidebar_get_tab_label; iface->get_tab_tooltip = caja_history_sidebar_get_tab_tooltip; iface->get_tab_icon = caja_history_sidebar_get_tab_icon; iface->is_visible_changed = caja_history_sidebar_is_visible_changed; } static void caja_history_sidebar_set_parent_window (CajaHistorySidebar *sidebar, CajaWindowInfo *window) { sidebar->window = window; update_history (sidebar); } static void caja_history_sidebar_style_updated (GtkWidget *widget) { CajaHistorySidebar *sidebar; sidebar = CAJA_HISTORY_SIDEBAR (widget); update_history (sidebar); } static CajaSidebar * caja_history_sidebar_create (CajaSidebarProvider *provider, CajaWindowInfo *window) { CajaHistorySidebar *sidebar; sidebar = g_object_new (caja_history_sidebar_get_type (), NULL); caja_history_sidebar_set_parent_window (sidebar, window); g_object_ref_sink (sidebar); return CAJA_SIDEBAR (sidebar); } static void sidebar_provider_iface_init (CajaSidebarProviderIface *iface) { iface->create = caja_history_sidebar_create; } static void caja_history_sidebar_provider_init (CajaHistorySidebarProvider *sidebar) { } static void caja_history_sidebar_provider_class_init (CajaHistorySidebarProviderClass *class) { } void caja_history_sidebar_register (void) { caja_module_add_type (caja_history_sidebar_provider_get_type ()); }