Re: [PATCH] - New sidepanel plug-in for Gtk bookmarks and places



Jamie McCracken wrote:
Helllo Jamie,

The patch didn't apply fine.
it seems you don't use the same source, the patch produced against
your vanilla nautilus failed specially on
nautilus-navigation-window-menus.c.
for instance the line "static NautilusBookmarkList *get_bookmark_list
(void);, doesn't exists.
I use the anoncvs server.

Any clue ?


yes I was not developing against HEAD - wil fix shortly (I apoligise if I have wasted anyone's time)


Okay have adjusted patch to compile on HEAD (problem was caused by recent changes to the bookmarks code).

Also stopped adding of duplicate bookmarks in the new sidebar panel so please use attached files and ignore the previous version. As before attached files need to go in src directory.

(Alex : should I have added nautilus-bookmark_list.* to libnautilus-private as I need to expose this to nautilus-window-info?)

jamie.
Index: src/nautilus-application.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-application.c,v
retrieving revision 1.235
diff -u -r1.235 nautilus-application.c
--- src/nautilus-application.c	23 Jun 2005 14:16:58 -0000	1.235
+++ src/nautilus-application.c	28 Jun 2005 00:40:43 -0000
@@ -36,6 +36,7 @@
 #include "file-manager/fm-tree-view.h"
 #include "nautilus-information-panel.h"
 #include "nautilus-history-sidebar.h"
+#include "nautilus-places-sidebar.h"
 #include "nautilus-notes-viewer.h"
 #include "nautilus-emblem-sidebar.h"
 #include "nautilus-image-properties-page.h"
@@ -179,6 +180,7 @@
 	fm_list_view_register ();
 
 	/* register sidebars */
+	nautilus_places_sidebar_register ();
 	nautilus_information_panel_register ();
 	fm_tree_view_register ();
 	nautilus_history_sidebar_register ();
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gnome/nautilus/src/Makefile.am,v
retrieving revision 1.160
diff -u -r1.160 Makefile.am
--- src/Makefile.am	23 Jun 2005 14:16:58 -0000	1.160
+++ src/Makefile.am	28 Jun 2005 00:40:45 -0000
@@ -93,6 +93,8 @@
 	nautilus-navigation-window.h            \
 	nautilus-notes-viewer.c			\
 	nautilus-notes-viewer.h			\
+	nautilus-places-sidebar.c		\
+	nautilus-places-sidebar.h		\
 	nautilus-property-browser.c     	\
 	nautilus-property-browser.h		\
 	nautilus-self-check-functions.c 	\
Index: src/nautilus-window.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-window.c,v
retrieving revision 1.449
diff -u -r1.449 nautilus-window.c
--- src/nautilus-window.c	23 Jun 2005 14:16:59 -0000	1.449
+++ src/nautilus-window.c	28 Jun 2005 00:40:48 -0000
@@ -32,6 +32,7 @@
 
 #include "nautilus-actions.h"
 #include "nautilus-application.h"
+#include "nautilus-bookmark-list.h"
 #include "nautilus-bookmarks-window.h"
 #include "nautilus-information-panel.h"
 #include "nautilus-main.h"
@@ -1385,6 +1386,12 @@
 			       mode);
 }
 
+static NautilusBookmarkList *
+nautilus_window_get_bookmark_list (NautilusWindow *window)
+{
+  return nautilus_get_bookmark_list ();
+}
+
 static void
 nautilus_window_info_iface_init (NautilusWindowInfoIface *iface)
 {
@@ -1399,6 +1406,7 @@
 	iface->get_window_type = nautilus_window_get_window_type;
 	iface->get_title = nautilus_window_get_cached_title;
 	iface->get_history = nautilus_window_get_history;
+	iface->get_bookmark_list = nautilus_window_get_bookmark_list;
 	iface->get_current_location = nautilus_window_get_location;
 	iface->get_ui_manager = nautilus_window_get_ui_manager;
 	iface->get_selection_count = nautilus_window_get_selection_count;
Index: libnautilus-private/nautilus-window-info.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-window-info.c,v
retrieving revision 1.3
diff -u -r1.3 nautilus-window-info.c
--- libnautilus-private/nautilus-window-info.c	22 Mar 2005 09:22:22 -0000	1.3
+++ libnautilus-private/nautilus-window-info.c	28 Jun 2005 00:40:49 -0000
@@ -217,6 +217,15 @@
 	return (* NAUTILUS_WINDOW_INFO_GET_IFACE (window)->get_history) (window);
 }
 
