Merge branch 'places-sidebar' into master

This lands the GtkPlacesSidebar widget.  It is used in
GtkFileChooserDefault, and it can also be used by third-party
applications.
This commit is contained in:
Federico Mena Quintero 2013-04-11 19:45:12 -05:00
commit 5b827c53e5
21 changed files with 5771 additions and 3648 deletions

View File

@ -220,6 +220,7 @@
<xi:include href="xml/gtkfontbutton.xml" />
<xi:include href="xml/gtkfontchooserwidget.xml" />
<xi:include href="xml/gtkfontchooserdialog.xml" />
<xi:include href="xml/gtkplacessidebar.xml" />
</chapter>
<chapter id="LayoutContainers">

View File

@ -2483,6 +2483,32 @@ GTK_PANED_GET_CLASS
gtk_paned_get_type
</SECTION>
<SECTION>
<FILE>gtkplacessidebar</FILE>
<TITLE>GtkPlacesSidebar</FILE>
GtkPlacesSidebar
GtkPlacesOpenFlags
gtk_places_sidebar_new
gtk_places_sidebar_set_open_flags
gtk_places_sidebar_set_location
gtk_places_sidebar_get_location
gtk_places_sidebar_set_show_desktop
gtk_places_sidebar_set_accept_uri_drops
gtk_places_sidebar_add_shortcut
gtk_places_sidebar_remove_shortcut
gtk_places_sidebar_list_shortcuts
gtk_places_sidebar_get_nth_bookmark
<SUBSECTION Standard>
GTK_PLACES_SIDEBAR
GTK_IS_PLACES_SIDEBAR
GTK_TYPE_PLACES_SIDEBAR
GTK_PLACES_SIDEBAR_CLASS
GTK_IS_PLACES_SIDEBAR_CLASS
GTK_PLACES_SIDEBAR_GET_CLASS
<SUBSECTION Private>
gtk_places_sidebar_get_type
</SECTION>
<SECTION>
<FILE>gtkplug</FILE>
<TITLE>GtkPlug</TITLE>

View File

@ -295,6 +295,7 @@ gtk_public_h_sources = \
gtkpagesetup.h \
gtkpaned.h \
gtkpapersize.h \
gtkplacessidebar.h \
gtkplug.h \
gtkprintcontext.h \
gtkprintoperation.h \
@ -421,6 +422,7 @@ gtk_private_h_sources = \
gtkbindingsprivate.h \
gtkbitmaskprivate.h \
gtkbitmaskprivateimpl.h \
gtkbookmarksmanager.h \
gtkborderimageprivate.h \
gtkboxprivate.h \
gtkbubblewindowprivate.h \
@ -547,6 +549,7 @@ gtk_private_h_sources = \
gtktextutil.h \
gtkthemingbackgroundprivate.h \
gtkthemingengineprivate.h \
gtktrashmonitor.h \
gtktoolpaletteprivate.h \
gtktreedatalist.h \
gtktreeprivate.h \
@ -621,6 +624,7 @@ gtk_base_c_sources = \
gtkbbox.c \
gtkbin.c \
gtkbindings.c \
gtkbookmarksmanager.c \
gtkborder.c \
gtkborderimage.c \
gtkbox.c \
@ -783,6 +787,7 @@ gtk_base_c_sources = \
gtkpango.c \
gtkpapersize.c \
gtkpathbar.c \
gtkplacessidebar.c \
gtkpressandhold.c \
gtkprintcontext.c \
gtkprintoperation.c \
@ -866,6 +871,7 @@ gtk_base_c_sources = \
gtktoolpalette.c \
gtktoolshell.c \
gtktooltip.c \
gtktrashmonitor.c \
gtktreedatalist.c \
gtktreednd.c \
gtktreemenu.c \

View File

