gtk2/gtk/gtkfilechooser.c
Owen Taylor af6bc44d86 - Disconnect signal connections when appropriate. - Listen to
Wed Apr  9 12:28:04 2003  Owen Taylor  <otaylor@redhat.com>

        * gtkfilesystemmodel.c:
        - Disconnect signal connections when appropriate.
        - Listen to ::roots-changed on the file system
        - When the last reference count on a child is
          removed, queue an idle to unload the parent.

        * gtkfilesystemgnomevfs.c
        - When URI's outside of file:/// are acessed,
          add toplevel URI's to the list of roots.
        - Improve display name computations

        * gtkfilechooserentry.c: Don't complete on empty
        file parts; free stored folder when base directory
        changes.

        * gtkfilechooser.c: Fill in some docs.
2003-04-09 16:52:13 +00:00

709 lines
18 KiB
C

/* GTK - The GIMP Toolkit
* gtkfilechooser.c: Abstract interface for file selector GUIs
* Copyright (C) 2003, Red Hat, Inc.
*
* This library 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 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gtkfilechooser.h"
#include "gtkfilechooserprivate.h"
#include "gtkfilechooserenums.h"
#include "gtkfilesystem.h"
#define _(str) (str)
static void gtk_file_chooser_base_init (gpointer g_class);
static GtkFilePath *gtk_file_chooser_get_path (GtkFileChooser *chooser);
GType
gtk_file_chooser_get_type (void)
{
static GType file_chooser_type = 0;
if (!file_chooser_type)
{
static const GTypeInfo file_chooser_info =
{
sizeof (GtkFileChooserIface), /* class_size */
gtk_file_chooser_base_init, /* base_init */
NULL, /* base_finalize */
};
file_chooser_type = g_type_register_static (G_TYPE_INTERFACE,
"GtkFileChooser",
&file_chooser_info, 0);
g_type_interface_add_prerequisite (file_chooser_type, GTK_TYPE_WIDGET);
}
return file_chooser_type;
}
static void
gtk_file_chooser_base_init (gpointer g_class)
{
static gboolean initialized = FALSE;
if (!initialized)
{
GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
g_signal_new ("current_folder_changed",
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileChooserIface, current_folder_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
g_signal_new ("selection_changed",
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileChooserIface, selection_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
g_object_interface_install_property (iface_type,
g_param_spec_enum ("action",
_("Action"),
_("The type of action that the file selector is performing"),
GTK_TYPE_FILE_CHOOSER_ACTION,
GTK_FILE_CHOOSER_ACTION_OPEN,
G_PARAM_READWRITE));
g_object_interface_install_property (iface_type,
g_param_spec_object ("file_system",
_("File System"),
_("File system object to use"),
GTK_TYPE_FILE_SYSTEM,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
g_object_interface_install_property (iface_type,
g_param_spec_boolean ("folder_mode",
_("Folder Mode"),
_("Whether to select folders rather than files"),
FALSE,
G_PARAM_READWRITE));
g_object_interface_install_property (iface_type,
g_param_spec_boolean ("local_only",
_("Local Only"),
_("Whether the selected file(s) should be limited to local file: URLs"),
TRUE,
G_PARAM_READWRITE));
g_object_interface_install_property (iface_type,
g_param_spec_object ("preview_widget",
_("Preview widget"),
_("Application supplied widget for custom previews."),
GTK_TYPE_WIDGET,
G_PARAM_READWRITE));
g_object_interface_install_property (iface_type,
g_param_spec_boolean ("preview_widget_active",
_("Preview Widget Active"),
_("Whther the application supplied widget for custom previews should be shown."),
TRUE,
G_PARAM_READWRITE));
g_object_interface_install_property (iface_type,
g_param_spec_boolean ("select_multiple",
_("Select Multiple"),
_("Whether to allow multiple files to be selected"),
FALSE,
G_PARAM_READWRITE));
g_object_interface_install_property (iface_type,
g_param_spec_boolean ("show_hidden",
_("Show Hidden"),
_("Whether the hidden files and folders should be displayed"),
FALSE,
G_PARAM_READWRITE));
initialized = TRUE;
}
}
void
gtk_file_chooser_set_action (GtkFileChooser *chooser,
GtkFileChooserAction action)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_object_set (chooser, "action", action, NULL);
}
GtkFileChooserAction
gtk_file_chooser_get_action (GtkFileChooser *chooser)
{
GtkFileChooserAction action;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
g_object_get (chooser, "action", &action, NULL);
return action;
}
/**
* gtk_file_chooser_set_folder_mode:
* @chooser: a #GtkFileChooser
* @folder_mode: %TRUE if the file chooser is used to select folders
* rather than files.
*
* Sets whether the file chooser is used to select folders
* rather than files. If in folder mode, only folders are displayed
* to the use, and not the individual files inside the folders
* and the user selects a single folder rather than one or
* more files.
**/
void
gtk_file_chooser_set_folder_mode (GtkFileChooser *chooser,
gboolean folder_mode)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_object_set (chooser, "folder_mode", folder_mode, NULL);
}
/**
* gtk_file_chooser_get_folder_mode:
* @chooser: a #GtkFileChooser
*
* Gets whether the file chooser is used to select folders
* rather than files. See gtk_file_chooser_set_folder_mode()
*
* Return value: %TRUE if the file chooser is used to select
folders rather than files.
**/
gboolean
gtk_file_chooser_get_folder_mode (GtkFileChooser *chooser)
{
gboolean folder_mode;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
g_object_get (chooser, "folder_mode", &folder_mode, NULL);
return folder_mode;
}
/**
* gtk_file_chooser_set_local_only:
* @chooser: a #GtkFileChooser
* @local_only: %TRUE if only local files can be selected
*
* Sets whether only local files can be selected in the
* file selector. If @local_only is %TRUE (the default),
* then the selected file are files are guaranteed to be
* accessible through the operating systems native file
* file system and therefore the application only
* needs to worry about the filename functions in
* #GtkFileChooser, like gtk_file_chooser_get_filename(),
* rather than the URI functions like
* gtk_file_chooser_get_uri(),
**/
void
gtk_file_chooser_set_local_only (GtkFileChooser *chooser,
gboolean local_only)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_object_set (chooser, "local_only", local_only, NULL);
}
/**
* gtk_file_chooser_get_local_only:
* @chooser: a #GtkFileChoosre
*
* Gets whether only local files can be selected in the
* file selector. See gtk_file_chooser_set_local_only()
*
* Return value: %TRUE if only local files can be selected.
**/
gboolean
gtk_file_chooser_get_local_only (GtkFileChooser *chooser)
{
gboolean local_only;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
g_object_get (chooser, "local_only", &local_only, NULL);
return local_only;
}
/**
* gtk_file_chooser_set_select_multiple:
* @chooser: a #GtkFileChooser
* @select_multiple: %TRUE if multiple files can be selected.
*
* Sets whether multiple files can be selected in the file
* selector. If the file selector if in folder mode (see
* gtk_file_selector_set_folder_mode()) then only one folder
* can be selected, without regard to this setting.
**/
void
gtk_file_chooser_set_select_multiple (GtkFileChooser *chooser,
gboolean select_multiple)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_object_set (chooser, "select_multiple", select_multiple, NULL);
}
/**
* gtk_file_chooser_get_select_multiple:
* @chooser: a #GtkFileChooser
*
* Gets whether multiple files can be selected in the file
* selector. See gtk_file_chooser_set_select_multiple().
*
* Return value: %TRUE if multiple files can be selected.
**/
gboolean
gtk_file_chooser_get_select_multiple (GtkFileChooser *chooser)
{
gboolean select_multiple;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
g_object_get (chooser, "select_multiple", &select_multiple, NULL);
return select_multiple;
}
/**
* gtk_file_chooser_get_filename:
* @chooser: a #GtkFileChooser
*
* Gets the filename for the currently selected file in
* the file selector. If multiple files are selected,
* one of the filenames will be returned at random.
*
* Return value: The currently selected filename, or %NULL
* if no file is selected, or the selected file can't
* be represented with a local filename.
**/
gchar *
gtk_file_chooser_get_filename (GtkFileChooser *chooser)
{
GtkFileSystem *file_system;
GtkFilePath *path;
gchar *result = NULL;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
path = gtk_file_chooser_get_path (chooser);
if (path)
{
result = gtk_file_system_path_to_filename (file_system, path);
gtk_file_path_free (path);
}
return result;
}
void
gtk_file_chooser_set_filename (GtkFileChooser *chooser,
const gchar *filename)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
gtk_file_chooser_unselect_all (chooser);
gtk_file_chooser_select_filename (chooser, filename);
}
void
gtk_file_chooser_select_filename (GtkFileChooser *chooser,
const gchar *filename)
{
GtkFileSystem *file_system;
GtkFilePath *path;
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_return_if_fail (filename != NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
path = gtk_file_system_filename_to_path (file_system, filename);
if (path)
{
_gtk_file_chooser_select_path (chooser, path);
gtk_file_path_free (path);
}
}
void
gtk_file_chooser_unselect_filename (GtkFileChooser *chooser,
const char *filename)
{
GtkFileSystem *file_system;
GtkFilePath *path;
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_return_if_fail (filename != NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
path = gtk_file_system_filename_to_path (file_system, filename);
if (path)
{
_gtk_file_chooser_unselect_path (chooser, path);
gtk_file_path_free (path);
}
}
GSList *
gtk_file_chooser_get_filenames (GtkFileChooser *chooser)
{
GtkFileSystem *file_system;
GSList *paths;
GSList *tmp_list;
GSList *result = NULL;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
paths = _gtk_file_chooser_get_paths (chooser);
for (tmp_list = paths; tmp_list; tmp_list = tmp_list->next)
{
gchar *filename = gtk_file_system_path_to_filename (file_system, tmp_list->data);
if (filename)
result = g_slist_prepend (result, filename);
}
gtk_file_paths_free (paths);
return g_slist_reverse (result);
}
void
gtk_file_chooser_set_current_folder (GtkFileChooser *chooser,
const gchar *filename)
{
GtkFileSystem *file_system;
GtkFilePath *path;
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_return_if_fail (filename != NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
path = gtk_file_system_filename_to_path (file_system, filename);
if (path)
{
_gtk_file_chooser_set_current_folder (chooser, path);
gtk_file_path_free (path);
}
}
gchar *
gtk_file_chooser_get_current_folder (GtkFileChooser *chooser)
{
GtkFileSystem *file_system;
GtkFilePath *path;
gchar *filename;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
path = _gtk_file_chooser_get_current_folder (chooser);
filename = gtk_file_system_path_to_filename (file_system, path);
gtk_file_path_free (path);
return filename;
}
gchar *
gtk_file_chooser_get_uri (GtkFileChooser *chooser)
{
GtkFileSystem *file_system;
GtkFilePath *path;
gchar *result = NULL;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
path = gtk_file_chooser_get_path (chooser);
if (path)
{
result = gtk_file_system_path_to_uri (file_system, path);
gtk_file_path_free (path);
}
return result;
}
void
gtk_file_chooser_set_uri (GtkFileChooser *chooser,
const char *uri)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
gtk_file_chooser_unselect_all (chooser);
gtk_file_chooser_select_uri (chooser, uri);
}
void
gtk_file_chooser_select_uri (GtkFileChooser *chooser,
const char *uri)
{
GtkFileSystem *file_system;
GtkFilePath *path;
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_return_if_fail (uri != NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
path = gtk_file_system_uri_to_path (file_system, uri);
if (path)
{
_gtk_file_chooser_select_path (chooser, path);
gtk_file_path_free (path);
}
}
void
gtk_file_chooser_unselect_uri (GtkFileChooser *chooser,
const char *uri)
{
GtkFileSystem *file_system;
GtkFilePath *path;
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_return_if_fail (uri != NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
path = gtk_file_system_uri_to_path (file_system, uri);
if (path)
{
_gtk_file_chooser_unselect_path (chooser, path);
gtk_file_path_free (path);
}
}
void
gtk_file_chooser_select_all (GtkFileChooser *chooser)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
GTK_FILE_CHOOSER_GET_IFACE (chooser)->select_all (chooser);
}
void
gtk_file_chooser_unselect_all (GtkFileChooser *chooser)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
GTK_FILE_CHOOSER_GET_IFACE (chooser)->unselect_all (chooser);
}
GSList *
gtk_file_chooser_get_uris (GtkFileChooser *chooser)
{
GtkFileSystem *file_system;
GSList *paths;
GSList *tmp_list;
GSList *result = NULL;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
paths = _gtk_file_chooser_get_paths (chooser);
for (tmp_list = paths; tmp_list; tmp_list = tmp_list->next)
{
gchar *uri = gtk_file_system_path_to_uri (file_system, tmp_list->data);
if (uri)
result = g_slist_prepend (result, uri);
}
gtk_file_paths_free (paths);
return g_slist_reverse (result);
}
void
gtk_file_chooser_set_current_folder_uri (GtkFileChooser *chooser,
const gchar *uri)
{
GtkFileSystem *file_system;
GtkFilePath *path;
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_return_if_fail (uri != NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
path = gtk_file_system_uri_to_path (file_system, uri);
if (path)
{
_gtk_file_chooser_set_current_folder (chooser, path);
gtk_file_path_free (path);
}
}
gchar *
gtk_file_chooser_get_current_folder_uri (GtkFileChooser *chooser)
{
GtkFileSystem *file_system;
GtkFilePath *path;
gchar *uri;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
path = _gtk_file_chooser_get_current_folder (chooser);
uri = gtk_file_system_path_to_uri (file_system, path);
gtk_file_path_free (path);
return uri;
}
void
_gtk_file_chooser_set_current_folder (GtkFileChooser *chooser,
const GtkFilePath *path)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_return_if_fail (path != NULL);
GTK_FILE_CHOOSER_GET_IFACE (chooser)->set_current_folder (chooser, path);
}
GtkFilePath *
_gtk_file_chooser_get_current_folder (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_current_folder (chooser);
}
void
_gtk_file_chooser_select_path (GtkFileChooser *chooser,
const GtkFilePath *path)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
GTK_FILE_CHOOSER_GET_IFACE (chooser)->select_path (chooser, path);
}
void
_gtk_file_chooser_unselect_path (GtkFileChooser *chooser,
const GtkFilePath *path)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
GTK_FILE_CHOOSER_GET_IFACE (chooser)->unselect_path (chooser, path);
}
GSList *
_gtk_file_chooser_get_paths (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_paths (chooser);
}
static GtkFilePath *
gtk_file_chooser_get_path (GtkFileChooser *chooser)
{
GSList *list;
GtkFilePath *result = NULL;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
list = _gtk_file_chooser_get_paths (chooser);
if (list)
{
result = list->data;
list = g_slist_delete_link (list, list);
gtk_file_paths_free (list);
}
return result;
}
GtkFileSystem *
_gtk_file_chooser_get_file_system (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_file_system (chooser);
}
/* Preview widget
*/
void
gtk_file_chooser_set_preview_widget (GtkFileChooser *chooser,
GtkWidget *preview_widget)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_object_set (chooser, "preview_widget", preview_widget, NULL);
}
GtkWidget *
gtk_file_chooser_get_preview_widget (GtkFileChooser *chooser)
{
GtkWidget *preview_widget;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
g_object_get (chooser, "preview_widget", &preview_widget, NULL);
return preview_widget;
}
void
gtk_file_chooser_set_preview_widget_active (GtkFileChooser *chooser,
gboolean active)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_object_set (chooser, "preview_widget_active", active, NULL);
}
gboolean
gtk_file_chooser_get_preview_widget_active (GtkFileChooser *chooser)
{
gboolean active;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
g_object_get (chooser, "preview_widget_active", &active, NULL);
return active;
}
const char *
gtk_file_chooser_get_preview_filename (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
return NULL;
}
const char *
gtk_file_chooser_get_preview_uri (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
return NULL;
}