+NautilusBookmarkList *
+nautilus_window_info_get_bookmark_list (NautilusWindowInfo *window)
+{
+	g_return_val_if_fail (NAUTILUS_IS_WINDOW_INFO (window), NULL);
+	
+	return (* NAUTILUS_WINDOW_INFO_GET_IFACE (window)->get_bookmark_list) (window);
+}
+
+
 char *
 nautilus_window_info_get_current_location (NautilusWindowInfo *window)
 {
Index: libnautilus-private/nautilus-window-info.h
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-window-info.h,v
retrieving revision 1.3
diff -u -r1.3 nautilus-window-info.h
--- libnautilus-private/nautilus-window-info.h	22 Mar 2005 09:22:22 -0000	1.3
+++ libnautilus-private/nautilus-window-info.h	28 Jun 2005 00:40:49 -0000
@@ -28,6 +28,7 @@
 #include <glib-object.h>
 #include <libnautilus-private/nautilus-view.h>
 #include <gtk/gtkuimanager.h>
+#include "../src/nautilus-bookmark-list.h"
 
 G_BEGIN_DECLS
 
@@ -115,6 +116,8 @@
 					  const char *status);
 	char * (* get_title)             (NautilusWindowInfo *window);
 	GList *(* get_history)           (NautilusWindowInfo *window);
+	NautilusBookmarkList *  
+	       (* get_bookmark_list)     (NautilusWindowInfo *window);
 	NautilusWindowType
 	       (* get_window_type)       (NautilusWindowInfo *window);
 	NautilusWindowShowHiddenFilesMode
@@ -152,6 +155,7 @@
 NautilusWindowType                nautilus_window_info_get_window_type          (NautilusWindowInfo                *window);
 char *                            nautilus_window_info_get_title                (NautilusWindowInfo                *window);
 GList *                           nautilus_window_info_get_history              (NautilusWindowInfo                *window);
+NautilusBookmarkList *		  nautilus_window_info_get_bookmark_list        (NautilusWindowInfo                *window);
 char *                            nautilus_window_info_get_current_location     (NautilusWindowInfo                *window);
 int                               nautilus_window_info_get_selection_count      (NautilusWindowInfo                *window);
 GList *                           nautilus_window_info_get_selection            (NautilusWindowInfo                *window);
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */

/*
 *  Nautilus
 *
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Author : Mr Jamie McCracken (jamiemcc at blueyonder dot co dot uk)
 *
 */
 
#include <config.h>

#include <eel/eel-debug.h>
#include <eel/eel-gtk-extensions.h>
#include <eel/eel-glib-extensions.h>
#include <eel/eel-preferences.h>
#include <eel/eel-string.h>
#include <gtk/gtkalignment.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtkvbox.h>
#include <gtk/gtkcellrendererpixbuf.h>
#include <gtk/gtkcellrenderertext.h>
#include <gtk/gtkliststore.h>
#include <gtk/gtksizegroup.h>
#include <gtk/gtkstock.h>
#include <gtk/gtktreemodel.h>
#include <gtk/gtktreeselection.h>
#include <libgnome/gnome-macros.h>
#include <libgnome/gnome-i18n.h>
#include <libnautilus-private/nautilus-bookmark.h>
#include <libnautilus-private/nautilus-global-preferences.h>
#include <libnautilus-private/nautilus-sidebar-provider.h>
#include <libnautilus-private/nautilus-module.h>
#include <libnautilus-private/nautilus-file-utilities.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libgnomevfs/gnome-vfs-volume-monitor.h>

#include "nautilus-bookmark-list.h"
#include "nautilus-places-sidebar.h"

#define MAX_BOOKMARK_LENGTH 80
#define NAUTILUS_PLACES_SIDEBAR_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_PLACES_SIDEBAR, NautilusPlacesSidebarClass))
#define NAUTILUS_IS_PLACES_SIDEBAR(obj)         (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_PLACES_SIDEBAR))
#define NAUTILUS_IS_PLACES_SIDEBAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_PLACES_SIDEBAR))