@ -41,6 +41,13 @@ GtkTreeView.view.expander:selected:hover {
color: @text_color;
}
GtkTreeView.dnd {
border-color: @internal_element_color;
border-radius: 0;
border-width: 1px;
border-style: solid;
}
*:insensitive {
border-color: shade (@bg_color, 0.7);
background-color: shade (@bg_color, 0.9);

View File

@ -145,6 +145,7 @@
#include <gtk/gtkpagesetup.h>
#include <gtk/gtkpapersize.h>
#include <gtk/gtkpaned.h>
#include <gtk/gtkplacessidebar.h>
#include <gtk/gtkprintcontext.h>
#include <gtk/gtkprintoperation.h>
#include <gtk/gtkprintoperationpreview.h>

596
gtk/gtkbookmarksmanager.c Normal file
View File

@ -0,0 +1,596 @@
/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
/* GTK - The GIMP Toolkit
* gtkbookmarksmanager.c: Utilities to manage and monitor ~/.gtk-bookmarks
* Copyright (C) 2003, Red Hat, Inc.
* Copyright (C) 2007-2008 Carlos Garnacho
* Copyright (C) 2011 Suse
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Authors: Federico Mena Quintero <federico@gnome.org>
*/
#include "config.h"
#include <string.h>
#include <glib/gi18n-lib.h>
#include "gtkbookmarksmanager.h"
#include "gtkfilechooser.h" /* for the GError types */
static void
_gtk_bookmark_free (GtkBookmark *bookmark)
{
g_object_unref (bookmark->file);
g_free (bookmark->label);
g_slice_free (GtkBookmark, bookmark);
}
static GFile *
get_legacy_bookmarks_file (void)
{
GFile *file;
gchar *filename;
filename = g_build_filename (g_get_home_dir (), ".gtk-bookmarks", NULL);
file = g_file_new_for_path (filename);
g_free (filename);
return file;
}
static GFile *
get_bookmarks_file (void)
{
GFile *file;
gchar *filename;
filename = g_build_filename (g_get_user_config_dir (), "gtk-3.0", "bookmarks", NULL);
file = g_file_new_for_path (filename);
g_free (filename);
return file;
}
static GSList *
read_bookmarks (GFile *file)
{
gchar *contents;
gchar **lines, *space;
GSList *bookmarks = NULL;
gint i;
if (!g_file_load_contents (file, NULL, &contents,
NULL, NULL, NULL))
return NULL;
lines = g_strsplit (contents, "\n", -1);
for (i = 0; lines[i]; i++)
{
GtkBookmark *bookmark;
if (!*lines[i])
continue;
if (!g_utf8_validate (lines[i], -1, NULL))
continue;
bookmark = g_slice_new0 (GtkBookmark);
if ((space = strchr (lines[i], ' ')) != NULL)
{
space[0] = '\0';
bookmark->label = g_strdup (space + 1);
}
bookmark->file = g_file_new_for_uri (lines[i]);
bookmarks = g_slist_prepend (bookmarks, bookmark);
}
bookmarks = g_slist_reverse (bookmarks);
g_strfreev (lines);
g_free (contents);
return bookmarks;
}
static void
save_bookmarks (GFile *bookmarks_file,
GSList *bookmarks)
{
GError *error = NULL;
GString *contents;
GSList *l;
contents = g_string_new ("");
for (l = bookmarks; l; l = l->next)
{
GtkBookmark *bookmark = l->data;
gchar *uri;
uri = g_file_get_uri (bookmark->file);
if (!uri)
continue;
g_string_append (contents, uri);
if (bookmark->label)
g_string_append_printf (contents, " %s", bookmark->label);
g_string_append_c (contents, '\n');
g_free (uri);
}
if (!g_file_replace_contents (bookmarks_file,
contents->str,
strlen (contents->str),
NULL, FALSE, 0, NULL,
NULL, &error))
{
g_critical ("%s", error->message);
g_error_free (error);
}
g_string_free (contents, TRUE);
}
static void
notify_changed (GtkBookmarksManager *manager)
{
if (manager->changed_func)
manager->changed_func (manager->changed_func_data);
}
static void
bookmarks_file_changed (GFileMonitor *monitor,
GFile *file,
GFile *other_file,
GFileMonitorEvent event,
gpointer data)
{
GtkBookmarksManager *manager = data;
switch (event)
{
case G_FILE_MONITOR_EVENT_CHANGED:
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
case G_FILE_MONITOR_EVENT_CREATED:
case G_FILE_MONITOR_EVENT_DELETED:
g_slist_foreach (manager->bookmarks, (GFunc) _gtk_bookmark_free, NULL);
g_slist_free (manager->bookmarks);
manager->bookmarks = read_bookmarks (file);
gdk_threads_enter ();
notify_changed (manager);
gdk_threads_leave ();
break;
default:
/* ignore at the moment */
break;
}
}
GtkBookmarksManager *
_gtk_bookmarks_manager_new (GtkBookmarksChangedFunc changed_func, gpointer changed_func_data)
{
GtkBookmarksManager *manager;
GFile *bookmarks_file;
GError *error;
manager = g_new0 (GtkBookmarksManager, 1);
manager->changed_func = changed_func;
manager->changed_func_data = changed_func_data;
bookmarks_file = get_bookmarks_file ();
manager->bookmarks = read_bookmarks (bookmarks_file);
if (!manager->bookmarks)
{
GFile *legacy_bookmarks_file;
/* Read the legacy one and write it to the new one */
legacy_bookmarks_file = get_legacy_bookmarks_file ();
manager->bookmarks = read_bookmarks (legacy_bookmarks_file);
save_bookmarks (bookmarks_file, manager->bookmarks);
g_object_unref (legacy_bookmarks_file);
}
error = NULL;
manager->bookmarks_monitor = g_file_monitor_file (bookmarks_file,
G_FILE_MONITOR_NONE,
NULL, &error);
if (error)
{
g_warning ("%s", error->message);
g_error_free (error);
}
else
manager->bookmarks_monitor_changed_id = g_signal_connect (manager->bookmarks_monitor, "changed",
G_CALLBACK (bookmarks_file_changed), manager);
g_object_unref (bookmarks_file);
return manager;
}
void
_gtk_bookmarks_manager_free (GtkBookmarksManager *manager)
{
g_return_if_fail (manager != NULL);
if (manager->bookmarks_monitor)
{
g_file_monitor_cancel (manager->bookmarks_monitor);
g_signal_handler_disconnect (manager->bookmarks_monitor, manager->bookmarks_monitor_changed_id);
manager->bookmarks_monitor_changed_id = 0;
g_object_unref (manager->bookmarks_monitor);
}
if (manager->bookmarks)
{
g_slist_foreach (manager->bookmarks, (GFunc) _gtk_bookmark_free, NULL);
g_slist_free (manager->bookmarks);
}
g_free (manager);
}
GSList *
_gtk_bookmarks_manager_list_bookmarks (GtkBookmarksManager *manager)
{
GSList *bookmarks, *files = NULL;
g_return_val_if_fail (manager != NULL, NULL);
bookmarks = manager->bookmarks;
while (bookmarks)
{
GtkBookmark *bookmark;
bookmark = bookmarks->data;
bookmarks = bookmarks->next;
files = g_slist_prepend (files, g_object_ref (bookmark->file));
}
return g_slist_reverse (files);
}
static GSList *
find_bookmark_link_for_file (GSList *bookmarks, GFile *file, int *position_ret)
{
int pos;
pos = 0;
for (; bookmarks; bookmarks = bookmarks->next)
{
GtkBookmark *bookmark = bookmarks->data;
if (g_file_equal (file, bookmark->file))
{
if (position_ret)
*position_ret = pos;
return bookmarks;
}
pos++;
}
if (position_ret)
*position_ret = -1;
return NULL;
}
gboolean
_gtk_bookmarks_manager_has_bookmark (GtkBookmarksManager *manager,
GFile *file)
{
GSList *link;
link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
return (link != NULL);
}
gboolean
_gtk_bookmarks_manager_insert_bookmark (GtkBookmarksManager *manager,
GFile *file,
gint position,
GError **error)
{
GSList *link;
GtkBookmark *bookmark;
GFile *bookmarks_file;
g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
if (link)
{
bookmark = link->data;
gchar *uri = g_file_get_uri (bookmark->file);
g_set_error (error,
GTK_FILE_CHOOSER_ERROR,
GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS,
"%s already exists in the bookmarks list",
uri);
g_free (uri);
return FALSE;
}
bookmark = g_slice_new0 (GtkBookmark);
bookmark->file = g_object_ref (file);
manager->bookmarks = g_slist_insert (manager->bookmarks, bookmark, position);
bookmarks_file = get_bookmarks_file ();
save_bookmarks (bookmarks_file, manager->bookmarks);
g_object_unref (bookmarks_file);
notify_changed (manager);
return TRUE;
}
gboolean
_gtk_bookmarks_manager_remove_bookmark (GtkBookmarksManager *manager,
GFile *file,
GError **error)
{
GSList *link;
GFile *bookmarks_file;
g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if (!manager->bookmarks)
return FALSE;
link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
if (link)
{
GtkBookmark *bookmark = link->data;
manager->bookmarks = g_slist_remove_link (manager->bookmarks, link);
_gtk_bookmark_free (bookmark);
g_slist_free_1 (link);
}
else
{
gchar *uri = g_file_get_uri (file);
g_set_error (error,
GTK_FILE_CHOOSER_ERROR,
GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
"%s does not exist in the bookmarks list",
uri);
g_free (uri);
return FALSE;
}
bookmarks_file = get_bookmarks_file ();
save_bookmarks (bookmarks_file, manager->bookmarks);
g_object_unref (bookmarks_file);
notify_changed (manager);
return TRUE;
}
gboolean
_gtk_bookmarks_manager_reorder_bookmark (GtkBookmarksManager *manager,
GFile *file,
gint new_position,
GError **error)
{
GSList *link;
GFile *bookmarks_file;
int old_position;
g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
g_return_val_if_fail (new_position >= 0, FALSE);
if (!manager->bookmarks)
return FALSE;
link = find_bookmark_link_for_file (manager->bookmarks, file, &old_position);
if (new_position == old_position)
return TRUE;
if (link)
{
GtkBookmark *bookmark = link->data;
manager->bookmarks = g_slist_remove_link (manager->bookmarks, link);
g_slist_free_1 (link);
if (new_position > old_position)
new_position--;
manager->bookmarks = g_slist_insert (manager->bookmarks, bookmark, new_position);
}
else
{
gchar *uri = g_file_get_uri (file);
g_set_error (error,
GTK_FILE_CHOOSER_ERROR,
GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
"%s does not exist in the bookmarks list",
uri);
g_free (uri);
return FALSE;
}
bookmarks_file = get_bookmarks_file ();
save_bookmarks (bookmarks_file, manager->bookmarks);
g_object_unref (bookmarks_file);
notify_changed (manager);
return TRUE;
}
gchar *
_gtk_bookmarks_manager_get_bookmark_label (GtkBookmarksManager *manager,
GFile *file)
{
GSList *bookmarks;
gchar *label = NULL;
g_return_val_if_fail (manager != NULL, NULL);
g_return_val_if_fail (file != NULL, NULL);
bookmarks = manager->bookmarks;
while (bookmarks)
{
GtkBookmark *bookmark;
bookmark = bookmarks->data;
bookmarks = bookmarks->next;
if (g_file_equal (file, bookmark->file))
{
label = g_strdup (bookmark->label);
break;
}
}
return label;
}
gboolean
_gtk_bookmarks_manager_set_bookmark_label (GtkBookmarksManager *manager,
GFile *file,
const gchar *label,
GError **error)
{
GFile *bookmarks_file;
GSList *link;
g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (file != NULL, FALSE);
link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
if (link)
{
GtkBookmark *bookmark = link->data;
g_free (bookmark->label);
bookmark->label = g_strdup (label);
}
else
{
gchar *uri = g_file_get_uri (file);
g_set_error (error,
GTK_FILE_CHOOSER_ERROR,
GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
"%s does not exist in the bookmarks list",
uri);
g_free (uri);
return FALSE;
}
bookmarks_file = get_bookmarks_file ();
save_bookmarks (bookmarks_file, manager->bookmarks);
g_object_unref (bookmarks_file);
notify_changed (manager);
return TRUE;
}
gboolean
_gtk_bookmarks_manager_get_xdg_type (GtkBookmarksManager *manager,
GFile *file,
GUserDirectory *directory)
{
GSList *link;
gboolean match;
GFile *location;
const gchar *path;
GUserDirectory dir;
GtkBookmark *bookmark;
link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
if (!link)
return FALSE;
match = FALSE;
bookmark = link->data;
for (dir = 0; dir < G_USER_N_DIRECTORIES; dir++)
{
path = g_get_user_special_dir (dir);
if (!path)
continue;
location = g_file_new_for_path (path);
match = g_file_equal (location, bookmark->file);
g_object_unref (location);
if (match)
break;
}
if (match && directory != NULL)
*directory = dir;
return match;
}
gboolean
_gtk_bookmarks_manager_get_is_builtin (GtkBookmarksManager *manager,
GFile *file)
{
GUserDirectory xdg_type;
/* if this is not an XDG dir, it's never builtin */
if (!_gtk_bookmarks_manager_get_xdg_type (manager, file, &xdg_type))
return FALSE;
/* exclude XDG locations we don't display by default */
return _gtk_bookmarks_manager_get_is_xdg_dir_builtin (xdg_type);
}
gboolean
_gtk_bookmarks_manager_get_is_xdg_dir_builtin (GUserDirectory xdg_type)
{
return (xdg_type != G_USER_DIRECTORY_DESKTOP) &&
(xdg_type != G_USER_DIRECTORY_TEMPLATES) &&
(xdg_type != G_USER_DIRECTORY_PUBLIC_SHARE);
}

91
gtk/gtkbookmarksmanager.h Normal file
View File

@ -0,0 +1,91 @@
/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
/* GTK - The GIMP Toolkit
* gtkbookmarksmanager.h: Utilities to manage and monitor ~/.gtk-bookmarks
* Copyright (C) 2003, Red Hat, Inc.
* Copyright (C) 2007-2008 Carlos Garnacho
* Copyright (C) 2011 Suse
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Authors: Federico Mena Quintero <federico@gnome.org>
*/
#ifndef __GTK_BOOKMARKS_MANAGER_H__
#define __GTK_BOOKMARKS_MANAGER_H__
#include <gio/gio.h>
typedef void (* GtkBookmarksChangedFunc) (gpointer data);
typedef struct
{
/* This list contains GtkBookmark structs */
GSList *bookmarks;
GFileMonitor *bookmarks_monitor;
gulong bookmarks_monitor_changed_id;
gpointer changed_func_data;
GtkBookmarksChangedFunc changed_func;
} GtkBookmarksManager;
typedef struct
{
GFile *file;
gchar *label;
} GtkBookmark;
GtkBookmarksManager *_gtk_bookmarks_manager_new (GtkBookmarksChangedFunc changed_func,
gpointer changed_func_data);
void _gtk_bookmarks_manager_free (GtkBookmarksManager *manager);
GSList *_gtk_bookmarks_manager_list_bookmarks (GtkBookmarksManager *manager);
gboolean _gtk_bookmarks_manager_insert_bookmark (GtkBookmarksManager *manager,
GFile *file,
gint position,
GError **error);
gboolean _gtk_bookmarks_manager_remove_bookmark (GtkBookmarksManager *manager,
GFile *file,
GError **error);
gboolean _gtk_bookmarks_manager_reorder_bookmark (GtkBookmarksManager *manager,
GFile *file,
gint new_position,
GError **error);
gboolean _gtk_bookmarks_manager_has_bookmark (GtkBookmarksManager *manager,
GFile *file);
gchar * _gtk_bookmarks_manager_get_bookmark_label (GtkBookmarksManager *manager,
GFile *file);
gboolean _gtk_bookmarks_manager_set_bookmark_label (GtkBookmarksManager *manager,
GFile *file,
const gchar *label,
GError **error);
gboolean _gtk_bookmarks_manager_get_xdg_type (GtkBookmarksManager *manager,
GFile *file,
GUserDirectory *directory);
gboolean _gtk_bookmarks_manager_get_is_builtin (GtkBookmarksManager *manager,
GFile *file);
gboolean _gtk_bookmarks_manager_get_is_xdg_dir_builtin (GUserDirectory xdg_type);
#endif /* __GTK_BOOKMARKS_MANAGER_H__ */

View File

@ -55,9 +55,8 @@
* <varlistentry>
* <term>Shortcuts</term>
* <listitem>
* can be provided by the application or by the underlying filesystem
* abstraction (e.g. both the gnome-vfs and the Windows filesystems
* provide "Desktop" shortcuts). Shortcuts cannot be modified by the
* can be provided by the application. For example, a Paint program may
* want to add a shortcut for a Clipart folder. Shortcuts cannot be modified by the
* user.
* </listitem>
* </varlistentry>

View File

@ -186,12 +186,13 @@ struct _GtkFileChooserButtonPrivate
GFile *current_folder_while_inactive;
gulong fs_volumes_changed_id;
gulong fs_bookmarks_changed_id;
GCancellable *dnd_select_folder_cancellable;
GCancellable *update_button_cancellable;
GSList *change_icon_theme_cancellables;
GtkBookmarksManager *bookmarks_manager;
gint icon_size;
guint8 n_special;
@ -323,8 +324,7 @@ static void update_label_and_image (GtkFileChooserButton *button)
/* Child Object Callbacks */
static void fs_volumes_changed_cb (GtkFileSystem *fs,
gpointer user_data);
static void fs_bookmarks_changed_cb (GtkFileSystem *fs,
gpointer user_data);
static void bookmarks_changed_cb (gpointer user_data);
static void combo_box_changed_cb (GtkComboBox *combo_box,
gpointer user_data);
@ -502,6 +502,8 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button)
gtk_widget_init_template (GTK_WIDGET (button));
/* Bookmarks manager */
priv->bookmarks_manager = _gtk_bookmarks_manager_new (bookmarks_changed_cb, button);
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (priv->combo_box),
priv->name_cell, name_cell_data_func,
NULL, NULL);
@ -849,7 +851,7 @@ gtk_file_chooser_button_constructor (GType type,
model_add_volumes (button, list);
g_slist_free (list);
list = _gtk_file_system_list_bookmarks (priv->fs);
list = _gtk_bookmarks_manager_list_bookmarks (priv->bookmarks_manager);
model_add_bookmarks (button, list);
g_slist_foreach (list, (GFunc) g_object_unref, NULL);
g_slist_free (list);
@ -878,9 +880,6 @@ gtk_file_chooser_button_constructor (GType type,
priv->fs_volumes_changed_id =
g_signal_connect (priv->fs, "volumes-changed",
G_CALLBACK (fs_volumes_changed_cb), object);
priv->fs_bookmarks_changed_id =
g_signal_connect (priv->fs, "bookmarks-changed",
G_CALLBACK (fs_bookmarks_changed_cb), object);
update_label_and_image (button);
update_combo_box (button);
@ -964,7 +963,7 @@ gtk_file_chooser_button_set_property (GObject *object,
case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY:
g_object_set_property (G_OBJECT (priv->dialog), pspec->name, value);
fs_volumes_changed_cb (priv->fs, button);
fs_bookmarks_changed_cb (priv->fs, button);
bookmarks_changed_cb (button);
break;
case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
@ -1089,11 +1088,16 @@ gtk_file_chooser_button_destroy (GtkWidget *widget)
if (priv->fs)
{
g_signal_handler_disconnect (priv->fs, priv->fs_volumes_changed_id);
g_signal_handler_disconnect (priv->fs, priv->fs_bookmarks_changed_id);
g_object_unref (priv->fs);
priv->fs = NULL;
}
if (priv->bookmarks_manager)
{
_gtk_bookmarks_manager_free (priv->bookmarks_manager);
priv->bookmarks_manager = NULL;
}
GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->destroy (widget);
}
@ -1604,7 +1608,7 @@ set_info_for_file_at_iter (GtkFileChooserButton *button,
data = g_new0 (struct SetDisplayNameData, 1);
data->button = g_object_ref (button);
data->label = _gtk_file_system_get_bookmark_label (button->priv->fs, file);
data->label = _gtk_bookmarks_manager_get_bookmark_label (button->priv->bookmarks_manager, file);
tree_path = gtk_tree_model_get_path (button->priv->model, iter);
data->row_ref = gtk_tree_row_reference_new (button->priv->model, tree_path);
@ -1988,7 +1992,7 @@ model_add_bookmarks (GtkFileChooserButton *button,
* If we switch to a better bookmarks file format (XBEL), we
* should use mime info to get a better icon.
*/
label = _gtk_file_system_get_bookmark_label (button->priv->fs, file);
label = _gtk_bookmarks_manager_get_bookmark_label (button->priv->bookmarks_manager, file);
if (!label)
label = _gtk_file_chooser_label_for_file (file);
@ -2091,7 +2095,7 @@ model_update_current_folder (GtkFileChooserButton *button,
* If we switch to a better bookmarks file format (XBEL), we
* should use mime info to get a better icon.
*/
label = _gtk_file_system_get_bookmark_label (button->priv->fs, file);
label = _gtk_bookmarks_manager_get_bookmark_label (button->priv->bookmarks_manager, file);
if (!label)
label = _gtk_file_chooser_label_for_file (file);
@ -2548,7 +2552,7 @@ update_label_and_image (GtkFileChooserButton *button)
{
GdkPixbuf *pixbuf;
label_text = _gtk_file_system_get_bookmark_label (button->priv->fs, file);
label_text = _gtk_bookmarks_manager_get_bookmark_label (button->priv->bookmarks_manager, file);
pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (priv->image)),
"text-x-generic",
priv->icon_size, 0, NULL);
@ -2616,14 +2620,13 @@ fs_volumes_changed_cb (GtkFileSystem *fs,
}
static void
fs_bookmarks_changed_cb (GtkFileSystem *fs,
gpointer user_data)
bookmarks_changed_cb (gpointer user_data)
{
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data);
GtkFileChooserButtonPrivate *priv = button->priv;
GSList *bookmarks;
bookmarks = _gtk_file_system_list_bookmarks (fs);
bookmarks = _gtk_bookmarks_manager_list_bookmarks (priv->bookmarks_manager);
model_remove_rows (user_data,
model_get_type_position (user_data,
ROW_TYPE_BOOKMARK_SEPARATOR),

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@
#ifndef __GTK_FILE_CHOOSER_PRIVATE_H__
#define __GTK_FILE_CHOOSER_PRIVATE_H__
#include "gtkbookmarksmanager.h"
#include "gtkfilechooser.h"
#include "gtkfilesystem.h"
#include "gtkfilesystemmodel.h"
@ -42,6 +43,7 @@ G_BEGIN_DECLS
#define SETTINGS_KEY_WINDOW_POSITION "window-position"
#define SETTINGS_KEY_WINDOW_SIZE "window-size"
#define SETTINGS_KEY_SIDEBAR_WIDTH "sidebar-width"
#define SETTINGS_KEY_STARTUP_MODE "startup-mode"
#define GTK_FILE_CHOOSER_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GTK_TYPE_FILE_CHOOSER, GtkFileChooserIface))
@ -146,6 +148,13 @@ typedef enum {
OPERATION_MODE_RECENT
} OperationMode;
typedef enum {
STARTUP_MODE_RECENT,
STARTUP_MODE_CWD
} StartupMode;
#define REMOVE_FOR_PLACES_SIDEBAR 0
struct _GtkFileChooserDefault
{
GtkBox parent_instance;
@ -164,12 +173,6 @@ struct _GtkFileChooserDefault
GtkWidget *browse_widgets_box;
GtkWidget *browse_widgets_hpaned;
GtkWidget *browse_header_box;
GtkWidget *browse_shortcuts_tree_view;
GtkWidget *browse_shortcuts_add_button;
GtkWidget *browse_shortcuts_remove_button;
GtkWidget *browse_shortcuts_popup_menu;
GtkWidget *browse_shortcuts_popup_menu_remove_item;
GtkWidget *browse_shortcuts_popup_menu_rename_item;
GtkWidget *browse_files_tree_view;
GtkWidget *browse_files_popup_menu;
GtkWidget *browse_files_popup_menu_add_shortcut_item;
@ -190,6 +193,9 @@ struct _GtkFileChooserDefault
GtkFileSystemModel *browse_files_model;
char *browse_files_last_selected_name;
GtkWidget *places_sidebar;
StartupMode startup_mode;
/* OPERATION_MODE_SEARCH */
GtkWidget *search_hbox;
GtkWidget *search_entry;
@ -216,13 +222,6 @@ struct _GtkFileChooserDefault
GtkWidget *location_entry;
LocationMode location_mode;
GtkListStore *shortcuts_model;
/* Filter for the shortcuts pane. We filter out the "current folder" row and
* the separator that we use for the "Save in folder" combo.
*/
GtkTreeModel *shortcuts_pane_filter_model;
/* Handles */
GSList *loading_shortcuts;
GSList *reload_icon_cancellables;
@ -244,6 +243,8 @@ struct _GtkFileChooserDefault
GtkFileFilter *current_filter;
GSList *filters;
GtkBookmarksManager *bookmarks_manager;
int num_volumes;
int num_shortcuts;
int num_bookmarks;

View File

@ -55,7 +55,6 @@ enum {
};
enum {
BOOKMARKS_CHANGED,
VOLUMES_CHANGED,
FS_LAST_SIGNAL
};
@ -81,11 +80,6 @@ struct GtkFileSystemPrivate
* of type GDrive, GVolume and GMount
*/
GSList *volumes;
/* This list contains GtkFileSystemBookmark structs */
GSList *bookmarks;
GFileMonitor *bookmarks_monitor;
};
struct AsyncFuncData
@ -99,24 +93,9 @@ struct AsyncFuncData
gpointer data;
};
struct GtkFileSystemBookmark
{
GFile *file;
gchar *label;
};
G_DEFINE_TYPE (GtkFileSystem, _gtk_file_system, G_TYPE_OBJECT)
/* GtkFileSystemBookmark methods */
void
_gtk_file_system_bookmark_free (GtkFileSystemBookmark *bookmark)
{
g_object_unref (bookmark->file);
g_free (bookmark->label);
g_slice_free (GtkFileSystemBookmark, bookmark);
}
/* GtkFileSystem methods */
static void
volumes_changed (GVolumeMonitor *volume_monitor,
@ -157,42 +136,12 @@ gtk_file_system_dispose (GObject *object)
G_OBJECT_CLASS (_gtk_file_system_parent_class)->dispose (object);
}
static void
gtk_file_system_finalize (GObject *object)
{
GtkFileSystem *file_system = GTK_FILE_SYSTEM (object);
GtkFileSystemPrivate *priv = file_system->priv;
DEBUG ("finalize");
if (priv->bookmarks_monitor)
g_object_unref (priv->bookmarks_monitor);
if (priv->bookmarks)
{
g_slist_foreach (priv->bookmarks, (GFunc) _gtk_file_system_bookmark_free, NULL);
g_slist_free (priv->bookmarks);
}
G_OBJECT_CLASS (_gtk_file_system_parent_class)->finalize (object);
}
static void
_gtk_file_system_class_init (GtkFileSystemClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = gtk_file_system_dispose;
object_class->finalize = gtk_file_system_finalize;
fs_signals[BOOKMARKS_CHANGED] =
g_signal_new ("bookmarks-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileSystemClass, bookmarks_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
fs_signals[VOLUMES_CHANGED] =
g_signal_new ("volumes-changed",
@ -206,155 +155,6 @@ _gtk_file_system_class_init (GtkFileSystemClass *class)
g_type_class_add_private (object_class, sizeof (GtkFileSystemPrivate));
}
static GFile *
get_legacy_bookmarks_file (void)
{
GFile *file;
gchar *filename;
filename = g_build_filename (g_get_home_dir (), ".gtk-bookmarks", NULL);
file = g_file_new_for_path (filename);
g_free (filename);
return file;
}
static GFile *
get_bookmarks_file (void)
{
GFile *file;
gchar *filename;
filename = g_build_filename (g_get_user_config_dir (), "gtk-3.0", "bookmarks", NULL);
file = g_file_new_for_path (filename);
g_free (filename);
return file;
}
static GSList *
read_bookmarks (GFile *file)
{
gchar *contents;
gchar **lines, *space;
GSList *bookmarks = NULL;
gint i;
if (!g_file_load_contents (file, NULL, &contents,
NULL, NULL, NULL))
return NULL;
lines = g_strsplit (contents, "\n", -1);
for (i = 0; lines[i]; i++)
{
GtkFileSystemBookmark *bookmark;
if (!*lines[i])
continue;
if (!g_utf8_validate (lines[i], -1, NULL))
continue;
bookmark = g_slice_new0 (GtkFileSystemBookmark);
if ((space = strchr (lines[i], ' ')) != NULL)
{
space[0] = '\0';
bookmark->label = g_strdup (space + 1);
}
bookmark->file = g_file_new_for_uri (lines[i]);
bookmarks = g_slist_prepend (bookmarks, bookmark);
}
bookmarks = g_slist_reverse (bookmarks);
g_strfreev (lines);
g_free (contents);
return bookmarks;
}
static void
save_bookmarks (GFile *bookmarks_file,
GSList *bookmarks)
{
GError *error = NULL;
GString *contents;
GSList *l;
GFile *parent_file;
gchar *path;
contents = g_string_new ("");
for (l = bookmarks; l; l = l->next)
{
GtkFileSystemBookmark *bookmark = l->data;
gchar *uri;
uri = g_file_get_uri (bookmark->file);
if (!uri)
continue;
g_string_append (contents, uri);
if (bookmark->label)
g_string_append_printf (contents, " %s", bookmark->label);
g_string_append_c (contents, '\n');
g_free (uri);
}
parent_file = g_file_get_parent (bookmarks_file);
path = g_file_get_path (parent_file);
if (g_mkdir_with_parents (path, 0700) == 0)
{
if (!g_file_replace_contents (bookmarks_file,
contents->str,
strlen (contents->str),
NULL, FALSE, 0, NULL,
NULL, &error))
{
g_critical ("%s", error->message);
g_error_free (error);
}
}
g_free (path);
g_object_unref (parent_file);
g_string_free (contents, TRUE);
}
static void
bookmarks_file_changed (GFileMonitor *monitor,
GFile *file,
GFile *other_file,
GFileMonitorEvent event,
gpointer data)
{
GtkFileSystem *file_system = GTK_FILE_SYSTEM (data);
GtkFileSystemPrivate *priv = file_system->priv;
switch (event)
{
case G_FILE_MONITOR_EVENT_CHANGED:
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
case G_FILE_MONITOR_EVENT_CREATED:
case G_FILE_MONITOR_EVENT_DELETED:
g_slist_foreach (priv->bookmarks, (GFunc) _gtk_file_system_bookmark_free, NULL);
g_slist_free (priv->bookmarks);
priv->bookmarks = read_bookmarks (file);
gdk_threads_enter ();
g_signal_emit (data, fs_signals[BOOKMARKS_CHANGED], 0);
gdk_threads_leave ();
break;
default:
/* ignore at the moment */
break;
}
}
static gboolean
mount_referenced_by_volume_activation_root (GList *volumes, GMount *mount)
{
@ -533,8 +333,6 @@ static void
_gtk_file_system_init (GtkFileSystem *file_system)
{
GtkFileSystemPrivate *priv;
GFile *bookmarks_file;
GError *error = NULL;
DEBUG ("init");
@ -564,35 +362,6 @@ _gtk_file_system_init (GtkFileSystem *file_system)
G_CALLBACK (volumes_changed), file_system);
g_signal_connect (priv->volume_monitor, "drive-changed",
G_CALLBACK (volumes_changed), file_system);
/* Bookmarks */
bookmarks_file = get_bookmarks_file ();
priv->bookmarks = read_bookmarks (bookmarks_file);
if (!priv->bookmarks)
{
GFile *legacy_bookmarks_file;
/* Read the legacy one and write it to the new one */
legacy_bookmarks_file = get_legacy_bookmarks_file ();
priv->bookmarks = read_bookmarks (legacy_bookmarks_file);
save_bookmarks (bookmarks_file, priv->bookmarks);
g_object_unref (legacy_bookmarks_file);
}
priv->bookmarks_monitor = g_file_monitor_file (bookmarks_file,
G_FILE_MONITOR_NONE,
NULL, &error);
if (error)
{
g_warning ("%s", error->message);
g_error_free (error);
}
else
g_signal_connect (priv->bookmarks_monitor, "changed",
G_CALLBACK (bookmarks_file_changed), file_system);
g_object_unref (bookmarks_file);
}
/* GtkFileSystem public methods */
@ -622,29 +391,6 @@ _gtk_file_system_list_volumes (GtkFileSystem *file_system)
return list;
}
GSList *
_gtk_file_system_list_bookmarks (GtkFileSystem *file_system)
{
GtkFileSystemPrivate *priv = file_system->priv;
GSList *bookmarks, *files = NULL;
DEBUG ("list_bookmarks");
bookmarks = priv->bookmarks;
while (bookmarks)
{
GtkFileSystemBookmark *bookmark;
bookmark = bookmarks->data;
bookmarks = bookmarks->next;
files = g_slist_prepend (files, g_object_ref (bookmark->file));
}
return g_slist_reverse (files);
}
static void
free_async_data (AsyncFuncData *async_data)
{
@ -871,185 +617,6 @@ _gtk_file_system_mount_enclosing_volume (GtkFileSystem *file
return cancellable;
}
gboolean
_gtk_file_system_insert_bookmark (GtkFileSystem *file_system,
GFile *file,
gint position,
GError **error)
{
GtkFileSystemPrivate *priv = file_system->priv;
GSList *bookmarks;
GtkFileSystemBookmark *bookmark;
gboolean result = TRUE;
GFile *bookmarks_file;
bookmarks = priv->bookmarks;
while (bookmarks)
{
bookmark = bookmarks->data;
bookmarks = bookmarks->next;
if (g_file_equal (bookmark->file, file))
{
/* File is already in bookmarks */
result = FALSE;
break;
}
}
if (!result)
{
gchar *uri = g_file_get_uri (file);
g_set_error (error,
GTK_FILE_CHOOSER_ERROR,
GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS,
"%s already exists in the bookmarks list",
uri);
g_free (uri);
return FALSE;
}
bookmark = g_slice_new0 (GtkFileSystemBookmark);
bookmark->file = g_object_ref (file);
priv->bookmarks = g_slist_insert (priv->bookmarks, bookmark, position);
bookmarks_file = get_bookmarks_file ();
save_bookmarks (bookmarks_file, priv->bookmarks);
g_object_unref (bookmarks_file);
g_signal_emit (file_system, fs_signals[BOOKMARKS_CHANGED], 0);
return TRUE;
}
gboolean
_gtk_file_system_remove_bookmark (GtkFileSystem *file_system,
GFile *file,
GError **error)
{
GtkFileSystemPrivate *priv = file_system->priv;
GtkFileSystemBookmark *bookmark;
GSList *bookmarks;
gboolean result = FALSE;
GFile *bookmarks_file;
if (!priv->bookmarks)
return FALSE;
bookmarks = priv->bookmarks;
while (bookmarks)
{
bookmark = bookmarks->data;
if (g_file_equal (bookmark->file, file))
{
result = TRUE;
priv->bookmarks = g_slist_remove_link (priv->bookmarks, bookmarks);
_gtk_file_system_bookmark_free (bookmark);
g_slist_free_1 (bookmarks);
break;
}
bookmarks = bookmarks->next;
}
if (!result)
{
gchar *uri = g_file_get_uri (file);
g_set_error (error,
GTK_FILE_CHOOSER_ERROR,
GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
"%s does not exist in the bookmarks list",
uri);
g_free (uri);
return FALSE;
}
bookmarks_file = get_bookmarks_file ();
save_bookmarks (bookmarks_file, priv->bookmarks);
g_object_unref (bookmarks_file);
g_signal_emit (file_system, fs_signals[BOOKMARKS_CHANGED], 0);
return TRUE;
}
gchar *
_gtk_file_system_get_bookmark_label (GtkFileSystem *file_system,
GFile *file)
{
GtkFileSystemPrivate *priv = file_system->priv;
GSList *bookmarks;
gchar *label = NULL;
DEBUG ("get_bookmark_label");
bookmarks = priv->bookmarks;
while (bookmarks)
{
GtkFileSystemBookmark *bookmark;
bookmark = bookmarks->data;
bookmarks = bookmarks->next;
if (g_file_equal (file, bookmark->file))
{
label = g_strdup (bookmark->label);
break;
}
}
return label;
}
void
_gtk_file_system_set_bookmark_label (GtkFileSystem *file_system,
GFile *file,
const gchar *label)
{
GtkFileSystemPrivate *priv = file_system->priv;
gboolean changed = FALSE;
GFile *bookmarks_file;
GSList *bookmarks;
DEBUG ("set_bookmark_label");
bookmarks = priv->bookmarks;
while (bookmarks)
{
GtkFileSystemBookmark *bookmark;
bookmark = bookmarks->data;
bookmarks = bookmarks->next;
if (g_file_equal (file, bookmark->file))
{
g_free (bookmark->label);
bookmark->label = g_strdup (label);
changed = TRUE;
break;
}
}
bookmarks_file = get_bookmarks_file ();
save_bookmarks (bookmarks_file, priv->bookmarks);
g_object_unref (bookmarks_file);
if (changed)
g_signal_emit_by_name (file_system, "bookmarks-changed", 0);
}
GtkFileSystemVolume *
_gtk_file_system_get_volume_for_file (GtkFileSystem *file_system,
GFile *file)

View File

@ -37,7 +37,6 @@ typedef struct GtkFileSystemClass GtkFileSystemClass;
typedef struct GtkFileSystemVolume GtkFileSystemVolume; /* opaque struct */
typedef struct GtkFileSystemBookmark GtkFileSystemBookmark; /* opaque struct */
struct GtkFileSystem
@ -51,7 +50,6 @@ struct GtkFileSystemClass
{
GObjectClass parent_class;
void (*bookmarks_changed) (GtkFileSystem *file_system);
void (*volumes_changed) (GtkFileSystem *file_system);
};
@ -71,7 +69,6 @@ GType _gtk_file_system_get_type (void) G_GNUC_CONST;
GtkFileSystem * _gtk_file_system_new (void);
GSList * _gtk_file_system_list_volumes (GtkFileSystem *file_system);
GSList * _gtk_file_system_list_bookmarks (GtkFileSystem *file_system);
GCancellable * _gtk_file_system_get_info (GtkFileSystem *file_system,
GFile *file,
@ -89,20 +86,6 @@ GCancellable * _gtk_file_system_mount_enclosing_volume (GtkFileSystem
GtkFileSystemVolumeMountCallback callback,
gpointer data);
gboolean _gtk_file_system_insert_bookmark (GtkFileSystem *file_system,
GFile *file,
gint position,
GError **error);
gboolean _gtk_file_system_remove_bookmark (GtkFileSystem *file_system,
GFile *file,
GError **error);
gchar * _gtk_file_system_get_bookmark_label (GtkFileSystem *file_system,
GFile *file);
void _gtk_file_system_set_bookmark_label (GtkFileSystem *file_system,
GFile *file,
const gchar *label);
GtkFileSystemVolume * _gtk_file_system_get_volume_for_file (GtkFileSystem *file_system,
GFile *file);
@ -118,9 +101,6 @@ GdkPixbuf * _gtk_file_system_volume_render_icon (GtkFileSystemVol
GtkFileSystemVolume *_gtk_file_system_volume_ref (GtkFileSystemVolume *volume);
void _gtk_file_system_volume_unref (GtkFileSystemVolume *volume);
/* GtkFileSystemBookmark methods */
void _gtk_file_system_bookmark_free (GtkFileSystemBookmark *bookmark);
/* GFileInfo helper functions */
GdkPixbuf * _gtk_file_info_render_icon (GFileInfo *info,
GtkWidget *widget,

View File

@ -30,7 +30,6 @@
/* Some forward declarations of internal types */
GType _gtk_scale_button_scale_get_type (void);
GType _shortcuts_pane_model_filter_get_type (void);
/* This function is referred to in gtk/glade/gtk-private-widgets.xml
* and is used to ensure the private types for use in Glade while
@ -44,7 +43,6 @@ gtk_glade_catalog_init (const gchar *catalog_name)
g_type_ensure (GTK_TYPE_COLOR_PLANE);
g_type_ensure (GTK_TYPE_COLOR_SCALE);
g_type_ensure (_gtk_scale_button_scale_get_type ());
g_type_ensure (_shortcuts_pane_model_filter_get_type ());
#ifdef G_OS_UNIX
g_type_ensure (GTK_TYPE_PRINTER_OPTION_WIDGET);

View File

@ -83,12 +83,15 @@ VOID:OBJECT,BOOLEAN
VOID:OBJECT,BOXED,BOXED
VOID:OBJECT,BOXED,UINT,UINT
VOID:OBJECT,BOXED,BOOLEAN,BOOLEAN
VOID:OBJECT,ENUM
VOID:OBJECT,FLAGS
VOID:OBJECT,INT
VOID:OBJECT,INT,OBJECT
VOID:OBJECT,INT,INT
VOID:OBJECT,INT,INT,BOXED,UINT,UINT
VOID:OBJECT,OBJECT
VOID:OBJECT,POINTER
VOID:OBJECT,POINTER,INT
VOID:OBJECT,STRING
VOID:OBJECT,STRING,STRING
VOID:OBJECT,UINT
@ -97,6 +100,7 @@ VOID:OBJECT,STRING
VOID:OBJECT,OBJECT,STRING
VOID:OBJECT,OBJECT,OBJECT
VOID:OBJECT,OBJECT,BOXED,STRING
VOID:OBJECT,OBJECT,POINTER,POINTER
VOID:POINTER
VOID:POINTER,INT
VOID:POINTER,BOOLEAN
@ -120,3 +124,7 @@ VOID:UINT,UINT
VOID:VOID
OBJECT:OBJECT,INT,INT
VOID:POINTER,POINTER,POINTER,POINTER,STRING
VOID:OBJECT,STRING,POINTER,POINTER
INT:INT
VOID:POINTER,STRING,INT
INT:OBJECT,OBJECT,POINTER

4336
gtk/gtkplacessidebar.c Normal file

File diff suppressed because it is too large Load Diff

100
gtk/gtkplacessidebar.h Normal file
View File

@ -0,0 +1,100 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
* GtkPlacesSidebar - sidebar widget for places in the filesystem
*
* This code comes from Nautilus, GNOME's file manager.
*
* 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.
*
* Authors : Mr Jamie McCracken (jamiemcc at blueyonder dot co dot uk)
* Federico Mena Quintero <federico@gnome.org>
*
*/
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#ifndef __GTK_PLACES_SIDEBAR_H__
#define __GTK_PLACES_SIDEBAR_H__
#include <gtk/gtkwidget.h>
G_BEGIN_DECLS
#define GTK_TYPE_PLACES_SIDEBAR (gtk_places_sidebar_get_type ())
#define GTK_PLACES_SIDEBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PLACES_SIDEBAR, GtkPlacesSidebar))
#define GTK_PLACES_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PLACES_SIDEBAR, GtkPlacesSidebarClass))
#define GTK_IS_PLACES_SIDEBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PLACES_SIDEBAR))
#define GTK_IS_PLACES_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PLACES_SIDEBAR))
#define GTK_PLACES_SIDEBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PLACES_SIDEBAR, GtkPlacesSidebarClass))
typedef struct _GtkPlacesSidebar GtkPlacesSidebar;
typedef struct _GtkPlacesSidebarClass GtkPlacesSidebarClass;
/**
* GtkPlacesOpenFlags:
* @GTK_PLACES_OPEN_NORMAL: This is the default mode that #GtkPlacesSidebar uses if no other flags
* are specified. It indicates that the calling application should open the selected location
* in the normal way, for example, in the folder view beside the sidebar.
* @GTK_PLACES_OPEN_NEW_TAB: When passed to gtk_places_sidebar_set_open_flags(), this indicates
* that the application can open folders selected from the sidebar in new tabs. This value
* will be passed to the #GtkPlacesSidebar::open-location signal when the user selects
* that a location be opened in a new tab instead of in the standard fashion.
* @GTK_PLACES_OPEN_NEW_WINDOW: Similar to @GTK_PLACES_OPEN_NEW_TAB, but indicates that the application
* can open folders in new windows.
*
* These flags serve two purposes. First, the application can call gtk_places_sidebar_set_open_flags()
* using these flags as a bitmask. This tells the sidebar that the application is able to open
* folders selected from the sidebar in various ways, for example, in new tabs or in new windows in
* addition to the normal mode.
*
* Second, when one of these values gets passed back to the application in the
* #GtkPlacesSidebar::open-location signal, it means that the application should
* open the selected location in the normal way, in a new tab, or in a new
* window. The sidebar takes care of determining the desired way to open the location,
* based on the modifier keys that the user is pressing at the time the selection is made.
*
* If the application never calls gtk_places_sidebar_set_open_flags(), then the sidebar will only
* use #GTK_PLACES_OPEN_NORMAL in the #GtkPlacesSidebar::open-location signal. This is the
* default mode of operation.
*/
typedef enum {
GTK_PLACES_OPEN_NORMAL = 1 << 0,
GTK_PLACES_OPEN_NEW_TAB = 1 << 1,
GTK_PLACES_OPEN_NEW_WINDOW = 1 << 2
} GtkPlacesOpenFlags;
GType gtk_places_sidebar_get_type (void);
GtkWidget *gtk_places_sidebar_new (void);
GtkPlacesOpenFlags gtk_places_sidebar_get_open_flags (GtkPlacesSidebar *sidebar);
void gtk_places_sidebar_set_open_flags (GtkPlacesSidebar *sidebar, GtkPlacesOpenFlags flags);
GFile *gtk_places_sidebar_get_location (GtkPlacesSidebar *sidebar);
void gtk_places_sidebar_set_location (GtkPlacesSidebar *sidebar, GFile *location);
gboolean gtk_places_sidebar_get_show_desktop (GtkPlacesSidebar *sidebar);
void gtk_places_sidebar_set_show_desktop (GtkPlacesSidebar *sidebar, gboolean show_desktop);
void gtk_places_sidebar_add_shortcut (GtkPlacesSidebar *sidebar, GFile *location);
void gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar, GFile *location);
GSList *gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar);
GFile *gtk_places_sidebar_get_nth_bookmark (GtkPlacesSidebar *sidebar, int n);
G_END_DECLS
#endif /* __GTK_PLACES_SIDEBAR_H__ */

267
gtk/gtktrashmonitor.c Normal file
View File

@ -0,0 +1,267 @@
/* GTK - The GIMP Toolkit
* gtktrashmonitor.h: Monitor the trash:/// folder to see if there is trash or not
* Copyright (C) 2011 Suse
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Authors: Federico Mena Quintero <federico@gnome.org>
*/
#include "config.h"
#include "gtkintl.h"
#include "gtkmarshalers.h"
#include "gtktrashmonitor.h"
struct _GtkTrashMonitor
{
GObject parent;
GFileMonitor *file_monitor;
gulong file_monitor_changed_id;
guint has_trash : 1;
};
struct _GtkTrashMonitorClass
{
GObjectClass parent_class;
void (* trash_state_changed) (GtkTrashMonitor *monitor);
};
enum {
TRASH_STATE_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE (GtkTrashMonitor, _gtk_trash_monitor, G_TYPE_OBJECT)
static GtkTrashMonitor *the_trash_monitor;
#define ICON_NAME_TRASH_EMPTY "user-trash-symbolic"
#define ICON_NAME_TRASH_FULL "user-trash-full-symbolic"
static void
gtk_trash_monitor_dispose (GObject *object)
{
GtkTrashMonitor *monitor;
monitor = GTK_TRASH_MONITOR (object);
if (monitor->file_monitor)
{
g_signal_handler_disconnect (monitor->file_monitor, monitor->file_monitor_changed_id);
monitor->file_monitor_changed_id = 0;
g_clear_object (&monitor->file_monitor);
}
G_OBJECT_CLASS (_gtk_trash_monitor_parent_class)->dispose (object);
}
static void
_gtk_trash_monitor_class_init (GtkTrashMonitorClass *class)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass *) class;
gobject_class->dispose = gtk_trash_monitor_dispose;
signals[TRASH_STATE_CHANGED] =
g_signal_new (I_("trash-state-changed"),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkTrashMonitorClass, trash_state_changed),
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
/* Updates the internal has_trash flag and emits the "trash-state-changed" signal */
static void
update_has_trash_and_notify (GtkTrashMonitor *monitor,
gboolean has_trash)
{
monitor->has_trash = !!has_trash;
g_signal_emit (monitor, signals[TRASH_STATE_CHANGED], 0);
}
static void
trash_enumerate_next_files_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GtkTrashMonitor *monitor = GTK_TRASH_MONITOR (user_data);
GFileEnumerator *enumerator;
GList *infos;
enumerator = G_FILE_ENUMERATOR (source);
infos = g_file_enumerator_next_files_finish (enumerator, result, NULL);
if (infos)
{
update_has_trash_and_notify (monitor, TRUE);
g_list_free_full (infos, g_object_unref);
}
else
{
update_has_trash_and_notify (monitor, FALSE);
}
g_object_unref (monitor); /* was reffed in recompute_trash_state() */
}
/* Callback used from g_file_enumerate_children_async() - this is what enumerates "trash:///" */
static void
trash_enumerate_children_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GtkTrashMonitor *monitor = GTK_TRASH_MONITOR (user_data);
GFileEnumerator *enumerator;
enumerator = g_file_enumerate_children_finish (G_FILE (source), result, NULL);
if (enumerator)
{
g_file_enumerator_next_files_async (enumerator,
1,
G_PRIORITY_DEFAULT,
NULL,
trash_enumerate_next_files_cb,
monitor);
g_object_unref (enumerator);
}
else
{
update_has_trash_and_notify (monitor, FALSE);
g_object_unref (monitor); /* was reffed in recompute_trash_state() */
}
}
/* Asynchronously recomputes whether there is trash or not */
static void
recompute_trash_state (GtkTrashMonitor *monitor)
{
GFile *file;
g_object_ref (monitor);
file = g_file_new_for_uri ("trash:///");
g_file_enumerate_children_async (file,
G_FILE_ATTRIBUTE_STANDARD_TYPE,
G_FILE_QUERY_INFO_NONE,
G_PRIORITY_DEFAULT,
NULL,
trash_enumerate_children_cb,
monitor);
g_object_unref (file);
}
/* Callback used when the "trash:///" file monitor changes; we just recompute the trash state
* whenever something happens.
*/
static void
file_monitor_changed_cb (GFileMonitor *file_monitor,
GFile *child,
GFile *other_file,
GFileMonitorEvent event_type,
GtkTrashMonitor *monitor)
{
recompute_trash_state (monitor);
}
static void
_gtk_trash_monitor_init (GtkTrashMonitor *monitor)
{
GFile *file;
file = g_file_new_for_uri ("trash:///");
monitor->file_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
g_object_unref (file);
if (monitor->file_monitor)
monitor->file_monitor_changed_id = g_signal_connect (monitor->file_monitor, "changed",
G_CALLBACK (file_monitor_changed_cb), monitor);
recompute_trash_state (monitor);
}
/**
* _gtk_trash_monitor_get:
*
* Return value: (transfer full): a new reference to the singleton
* #GtkTrashMonitor object. Be sure to call g_object_unref() on it when you are
* done with the trash monitor.
*/
GtkTrashMonitor *
_gtk_trash_monitor_get (void)
{
if (the_trash_monitor != NULL)
{
g_object_ref (the_trash_monitor);
}
else
{
the_trash_monitor = g_object_new (GTK_TYPE_TRASH_MONITOR, NULL);
g_object_add_weak_pointer (G_OBJECT (the_trash_monitor), (gpointer *) &the_trash_monitor);
}
return the_trash_monitor;
}
/**
* _gtk_trash_monitor_get_icon:
* @monitor: a #GtkTrashMonitor
*
* Return value: (transfer full): the #GIcon that should be used to represent
* the state of the trash folder on screen, based on whether there is trash or
* not.
*/
GIcon *
_gtk_trash_monitor_get_icon (GtkTrashMonitor *monitor)
{
const char *icon_name;
g_return_val_if_fail (GTK_IS_TRASH_MONITOR (monitor), NULL);
if (monitor->has_trash)
icon_name = ICON_NAME_TRASH_FULL;
else
icon_name = ICON_NAME_TRASH_EMPTY;
return g_themed_icon_new (icon_name);
}
/**
* _gtk_trash_monitor_get_has_trash:
* @monitor: a #GtkTrashMonitor
*
* Return value: #TRUE if there is trash in the trash:/// folder, or #FALSE otherwise.
*/
gboolean
_gtk_trash_monitor_get_has_trash (GtkTrashMonitor *monitor)
{
g_return_val_if_fail (GTK_IS_TRASH_MONITOR (monitor), FALSE);
return monitor->has_trash;
}

48
gtk/gtktrashmonitor.h Normal file
View File

@ -0,0 +1,48 @@
/* GTK - The GIMP Toolkit
* gtktrashmonitor.h: Monitor the trash:/// folder to see if there is trash or not
* Copyright (C) 2011 Suse
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Authors: Federico Mena Quintero <federico@gnome.org>
*/
#ifndef __GTK_TRASH_MONITOR_H__
#define __GTK_TRASH_MONITOR_H__
#include <gio/gio.h>
G_BEGIN_DECLS
#define GTK_TYPE_TRASH_MONITOR (_gtk_trash_monitor_get_type ())
#define GTK_TRASH_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TRASH_MONITOR, GtkTrashMonitor))
#define GTK_TRASH_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TRASH_MONITOR, GtkTrashMonitorClass))
#define GTK_IS_TRASH_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TRASH_MONITOR))
#define GTK_IS_TRASH_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TRASH_MONITOR))
#define GTK_TRASH_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TRASH_MONITOR, GtkTrashMonitorClass))
typedef struct _GtkTrashMonitor GtkTrashMonitor;
typedef struct _GtkTrashMonitorClass GtkTrashMonitorClass;
GType _gtk_trash_monitor_get_type (void);
GtkTrashMonitor *_gtk_trash_monitor_get (void);
GIcon *_gtk_trash_monitor_get_icon (GtkTrashMonitor *monitor);
gboolean _gtk_trash_monitor_get_has_trash (GtkTrashMonitor *monitor);
G_END_DECLS
#endif /* __GTK_TRASH_MONITOR_H__ */

View File

@ -33,6 +33,11 @@
<value nick='descending' value='1'/>
</enum>
<enum id='org.gtk.Settings.FileChooser.StartupMode'>
<value nick='recent' value='0'/>
<value nick='cwd' value='1'/>
</enum>
<schema id='org.gtk.Settings.FileChooser' path='/org/gtk/settings/file-chooser/'>
<key name='last-folder-uri' type='s'>
<default>""</default>
@ -63,6 +68,9 @@
<key name='window-size' type='(ii)'>
<default>(-1, -1)</default>
</key>
<key name='startup-mode' enum='org.gtk.Settings.FileChooser.StartupMode'>
<default>'recent'</default>
</key>
<key name='sidebar-width' type='i'>
<default>148</default>
</key>

View File

@ -57,6 +57,7 @@ gtk/gtkassistant.c
gtk/gtkbbox.c
gtk/gtkbin.c
gtk/gtkbindings.c
gtk/gtkbookmarksmanager.c
gtk/gtkbox.c
gtk/gtkbubblewindow.c
gtk/gtkbuildable.c