Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 56ed4f574b | |||
| 1358953103 | |||
| 44ef4e8bb9 | |||
| 2ac688681c | |||
| 52472eaf9a | |||
| a174fba992 | |||
| b2e19e0056 | |||
| 00592c3d4a | |||
| da2e50ba63 | |||
| 68f25e54d8 | |||
| aabe7d0086 | |||
| c3524bab42 | |||
| 8e164cc477 | |||
| bad39dda20 | |||
| 57f4b48391 | |||
| 1abc6ef78c | |||
| 2738786c6f | |||
| 9b1bd76a9b | |||
| d8e078b7a3 | |||
| b997b7f7f1 | |||
| 5cbaf53d9b | |||
| 90670ccda5 | |||
| 3cbcb110e0 | |||
| d73dfd118e | |||
| a07db264a4 | |||
| 93a91f91d8 | |||
| b11da2d25b | |||
| 9289e75934 | |||
| 7056f9a39b | |||
| 2d8588a2e3 | |||
| 5673ef9463 | |||
| 40669f960a | |||
| c3abc8a89d | |||
| e17b9ae8ba | |||
| e3e243688a |
@@ -285,7 +285,6 @@ gtk_public_h_sources = \
|
||||
gtksocket.h \
|
||||
gtkspinbutton.h \
|
||||
gtkspinner.h \
|
||||
gtkspreadtable.h \
|
||||
gtkstatusbar.h \
|
||||
gtkstatusicon.h \
|
||||
gtkstock.h \
|
||||
@@ -559,7 +558,6 @@ gtk_base_c_sources = \
|
||||
gtksocket.c \
|
||||
gtkspinbutton.c \
|
||||
gtkspinner.c \
|
||||
gtkspreadtable.c \
|
||||
gtkstatusbar.c \
|
||||
gtkstatusicon.c \
|
||||
gtkstock.c \
|
||||
|
||||
@@ -167,7 +167,6 @@
|
||||
#include <gtk/gtksocket.h>
|
||||
#include <gtk/gtkspinbutton.h>
|
||||
#include <gtk/gtkspinner.h>
|
||||
#include <gtk/gtkspreadtable.h>
|
||||
#include <gtk/gtkstatusbar.h>
|
||||
#include <gtk/gtkstatusicon.h>
|
||||
#include <gtk/gtkstock.h>
|
||||
|
||||
@@ -3080,20 +3080,6 @@ gtk_spinner_stop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GTK_SPREAD_TABLE_H__)
|
||||
#if IN_FILE(__GTK_SPREAD_TABLE_C__)
|
||||
gtk_spread_table_get_horizontal_spacing
|
||||
gtk_spread_table_get_lines
|
||||
gtk_spread_table_get_type
|
||||
gtk_spread_table_get_vertical_spacing
|
||||
gtk_spread_table_insert_child
|
||||
gtk_spread_table_new
|
||||
gtk_spread_table_set_horizontal_spacing
|
||||
gtk_spread_table_set_lines
|
||||
gtk_spread_table_set_vertical_spacing
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GTK_STATUSBAR_H__)
|
||||
#if IN_FILE(__GTK_STATUSBAR_C__)
|
||||
gtk_statusbar_get_context_id
|
||||
|
||||
+453
-2
@@ -825,6 +825,25 @@ gtk_file_chooser_default_init (GtkFileChooserInterface *iface)
|
||||
"will offer the user to create new folders."),
|
||||
TRUE,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkFileChooser:root-uris:
|
||||
*
|
||||
* The absolute root URIs that can be accessed in the file chooser.
|
||||
* Any shortcuts (special or user-defined) or volumes not within
|
||||
* these URIs will be filtered out for this dialog.
|
||||
*
|
||||
* The default is NULL, which provides the default level of access
|
||||
* for the file chooser.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_boxed ("root-uris",
|
||||
P_("Root URIs"),
|
||||
P_("The URIs, if any, to use as the root for all access in the file chooser."),
|
||||
G_TYPE_STRV,
|
||||
GTK_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -902,6 +921,9 @@ gtk_file_chooser_get_action (GtkFileChooser *chooser)
|
||||
* rather than the URI functions like
|
||||
* gtk_file_chooser_get_uri(),
|
||||
*
|
||||
* This implies a single root URI of "file://". See
|
||||
* gtk_file_chooser_set_root_uris().
|
||||
*
|
||||
* Since: 2.4
|
||||
**/
|
||||
void
|
||||
@@ -915,10 +937,13 @@ gtk_file_chooser_set_local_only (GtkFileChooser *chooser,
|
||||
|
||||
/**
|
||||
* gtk_file_chooser_get_local_only:
|
||||
* @chooser: a #GtkFileChoosre
|
||||
* @chooser: a #GtkFileChooser
|
||||
*
|
||||
* Gets whether only local files can be selected in the
|
||||
* file selector. See gtk_file_chooser_set_local_only()
|
||||
*
|
||||
* This is %TRUE when the root URI of the file chooser is
|
||||
* "file://". See gtk_file_chooser_get_root_uris().
|
||||
*
|
||||
* Return value: %TRUE if only local files can be selected.
|
||||
*
|
||||
@@ -936,6 +961,76 @@ gtk_file_chooser_get_local_only (GtkFileChooser *chooser)
|
||||
return local_only;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_file_chooser_set_root_uris:
|
||||
* @chooser: a #GtkFileChooser
|
||||
* @root_uris: A %NULL-terminated array of strings with the root URIs, or %NULL to allow access to everything.
|
||||
*
|
||||
* Sets the URIs that will be the roots of the file chooser. The file
|
||||
* chooser will not display or allow access to files outside of these URIs.
|
||||
*
|
||||
* If this is set to %NULL, then the file chooser will have access to all
|
||||
* local and remote volumes and files.
|
||||
*
|
||||
* This is useful when needing to restrict the file chooser to a particular
|
||||
* directory and its subdirectories, to a particular storage device, or to a
|
||||
* remote server.
|
||||
*
|
||||
* If more than one root URI is provided for the same filesystem or protocol
|
||||
* (for example, "file:///home" and "file:///"), then the most permissive will
|
||||
* be used (in this case, "file:///").
|
||||
*
|
||||
* See gtk_file_chooser_get_root_uris()
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gtk_file_chooser_set_root_uris (GtkFileChooser *chooser,
|
||||
const gchar **root_uris)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
|
||||
|
||||
g_object_set (chooser, "root-uris", root_uris, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_file_chooser_get_root_uris:
|
||||
* @chooser: a #GtkFileChooser
|
||||
*
|
||||
* Gets the URIs that are the roots of the file chooser. The file chooser
|
||||
* will not display or allow access to files outside of these URIs.
|
||||
*
|
||||
* If this is %NULL, then the file chooser has access to all local and
|
||||
* remote volumes and files.
|
||||
*
|
||||
* This is useful when needing to restrict the file chooser to a particular
|
||||
* directory and its subdirectories, to a particular storage device, or to a
|
||||
* remote server.
|
||||
*
|
||||
* If more than one root URI is provided for the same filesystem or protocol
|
||||
* (for example, "file:///home" and "file:///"), then the most permissive will
|
||||
* be used (in this case, "file:///").
|
||||
*
|
||||
* See gtk_file_chooser_set_root_uris()
|
||||
*
|
||||
* Return value: A %NULL-terminated array of strings with the URIs of the roots,
|
||||
* or simply %NULL if there are no roots set for the @chooser. You should free
|
||||
* this array with g_strfreev().
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
gchar **
|
||||
gtk_file_chooser_get_root_uris (GtkFileChooser *chooser)
|
||||
{
|
||||
gchar **root_uris;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
|
||||
|
||||
g_object_get (chooser, "root-uris", &root_uris, NULL);
|
||||
|
||||
return root_uris;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_file_chooser_set_select_multiple:
|
||||
* @chooser: a #GtkFileChooser
|
||||
@@ -1705,9 +1800,21 @@ gtk_file_chooser_unselect_file (GtkFileChooser *chooser,
|
||||
GSList *
|
||||
gtk_file_chooser_get_files (GtkFileChooser *chooser)
|
||||
{
|
||||
GSList *files, *l;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
|
||||
|
||||
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_files (chooser);
|
||||
files = GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_files (chooser);
|
||||
|
||||
for (l = files; l != NULL; l = l->next)
|
||||
{
|
||||
GFile *file = (GFile *)l->data;
|
||||
|
||||
g_return_val_if_fail (_gtk_file_chooser_is_file_in_roots (chooser, file),
|
||||
NULL);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2567,3 +2674,347 @@ gtk_file_chooser_get_do_overwrite_confirmation (GtkFileChooser *chooser)
|
||||
|
||||
return do_overwrite_confirmation;
|
||||
}
|
||||
|
||||
#if defined (G_OS_WIN32) && !defined (_WIN64)
|
||||
|
||||
/* DLL ABI stability backward compatibility versions */
|
||||
|
||||
#undef gtk_file_chooser_get_filename
|
||||
|
||||
gchar *
|
||||
gtk_file_chooser_get_filename (GtkFileChooser *chooser)
|
||||
{
|
||||
gchar *utf8_filename = gtk_file_chooser_get_filename_utf8 (chooser);
|
||||
gchar *retval = g_locale_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
|
||||
|
||||
g_free (utf8_filename);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#undef gtk_file_chooser_set_filename
|
||||
|
||||
gboolean
|
||||
gtk_file_chooser_set_filename (GtkFileChooser *chooser,
|
||||
const gchar *filename)
|
||||
{
|
||||
gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, NULL);
|
||||
gboolean retval = gtk_file_chooser_set_filename_utf8 (chooser, utf8_filename);
|
||||
|
||||
g_free (utf8_filename);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#undef gtk_file_chooser_select_filename
|
||||
|
||||
gboolean
|
||||
gtk_file_chooser_select_filename (GtkFileChooser *chooser,
|
||||
const gchar *filename)
|
||||
{
|
||||
gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, NULL);
|
||||
gboolean retval = gtk_file_chooser_select_filename_utf8 (chooser, utf8_filename);
|
||||
|
||||
g_free (utf8_filename);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#undef gtk_file_chooser_unselect_filename
|
||||
|
||||
void
|
||||
gtk_file_chooser_unselect_filename (GtkFileChooser *chooser,
|
||||
const char *filename)
|
||||
{
|
||||
gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, NULL);
|
||||
|
||||
gtk_file_chooser_unselect_filename_utf8 (chooser, utf8_filename);
|
||||
g_free (utf8_filename);
|
||||
}
|
||||
|
||||
#undef gtk_file_chooser_get_filenames
|
||||
|
||||
GSList *
|
||||
gtk_file_chooser_get_filenames (GtkFileChooser *chooser)
|
||||
{
|
||||
GSList *list = gtk_file_chooser_get_filenames_utf8 (chooser);
|
||||
GSList *rover = list;
|
||||
|
||||
while (rover)
|
||||
{
|
||||
gchar *tem = (gchar *) rover->data;
|
||||
rover->data = g_locale_from_utf8 ((gchar *) rover->data, -1, NULL, NULL, NULL);
|
||||
g_free (tem);
|
||||
rover = rover->next;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
#undef gtk_file_chooser_set_current_folder
|
||||
|
||||
gboolean
|
||||
gtk_file_chooser_set_current_folder (GtkFileChooser *chooser,
|
||||
const gchar *filename)
|
||||
{
|
||||
gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, NULL);
|
||||
gboolean retval = gtk_file_chooser_set_current_folder_utf8 (chooser, utf8_filename);
|
||||
|
||||
g_free (utf8_filename);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#undef gtk_file_chooser_get_current_folder
|
||||
|
||||
gchar *
|
||||
gtk_file_chooser_get_current_folder (GtkFileChooser *chooser)
|
||||
{
|
||||
gchar *utf8_folder = gtk_file_chooser_get_current_folder_utf8 (chooser);
|
||||
gchar *retval = g_locale_from_utf8 (utf8_folder, -1, NULL, NULL, NULL);
|
||||
|
||||
g_free (utf8_folder);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#undef gtk_file_chooser_get_preview_filename
|
||||
|
||||
char *
|
||||
gtk_file_chooser_get_preview_filename (GtkFileChooser *chooser)
|
||||
{
|
||||
char *utf8_filename = gtk_file_chooser_get_preview_filename_utf8 (chooser);
|
||||
char *retval = g_locale_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
|
||||
|
||||
g_free (utf8_filename);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#undef gtk_file_chooser_add_shortcut_folder
|
||||
|
||||
gboolean
|
||||
gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
|
||||
const char *folder,
|
||||
GError **error)
|
||||
{
|
||||
char *utf8_folder = g_locale_to_utf8 (folder, -1, NULL, NULL, NULL);
|
||||
gboolean retval =
|
||||
gtk_file_chooser_add_shortcut_folder_utf8 (chooser, utf8_folder, error);
|
||||
|
||||
g_free (utf8_folder);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#undef gtk_file_chooser_remove_shortcut_folder
|
||||
|
||||
gboolean
|
||||
gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *chooser,
|
||||
const char *folder,
|
||||
GError **error)
|
||||
{
|
||||
char *utf8_folder = g_locale_to_utf8 (folder, -1, NULL, NULL, NULL);
|
||||
gboolean retval =
|
||||
gtk_file_chooser_remove_shortcut_folder_utf8 (chooser, utf8_folder, error);
|
||||
|
||||
g_free (utf8_folder);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#undef gtk_file_chooser_list_shortcut_folders
|
||||
|
||||
GSList *
|
||||
gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser)
|
||||
{
|
||||
GSList *list = gtk_file_chooser_list_shortcut_folders_utf8 (chooser);
|
||||
GSList *rover = list;
|
||||
|
||||
while (rover)
|
||||
{
|
||||
gchar *tem = (gchar *) rover->data;
|
||||
rover->data = g_locale_from_utf8 ((gchar *) rover->data, -1, NULL, NULL, NULL);
|
||||
g_free (tem);
|
||||
rover = rover->next;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
uri_has_prefix (const char *uri, const char *prefix)
|
||||
{
|
||||
int prefix_len;
|
||||
const char *remainder;
|
||||
|
||||
prefix_len = strlen (prefix);
|
||||
if (prefix_len > 0 && prefix[prefix_len - 1] == '/')
|
||||
prefix_len--;
|
||||
|
||||
if (strncmp (uri, prefix, prefix_len) != 0)
|
||||
return FALSE;
|
||||
|
||||
remainder = uri + prefix_len;
|
||||
|
||||
return (*remainder == '/') || (*remainder == '\0');
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_file_chooser_uri_is_in_roots_list (const char *uri, GSList *roots)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
g_return_val_if_fail (uri != NULL, FALSE);
|
||||
|
||||
if (roots == NULL)
|
||||
return TRUE; /* No roots means all URIs are good */
|
||||
|
||||
for (l = roots; l; l = l->next)
|
||||
{
|
||||
const char *prefix = l->data;
|
||||
|
||||
if (uri_has_prefix (uri, prefix))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
uri_is_in_roots_strv (const char *uri, gchar **roots)
|
||||
{
|
||||
gchar **r;
|
||||
|
||||
if (!roots)
|
||||
return TRUE; /* No roots means all URIs are good */
|
||||
|
||||
for (r = roots; *r; r++)
|
||||
if (uri_has_prefix (uri, *r))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_uri_in_roots (GtkFileChooser *chooser,
|
||||
const char *uri)
|
||||
{
|
||||
gchar **root_uris;
|
||||
gboolean is_in_roots;
|
||||
|
||||
root_uris = gtk_file_chooser_get_root_uris (chooser);
|
||||
is_in_roots = uri_is_in_roots_strv (uri, root_uris);
|
||||
g_strfreev (root_uris);
|
||||
|
||||
return is_in_roots;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_file_chooser_is_file_in_roots (GtkFileChooser *chooser,
|
||||
GFile *file)
|
||||
{
|
||||
char *uri;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
|
||||
g_return_val_if_fail (file != NULL, FALSE);
|
||||
|
||||
uri = g_file_get_uri (file);
|
||||
result = is_uri_in_roots (chooser, uri);
|
||||
g_free (uri);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GSList *
|
||||
_gtk_file_chooser_get_visible_roots (GtkFileChooser *chooser)
|
||||
{
|
||||
GSList *results = NULL;
|
||||
GtkFileSystem *file_system = _gtk_file_chooser_get_file_system (chooser);
|
||||
gchar **root_uris;
|
||||
gchar **r;
|
||||
|
||||
root_uris = gtk_file_chooser_get_root_uris (chooser);
|
||||
|
||||
for (r = root_uris; r && *r; r++)
|
||||
{
|
||||
GFile *file = g_file_new_for_uri (*r);
|
||||
gboolean skip = FALSE;
|
||||
GtkFileSystemVolume *volume;
|
||||
GFileInfo *file_info;
|
||||
char *file_path;
|
||||
gboolean is_home_or_desktop;
|
||||
|
||||
if (file == NULL)
|
||||
continue;
|
||||
|
||||
file_path = g_file_get_path (file);
|
||||
|
||||
/*
|
||||
* See if this is the Desktop directory or Home directory, which will
|
||||
* already be listed.
|
||||
*/
|
||||
is_home_or_desktop = (!g_strcmp0 (file_path,
|
||||
g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP)) ||
|
||||
!g_strcmp0 (file_path, g_get_home_dir()));
|
||||
g_free (file_path);
|
||||
|
||||
if (is_home_or_desktop)
|
||||
{
|
||||
g_object_unref (file);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Make sure the file exists in some form. */
|
||||
file_info = g_file_query_info (file,
|
||||
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (file_info == NULL)
|
||||
{
|
||||
g_object_unref (file);
|
||||
continue;
|
||||
}
|
||||
|
||||
volume = _gtk_file_system_get_volume_for_file (file_system, file);
|
||||
|
||||
if (volume != NULL)
|
||||
{
|
||||
GFile *fs_root = _gtk_file_system_volume_get_root (volume);
|
||||
|
||||
if (fs_root != NULL)
|
||||
{
|
||||
char *fs_root_uri = g_file_get_uri (fs_root);
|
||||
|
||||
if (uri_is_in_roots_strv (fs_root_uri, root_uris))
|
||||
{
|
||||
/* This is going to be listed already. Ignore it for now. */
|
||||
skip = TRUE;
|
||||
}
|
||||
|
||||
g_free (fs_root_uri);
|
||||
g_object_unref (fs_root);
|
||||
}
|
||||
}
|
||||
|
||||
if (skip)
|
||||
{
|
||||
g_object_unref (file);
|
||||
continue;
|
||||
}
|
||||
|
||||
results = g_slist_append (results, file);
|
||||
}
|
||||
|
||||
g_strfreev (root_uris);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
/* vim: et sw=2 cinoptions=(0,t0,f1s,n-1s,{1s,>2s,^-1s */
|
||||
|
||||
@@ -123,6 +123,9 @@ GtkFileChooserAction gtk_file_chooser_get_action (GtkFileChooser
|
||||
void gtk_file_chooser_set_local_only (GtkFileChooser *chooser,
|
||||
gboolean local_only);
|
||||
gboolean gtk_file_chooser_get_local_only (GtkFileChooser *chooser);
|
||||
void gtk_file_chooser_set_root_uris (GtkFileChooser *chooser,
|
||||
const gchar **root_uris);
|
||||
gchar **gtk_file_chooser_get_root_uris (GtkFileChooser *chooser);
|
||||
void gtk_file_chooser_set_select_multiple (GtkFileChooser *chooser,
|
||||
gboolean select_multiple);
|
||||
gboolean gtk_file_chooser_get_select_multiple (GtkFileChooser *chooser);
|
||||
|
||||
+191
-38
@@ -103,6 +103,7 @@ enum
|
||||
typedef enum
|
||||
{
|
||||
ROW_TYPE_SPECIAL,
|
||||
ROW_TYPE_ROOT,
|
||||
ROW_TYPE_VOLUME,
|
||||
ROW_TYPE_SHORTCUT,
|
||||
ROW_TYPE_BOOKMARK_SEPARATOR,
|
||||
@@ -137,6 +138,8 @@ struct _GtkFileChooserButtonPrivate
|
||||
GtkFileSystem *fs;
|
||||
GFile *old_file;
|
||||
|
||||
GSList *shortcuts;
|
||||
|
||||
gulong combo_box_changed_id;
|
||||
gulong dialog_file_activated_id;
|
||||
gulong dialog_folder_changed_id;
|
||||
@@ -151,6 +154,7 @@ struct _GtkFileChooserButtonPrivate
|
||||
gint icon_size;
|
||||
|
||||
guint8 n_special;
|
||||
guint8 n_roots;
|
||||
guint8 n_volumes;
|
||||
guint8 n_shortcuts;
|
||||
guint8 n_bookmarks;
|
||||
@@ -433,6 +437,8 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button)
|
||||
|
||||
priv->icon_size = FALLBACK_ICON_SIZE;
|
||||
priv->focus_on_click = TRUE;
|
||||
priv->shortcuts = NULL;
|
||||
priv->n_shortcuts = 0;
|
||||
|
||||
gtk_widget_push_composite_child ();
|
||||
|
||||
@@ -525,6 +531,98 @@ gtk_file_chooser_button_file_chooser_iface_init (GtkFileChooserIface *iface)
|
||||
iface->remove_shortcut_folder = gtk_file_chooser_button_remove_shortcut_folder;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_roots (GtkFileChooserButton *button)
|
||||
{
|
||||
GtkFileChooser *filechooser;
|
||||
GtkFileChooserButtonPrivate *priv = button->priv;
|
||||
GSList *l, *roots;
|
||||
gint start_pos;
|
||||
|
||||
start_pos = model_get_type_position (button, ROW_TYPE_ROOT);
|
||||
model_remove_rows (button, start_pos, priv->n_roots);
|
||||
priv->n_roots = 0;
|
||||
|
||||
filechooser = GTK_FILE_CHOOSER (button->priv->dialog);
|
||||
roots = _gtk_file_chooser_get_visible_roots (GTK_FILE_CHOOSER (filechooser));
|
||||
|
||||
for (l = roots; l != NULL; l = l->next)
|
||||
{
|
||||
GFile *file = (GFile *)l->data;
|
||||
gint pos = start_pos + priv->n_roots;
|
||||
GtkTreeIter iter;
|
||||
|
||||
gtk_list_store_insert (GTK_LIST_STORE (priv->model), &iter, pos);
|
||||
gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter,
|
||||
ICON_COLUMN, NULL,
|
||||
DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
|
||||
TYPE_COLUMN, ROW_TYPE_ROOT,
|
||||
DATA_COLUMN, file,
|
||||
IS_FOLDER_COLUMN, FALSE,
|
||||
-1);
|
||||
set_info_for_file_at_iter (button, file, &iter);
|
||||
priv->n_roots++;
|
||||
}
|
||||
|
||||
g_slist_free (roots);
|
||||
|
||||
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model));
|
||||
|
||||
update_label_and_image (button);
|
||||
update_combo_box (button);
|
||||
}
|
||||
|
||||
static void
|
||||
add_shortcut_to_list (GtkFileChooserButton *button,
|
||||
GFile *shortcut)
|
||||
{
|
||||
GtkFileChooserButtonPrivate *priv = button->priv;
|
||||
gint pos = model_get_type_position (button, ROW_TYPE_SHORTCUT) +
|
||||
priv->n_shortcuts;
|
||||
GtkTreeIter iter;
|
||||
|
||||
gtk_list_store_insert (GTK_LIST_STORE (priv->model), &iter, pos);
|
||||
gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter,
|
||||
ICON_COLUMN, NULL,
|
||||
DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
|
||||
TYPE_COLUMN, ROW_TYPE_SHORTCUT,
|
||||
DATA_COLUMN, g_object_ref (shortcut),
|
||||
IS_FOLDER_COLUMN, FALSE,
|
||||
-1);
|
||||
set_info_for_file_at_iter (button, shortcut, &iter);
|
||||
priv->n_shortcuts++;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_shortcuts (GtkFileChooserButton *button)
|
||||
{
|
||||
GtkFileChooser *filechooser;
|
||||
GtkFileChooserButtonPrivate *priv = button->priv;
|
||||
GSList *l;
|
||||
|
||||
model_remove_rows (button,
|
||||
model_get_type_position (button, ROW_TYPE_SHORTCUT),
|
||||
priv->n_shortcuts);
|
||||
priv->n_shortcuts = 0;
|
||||
|
||||
filechooser = GTK_FILE_CHOOSER (button->priv->dialog);
|
||||
|
||||
for (l = priv->shortcuts; l != NULL; l = l->next)
|
||||
{
|
||||
GFile *shortcut = (GFile *)l->data;
|
||||
|
||||
if (_gtk_file_chooser_is_file_in_roots (filechooser, shortcut))
|
||||
{
|
||||
add_shortcut_to_list (button, shortcut);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model));
|
||||
|
||||
update_label_and_image (button);
|
||||
update_combo_box (button);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser,
|
||||
GFile *file,
|
||||
@@ -541,24 +639,16 @@ gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser,
|
||||
{
|
||||
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
|
||||
GtkFileChooserButtonPrivate *priv = button->priv;
|
||||
GtkTreeIter iter;
|
||||
gint pos;
|
||||
|
||||
pos = model_get_type_position (button, ROW_TYPE_SHORTCUT);
|
||||
pos += priv->n_shortcuts;
|
||||
g_object_ref (G_OBJECT (file));
|
||||
priv->shortcuts = g_slist_append (priv->shortcuts, file);
|
||||
|
||||
gtk_list_store_insert (GTK_LIST_STORE (priv->model), &iter, pos);
|
||||
gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter,
|
||||
ICON_COLUMN, NULL,
|
||||
DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
|
||||
TYPE_COLUMN, ROW_TYPE_SHORTCUT,
|
||||
DATA_COLUMN, g_object_ref (file),
|
||||
IS_FOLDER_COLUMN, FALSE,
|
||||
-1);
|
||||
set_info_for_file_at_iter (button, file, &iter);
|
||||
priv->n_shortcuts++;
|
||||
|
||||
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model));
|
||||
if (_gtk_file_chooser_is_file_in_roots (GTK_FILE_CHOOSER (priv->dialog),
|
||||
file))
|
||||
{
|
||||
add_shortcut_to_list (button, file);
|
||||
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model));
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
@@ -584,6 +674,7 @@ gtk_file_chooser_button_remove_shortcut_folder (GtkFileChooser *chooser,
|
||||
GtkTreeIter iter;
|
||||
gint pos;
|
||||
gchar type;
|
||||
GSList *l;
|
||||
|
||||
pos = model_get_type_position (button, ROW_TYPE_SHORTCUT);
|
||||
gtk_tree_model_iter_nth_child (priv->model, &iter, NULL, pos);
|
||||
@@ -610,6 +701,18 @@ gtk_file_chooser_button_remove_shortcut_folder (GtkFileChooser *chooser,
|
||||
}
|
||||
while (type == ROW_TYPE_SHORTCUT &&
|
||||
gtk_tree_model_iter_next (priv->model, &iter));
|
||||
|
||||
for (l = priv->shortcuts; l != NULL; l = l->next)
|
||||
{
|
||||
GFile *shortcut = (GFile *)l->data;
|
||||
|
||||
if (g_file_equal (shortcut, file))
|
||||
{
|
||||
g_object_unref (G_OBJECT (shortcut));
|
||||
priv->shortcuts = g_slist_remove_link (priv->shortcuts, l);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
@@ -743,6 +846,7 @@ gtk_file_chooser_button_set_property (GObject *object,
|
||||
{
|
||||
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object);
|
||||
GtkFileChooserButtonPrivate *priv = button->priv;
|
||||
GtkFileChooser *filechooser = GTK_FILE_CHOOSER (priv->dialog);
|
||||
|
||||
switch (param_id)
|
||||
{
|
||||
@@ -809,9 +913,28 @@ gtk_file_chooser_button_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY:
|
||||
case GTK_FILE_CHOOSER_PROP_ROOT_URIS:
|
||||
g_object_set_property (G_OBJECT (priv->dialog), pspec->name, value);
|
||||
|
||||
if (!_gtk_file_chooser_is_file_in_roots (filechooser, gtk_file_chooser_get_current_folder_file (filechooser)))
|
||||
{
|
||||
char **root_uris = gtk_file_chooser_get_root_uris (filechooser);
|
||||
|
||||
GFile *file = g_file_new_for_uri ((root_uris == NULL || *root_uris == NULL)
|
||||
? "file:///"
|
||||
: root_uris[0]);
|
||||
g_strfreev (root_uris);
|
||||
|
||||
gtk_file_chooser_set_current_folder_file (filechooser, file, NULL);
|
||||
model_update_current_folder (button, file);
|
||||
g_object_unref (G_OBJECT (file));
|
||||
}
|
||||
|
||||
fs_volumes_changed_cb (priv->fs, button);
|
||||
fs_bookmarks_changed_cb (priv->fs, button);
|
||||
reload_roots (button);
|
||||
reload_shortcuts (button);
|
||||
|
||||
break;
|
||||
|
||||
case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
|
||||
@@ -856,6 +979,7 @@ gtk_file_chooser_button_get_property (GObject *object,
|
||||
case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN:
|
||||
case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION:
|
||||
case GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS:
|
||||
case GTK_FILE_CHOOSER_PROP_ROOT_URIS:
|
||||
g_object_get_property (G_OBJECT (priv->dialog), pspec->name, value);
|
||||
break;
|
||||
|
||||
@@ -874,6 +998,13 @@ gtk_file_chooser_button_finalize (GObject *object)
|
||||
if (priv->old_file)
|
||||
g_object_unref (priv->old_file);
|
||||
|
||||
if (priv->shortcuts)
|
||||
{
|
||||
g_slist_foreach (priv->shortcuts, (GFunc)g_object_unref, NULL);
|
||||
g_slist_free (priv->shortcuts);
|
||||
priv->shortcuts = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -1502,6 +1633,11 @@ model_get_type_position (GtkFileChooserButton *button,
|
||||
|
||||
retval += button->priv->n_special;
|
||||
|
||||
if (row_type == ROW_TYPE_ROOT)
|
||||
return retval;
|
||||
|
||||
retval += button->priv->n_roots;
|
||||
|
||||
if (row_type == ROW_TYPE_VOLUME)
|
||||
return retval;
|
||||
|
||||
@@ -1735,6 +1871,7 @@ model_add_volumes (GtkFileChooserButton *button,
|
||||
gint pos;
|
||||
gboolean local_only;
|
||||
GtkFileSystem *file_system;
|
||||
GtkFileChooser *filechooser;
|
||||
GSList *l;
|
||||
|
||||
if (!volumes)
|
||||
@@ -1742,7 +1879,8 @@ model_add_volumes (GtkFileChooserButton *button,
|
||||
|
||||
store = GTK_LIST_STORE (button->priv->model);
|
||||
pos = model_get_type_position (button, ROW_TYPE_VOLUME);
|
||||
local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (button->priv->dialog));
|
||||
filechooser = GTK_FILE_CHOOSER (button->priv->dialog);
|
||||
local_only = gtk_file_chooser_get_local_only (filechooser);
|
||||
file_system = button->priv->fs;
|
||||
|
||||
for (l = volumes; l; l = l->next)
|
||||
@@ -1751,28 +1889,30 @@ model_add_volumes (GtkFileChooserButton *button,
|
||||
GtkTreeIter iter;
|
||||
GdkPixbuf *pixbuf;
|
||||
gchar *display_name;
|
||||
GFile *base_file;
|
||||
gboolean skip = FALSE;
|
||||
|
||||
volume = l->data;
|
||||
|
||||
if (local_only)
|
||||
{
|
||||
if (_gtk_file_system_volume_is_mounted (volume))
|
||||
{
|
||||
GFile *base_file;
|
||||
base_file = _gtk_file_system_volume_get_root (volume);
|
||||
|
||||
base_file = _gtk_file_system_volume_get_root (volume);
|
||||
if (base_file != NULL)
|
||||
{
|
||||
if (!g_file_is_native (base_file))
|
||||
{
|
||||
g_object_unref (base_file);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
g_object_unref (base_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (local_only &&
|
||||
base_file != NULL &&
|
||||
_gtk_file_system_volume_is_mounted (volume) &&
|
||||
!g_file_is_native (base_file))
|
||||
skip = TRUE;
|
||||
else if (base_file == NULL ||
|
||||
!_gtk_file_chooser_is_file_in_roots (filechooser, base_file))
|
||||
skip = TRUE;
|
||||
|
||||
if (base_file != NULL)
|
||||
g_object_unref (base_file);
|
||||
|
||||
if (skip)
|
||||
{
|
||||
_gtk_file_system_volume_unref (volume);
|
||||
continue;
|
||||
}
|
||||
|
||||
pixbuf = _gtk_file_system_volume_render_icon (volume,
|
||||
GTK_WIDGET (button),
|
||||
@@ -1809,13 +1949,15 @@ model_add_bookmarks (GtkFileChooserButton *button,
|
||||
gint pos;
|
||||
gboolean local_only;
|
||||
GSList *l;
|
||||
GtkFileChooser *filechooser;
|
||||
|
||||
if (!bookmarks)
|
||||
return;
|
||||
|
||||
store = GTK_LIST_STORE (button->priv->model);
|
||||
pos = model_get_type_position (button, ROW_TYPE_BOOKMARK);
|
||||
local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (button->priv->dialog));
|
||||
filechooser = GTK_FILE_CHOOSER (button->priv->dialog);
|
||||
local_only = gtk_file_chooser_get_local_only (filechooser);
|
||||
|
||||
for (l = bookmarks; l; l = l->next)
|
||||
{
|
||||
@@ -1823,6 +1965,9 @@ model_add_bookmarks (GtkFileChooserButton *button,
|
||||
|
||||
file = l->data;
|
||||
|
||||
if (!_gtk_file_chooser_is_file_in_roots (filechooser, file))
|
||||
continue;
|
||||
|
||||
if (g_file_is_native (file))
|
||||
{
|
||||
gtk_list_store_insert (store, &iter, pos);
|
||||
@@ -2037,17 +2182,24 @@ model_remove_rows (GtkFileChooserButton *button,
|
||||
|
||||
/* Filter Model */
|
||||
static inline gboolean
|
||||
test_if_file_is_visible (GtkFileSystem *fs,
|
||||
test_if_file_is_visible (GtkFileChooserButton *button,
|
||||
GFile *file,
|
||||
gboolean local_only,
|
||||
gboolean is_folder)
|
||||
{
|
||||
gboolean result;
|
||||
|
||||
if (!file)
|
||||
return FALSE;
|
||||
|
||||
if (local_only && !g_file_is_native (file))
|
||||
return FALSE;
|
||||
|
||||
result = _gtk_file_chooser_is_file_in_roots (GTK_FILE_CHOOSER (button), file);
|
||||
|
||||
if (!result)
|
||||
return FALSE;
|
||||
|
||||
if (!is_folder)
|
||||
return FALSE;
|
||||
|
||||
@@ -2083,7 +2235,7 @@ filter_model_visible_func (GtkTreeModel *model,
|
||||
case ROW_TYPE_SPECIAL:
|
||||
case ROW_TYPE_SHORTCUT:
|
||||
case ROW_TYPE_BOOKMARK:
|
||||
retval = test_if_file_is_visible (priv->fs, data, local_only, is_folder);
|
||||
retval = test_if_file_is_visible (button, data, local_only, is_folder);
|
||||
break;
|
||||
case ROW_TYPE_VOLUME:
|
||||
{
|
||||
@@ -2501,6 +2653,7 @@ combo_box_changed_cb (GtkComboBox *combo_box,
|
||||
switch (type)
|
||||
{
|
||||
case ROW_TYPE_SPECIAL:
|
||||
case ROW_TYPE_ROOT:
|
||||
case ROW_TYPE_SHORTCUT:
|
||||
case ROW_TYPE_BOOKMARK:
|
||||
case ROW_TYPE_CURRENT_FOLDER:
|
||||
|
||||
+592
-152
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,8 @@
|
||||
#include "gtkcelllayout.h"
|
||||
#include "gtkcellrenderertext.h"
|
||||
#include "gtkentry.h"
|
||||
#include "gtkfilechooserentry.h"
|
||||
#include "gtkfilechooserprivate.h"
|
||||
#include "gtklabel.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtksizerequest.h"
|
||||
@@ -70,6 +72,7 @@ struct _GtkFileChooserEntry
|
||||
GtkFileChooserAction action;
|
||||
|
||||
GtkFileSystem *file_system;
|
||||
GSList *root_uris;
|
||||
GFile *base_folder;
|
||||
GFile *current_folder_file;
|
||||
gchar *file_part;
|
||||
@@ -210,6 +213,7 @@ _gtk_file_chooser_entry_init (GtkFileChooserEntry *chooser_entry)
|
||||
GtkCellRenderer *cell;
|
||||
|
||||
chooser_entry->local_only = TRUE;
|
||||
chooser_entry->root_uris = NULL;
|
||||
|
||||
g_object_set (chooser_entry, "truncate-multiline", TRUE, NULL);
|
||||
|
||||
@@ -450,6 +454,17 @@ beep (GtkFileChooserEntry *chooser_entry)
|
||||
gtk_widget_error_bell (GTK_WIDGET (chooser_entry));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_file_in_roots (GtkFileChooserEntry *chooser_entry,
|
||||
GFile *file)
|
||||
{
|
||||
char *uri = g_file_get_uri (file);
|
||||
gboolean result = _gtk_file_chooser_uri_is_in_roots_list (uri, chooser_entry->root_uris);
|
||||
g_free (uri);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* This function will append a directory separator to paths to
|
||||
* display_name iff the path associated with it is a directory.
|
||||
* maybe_append_separator_to_file will g_free the display_name and
|
||||
@@ -1469,8 +1484,9 @@ start_loading_current_folder (GtkFileChooserEntry *chooser_entry)
|
||||
g_assert (chooser_entry->current_folder == NULL);
|
||||
g_assert (chooser_entry->load_folder_cancellable == NULL);
|
||||
|
||||
if (chooser_entry->local_only
|
||||
&& !g_file_is_native (chooser_entry->current_folder_file))
|
||||
if ((chooser_entry->local_only
|
||||
&& !g_file_is_native (chooser_entry->current_folder_file))
|
||||
|| !is_file_in_roots (chooser_entry, chooser_entry->current_folder_file))
|
||||
{
|
||||
g_object_unref (chooser_entry->current_folder_file);
|
||||
chooser_entry->current_folder_file = NULL;
|
||||
@@ -1618,6 +1634,12 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry,
|
||||
if (folder_file)
|
||||
g_object_unref (folder_file);
|
||||
|
||||
if (result != REFRESH_OK)
|
||||
{
|
||||
clear_completions (chooser_entry);
|
||||
discard_completion_store (chooser_entry);
|
||||
}
|
||||
|
||||
g_assert (/* we are OK and we have a current folder file and (loading process or folder handle)... */
|
||||
((result == REFRESH_OK)
|
||||
&& (chooser_entry->current_folder_file != NULL)
|
||||
@@ -2006,3 +2028,14 @@ _gtk_file_chooser_entry_get_local_only (GtkFileChooserEntry *chooser_entry)
|
||||
{
|
||||
return chooser_entry->local_only;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_file_chooser_entry_set_root_uris (GtkFileChooserEntry *chooser_entry,
|
||||
GSList *root_uris)
|
||||
{
|
||||
/* This doesn't need its own copy. */
|
||||
chooser_entry->root_uris = root_uris;
|
||||
clear_completions (chooser_entry);
|
||||
}
|
||||
|
||||
/* vim: et sw=2 cinoptions=(0,t0,f1s,n-1s,{1s,>2s,^-1s */
|
||||
|
||||
@@ -51,6 +51,8 @@ void _gtk_file_chooser_entry_select_filename (GtkFileChooserEnt
|
||||
void _gtk_file_chooser_entry_set_local_only (GtkFileChooserEntry *chooser_entry,
|
||||
gboolean local_only);
|
||||
gboolean _gtk_file_chooser_entry_get_local_only (GtkFileChooserEntry *chooser_entry);
|
||||
void _gtk_file_chooser_entry_set_root_uris (GtkFileChooserEntry *chooser_entry,
|
||||
GSList *root_uris);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -104,6 +104,14 @@ gboolean _gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *cho
|
||||
GError **error);
|
||||
GSList * _gtk_file_chooser_list_shortcut_folder_files (GtkFileChooser *chooser);
|
||||
|
||||
GSList * _gtk_file_chooser_list_shortcut_folder_files (GtkFileChooser *chooser);
|
||||
|
||||
gboolean _gtk_file_chooser_is_file_in_roots (GtkFileChooser *chooser,
|
||||
GFile *file);
|
||||
GSList * _gtk_file_chooser_get_visible_roots (GtkFileChooser *chooser);
|
||||
|
||||
gboolean _gtk_file_chooser_uri_is_in_roots_list (const char *uri, GSList *roots);
|
||||
|
||||
/* GtkFileChooserDialog private */
|
||||
|
||||
struct _GtkFileChooserDialogPrivate
|
||||
@@ -159,6 +167,7 @@ struct _GtkFileChooserDefault
|
||||
GtkFileChooserAction action;
|
||||
|
||||
GtkFileSystem *file_system;
|
||||
GSList *root_uris;
|
||||
|
||||
/* Save mode widgets */
|
||||
GtkWidget *save_widgets;
|
||||
@@ -229,6 +238,7 @@ struct _GtkFileChooserDefault
|
||||
|
||||
/* Handles */
|
||||
GSList *loading_shortcuts;
|
||||
GSList *shortcuts;
|
||||
GSList *reload_icon_cancellables;
|
||||
GCancellable *file_list_drag_data_received_cancellable;
|
||||
GCancellable *update_current_folder_cancellable;
|
||||
@@ -249,6 +259,7 @@ struct _GtkFileChooserDefault
|
||||
GtkFileFilter *current_filter;
|
||||
GSList *filters;
|
||||
|
||||
int num_roots;
|
||||
int num_volumes;
|
||||
int num_shortcuts;
|
||||
int num_bookmarks;
|
||||
@@ -285,7 +296,6 @@ struct _GtkFileChooserDefault
|
||||
|
||||
/* Flags */
|
||||
|
||||
guint local_only : 1;
|
||||
guint preview_widget_active : 1;
|
||||
guint use_preview_label : 1;
|
||||
guint select_multiple : 1;
|
||||
|
||||
@@ -117,6 +117,9 @@ _gtk_file_chooser_install_properties (GObjectClass *klass)
|
||||
g_object_class_override_property (klass,
|
||||
GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS,
|
||||
"create-folders");
|
||||
g_object_class_override_property (klass,
|
||||
GTK_FILE_CHOOSER_PROP_ROOT_URIS,
|
||||
"root-uris");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,7 +41,8 @@ typedef enum {
|
||||
GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN,
|
||||
GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION,
|
||||
GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS,
|
||||
GTK_FILE_CHOOSER_PROP_LAST = GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS
|
||||
GTK_FILE_CHOOSER_PROP_ROOT_URIS,
|
||||
GTK_FILE_CHOOSER_PROP_LAST = GTK_FILE_CHOOSER_PROP_ROOT_URIS
|
||||
} GtkFileChooserProp;
|
||||
|
||||
void _gtk_file_chooser_install_properties (GObjectClass *klass);
|
||||
|
||||
+116
-7
@@ -28,6 +28,7 @@
|
||||
#include "gtkalignment.h"
|
||||
#include "gtkarrow.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkfilechooserprivate.h"
|
||||
#include "gtkimage.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkicontheme.h"
|
||||
@@ -46,6 +47,7 @@ enum {
|
||||
typedef enum {
|
||||
NORMAL_BUTTON,
|
||||
ROOT_BUTTON,
|
||||
VIRTUAL_ROOT_BUTTON,
|
||||
HOME_BUTTON,
|
||||
DESKTOP_BUTTON
|
||||
} ButtonType;
|
||||
@@ -464,7 +466,7 @@ gtk_path_bar_size_allocate (GtkWidget *widget,
|
||||
GtkPathBar *path_bar = GTK_PATH_BAR (widget);
|
||||
GtkTextDirection direction;
|
||||
GtkAllocation child_allocation;
|
||||
GList *list, *first_button;
|
||||
GList *list, *first_button, *root_button;
|
||||
gint width;
|
||||
gint allocation_width;
|
||||
guint border_width;
|
||||
@@ -481,7 +483,11 @@ gtk_path_bar_size_allocate (GtkWidget *widget,
|
||||
|
||||
/* No path is set; we don't have to allocate anything. */
|
||||
if (path_bar->button_list == NULL)
|
||||
return;
|
||||
{
|
||||
gtk_widget_set_child_visible (path_bar->up_slider_button, FALSE);
|
||||
gtk_widget_set_child_visible (path_bar->down_slider_button, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
direction = gtk_widget_get_direction (widget);
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (path_bar));
|
||||
@@ -501,15 +507,17 @@ gtk_path_bar_size_allocate (GtkWidget *widget,
|
||||
|
||||
width += child_requisition.width + path_bar->spacing;
|
||||
if (list == path_bar->fake_root)
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
root_button = g_list_last (path_bar->button_list);
|
||||
|
||||
if (width <= allocation_width)
|
||||
{
|
||||
if (path_bar->fake_root)
|
||||
first_button = path_bar->fake_root;
|
||||
else
|
||||
first_button = g_list_last (path_bar->button_list);
|
||||
first_button = root_button;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -578,7 +586,8 @@ gtk_path_bar_size_allocate (GtkWidget *widget,
|
||||
if (direction == GTK_TEXT_DIR_RTL)
|
||||
{
|
||||
child_allocation.x = allocation->x + allocation->width - border_width;
|
||||
if (need_sliders || path_bar->fake_root)
|
||||
if (need_sliders ||
|
||||
(path_bar->fake_root && path_bar->fake_root != root_button))
|
||||
{
|
||||
child_allocation.x -= (path_bar->spacing + path_bar->slider_width);
|
||||
up_slider_offset = allocation->width - border_width - path_bar->slider_width;
|
||||
@@ -587,7 +596,8 @@ gtk_path_bar_size_allocate (GtkWidget *widget,
|
||||
else
|
||||
{
|
||||
child_allocation.x = allocation->x + border_width;
|
||||
if (need_sliders || path_bar->fake_root)
|
||||
if (need_sliders ||
|
||||
(path_bar->fake_root && path_bar->fake_root != root_button))
|
||||
{
|
||||
up_slider_offset = border_width;
|
||||
child_allocation.x += (path_bar->spacing + path_bar->slider_width);
|
||||
@@ -652,7 +662,8 @@ gtk_path_bar_size_allocate (GtkWidget *widget,
|
||||
gtk_widget_set_child_visible (BUTTON_DATA (list->data)->button, FALSE);
|
||||
}
|
||||
|
||||
if (need_sliders || path_bar->fake_root)
|
||||
if (need_sliders ||
|
||||
(path_bar->fake_root && path_bar->fake_root != root_button))
|
||||
{
|
||||
child_allocation.width = path_bar->slider_width;
|
||||
child_allocation.x = up_slider_offset + allocation->x;
|
||||
@@ -1241,6 +1252,13 @@ set_button_image_get_info_cb (GCancellable *cancellable,
|
||||
|
||||
switch (data->button_data->type)
|
||||
{
|
||||
case VIRTUAL_ROOT_BUTTON:
|
||||
if (data->path_bar->root_icon != NULL)
|
||||
g_object_unref (data->path_bar->root_icon);
|
||||
else
|
||||
data->path_bar->root_icon = pixbuf;
|
||||
break;
|
||||
|
||||
case HOME_BUTTON:
|
||||
if (data->path_bar->home_icon)
|
||||
g_object_unref (pixbuf);
|
||||
@@ -1294,6 +1312,38 @@ set_button_image (GtkPathBar *path_bar,
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), path_bar->root_icon);
|
||||
break;
|
||||
|
||||
case VIRTUAL_ROOT_BUTTON:
|
||||
/*
|
||||
* This is the first button, meaning that it's the root of the
|
||||
* file chooser. Give it a special icon.
|
||||
*
|
||||
* We're reusing the root_icon variable, which in this particular
|
||||
* case will actually represent this root. This is reset every time
|
||||
* the icon theme or root URI changes.
|
||||
*/
|
||||
if (path_bar->root_icon != NULL)
|
||||
{
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image),
|
||||
path_bar->root_icon);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = g_new0 (struct SetButtonImageData, 1);
|
||||
data->path_bar = path_bar;
|
||||
data->button_data = button_data;
|
||||
|
||||
if (button_data->cancellable)
|
||||
g_cancellable_cancel (button_data->cancellable);
|
||||
|
||||
button_data->cancellable =
|
||||
_gtk_file_system_get_info (path_bar->file_system,
|
||||
button_data->file,
|
||||
"standard::icon",
|
||||
set_button_image_get_info_cb,
|
||||
data);
|
||||
}
|
||||
break;
|
||||
|
||||
case HOME_BUTTON:
|
||||
if (path_bar->home_icon != NULL)
|
||||
{
|
||||
@@ -1337,6 +1387,7 @@ set_button_image (GtkPathBar *path_bar,
|
||||
set_button_image_get_info_cb,
|
||||
data);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1432,6 +1483,8 @@ static ButtonType
|
||||
find_button_type (GtkPathBar *path_bar,
|
||||
GFile *file)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
if (path_bar->root_file != NULL &&
|
||||
g_file_equal (file, path_bar->root_file))
|
||||
return ROOT_BUTTON;
|
||||
@@ -1442,6 +1495,21 @@ find_button_type (GtkPathBar *path_bar,
|
||||
g_file_equal (file, path_bar->desktop_file))
|
||||
return DESKTOP_BUTTON;
|
||||
|
||||
for (l = path_bar->root_uris; l != NULL; l = l->next)
|
||||
{
|
||||
char *root_uri = (char *)l->data;
|
||||
char *uri = g_file_get_uri (file);
|
||||
int root_uri_len = strlen (root_uri);
|
||||
|
||||
if (!strcmp (uri, root_uri) ||
|
||||
(root_uri[root_uri_len - 1] == '/' &&
|
||||
root_uri_len == strlen (uri) + 1 &&
|
||||
!strncmp (uri, root_uri, root_uri_len - 1)))
|
||||
{
|
||||
return VIRTUAL_ROOT_BUTTON;
|
||||
}
|
||||
}
|
||||
|
||||
return NORMAL_BUTTON;
|
||||
}
|
||||
|
||||
@@ -1498,6 +1566,7 @@ make_directory_button (GtkPathBar *path_bar,
|
||||
break;
|
||||
case HOME_BUTTON:
|
||||
case DESKTOP_BUTTON:
|
||||
case VIRTUAL_ROOT_BUTTON:
|
||||
button_data->image = gtk_image_new ();
|
||||
button_data->label = gtk_label_new (NULL);
|
||||
label_alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
|
||||
@@ -1620,6 +1689,17 @@ struct SetFileInfo
|
||||
gboolean first_directory;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
is_file_in_roots (GtkPathBar *path_bar,
|
||||
GFile *file)
|
||||
{
|
||||
char *uri = g_file_get_uri (file);
|
||||
gboolean result = _gtk_file_chooser_uri_is_in_roots_list (uri, path_bar->root_uris);
|
||||
g_free(uri);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_bar_set_file_finish (struct SetFileInfo *info,
|
||||
gboolean result)
|
||||
@@ -1691,6 +1771,12 @@ gtk_path_bar_get_info_callback (GCancellable *cancellable,
|
||||
display_name = g_file_info_get_display_name (info);
|
||||
is_hidden = g_file_info_get_is_hidden (info) || g_file_info_get_is_backup (info);
|
||||
|
||||
if (!is_file_in_roots (file_info->path_bar, file_info->file))
|
||||
{
|
||||
gtk_path_bar_set_file_finish (file_info, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_widget_push_composite_child ();
|
||||
button_data = make_directory_button (file_info->path_bar, display_name,
|
||||
file_info->file,
|
||||
@@ -1798,6 +1884,29 @@ _gtk_path_bar_set_file_system (GtkPathBar *path_bar,
|
||||
path_bar->root_file = g_file_new_for_path ("/");
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_path_bar_set_root_uris (GtkPathBar *path_bar,
|
||||
GSList *root_uris)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_PATH_BAR (path_bar));
|
||||
|
||||
path_bar->root_uris = root_uris;
|
||||
|
||||
/*
|
||||
* We don't know if we can even query this URI, so clear the buttons as
|
||||
* a precaution. Otherwise the user could jump to folders outside the root
|
||||
* URI and break things.
|
||||
*/
|
||||
gtk_path_bar_clear_buttons (path_bar);
|
||||
|
||||
/* Also clear the root icon, as we'll be using this for the root URI button. */
|
||||
if (path_bar->root_icon)
|
||||
{
|
||||
g_object_unref (path_bar->root_icon);
|
||||
path_bar->root_icon = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_path_bar_up:
|
||||
* @path_bar: a #GtkPathBar
|
||||
|
||||
@@ -45,6 +45,8 @@ struct _GtkPathBar
|
||||
GFile *home_file;
|
||||
GFile *desktop_file;
|
||||
|
||||
GSList *root_uris;
|
||||
|
||||
GCancellable *get_info_cancellable;
|
||||
|
||||
GdkPixbuf *root_icon;
|
||||
@@ -88,6 +90,8 @@ gboolean _gtk_path_bar_set_file (GtkPathBar *path_bar,
|
||||
GFile *file,
|
||||
gboolean keep_trail,
|
||||
GError **error);
|
||||
void _gtk_path_bar_set_root_uris (GtkPathBar *path_bar,
|
||||
GSList *root_uris);
|
||||
void _gtk_path_bar_up (GtkPathBar *path_bar);
|
||||
void _gtk_path_bar_down (GtkPathBar *path_bar);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Openismus GmbH
|
||||
*
|
||||
* Authors:
|
||||
* Tristan Van Berkom <tristanvb@openismus.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library 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.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_SPREAD_TABLE_H__
|
||||
#define __GTK_SPREAD_TABLE_H__
|
||||
|
||||
#include <gtk/gtkcontainer.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define GTK_TYPE_SPREAD_TABLE (gtk_spread_table_get_type ())
|
||||
#define GTK_SPREAD_TABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SPREAD_TABLE, GtkSpreadTable))
|
||||
#define GTK_SPREAD_TABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SPREAD_TABLE, GtkSpreadTableClass))
|
||||
#define GTK_IS_SPREAD_TABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SPREAD_TABLE))
|
||||
#define GTK_IS_SPREAD_TABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SPREAD_TABLE))
|
||||
#define GTK_SPREAD_TABLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SPREAD_TABLE, GtkSpreadTableClass))
|
||||
|
||||
typedef struct _GtkSpreadTable GtkSpreadTable;
|
||||
typedef struct _GtkSpreadTablePrivate GtkSpreadTablePrivate;
|
||||
typedef struct _GtkSpreadTableClass GtkSpreadTableClass;
|
||||
|
||||
|
||||
struct _GtkSpreadTable
|
||||
{
|
||||
GtkContainer parent_instance;
|
||||
|
||||
/*< private >*/
|
||||
GtkSpreadTablePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkSpreadTableClass
|
||||
{
|
||||
GtkContainerClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType gtk_spread_table_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
GtkWidget *gtk_spread_table_new (GtkOrientation orientation,
|
||||
guint lines);
|
||||
|
||||
void gtk_spread_table_insert_child (GtkSpreadTable *table,
|
||||
GtkWidget *child,
|
||||
gint index);
|
||||
|
||||
guint gtk_spread_table_get_child_line (GtkSpreadTable *table,
|
||||
GtkWidget *child,
|
||||
gint size);
|
||||
|
||||
void gtk_spread_table_set_lines (GtkSpreadTable *table,
|
||||
guint lines);
|
||||
guint gtk_spread_table_get_lines (GtkSpreadTable *table);
|
||||
|
||||
void gtk_spread_table_set_horizontal_spacing (GtkSpreadTable *table,
|
||||
guint spacing);
|
||||
guint gtk_spread_table_get_horizontal_spacing (GtkSpreadTable *table);
|
||||
|
||||
void gtk_spread_table_set_vertical_spacing (GtkSpreadTable *table,
|
||||
guint spacing);
|
||||
guint gtk_spread_table_get_vertical_spacing (GtkSpreadTable *table);
|
||||
|
||||
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
#endif /* __GTK_SPREAD_TABLE_H__ */
|
||||
+3
-3
@@ -1341,12 +1341,12 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
* GtkWidget::draw:
|
||||
* @widget: the object which received the signal
|
||||
* @cr: the cairo context to draw to
|
||||
* @width: width of the widget
|
||||
* @height: height of the widget
|
||||
*
|
||||
* This signal is emitted when a widget is supposed to render itself.
|
||||
* The @widget's top left corner must be painted at the origin of
|
||||
* the passed in context and be sized in the given @width and @height.
|
||||
* the passed in context and be sized to the values returned by
|
||||
* gtk_widget_get_allocated_width() and
|
||||
* gtk_widget_get_allocated_height().
|
||||
*
|
||||
* Signal handlers connected to this signal can modify the cairo
|
||||
* context passed as @cr in any way they like and don't need to
|
||||
|
||||
+1
-7
@@ -91,8 +91,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
|
||||
testtooltips \
|
||||
testexpander \
|
||||
testvolumebutton \
|
||||
testwrapbox \
|
||||
testspreadtable
|
||||
testwrapbox
|
||||
|
||||
if USE_X11
|
||||
noinst_PROGRAMS += testapplication testerrors
|
||||
@@ -176,7 +175,6 @@ testgrouping_DEPENDENCIES = $(TEST_DEPS)
|
||||
testtooltips_DEPENDENCIES = $(TEST_DEPS)
|
||||
testvolumebutton_DEPENDENCIES = $(TEST_DEPS)
|
||||
testwrapbox_DEPENDENCIES = $(TEST_DEPS)
|
||||
testspreadtable_DEPENDENCIES = $(TEST_DEPS)
|
||||
testwindows_DEPENDENCIES = $(TEST_DEPS)
|
||||
testexpander_DEPENDENCIES = $(TEST_DEPS)
|
||||
|
||||
@@ -248,7 +246,6 @@ testgrouping_LDADD = $(LDADDS)
|
||||
testtooltips_LDADD = $(LDADDS)
|
||||
testvolumebutton_LDADD = $(LDADDS)
|
||||
testwrapbox_LDADD = $(LDADDS)
|
||||
testspreadtable_LDADD = $(LDADDS)
|
||||
testwindows_LDADD = $(LDADDS)
|
||||
testexpander_LDADD = $(LDADDS)
|
||||
|
||||
@@ -351,9 +348,6 @@ testvolumebutton_SOURCES = \
|
||||
testwrapbox_SOURCES = \
|
||||
testwrapbox.c
|
||||
|
||||
testspreadtable_SOURCES = \
|
||||
testspreadtable.c
|
||||
|
||||
testoffscreen_SOURCES = \
|
||||
gtkoffscreenbox.c \
|
||||
gtkoffscreenbox.h \
|
||||
|
||||
+37
-24
@@ -406,6 +406,26 @@ unmap_and_remap_cb (GtkButton *button,
|
||||
gtk_widget_show (GTK_WIDGET (chooser));
|
||||
}
|
||||
|
||||
static void
|
||||
root_to_home_and_tmp_cb (GtkButton *button,
|
||||
GtkFileChooser *chooser)
|
||||
{
|
||||
char *root_uris[] = { "",
|
||||
"file:///tmp",
|
||||
NULL };
|
||||
|
||||
root_uris[0] = g_strconcat ("file://", g_get_home_dir (), NULL);
|
||||
gtk_file_chooser_set_root_uris (chooser, (const char **) root_uris);
|
||||
g_free (root_uris[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
unroot_cb (GtkButton *button,
|
||||
GtkFileChooser *chooser)
|
||||
{
|
||||
gtk_file_chooser_set_root_uris (chooser, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
kill_dependent (GtkWindow *win, GtkWidget *dep)
|
||||
{
|
||||
@@ -474,6 +494,16 @@ confirm_overwrite_cb (GtkFileChooser *chooser,
|
||||
return conf;
|
||||
}
|
||||
|
||||
static void
|
||||
add_test_button (GtkWidget *container, const char *label_text, GCallback callback, gpointer data)
|
||||
{
|
||||
GtkWidget *button;
|
||||
|
||||
button = gtk_button_new_with_label (label_text);
|
||||
gtk_container_add (GTK_CONTAINER (container), button);
|
||||
g_signal_connect (button, "clicked", callback, data);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@@ -660,30 +690,13 @@ main (int argc, char **argv)
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_file_chooser_unselect_all), dialog);
|
||||
|
||||
button = gtk_button_new_with_label ("set_current_folder (\"/nonexistent\")");
|
||||
gtk_container_add (GTK_CONTAINER (vbbox), button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (set_folder_nonexistent_cb), dialog);
|
||||
|
||||
button = gtk_button_new_with_label ("set_current_folder (\"/usr/nonexistent\")");
|
||||
gtk_container_add (GTK_CONTAINER (vbbox), button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (set_folder_existing_nonexistent_cb), dialog);
|
||||
|
||||
button = gtk_button_new_with_label ("set_filename (\"/nonexistent\")");
|
||||
gtk_container_add (GTK_CONTAINER (vbbox), button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (set_filename_nonexistent_cb), dialog);
|
||||
|
||||
button = gtk_button_new_with_label ("set_filename (\"/usr/nonexistent\")");
|
||||
gtk_container_add (GTK_CONTAINER (vbbox), button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (set_filename_existing_nonexistent_cb), dialog);
|
||||
|
||||
button = gtk_button_new_with_label ("Unmap and remap");
|
||||
gtk_container_add (GTK_CONTAINER (vbbox), button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (unmap_and_remap_cb), dialog);
|
||||
add_test_button (vbbox, "set_current_folder (\"/nonexistent\")", G_CALLBACK (set_folder_nonexistent_cb), dialog);
|
||||
add_test_button (vbbox, "set_current_folder (\"/usr/nonexistent\")", G_CALLBACK (set_folder_existing_nonexistent_cb), dialog);
|
||||
add_test_button (vbbox, "set_filename (\"/nonexistent\")", G_CALLBACK (set_filename_nonexistent_cb), dialog);
|
||||
add_test_button (vbbox, "set_filename (\"/usr/nonexistent\")", G_CALLBACK (set_filename_existing_nonexistent_cb), dialog);
|
||||
add_test_button (vbbox, "Unmap and remap", G_CALLBACK (unmap_and_remap_cb), dialog);
|
||||
add_test_button (vbbox, "Root to $HOME and /tmp", G_CALLBACK (root_to_home_and_tmp_cb), dialog);
|
||||
add_test_button (vbbox, "Unroot", G_CALLBACK (unroot_cb), dialog);
|
||||
|
||||
gtk_widget_show_all (control_window);
|
||||
|
||||
|
||||
@@ -1,393 +0,0 @@
|
||||
/* testspreadtable.c
|
||||
* Copyright (C) 2010 Openismus GmbH
|
||||
*
|
||||
* Author:
|
||||
* Tristan Van Berkom <tristanvb@openismus.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library 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 <gtk/gtk.h>
|
||||
|
||||
enum {
|
||||
IMAGE_NONE,
|
||||
IMAGE_SMALL,
|
||||
IMAGE_LARGE,
|
||||
IMAGE_HUGE
|
||||
};
|
||||
|
||||
#define INITIAL_HSPACING 2
|
||||
#define INITIAL_VSPACING 2
|
||||
#define INITIAL_LINES 3
|
||||
#define INITIAL_HALIGN GTK_ALIGN_FILL
|
||||
#define INITIAL_IMAGE IMAGE_NONE
|
||||
#define INITIAL_IMAGE_INDEX 10
|
||||
|
||||
static GtkWidget *paper = NULL;
|
||||
static GtkAlign child_halign = INITIAL_HALIGN;
|
||||
static int test_image = INITIAL_IMAGE;
|
||||
static int test_image_index = INITIAL_IMAGE_INDEX;
|
||||
|
||||
static void
|
||||
populate_spread_table_wrappy (GtkSpreadTable *spread_table)
|
||||
{
|
||||
GList *children, *l;
|
||||
GtkWidget *widget, *frame;
|
||||
gint i;
|
||||
|
||||
const gchar *strings[] = {
|
||||
"These are", "some wrappy label", "texts", "of various", "lengths.",
|
||||
"They should always be", "shown", "consecutively. Except it's",
|
||||
"hard to say", "where exactly the", "label", "will wrap", "and where exactly",
|
||||
"the actual", "container", "will wrap.", "This label is really really really long !",
|
||||
"Let's add some more", "labels to the",
|
||||
"mix. Just to", "make sure we", "got something to work", "with here."
|
||||
};
|
||||
|
||||
/* Remove all children first */
|
||||
children = gtk_container_get_children (GTK_CONTAINER (paper));
|
||||
for (l = children; l; l = l->next)
|
||||
{
|
||||
GtkWidget *child = l->data;
|
||||
|
||||
gtk_container_remove (GTK_CONTAINER (paper), child);
|
||||
}
|
||||
g_list_free (children);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (strings); i++)
|
||||
{
|
||||
widget = gtk_label_new (strings[i]);
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_show (widget);
|
||||
gtk_widget_show (frame);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (frame), widget);
|
||||
|
||||
gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
|
||||
gtk_label_set_line_wrap_mode (GTK_LABEL (widget), PANGO_WRAP_WORD);
|
||||
gtk_label_set_width_chars (GTK_LABEL (widget), 10);
|
||||
|
||||
gtk_widget_set_halign (frame, child_halign);
|
||||
|
||||
gtk_spread_table_insert_child (GTK_SPREAD_TABLE (spread_table), frame, -1);
|
||||
}
|
||||
|
||||
/* Insert an image into the mix */
|
||||
if (test_image)
|
||||
{
|
||||
widget = gtk_image_new_from_file ("apple-red.png");
|
||||
|
||||
switch (test_image)
|
||||
{
|
||||
case IMAGE_SMALL:
|
||||
gtk_widget_set_size_request (widget, 100, 100);
|
||||
break;
|
||||
case IMAGE_LARGE:
|
||||
gtk_widget_set_size_request (widget, 150, 200);
|
||||
break;
|
||||
case IMAGE_HUGE:
|
||||
gtk_widget_set_size_request (widget, 200, 300);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_show (widget);
|
||||
gtk_widget_show (frame);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (frame), widget);
|
||||
gtk_spread_table_insert_child (GTK_SPREAD_TABLE (spread_table), frame, test_image_index);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
orientation_changed (GtkComboBox *box,
|
||||
GtkSpreadTable *paper)
|
||||
{
|
||||
GtkOrientation orientation = gtk_combo_box_get_active (box);
|
||||
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (paper), orientation);
|
||||
}
|
||||
|
||||
static void
|
||||
lines_changed (GtkSpinButton *button,
|
||||
gpointer data)
|
||||
{
|
||||
gint lines = gtk_spin_button_get_value_as_int (button);
|
||||
|
||||
gtk_spread_table_set_lines (GTK_SPREAD_TABLE (paper), lines);
|
||||
}
|
||||
|
||||
static void
|
||||
spacing_changed (GtkSpinButton *button,
|
||||
gpointer data)
|
||||
{
|
||||
GtkOrientation orientation = GPOINTER_TO_INT (data);
|
||||
gint state = gtk_spin_button_get_value_as_int (button);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
gtk_spread_table_set_horizontal_spacing (GTK_SPREAD_TABLE (paper), state);
|
||||
else
|
||||
gtk_spread_table_set_vertical_spacing (GTK_SPREAD_TABLE (paper), state);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
halign_changed (GtkComboBox *box,
|
||||
GtkSpreadTable *paper)
|
||||
{
|
||||
child_halign = gtk_combo_box_get_active (box);
|
||||
|
||||
populate_spread_table_wrappy (GTK_SPREAD_TABLE (paper));
|
||||
}
|
||||
|
||||
static void
|
||||
test_image_changed (GtkComboBox *box,
|
||||
GtkSpreadTable *paper)
|
||||
{
|
||||
test_image = gtk_combo_box_get_active (box);
|
||||
|
||||
populate_spread_table_wrappy (GTK_SPREAD_TABLE (paper));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
test_image_index_changed (GtkSpinButton *button,
|
||||
gpointer data)
|
||||
{
|
||||
test_image_index = gtk_spin_button_get_value_as_int (button);
|
||||
|
||||
populate_spread_table_wrappy (GTK_SPREAD_TABLE (paper));
|
||||
}
|
||||
|
||||
|
||||
static GtkWidget *
|
||||
create_window (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *hbox, *vbox, *widget;
|
||||
GtkWidget *swindow, *frame, *expander;
|
||||
GtkWidget *paper_cntl, *items_cntl;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
hbox = gtk_hbox_new (FALSE, 2);
|
||||
vbox = gtk_vbox_new (FALSE, 6);
|
||||
|
||||
gtk_container_set_border_width (GTK_CONTAINER (window), 8);
|
||||
|
||||
gtk_widget_show (vbox);
|
||||
gtk_widget_show (hbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
|
||||
|
||||
frame = gtk_frame_new ("SpreadTable");
|
||||
gtk_widget_show (frame);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
|
||||
|
||||
swindow = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
|
||||
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
|
||||
gtk_widget_show (swindow);
|
||||
gtk_container_add (GTK_CONTAINER (frame), swindow);
|
||||
|
||||
paper = gtk_spread_table_new (GTK_ORIENTATION_VERTICAL, INITIAL_LINES);
|
||||
gtk_spread_table_set_vertical_spacing (GTK_SPREAD_TABLE (paper), INITIAL_VSPACING);
|
||||
gtk_spread_table_set_horizontal_spacing (GTK_SPREAD_TABLE (paper), INITIAL_HSPACING);
|
||||
gtk_widget_show (paper);
|
||||
|
||||
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), paper);
|
||||
|
||||
/* Add SpreadTable test control frame */
|
||||
expander = gtk_expander_new ("SpreadTable controls");
|
||||
gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE);
|
||||
paper_cntl = gtk_vbox_new (FALSE, 2);
|
||||
gtk_widget_show (paper_cntl);
|
||||
gtk_widget_show (expander);
|
||||
gtk_container_add (GTK_CONTAINER (expander), paper_cntl);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), expander, FALSE, FALSE, 0);
|
||||
|
||||
/* Add Orientation control */
|
||||
widget = gtk_combo_box_new_text ();
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "Horizontal");
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "Vertical");
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
gtk_widget_set_tooltip_text (widget, "Set the spread_table orientation");
|
||||
gtk_box_pack_start (GTK_BOX (paper_cntl), widget, FALSE, FALSE, 0);
|
||||
|
||||
g_signal_connect (G_OBJECT (widget), "changed",
|
||||
G_CALLBACK (orientation_changed), paper);
|
||||
|
||||
|
||||
/* Add horizontal/vertical spacing controls */
|
||||
hbox = gtk_hbox_new (FALSE, 2);
|
||||
gtk_widget_show (hbox);
|
||||
|
||||
widget = gtk_label_new ("H Spacing");
|
||||
gtk_widget_show (widget);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
|
||||
|
||||
widget = gtk_spin_button_new_with_range (0, 30, 1);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), INITIAL_HSPACING);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
gtk_widget_set_tooltip_text (widget, "Set the horizontal spacing between children");
|
||||
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
|
||||
|
||||
g_signal_connect (G_OBJECT (widget), "changed",
|
||||
G_CALLBACK (spacing_changed), GINT_TO_POINTER (GTK_ORIENTATION_HORIZONTAL));
|
||||
g_signal_connect (G_OBJECT (widget), "value-changed",
|
||||
G_CALLBACK (spacing_changed), GINT_TO_POINTER (GTK_ORIENTATION_HORIZONTAL));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (paper_cntl), hbox, FALSE, FALSE, 0);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, 2);
|
||||
gtk_widget_show (hbox);
|
||||
|
||||
widget = gtk_label_new ("V Spacing");
|
||||
gtk_widget_show (widget);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
|
||||
|
||||
widget = gtk_spin_button_new_with_range (0, 30, 1);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), INITIAL_VSPACING);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
gtk_widget_set_tooltip_text (widget, "Set the vertical spacing between children");
|
||||
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
|
||||
|
||||
g_signal_connect (G_OBJECT (widget), "changed",
|
||||
G_CALLBACK (spacing_changed), GINT_TO_POINTER (GTK_ORIENTATION_VERTICAL));
|
||||
g_signal_connect (G_OBJECT (widget), "value-changed",
|
||||
G_CALLBACK (spacing_changed), GINT_TO_POINTER (GTK_ORIENTATION_VERTICAL));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (paper_cntl), hbox, FALSE, FALSE, 0);
|
||||
|
||||
|
||||
/* Add lines controls */
|
||||
hbox = gtk_hbox_new (FALSE, 2);
|
||||
gtk_widget_show (hbox);
|
||||
|
||||
widget = gtk_label_new ("Lines");
|
||||
gtk_widget_show (widget);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
|
||||
|
||||
widget = gtk_spin_button_new_with_range (1, 30, 1);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), INITIAL_LINES);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
gtk_widget_set_tooltip_text (widget, "Set the horizontal spacing between children");
|
||||
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
|
||||
|
||||
g_signal_connect (G_OBJECT (widget), "changed",
|
||||
G_CALLBACK (lines_changed), NULL);
|
||||
g_signal_connect (G_OBJECT (widget), "value-changed",
|
||||
G_CALLBACK (lines_changed), NULL);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (paper_cntl), hbox, FALSE, FALSE, 0);
|
||||
|
||||
|
||||
/* Add test items control frame */
|
||||
expander = gtk_expander_new ("Test item controls");
|
||||
gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE);
|
||||
items_cntl = gtk_vbox_new (FALSE, 2);
|
||||
gtk_widget_show (items_cntl);
|
||||
gtk_widget_show (expander);
|
||||
gtk_container_add (GTK_CONTAINER (expander), items_cntl);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), expander, FALSE, FALSE, 0);
|
||||
|
||||
/* Add child halign control */
|
||||
widget = gtk_combo_box_new_text ();
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "Fill");
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "Start");
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "End");
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "Center");
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), INITIAL_HALIGN);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
gtk_widget_set_tooltip_text (widget, "Set the children's halign property");
|
||||
gtk_box_pack_start (GTK_BOX (items_cntl), widget, FALSE, FALSE, 0);
|
||||
|
||||
g_signal_connect (G_OBJECT (widget), "changed",
|
||||
G_CALLBACK (halign_changed), paper);
|
||||
|
||||
|
||||
/* Add image control */
|
||||
widget = gtk_combo_box_new_text ();
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "None");
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "Small");
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "Large");
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "Huge");
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), INITIAL_IMAGE);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
gtk_widget_set_tooltip_text (widget, "Use an image to test the container");
|
||||
gtk_box_pack_start (GTK_BOX (items_cntl), widget, FALSE, FALSE, 0);
|
||||
|
||||
g_signal_connect (G_OBJECT (widget), "changed",
|
||||
G_CALLBACK (test_image_changed), paper);
|
||||
|
||||
|
||||
/* Add horizontal/vertical spacing controls */
|
||||
hbox = gtk_hbox_new (FALSE, 2);
|
||||
gtk_widget_show (hbox);
|
||||
|
||||
widget = gtk_label_new ("Image index");
|
||||
gtk_widget_show (widget);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
|
||||
|
||||
widget = gtk_spin_button_new_with_range (0, 25, 1);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), INITIAL_IMAGE_INDEX);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
gtk_widget_set_tooltip_text (widget, "Set the child list index for the optional test image");
|
||||
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (items_cntl), hbox, FALSE, FALSE, 0);
|
||||
|
||||
g_signal_connect (G_OBJECT (widget), "changed",
|
||||
G_CALLBACK (test_image_index_changed), GINT_TO_POINTER (GTK_ORIENTATION_HORIZONTAL));
|
||||
g_signal_connect (G_OBJECT (widget), "value-changed",
|
||||
G_CALLBACK (test_image_index_changed), GINT_TO_POINTER (GTK_ORIENTATION_HORIZONTAL));
|
||||
|
||||
populate_spread_table_wrappy (GTK_SPREAD_TABLE (paper));
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 500, 400);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkWidget *window;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
window = create_window ();
|
||||
|
||||
g_signal_connect (window, "delete-event",
|
||||
G_CALLBACK (gtk_main_quit), window);
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user