typedef struct {
	GtkScrolledWindowClass parent;
} NautilusPlacesSidebarClass;

typedef struct {
        GObject parent;
} NautilusPlacesSidebarProvider;

typedef struct {
        GObjectClass parent;
} NautilusPlacesSidebarProviderClass;


enum {
	PLACES_SIDEBAR_COLUMN_ICON,
	PLACES_SIDEBAR_COLUMN_NAME,
	PLACES_SIDEBAR_COLUMN_BOOKMARK,
	PLACES_SIDEBAR_COLUMN_BOOKMARK_TYPE,
	PLACES_SIDEBAR_COLUMN_COUNT
};

typedef enum {
	PLACES_BUILT_IN,
	PLACES_MOUNTED_VOLUME,
	PLACES_BOOKMARK,
	PLACES_SEPARATOR
} PlaceType;

static NautilusBookmarkList *bookmarks;

static void  nautilus_places_sidebar_iface_init        (NautilusSidebarIface         *iface);
static void  sidebar_provider_iface_init               (NautilusSidebarProviderIface *iface);
static GType nautilus_places_sidebar_provider_get_type (void);

G_DEFINE_TYPE_WITH_CODE (NautilusPlacesSidebar, nautilus_places_sidebar, GTK_TYPE_SCROLLED_WINDOW,
			 G_IMPLEMENT_INTERFACE (NAUTILUS_TYPE_SIDEBAR,
						nautilus_places_sidebar_iface_init));

G_DEFINE_TYPE_WITH_CODE (NautilusPlacesSidebarProvider, nautilus_places_sidebar_provider, G_TYPE_OBJECT,
			 G_IMPLEMENT_INTERFACE (NAUTILUS_TYPE_SIDEBAR_PROVIDER,
						sidebar_provider_iface_init));


static GtkTreeIter
add_place (GtkListStore *store, NautilusBookmark *bookmark, PlaceType place_type, const char *icon)
{
	GdkPixbuf            *pixbuf;
	GtkTreeIter           iter;
	char 		     *name;

	if (!icon) { 
		pixbuf = nautilus_bookmark_get_pixbuf (bookmark, NAUTILUS_ICON_SIZE_FOR_MENUS, FALSE);
	} else {
		pixbuf = nautilus_icon_factory_get_pixbuf_from_name (icon, NULL, NAUTILUS_ICON_SIZE_FOR_MENUS, TRUE, NULL);
	}
	name = nautilus_bookmark_get_name (bookmark);
	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter,
			    PLACES_SIDEBAR_COLUMN_ICON, pixbuf,
			    PLACES_SIDEBAR_COLUMN_NAME, name,
			    PLACES_SIDEBAR_COLUMN_BOOKMARK, bookmark,
			    PLACES_SIDEBAR_COLUMN_BOOKMARK_TYPE, place_type,
			    -1);
	if (pixbuf != NULL) {
		g_object_unref (pixbuf);
	}
	g_free (name);
	return iter;

}



