summaryrefslogtreecommitdiff
path: root/gtk/gtkfilechooserdefault.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtk/gtkfilechooserdefault.c')
-rw-r--r--gtk/gtkfilechooserdefault.c202
1 files changed, 147 insertions, 55 deletions
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index 15c00996f1..7eaaef2830 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -61,7 +61,7 @@
#include "gtksizegroup.h"
#include "gtksizerequest.h"
#include "gtkstock.h"
-#include "gtktable.h"
+#include "gtkgrid.h"
#include "gtktoolbar.h"
#include "gtktoolbutton.h"
#include "gtktooltip.h"
@@ -86,6 +86,10 @@
#include <io.h>
#endif
+/* Values for GtkSelection-related "info" fields */
+#define SELECTION_TEXT 0
+#define SELECTION_URI 1
+
/* Profiling stuff */
#undef PROFILE_FILE_CHOOSER
#ifdef PROFILE_FILE_CHOOSER
@@ -96,6 +100,7 @@
#endif
#define PROFILE_INDENT 4
+
static int profile_indent;
static void
@@ -3787,6 +3792,7 @@ popup_menu_detach_cb (GtkWidget *attach_widget,
impl->browse_files_popup_menu = NULL;
impl->browse_files_popup_menu_add_shortcut_item = NULL;
impl->browse_files_popup_menu_hidden_files_item = NULL;
+ impl->browse_files_popup_menu_copy_file_location_item = NULL;
}
/* Callback used when the "Add to Bookmarks" menu item is activated */
@@ -3797,6 +3803,97 @@ add_to_shortcuts_cb (GtkMenuItem *item,
bookmarks_add_selected_folder (impl);
}
+/* callback used to set data to clipboard */
+static void
+copy_file_get_cb (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ guint info,
+ gpointer data)
+{
+ GSList *selected_files = data;
+
+ if (selected_files)
+ {
+ gint num_files = g_slist_length (selected_files);
+ gchar **uris;
+ gint i;
+ GSList *l;
+
+ uris = g_new (gchar *, num_files + 1);
+ uris[num_files] = NULL; /* null terminator */
+
+ i = 0;
+
+ for (l = selected_files; l; l = l->next)
+ {
+ GFile *file = (GFile *) l->data;
+
+ if (info == SELECTION_URI)
+ uris[i] = g_file_get_uri (file);
+ else /* if (info == SELECTION_TEXT) - let this be the fallback */
+ uris[i] = g_file_get_parse_name (file);
+
+ i++;
+ }
+
+ if (info == SELECTION_URI)
+ gtk_selection_data_set_uris (selection_data, uris);
+ else /* if (info == SELECTION_TEXT) - let this be the fallback */
+ {
+ char *str = g_strjoinv (" ", uris);
+ gtk_selection_data_set_text (selection_data, str, -1);
+ g_free (str);
+ }
+
+ g_strfreev (uris);
+ }
+}
+
+/* callback used to clear the clipboard data */
+static void
+copy_file_clear_cb (GtkClipboard *clipboard,
+ gpointer data)
+{
+ GSList *selected_files = data;
+
+ g_slist_foreach (selected_files, (GFunc) g_object_unref, NULL);
+ g_slist_free (selected_files);
+}
+
+/* Callback used when the "Copy file's location" menu item is activated */
+static void
+copy_file_location_cb (GtkMenuItem *item,
+ GtkFileChooserDefault *impl)
+{
+ GSList *selected_files = NULL;
+
+ selected_files = search_get_selected_files (impl);
+
+ if (selected_files)
+ {
+ GtkClipboard *clipboard;
+ GtkTargetList *target_list;
+ GtkTargetEntry *targets;
+ int n_targets;
+
+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (impl), GDK_SELECTION_CLIPBOARD);
+
+ target_list = gtk_target_list_new (NULL, 0);
+ gtk_target_list_add_text_targets (target_list, SELECTION_TEXT);
+ gtk_target_list_add_uri_targets (target_list, SELECTION_URI);
+
+ targets = gtk_target_table_new_from_list (target_list, &n_targets);
+ gtk_target_list_unref (target_list);
+
+ gtk_clipboard_set_with_data (clipboard, targets, n_targets,
+ copy_file_get_cb,
+ copy_file_clear_cb,
+ selected_files);
+
+ gtk_target_table_free (targets, n_targets);
+ }
+}
+
/* Callback used when the "Show Hidden Files" menu item is toggled */
static void
show_hidden_toggled_cb (GtkCheckMenuItem *item,
@@ -3984,6 +4081,25 @@ file_list_drag_motion_cb (GtkWidget *widget,
return TRUE;
}
+/* Sensitizes the "Copy file's location" context menu item if there is actually
+ * a selection active.
+ */
+static void
+check_copy_file_location_sensitivity (GtkFileChooserDefault *impl)
+{
+ GtkTreeSelection *selection;
+ gboolean active;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
+ if (gtk_tree_selection_count_selected_rows (selection) == 0)
+ active = FALSE;
+ else
+ active = TRUE;
+
+ if (impl->browse_files_popup_menu_copy_file_location_item)
+ gtk_widget_set_sensitive (impl->browse_files_popup_menu_copy_file_location_item, active);
+}
+
/* Constructs the popup menu for the file list if needed */
static void
file_list_build_popup_menu (GtkFileChooserDefault *impl)
@@ -3998,6 +4114,15 @@ file_list_build_popup_menu (GtkFileChooserDefault *impl)
impl->browse_files_tree_view,
popup_menu_detach_cb);
+ item = gtk_image_menu_item_new_with_mnemonic (_("_Copy file's location"));
+ impl->browse_files_popup_menu_copy_file_location_item = item;
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
+ gtk_image_new_from_stock (GTK_STOCK_COPY, GTK_ICON_SIZE_MENU));
+ g_signal_connect (item, "activate",
+ G_CALLBACK (copy_file_location_cb), impl);
+ gtk_widget_show (item);
+ gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
+
item = gtk_image_menu_item_new_with_mnemonic (_("_Add to Bookmarks"));
impl->browse_files_popup_menu_add_shortcut_item = item;
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
@@ -4026,6 +4151,7 @@ file_list_build_popup_menu (GtkFileChooserDefault *impl)
gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
bookmarks_check_add_sensitivity (impl);
+ check_copy_file_location_sensitivity (impl);
}
/* Updates the popup menu for the file list, creating it if necessary */
@@ -4420,30 +4546,25 @@ save_widgets_create (GtkFileChooserDefault *impl)
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- impl->save_widgets_table = gtk_table_new (2, 2, FALSE);
+ impl->save_widgets_table = gtk_grid_new ();
gtk_box_pack_start (GTK_BOX (vbox), impl->save_widgets_table, FALSE, FALSE, 0);
gtk_widget_show (impl->save_widgets_table);
- gtk_table_set_row_spacings (GTK_TABLE (impl->save_widgets_table), 12);
- gtk_table_set_col_spacings (GTK_TABLE (impl->save_widgets_table), 12);
+ gtk_grid_set_row_spacing (GTK_GRID (impl->save_widgets_table), 12);
+ gtk_grid_set_column_spacing (GTK_GRID (impl->save_widgets_table), 12);
/* Label */
widget = gtk_label_new_with_mnemonic (_("_Name:"));
gtk_widget_set_halign (widget, GTK_ALIGN_START);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
- gtk_table_attach (GTK_TABLE (impl->save_widgets_table), widget,
- 0, 1, 0, 1,
- GTK_FILL, GTK_FILL,
- 0, 0);
+ gtk_grid_attach (GTK_GRID (impl->save_widgets_table), widget, 0, 0, 1, 1);
gtk_widget_show (widget);
/* Location entry */
location_entry_create (impl);
- gtk_table_attach (GTK_TABLE (impl->save_widgets_table), impl->location_entry,
- 1, 2, 0, 1,
- GTK_EXPAND | GTK_FILL, 0,
- 0, 0);
+ gtk_widget_set_hexpand (impl->location_entry, TRUE);
+ gtk_grid_attach (GTK_GRID (impl->save_widgets_table), impl->location_entry, 1, 0, 1, 1);
gtk_widget_show (impl->location_entry);
gtk_label_set_mnemonic_widget (GTK_LABEL (widget), impl->location_entry);
@@ -4451,10 +4572,7 @@ save_widgets_create (GtkFileChooserDefault *impl)
impl->save_folder_label = gtk_label_new (NULL);
gtk_widget_set_halign (impl->save_folder_label, GTK_ALIGN_START);
gtk_widget_set_valign (impl->save_folder_label, GTK_ALIGN_CENTER);
- gtk_table_attach (GTK_TABLE (impl->save_widgets_table), impl->save_folder_label,
- 0, 1, 1, 2,
- GTK_FILL, GTK_FILL,
- 0, 0);
+ gtk_grid_attach (GTK_GRID (impl->save_widgets_table), impl->save_folder_label, 0, 1, 1, 1);
gtk_widget_show (impl->save_folder_label);
impl->save_widgets = vbox;
@@ -5116,10 +5234,8 @@ restore_path_bar (GtkFileChooserDefault *impl)
else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
{
- gtk_table_attach (GTK_TABLE (impl->save_widgets_table), impl->browse_path_bar_hbox,
- 1, 2, 1, 2,
- GTK_EXPAND | GTK_FILL, GTK_FILL,
- 0, 0);
+ gtk_widget_set_hexpand (impl->browse_path_bar_hbox, TRUE);
+ gtk_grid_attach (GTK_GRID (impl->save_widgets_table), impl->browse_path_bar_hbox, 1, 1, 1, 1);
gtk_label_set_mnemonic_widget (GTK_LABEL (impl->save_folder_label), impl->browse_path_bar);
}
else
@@ -9299,7 +9415,6 @@ typedef struct
{
GtkFileChooserDefault *impl;
GList *items;
- guint needs_sorting : 1;
} RecentLoadData;
static void
@@ -9311,6 +9426,7 @@ recent_idle_cleanup (gpointer data)
gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
GTK_TREE_MODEL (impl->recent_model));
file_list_set_sort_column_ids (impl);
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->recent_model), MODEL_COL_MTIME, GTK_SORT_DESCENDING);
set_busy_cursor (impl, FALSE);
@@ -9320,16 +9436,6 @@ recent_idle_cleanup (gpointer data)
}
static gint
-recent_sort_mru (gconstpointer a,
- gconstpointer b)
-{
- GtkRecentInfo *info_a = (GtkRecentInfo *) a;
- GtkRecentInfo *info_b = (GtkRecentInfo *) b;
-
- return (gtk_recent_info_get_modified (info_b) - gtk_recent_info_get_modified (info_a));
-}
-
-static gint
get_recent_files_limit (GtkWidget *widget)
{
GtkSettings *settings;
@@ -9404,32 +9510,18 @@ recent_idle_load (gpointer data)
if (!impl->recent_manager)
return FALSE;
- /* first iteration: load all the items */
+ load_data->items = gtk_recent_manager_get_items (impl->recent_manager);
if (!load_data->items)
- {
- load_data->items = gtk_recent_manager_get_items (impl->recent_manager);
- if (!load_data->items)
- return FALSE;
-
- load_data->needs_sorting = TRUE;
-
- return TRUE;
- }
-
- /* second iteration: MRU sorting and clamping, and populating the model */
- if (load_data->needs_sorting)
- {
- load_data->items = g_list_sort (load_data->items, recent_sort_mru);
+ return FALSE;
- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
- populate_model_with_recent_items (impl, load_data->items);
- else
- populate_model_with_folders (impl, load_data->items);
+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
+ populate_model_with_recent_items (impl, load_data->items);
+ else
+ populate_model_with_folders (impl, load_data->items);
- g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL);
- g_list_free (load_data->items);
- load_data->items = NULL;
- }
+ g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL);
+ g_list_free (load_data->items);
+ load_data->items = NULL;
return FALSE;
}
@@ -9449,7 +9541,6 @@ recent_start_loading (GtkFileChooserDefault *impl)
load_data = g_new (RecentLoadData, 1);
load_data->impl = impl;
load_data->items = NULL;
- load_data->needs_sorting = TRUE;
/* begin lazy loading the recent files into the model */
impl->load_recent_id = gdk_threads_add_idle_full (G_PRIORITY_HIGH_IDLE + 30,
@@ -9969,6 +10060,7 @@ list_selection_changed (GtkTreeSelection *selection,
check_preview_change (impl);
bookmarks_check_add_sensitivity (impl);
+ check_copy_file_location_sensitivity (impl);
g_signal_emit_by_name (impl, "selection-changed", 0);
}