static void
update_places (NautilusPlacesSidebar *sidebar)
{
	GtkListStore          *store;
	NautilusBookmark      *bookmark;
	GtkTreeSelection      *selection;
	GtkTreeIter           iter, last_iter;
	GnomeVFSVolumeMonitor *volume_monitor;
	GList 		      *volumes, *l;
	GnomeVFSVolume 	      *volume;
	int 		      bookmark_count, index;
	char 		      *uri, *location, *icon, *mount_uri, *name, *file_path;
		
	g_assert (bookmarks != NULL);
	store = GTK_LIST_STORE (gtk_tree_view_get_model (sidebar->tree_view));
	selection = gtk_tree_view_get_selection (sidebar->tree_view);
	gtk_list_store_clear (store);
	location = nautilus_window_info_get_current_location (sidebar->window);

	/* add built in bookmarks */

	file_path = g_build_filename (g_get_home_dir (), "Documents", NULL);
	if (g_file_test (file_path, G_FILE_TEST_IS_DIR)) {
		mount_uri = g_strconcat ("file://", file_path, NULL);
		name = g_strdup ("Documents");
		bookmark = nautilus_bookmark_new (mount_uri, name);
		last_iter = add_place (store, bookmark, PLACES_BUILT_IN, NULL);
		if (strcmp (location, mount_uri) == 0) {
			gtk_tree_selection_select_iter (selection, &last_iter);
		}	
		g_free (mount_uri);
		g_free (name);
	}
	g_free (file_path);

	file_path = g_strdup (g_get_home_dir ());
 	mount_uri = g_strconcat ("file://", file_path, NULL);
	name = g_strdup ("Home");
	bookmark = nautilus_bookmark_new (mount_uri, name);
	last_iter = add_place (store, bookmark, PLACES_BUILT_IN, NULL);
	if (strcmp (location, mount_uri) == 0) {
		gtk_tree_selection_select_iter (selection, &last_iter);
	}	
	g_free (mount_uri);
	g_free (name);
	g_free (file_path);

	file_path = g_build_filename (g_get_home_dir (), "Desktop", NULL);
	if (g_file_test (file_path, G_FILE_TEST_IS_DIR)) {
		mount_uri = g_strconcat ("file://", file_path, NULL);
		name = g_strdup ("Desktop");
		bookmark = nautilus_bookmark_new (mount_uri, name);
		last_iter = add_place (store, bookmark, PLACES_BUILT_IN, "gnome-fs-desktop");
		if (strcmp (location, mount_uri) == 0) {
			gtk_tree_selection_select_iter (selection, &last_iter);
		}	
		g_free (mount_uri);
		g_free (name);
	}
	g_free (file_path);
	
 	mount_uri = g_strdup ("file:///");
	name = g_strdup ("Filesystem");
	bookmark = nautilus_bookmark_new (mount_uri, name);
	last_iter = add_place (store, bookmark, PLACES_BUILT_IN, "gnome-fs-blockdev");
	if (strcmp (location, mount_uri) == 0) {
		gtk_tree_selection_select_iter (selection, &last_iter);
	}	
	g_free (mount_uri);
	g_free (name);



	/* add mounted volumes */

	volume_monitor = gnome_vfs_get_volume_monitor ();
	volumes = gnome_vfs_volume_monitor_get_mounted_volumes (volume_monitor);
	for (l = volumes; l != NULL; l = l->next) {
		volume = l->data;
		if (!gnome_vfs_volume_is_user_visible (volume)) {
			gnome_vfs_volume_unref (volume);
			continue;
		}
		icon = gnome_vfs_volume_get_icon (volume);
		mount_uri = gnome_vfs_volume_get_activation_uri (volume);
		name = gnome_vfs_volume_get_display_name (volume);
		bookmark = nautilus_bookmark_new (mount_uri, name);
		last_iter = add_place (store, bookmark, PLACES_MOUNTED_VOLUME, icon);
		if (strcmp (location, mount_uri) == 0) {
			gtk_tree_selection_select_iter (selection, &last_iter);
		}
		gnome_vfs_volume_unref (volume);
		g_free (icon);
		g_free (name);
		g_free (mount_uri);

	}
	g_list_free (volumes);
	

	/* add separator */

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter,
			    PLACES_SIDEBAR_COLUMN_BOOKMARK_TYPE, PLACES_SEPARATOR,
			    -1);

	/* add bookmarks */

	bookmark_count = nautilus_bookmark_list_length (bookmarks);
	for (index = 0; index < bookmark_count; ++index) {
		bookmark = nautilus_bookmark_list_item_at (bookmarks, index),
		last_iter = add_place (store, bookmark, PLACES_BOOKMARK, NULL);
		
		/* set selection if place is the current location */
		uri = nautilus_bookmark_get_uri (bookmark);
		
		if (strcmp (location, uri) == 0) {
			gtk_tree_selection_select_iter (selection, &last_iter);
		}
		g_free (uri);
	}

	g_free (location);
	
}


static void
selection_changed_callback (GtkTreeSelection *selection,
		      	    gpointer user_data)
{
	GtkTreeModel     	*model;
	GtkTreeIter      	iter;
	PlaceType	 	type; 
	NautilusPlacesSidebar 	*sidebar;

	sidebar = NAUTILUS_PLACES_SIDEBAR (user_data);

	/* only bookmarks can be removed */
	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
    		gtk_tree_model_get (model, &iter, PLACES_SIDEBAR_COLUMN_BOOKMARK_TYPE, &type, -1);
		gtk_widget_set_sensitive (sidebar->remove_button, (type == PLACES_BOOKMARK));
	}
}

static gboolean
shortcuts_row_separator_func (GtkTreeModel *model,
			      GtkTreeIter  *iter,
			      gpointer      data)
{
	gint column;
  	char *text;

	column = GPOINTER_TO_INT (data);
  	gtk_tree_model_get (model, iter, column, &text, -1);
  
  	if (!text) {
   		return TRUE;
	}

  	g_free (text);

  	return FALSE;
}


static GtkWidget *
button_new (const char *text,
	    const char *stock_id,
	    gboolean    sensitive,
	    gboolean    show,
	    GCallback   callback,
	    gpointer    user_data)
{
	GtkWidget *button;
	GtkWidget *hbox;
	GtkWidget *widget;
	GtkWidget *align;

	button = gtk_button_new ();
	hbox = gtk_hbox_new (FALSE, 2);
	align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
	
	gtk_container_add (GTK_CONTAINER (button), align);
	gtk_container_add (GTK_CONTAINER (align), hbox);
	widget = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON);

  	gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);

  	widget = gtk_label_new_with_mnemonic (text);
	gtk_label_set_mnemonic_widget (GTK_LABEL (widget), GTK_WIDGET (button));
	gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
	
	gtk_widget_set_sensitive (button, sensitive);
  	g_signal_connect (button, "clicked", callback, user_data);

  	gtk_widget_show_all (align);

	if (show) {
		gtk_widget_show (button);
	}
	return button;
}

static void
volume_mounted_callback (GnomeVFSVolumeMonitor *volume_monitor,
			 GnomeVFSVolume *volume,
			 NautilusPlacesSidebar *sidebar)
{
	update_places (sidebar);
}

static void
volume_unmounted_callback (GnomeVFSVolumeMonitor *volume_monitor,
			   GnomeVFSVolume *volume,
			   NautilusPlacesSidebar *sidebar)
{
	update_places (sidebar);
}



static void
row_activated_callback (GtkTreeView *tree_view,
			GtkTreePath *path,
			GtkTreeViewColumn *column,
			gpointer user_data)
{
	NautilusPlacesSidebar *sidebar;
	GtkTreeModel *model;
	GtkTreeIter iter;
	NautilusBookmark *bookmark;
	char *uri;
	
	sidebar = NAUTILUS_PLACES_SIDEBAR (user_data);
	model = gtk_tree_view_get_model (tree_view);
	
	if (!gtk_tree_model_get_iter (model, &iter, path)) {
		return;
	}
	

	gtk_tree_model_get 
		(model, &iter, PLACES_SIDEBAR_COLUMN_BOOKMARK, &bookmark, -1);
	if (!bookmark) {
		return;
	}
	
	/* Navigate to the clicked location. */
	uri = nautilus_bookmark_get_uri (NAUTILUS_BOOKMARK (bookmark));
	nautilus_window_info_open_location
		(sidebar->window, 
		 uri, NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE, 0, NULL);
	g_free (uri);
}

static void
update_click_policy (NautilusPlacesSidebar *sidebar)
{
	int policy;
	
	policy = eel_preferences_get_enum (NAUTILUS_PREFERENCES_CLICK_POLICY);
	
	eel_gtk_tree_view_set_activate_on_single_click
		(sidebar->tree_view, policy == NAUTILUS_CLICK_POLICY_SINGLE);
}

static void
click_policy_changed_callback (gpointer user_data)
{
	NautilusPlacesSidebar *sidebar;
	
	sidebar = NAUTILUS_PLACES_SIDEBAR (user_data);

	update_click_policy (sidebar);
}

static gboolean
is_bookmark_uri_in_list (const char* uri)
{
	int bookmark_count, index;
	NautilusBookmark *bookmark;
	gboolean result;
	char *bookmark_uri;

	result = FALSE;
	bookmark_count = nautilus_bookmark_list_length (bookmarks);
	for (index = 0; index < bookmark_count; ++index) {
		bookmark = nautilus_bookmark_list_item_at (bookmarks, index);
		if (!bookmark) {
			continue;
		}
		bookmark_uri = nautilus_bookmark_get_uri (bookmark);
		if (strcmp (bookmark_uri, uri) == 0) {
			result = TRUE;
			g_free (bookmark_uri);
			break;
		}
		g_free (bookmark_uri);
	}
	return result;
}

static void
add_bookmark_button_clicked_callback (GtkButton *button, gpointer user_data)
{
	NautilusPlacesSidebar 	 *sidebar;
	NautilusBookmark     	 *bookmark;
	GtkListStore	         *store;
	char			 *name;

	sidebar = NAUTILUS_PLACES_SIDEBAR (user_data);
	store = GTK_LIST_STORE (gtk_tree_view_get_model (sidebar->tree_view));
	
	/* dont add duplicate bookmark uri's */
	if (is_bookmark_uri_in_list (sidebar->uri)) {
		return;
	}
	
	name = nautilus_compute_title_for_uri (sidebar->uri);
	name = eel_str_middle_truncate (name, MAX_BOOKMARK_LENGTH);
	bookmark = nautilus_bookmark_new (sidebar->uri, name);
	g_free (name);
	nautilus_bookmark_list_append (bookmarks, bookmark);
}

static void
remove_bookmark_button_clicked_callback (GtkButton *button, gpointer user_data)
{
	GtkTreeSelection 	*selection;
	GtkTreeModel     	*model;
	GtkTreeIter       	iter;
	PlaceType	 	type; 
	NautilusPlacesSidebar 	*sidebar;
	NautilusBookmark     	*bookmark;
	char *			uri;

	sidebar = NAUTILUS_PLACES_SIDEBAR (user_data);
	selection = gtk_tree_view_get_selection (sidebar->tree_view);
	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
    		gtk_tree_model_get (model, &iter, PLACES_SIDEBAR_COLUMN_BOOKMARK_TYPE, &type, -1);
		if (type == PLACES_BOOKMARK) {
			gtk_tree_model_get (model, &iter, PLACES_SIDEBAR_COLUMN_BOOKMARK, &bookmark, -1);
			g_assert (bookmark != NULL);
			uri = nautilus_bookmark_get_uri (bookmark);
			nautilus_bookmark_list_delete_items_with_uri (bookmarks, uri);
			g_free (uri);
		}
  	}
}


static void
loading_uri_callback (NautilusWindowInfo *window,
		      char *location,
		      NautilusPlacesSidebar *sidebar)
{
	GtkTreeSelection *selection;
	GtkTreeIter 	 iter;
	GtkListStore     *store;
	gboolean 	 valid;
	NautilusBookmark *bookmark;
	char  		 *uri;

        if (strcmp (sidebar->uri, location) != 0) {
		if (sidebar->uri) {
	                g_free (sidebar->uri);
		}
                sidebar->uri = g_strdup (location);
               
  
		/* set selection if any place matches location */
 		store = GTK_LIST_STORE (gtk_tree_view_get_model (sidebar->tree_view));
		selection = gtk_tree_view_get_selection (sidebar->tree_view);
		gtk_tree_selection_unselect_all (selection);
  		valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);

		while (valid) {
    		
			gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 
		 		       	    PLACES_SIDEBAR_COLUMN_BOOKMARK, &bookmark,
		                        -1);
			if (bookmark) {
				uri = nautilus_bookmark_get_uri (bookmark);
				if (strcmp (uri, location) == 0) {
					gtk_tree_selection_select_iter (selection, &iter);
					break;
				}
				g_free (uri);
			}
        	 	valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
		}
    	}
}


static void
nautilus_places_sidebar_init (NautilusPlacesSidebar *sidebar)
{
	GtkTreeView       *tree_view;
	GtkTreeViewColumn *col;
	GtkCellRenderer   *cell;
	GtkListStore      *store;
	GtkTreeSelection  *selection;
	GtkWidget 	  *swin;
   	GtkWidget 	  *vbox;
  	GtkWidget 	  *hbox;
  	GtkWidget 	  *widget;
        GtkSizeGroup *size_group;

  	/* size group is used by the [+][-] buttons*/
  	size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
  	
	vbox = gtk_vbox_new (FALSE, 6);
  	gtk_widget_show (vbox);

 	/* Scrolled window */
	swin = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
		  		        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin),
				             GTK_SHADOW_IN);
	gtk_widget_show (swin);
  	gtk_box_pack_start (GTK_BOX (vbox), swin, TRUE, TRUE, 0);


  	/* tree view */
	tree_view = GTK_TREE_VIEW (gtk_tree_view_new ());
	gtk_tree_view_set_headers_visible (tree_view, FALSE);

	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", PLACES_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", PLACES_SIDEBAR_COLUMN_NAME,
					     NULL);

	gtk_tree_view_set_row_separator_func (tree_view,
					      shortcuts_row_separator_func,
					      GINT_TO_POINTER (PLACES_SIDEBAR_COLUMN_NAME),
					      NULL);

	gtk_tree_view_column_set_fixed_width (col, NAUTILUS_ICON_SIZE_SMALLER);
	gtk_tree_view_append_column (tree_view, col);
	
	store = gtk_list_store_new (PLACES_SIDEBAR_COLUMN_COUNT,
				    GDK_TYPE_PIXBUF,
				    G_TYPE_STRING,
				    NAUTILUS_TYPE_BOOKMARK,
				    G_TYPE_INT);

	gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (store));
	gtk_container_add (GTK_CONTAINER (swin), GTK_WIDGET (tree_view));
	gtk_widget_show (GTK_WIDGET (tree_view));

  	/* Box for buttons */

  	hbox = gtk_hbox_new (TRUE, 6);
  	gtk_container_set_border_width (GTK_CONTAINER (hbox), 1);
	gtk_size_group_add_widget (size_group, hbox);
  	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  	gtk_widget_show (hbox);

  	/* Add bookmark button */

  	widget = button_new (_("_Add"),
			    GTK_STOCK_ADD,
			    TRUE,
			    TRUE,
			    G_CALLBACK (add_bookmark_button_clicked_callback),
			    sidebar);

	gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
	sidebar->add_button = widget;

	/* Remove bookmark button */

  	widget = button_new (_("_Remove"),
			    GTK_STOCK_REMOVE,
			    FALSE,
			    TRUE,
			    G_CALLBACK (remove_bookmark_button_clicked_callback),
			    sidebar);

	gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
	sidebar->remove_button = widget;

	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sidebar),
					GTK_POLICY_NEVER,
					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_add_with_viewport (GTK_SCROLLED_WINDOW (sidebar), GTK_WIDGET (vbox));
	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_BROWSE);

	g_signal_connect_object
		(tree_view, "row_activated", 
		 G_CALLBACK (row_activated_callback), sidebar, 0);

	g_signal_connect (selection, "changed",
			  G_CALLBACK (selection_changed_callback), sidebar);
	
	eel_preferences_add_callback (NAUTILUS_PREFERENCES_CLICK_POLICY,
				      click_policy_changed_callback,
				      sidebar);
	update_click_policy (sidebar);

}

static void
nautilus_places_sidebar_finalize (GObject *object)
{
	NautilusPlacesSidebar *sidebar;
	
	sidebar = NAUTILUS_PLACES_SIDEBAR (object);

	if (sidebar->uri) {
		g_free (sidebar->uri);
	}

	eel_preferences_remove_callback (NAUTILUS_PREFERENCES_CLICK_POLICY,
					 click_policy_changed_callback,
					 sidebar);

	G_OBJECT_CLASS (nautilus_places_sidebar_parent_class)->finalize (object);
}

static void
nautilus_places_sidebar_class_init (NautilusPlacesSidebarClass *class)
{
	G_OBJECT_CLASS (class)->finalize = nautilus_places_sidebar_finalize;
}

static const char *
nautilus_places_sidebar_get_sidebar_id (NautilusSidebar *sidebar)
{
	return NAUTILUS_PLACES_SIDEBAR_ID;
}

static char *
nautilus_places_sidebar_get_tab_label (NautilusSidebar *sidebar)
{
	return g_strdup (_("Places"));
}

static GdkPixbuf *
nautilus_places_sidebar_get_tab_icon (NautilusSidebar *sidebar)
{
	return NULL;
}

static void
nautilus_places_sidebar_is_visible_changed (NautilusSidebar *sidebar,
					     gboolean         is_visible)
{
	/* Do nothing */
}

static void
nautilus_places_sidebar_iface_init (NautilusSidebarIface *iface)
{
	iface->get_sidebar_id = nautilus_places_sidebar_get_sidebar_id;
	iface->get_tab_label = nautilus_places_sidebar_get_tab_label;
	iface->get_tab_icon = nautilus_places_sidebar_get_tab_icon;
	iface->is_visible_changed = nautilus_places_sidebar_is_visible_changed;
}

static void
nautilus_places_sidebar_set_parent_window (NautilusPlacesSidebar *sidebar,
					    NautilusWindowInfo *window)
{	
	GnomeVFSVolumeMonitor *volume_monitor;

	sidebar->window = window;
	
	bookmarks = nautilus_window_info_get_bookmark_list (window);
	sidebar->uri = nautilus_window_info_get_current_location (window);

	g_signal_connect_object (bookmarks, "contents_changed",
				 G_CALLBACK (update_places),
				 sidebar, G_CONNECT_SWAPPED);

	g_signal_connect_object (window, "loading_uri",
				 G_CALLBACK (loading_uri_callback),
				 sidebar, 0);
			 
	volume_monitor = gnome_vfs_get_volume_monitor ();
	
	g_signal_connect_object (volume_monitor, "volume_mounted",
				 G_CALLBACK (volume_mounted_callback), sidebar, 0);
	g_signal_connect_object (volume_monitor, "volume_unmounted",
				 G_CALLBACK (volume_unmounted_callback), sidebar, 0);

	update_places (sidebar);
}

static NautilusSidebar *
nautilus_places_sidebar_create (NautilusSidebarProvider *provider,
				 NautilusWindowInfo *window)
{
	NautilusPlacesSidebar *sidebar;
	
	sidebar = g_object_new (nautilus_places_sidebar_get_type (), NULL);
	nautilus_places_sidebar_set_parent_window (sidebar, window);
	g_object_ref (sidebar);
	gtk_object_sink (GTK_OBJECT (sidebar));

	return NAUTILUS_SIDEBAR (sidebar);
}

static void 
sidebar_provider_iface_init (NautilusSidebarProviderIface *iface)
{
	iface->create = nautilus_places_sidebar_create;
}

static void
nautilus_places_sidebar_provider_init (NautilusPlacesSidebarProvider *sidebar)
{
}

static void
nautilus_places_sidebar_provider_class_init (NautilusPlacesSidebarProviderClass *class)
{
}

void
nautilus_places_sidebar_register (void)
{
        nautilus_module_add_type (nautilus_places_sidebar_provider_get_type ());
}

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */

/*
 *  Nautilus
 *
 *
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Author : Mr Jamie McCracken (jamiemcc at blueyonder dot co dot uk)
 *
 */
#ifndef _NAUTILUS_PLACES_SIDEBAR_H
#define _NAUTILUS_PLACES_SIDEBAR_H

#include <gtk/gtktreeview.h>
#include <libnautilus-private/nautilus-view.h>
#include <libnautilus-private/nautilus-window-info.h>
#include <gtk/gtkscrolledwindow.h>

#define NAUTILUS_PLACES_SIDEBAR_ID    "NautilusPlacesSidebar"

#define NAUTILUS_TYPE_PLACES_SIDEBAR (nautilus_places_sidebar_get_type ())
#define NAUTILUS_PLACES_SIDEBAR(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_PLACES_SIDEBAR, NautilusPlacesSidebar))

typedef struct {
	GtkScrolledWindow  parent;
	GtkTreeView        *tree_view;
	GtkWidget          *add_button;
	GtkWidget          *remove_button;
	char 	           *uri;
	NautilusWindowInfo *window;
} NautilusPlacesSidebar;

GType nautilus_places_sidebar_get_type (void);
void nautilus_places_sidebar_register (void);

#endif


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]