diff --git a/ChangeLog b/ChangeLog index 6a1fba209d7f3032806b821e2bbc22fc3b06a668..99b4b580b78be4c1bd1963deee02da076b60441b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2005-08-19 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-standard-view.{c,h}: Allow derived classes to add + custom actions to the user interface. + * thunar/thunar-standard-view-ui.xml, thunar/thunar-window-ui.xml: Add + support for custom view item actions. + * thunar/Makefile.am, thunar/thunar-icon-view-ui.xml, + thunar/thunar-icon-view.c: Add support to arrange items within the + icon view. + * thunar/thunar-file.h, thunar/thunar-local-file.c: Provide an emblem + for the desktop folder in regular file listings. + * thunar/thunar-icon-view.c(thunar_icon_view_init): Add 3 pixel padding + in vertical direction to the icon cell, to allow better placement + of the emblems. + * thunar/thunar-icon-renderer.c(thunar_icon_renderer_render): Improve + the emblem placement and drawing code to work-around issues with + most icon themes, that don't provide emblems in the appropriate + sizes. + 2005-08-19 Benedikt Meurer <benny@xfce.org> * thunar/thunar-statusbar.c: Drop the dependency on X11. diff --git a/thunar/Makefile.am b/thunar/Makefile.am index 638aaae886086cf20146fc303d4fe68ee08aecba..0d90f49f3e17a7626adba5403c2b85380fb42228 100644 --- a/thunar/Makefile.am +++ b/thunar/Makefile.am @@ -44,6 +44,7 @@ Thunar_SOURCES = \ thunar-icon-renderer.h \ thunar-icon-view.c \ thunar-icon-view.h \ + thunar-icon-view-ui.h \ thunar-launcher.c \ thunar-launcher.h \ thunar-list-model.c \ @@ -121,17 +122,22 @@ clean-local: if MAINTAINER_MODE DISTCLEANFILES = \ thunar-fallback-icon.c \ + thunar-icon-view-ui.h \ thunar-standard-view-ui.h \ thunar-window-ui.h BUILT_SOURCES = \ thunar-fallback-icon.c \ + thunar-icon-view-ui.h \ thunar-standard-view-ui.h \ thunar-window-ui.h thunar-fallback-icon.c: $(srcdir)/thunar-fallback-icon.png Makefile (echo "#include <thunar/thunar-fallback-icon.h>" && gdk-pixbuf-csource --extern --raw --stream --name=thunar_fallback_icon $(srcdir)/thunar-fallback-icon.png) > thunar-fallback-icon.c +thunar-icon-view-ui.h: Makefile $(srcdir)/thunar-icon-view-ui.xml + exo-csource --static --name=thunar_icon_view_ui $(srcdir)/thunar-icon-view-ui.xml > thunar-icon-view-ui.h + thunar-standard-view-ui.h: Makefile $(srcdir)/thunar-standard-view-ui.xml exo-csource --static --name=thunar_standard_view_ui $(srcdir)/thunar-standard-view-ui.xml > thunar-standard-view-ui.h @@ -141,6 +147,7 @@ endif EXTRA_DIST = \ thunar-fallback-icon.png \ + thunar-icon-view-ui.xml \ thunar-standard-view-ui.xml \ thunar-window-ui.xml diff --git a/thunar/thunar-file.h b/thunar/thunar-file.h index 7c01e87ed0ad37b701052a499b2f7c61ae710e99..b23adfebc0e97ad7151b22910385744d875d6fbe 100644 --- a/thunar/thunar-file.h +++ b/thunar/thunar-file.h @@ -60,6 +60,7 @@ typedef enum #define THUNAR_FILE_EMBLEM_NAME_SYMBOLIC_LINK "emblem-symbolic-link" #define THUNAR_FILE_EMBLEM_NAME_CANT_READ "emblem-noread" #define THUNAR_FILE_EMBLEM_NAME_CANT_WRITE "emblem-nowrite" +#define THUNAR_FILE_EMBLEM_NAME_DESKTOP "emblem-desktop" struct _ThunarFileClass { diff --git a/thunar/thunar-icon-renderer.c b/thunar/thunar-icon-renderer.c index 1c5115e5a72019ec7efe4f357da721204019736f..80792b21fb0140d4dff3e16af7b916d5a33e1d23 100644 --- a/thunar/thunar-icon-renderer.c +++ b/thunar/thunar-icon-renderer.c @@ -288,11 +288,13 @@ thunar_icon_renderer_render (GtkCellRenderer *renderer, { ThunarIconRenderer *icon_renderer = THUNAR_ICON_RENDERER (renderer); ThunarIconFactory *icon_factory; + GdkRectangle emblem_area; GdkRectangle icon_area; GdkRectangle draw_area; GtkStateType state; - GdkPixbuf *temp; + GdkPixbuf *emblem; GdkPixbuf *icon; + GdkPixbuf *temp; GList *emblems; GList *lp; @@ -357,29 +359,41 @@ thunar_icon_renderer_render (GtkCellRenderer *renderer, if (emblems != NULL) { /* lookup the first emblem icon that exits in the icon theme */ - for (icon = NULL, lp = emblems; lp != NULL; lp = lp->next) - { - icon = thunar_icon_factory_load_icon (icon_factory, lp->data, icon_renderer->size, NULL, FALSE); - if (G_LIKELY (icon != NULL)) - break; - } + for (emblem = NULL, lp = emblems; emblem == NULL && lp != NULL; lp = lp->next) + emblem = thunar_icon_factory_load_icon (icon_factory, lp->data, icon_renderer->size, NULL, FALSE); - if (G_LIKELY (icon != NULL)) + if (G_LIKELY (emblem != NULL)) { - icon_area.width = gdk_pixbuf_get_width (icon); - icon_area.height = gdk_pixbuf_get_height (icon); - icon_area.x = cell_area->x + (cell_area->width - renderer->xpad ) / 2; - icon_area.y = cell_area->y + (cell_area->height - renderer->ypad) / 2; + /* determine the dimensions of the emblem */ + emblem_area.width = gdk_pixbuf_get_width (emblem); + emblem_area.height = gdk_pixbuf_get_height (emblem); - if (gdk_rectangle_intersect (expose_area, &icon_area, &draw_area)) + /* shrink insane emblems */ + if (G_UNLIKELY (MAX (emblem_area.width, emblem_area.height) > (2 * icon_renderer->size) / 3)) { - gdk_draw_pixbuf (window, widget->style->black_gc, icon, - draw_area.x - icon_area.x, draw_area.y - icon_area.y, + temp = exo_gdk_pixbuf_scale_ratio (emblem, (2 * icon_renderer->size) / 3); + emblem_area.width = gdk_pixbuf_get_width (temp); + emblem_area.height = gdk_pixbuf_get_height (temp); + g_object_unref (G_OBJECT (emblem)); + emblem = temp; + } + + /* determine a good position for the emblem */ + emblem_area.x = MIN (icon_area.x + icon_area.width - emblem_area.width / 2, + cell_area->x + cell_area->width - emblem_area.width); + emblem_area.y = MIN (icon_area.y + icon_area.height - emblem_area.height / 2, + cell_area->y + cell_area->height -emblem_area.height); + + /* render the emblem */ + if (gdk_rectangle_intersect (expose_area, &emblem_area, &draw_area)) + { + gdk_draw_pixbuf (window, widget->style->black_gc, emblem, + draw_area.x - emblem_area.x, draw_area.y - emblem_area.y, draw_area.x, draw_area.y, draw_area.width, draw_area.height, GDK_RGB_DITHER_NORMAL, 0, 0); } - g_object_unref (G_OBJECT (icon)); + g_object_unref (G_OBJECT (emblem)); } g_list_free (emblems); diff --git a/thunar/thunar-icon-view-ui.xml b/thunar/thunar-icon-view-ui.xml new file mode 100644 index 0000000000000000000000000000000000000000..fe32c00aca8c8dad4f5077eba8f7e238e0b5233b --- /dev/null +++ b/thunar/thunar-icon-view-ui.xml @@ -0,0 +1,45 @@ +<ui> + + <!-- + $Id$ + + Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> + + Thunar icon view user interface description file. Do NOT + simply edit this file if you don't know how the whole system + works, because it's too easy to break something. + --> + + <menubar name="main-menu"> + <menu action="view-menu" name="view-menu"> + <placeholder name="placeholder-view-items-actions"> + <menu action="arrange-items-menu" name="arrange-items-menu"> + <menuitem action="sort-by-name" name="sort-by-name" /> + <menuitem action="sort-by-size" name="sort-by-size" /> + <menuitem action="sort-by-type" name="sort-by-type" /> + <menuitem action="sort-by-mtime" name="sort-by-mtime" /> + <separator /> + <menuitem action="sort-ascending" name="sort-ascending" /> + <menuitem action="sort-descending" name="sort-descending" /> + </menu> + </placeholder> + </menu> + </menubar> + + <popup action="folder-context-menu" name="folder-context-menu"> + <placeholder name="placeholder-view-items-actions"> + <menu action="arrange-items-menu" name="arrange-items-menu"> + <menuitem action="sort-by-name" name="sort-by-name" /> + <menuitem action="sort-by-size" name="sort-by-size" /> + <menuitem action="sort-by-type" name="sort-by-type" /> + <menuitem action="sort-by-mtime" name="sort-by-mtime" /> + <separator /> + <menuitem action="sort-ascending" name="sort-ascending" /> + <menuitem action="sort-descending" name="sort-descending" /> + </menu> + </placeholder> + </popup> + +</ui> + +<!-- vi: set ts=2 sw=2 et ai nocindent syntax=xml: --> diff --git a/thunar/thunar-icon-view.c b/thunar/thunar-icon-view.c index 93ee70cb155220f9963f888a7dffcb4b2e4241e4..1c93f2b83e24984d0715446c4b5e2c01cccbca0a 100644 --- a/thunar/thunar-icon-view.c +++ b/thunar/thunar-icon-view.c @@ -25,27 +25,37 @@ #include <thunar/thunar-icon-renderer.h> #include <thunar/thunar-icon-view.h> +#include <thunar/thunar-icon-view-ui.h> #include <thunar/thunar-text-renderer.h> -static void thunar_icon_view_class_init (ThunarIconViewClass *klass); -static void thunar_icon_view_init (ThunarIconView *icon_view); -static AtkObject *thunar_icon_view_get_accessible (GtkWidget *widget); -static GList *thunar_icon_view_get_selected_items (ThunarStandardView *standard_view); -static void thunar_icon_view_select_all (ThunarStandardView *standard_view); -static void thunar_icon_view_unselect_all (ThunarStandardView *standard_view); -static void thunar_icon_view_select_path (ThunarStandardView *standard_view, - GtkTreePath *path); -static gboolean thunar_icon_view_button_press_event (ExoIconView *view, - GdkEventButton *event, - ThunarIconView *icon_view); -static gboolean thunar_icon_view_key_press_event (ExoIconView *view, - GdkEventKey *event, - ThunarIconView *icon_view); -static void thunar_icon_view_item_activated (ExoIconView *view, - GtkTreePath *path, - ThunarIconView *icon_view); +static void thunar_icon_view_class_init (ThunarIconViewClass *klass); +static void thunar_icon_view_init (ThunarIconView *icon_view); +static AtkObject *thunar_icon_view_get_accessible (GtkWidget *widget); +static void thunar_icon_view_connect_ui_manager (ThunarStandardView *standard_view, + GtkUIManager *ui_manager); +static void thunar_icon_view_disconnect_ui_manager (ThunarStandardView *standard_view, + GtkUIManager *ui_manager); +static GList *thunar_icon_view_get_selected_items (ThunarStandardView *standard_view); +static void thunar_icon_view_select_all (ThunarStandardView *standard_view); +static void thunar_icon_view_unselect_all (ThunarStandardView *standard_view); +static void thunar_icon_view_select_path (ThunarStandardView *standard_view, + GtkTreePath *path); +static void thunar_icon_view_action_sort (GtkAction *action, + GtkAction *current, + ThunarStandardView *standard_view); +static gboolean thunar_icon_view_button_press_event (ExoIconView *view, + GdkEventButton *event, + ThunarIconView *icon_view); +static gboolean thunar_icon_view_key_press_event (ExoIconView *view, + GdkEventKey *event, + ThunarIconView *icon_view); +static void thunar_icon_view_item_activated (ExoIconView *view, + GtkTreePath *path, + ThunarIconView *icon_view); +static void thunar_icon_view_sort_column_changed (GtkTreeSortable *sortable, + ThunarIconView *icon_view); @@ -57,6 +67,29 @@ struct _ThunarIconViewClass struct _ThunarIconView { ThunarStandardView __parent__; + + gint ui_merge_id; +}; + + + +static const GtkActionEntry action_entries[] = +{ + { "arrange-items-menu", NULL, N_ ("Arran_ge Items"), NULL, NULL, NULL, }, +}; + +static const GtkRadioActionEntry column_action_entries[] = +{ + { "sort-by-name", NULL, N_ ("Sort By _Name"), NULL, N_ ("Keep items sorted by their name in rows"), THUNAR_LIST_MODEL_COLUMN_NAME, }, + { "sort-by-size", NULL, N_ ("Sort By _Size"), NULL, N_ ("Keep items sorted by their size in rows"), THUNAR_LIST_MODEL_COLUMN_SIZE, }, + { "sort-by-type", NULL, N_ ("Sort By _Type"), NULL, N_ ("Keep items sorted by their type in rows"), THUNAR_LIST_MODEL_COLUMN_TYPE, }, + { "sort-by-mtime", NULL, N_ ("Sort By Modification _Date"), NULL, N_ ("Keep items sorted by their modification date in rows"), THUNAR_LIST_MODEL_COLUMN_DATE_MODIFIED, }, +}; + +static const GtkRadioActionEntry order_action_entries[] = +{ + { "sort-ascending", NULL, N_ ("_Ascending"), NULL, N_ ("Sort items in ascending order"), GTK_SORT_ASCENDING, }, + { "sort-descending", NULL, N_ ("_Descending"), NULL, N_ ("Sort items in descending order"), GTK_SORT_DESCENDING, }, }; @@ -75,6 +108,8 @@ thunar_icon_view_class_init (ThunarIconViewClass *klass) gtkwidget_class->get_accessible = thunar_icon_view_get_accessible; thunarstandard_view_class = THUNAR_STANDARD_VIEW_CLASS (klass); + thunarstandard_view_class->connect_ui_manager = thunar_icon_view_connect_ui_manager; + thunarstandard_view_class->disconnect_ui_manager = thunar_icon_view_disconnect_ui_manager; thunarstandard_view_class->get_selected_items = thunar_icon_view_get_selected_items; thunarstandard_view_class->select_all = thunar_icon_view_select_all; thunarstandard_view_class->unselect_all = thunar_icon_view_unselect_all; @@ -105,6 +140,7 @@ thunar_icon_view_init (ThunarIconView *icon_view) renderer = g_object_new (THUNAR_TYPE_ICON_RENDERER, "follow-state", TRUE, "size", 48, + "ypad", 3u, NULL); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (view), renderer, FALSE); gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (view), renderer, "file", THUNAR_LIST_MODEL_COLUMN_FILE); @@ -118,6 +154,22 @@ thunar_icon_view_init (ThunarIconView *icon_view) NULL); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (view), renderer, TRUE); gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (view), renderer, "text", THUNAR_LIST_MODEL_COLUMN_NAME); + + /* setup the icon view actions */ + gtk_action_group_add_actions (THUNAR_STANDARD_VIEW (icon_view)->action_group, + action_entries, G_N_ELEMENTS (action_entries), + GTK_WIDGET (icon_view)); + gtk_action_group_add_radio_actions (THUNAR_STANDARD_VIEW (icon_view)->action_group, column_action_entries, + G_N_ELEMENTS (column_action_entries), THUNAR_LIST_MODEL_COLUMN_NAME, + G_CALLBACK (thunar_icon_view_action_sort), icon_view); + gtk_action_group_add_radio_actions (THUNAR_STANDARD_VIEW (icon_view)->action_group, order_action_entries, + G_N_ELEMENTS (order_action_entries), GTK_SORT_ASCENDING, + G_CALLBACK (thunar_icon_view_action_sort), icon_view); + + /* we need to listen to sort column changes to sync the menu items */ + g_signal_connect (G_OBJECT (THUNAR_STANDARD_VIEW (icon_view)->model), "sort-column-changed", + G_CALLBACK (thunar_icon_view_sort_column_changed), icon_view); + thunar_icon_view_sort_column_changed (GTK_TREE_SORTABLE (THUNAR_STANDARD_VIEW (icon_view)->model), icon_view); } @@ -142,6 +194,33 @@ thunar_icon_view_get_accessible (GtkWidget *widget) +static void +thunar_icon_view_connect_ui_manager (ThunarStandardView *standard_view, + GtkUIManager *ui_manager) +{ + ThunarIconView *icon_view = THUNAR_ICON_VIEW (standard_view); + GError *error = NULL; + + icon_view->ui_merge_id = gtk_ui_manager_add_ui_from_string (ui_manager, thunar_icon_view_ui, + thunar_icon_view_ui_length, &error); + if (G_UNLIKELY (icon_view->ui_merge_id == 0)) + { + g_error ("Failed to merge ThunarIconView menus: %s", error->message); + g_error_free (error); + } +} + + + +static void +thunar_icon_view_disconnect_ui_manager (ThunarStandardView *standard_view, + GtkUIManager *ui_manager) +{ + gtk_ui_manager_remove_ui (ui_manager, THUNAR_ICON_VIEW (standard_view)->ui_merge_id); +} + + + static GList* thunar_icon_view_get_selected_items (ThunarStandardView *standard_view) { @@ -178,6 +257,28 @@ thunar_icon_view_select_path (ThunarStandardView *standard_view, +static void +thunar_icon_view_action_sort (GtkAction *action, + GtkAction *current, + ThunarStandardView *standard_view) +{ + GtkSortType order; + gint column; + + /* query the new sort column id */ + action = gtk_action_group_get_action (standard_view->action_group, "sort-by-name"); + column = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); + + /* query the new sort order */ + action = gtk_action_group_get_action (standard_view->action_group, "sort-ascending"); + order = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); + + /* apply the new settings */ + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (standard_view->model), column, order); +} + + + static gboolean thunar_icon_view_button_press_event (ExoIconView *view, GdkEventButton *event, @@ -186,18 +287,27 @@ thunar_icon_view_button_press_event (ExoIconView *view, GtkTreePath *path; /* open the context menu on right clicks */ - if (event->type == GDK_BUTTON_PRESS && event->button == 3 - && exo_icon_view_get_item_at_pos (view, event->x, event->y, &path, NULL)) + if (event->type == GDK_BUTTON_PRESS && event->button == 3) { - /* select the path on which the user clicked if not selected yet */ - if (!exo_icon_view_path_is_selected (view, path)) + if (exo_icon_view_get_item_at_pos (view, event->x, event->y, &path, NULL)) { - /* we don't unselect all other items if Control is active */ - if ((event->state & GDK_CONTROL_MASK) == 0) - exo_icon_view_unselect_all (view); - exo_icon_view_select_path (view, path); + /* select the path on which the user clicked if not selected yet */ + if (!exo_icon_view_path_is_selected (view, path)) + { + /* we don't unselect all other items if Control is active */ + if ((event->state & GDK_CONTROL_MASK) == 0) + exo_icon_view_unselect_all (view); + exo_icon_view_select_path (view, path); + } + gtk_tree_path_free (path); + } + else if ((event->state & GDK_CONTROL_MASK) == 0) + { + /* user clicked on an empty area, so we unselect everything + * to make sure that the folder context menu is opened. + */ + exo_icon_view_unselect_all (view); } - gtk_tree_path_free (path); /* open the context menu */ thunar_standard_view_context_menu (THUNAR_STANDARD_VIEW (icon_view), event->button, event->time); @@ -248,6 +358,28 @@ thunar_icon_view_item_activated (ExoIconView *view, +static void +thunar_icon_view_sort_column_changed (GtkTreeSortable *sortable, + ThunarIconView *icon_view) +{ + GtkSortType order; + GtkAction *action; + gint column; + + if (gtk_tree_sortable_get_sort_column_id (sortable, &column, &order)) + { + /* apply the new sort column */ + action = gtk_action_group_get_action (THUNAR_STANDARD_VIEW (icon_view)->action_group, "sort-by-name"); + exo_gtk_radio_action_set_current_value (GTK_RADIO_ACTION (action), column); + + /* apply the new sort order */ + action = gtk_action_group_get_action (THUNAR_STANDARD_VIEW (icon_view)->action_group, "sort-ascending"); + exo_gtk_radio_action_set_current_value (GTK_RADIO_ACTION (action), order); + } +} + + + /** * thunar_icon_view_new: * diff --git a/thunar/thunar-local-file.c b/thunar/thunar-local-file.c index e446a7352c9875727e25ef4163dc19846857ad13..41e91115a79b3f30ccce47d894b832bd9a33f3ae 100644 --- a/thunar/thunar-local-file.c +++ b/thunar/thunar-local-file.c @@ -362,8 +362,17 @@ thunar_local_file_get_emblem_names (ThunarFile *file) { ThunarLocalFile *local_file = THUNAR_LOCAL_FILE (file); ThunarVfsInfo *info = local_file->info; + ThunarVfsURI *parent_uri; GList *emblems = NULL; + if (G_UNLIKELY (exo_str_is_equal (info->display_name, "Desktop"))) + { + parent_uri = thunar_vfs_uri_parent (info->uri); + if (thunar_vfs_uri_is_home (parent_uri)) + emblems = g_list_prepend (emblems, THUNAR_FILE_EMBLEM_NAME_DESKTOP); + thunar_vfs_uri_unref (parent_uri); + } + if ((info->flags & THUNAR_VFS_FILE_FLAGS_SYMLINK) != 0) emblems = g_list_prepend (emblems, THUNAR_FILE_EMBLEM_NAME_SYMBOLIC_LINK); diff --git a/thunar/thunar-standard-view-ui.xml b/thunar/thunar-standard-view-ui.xml index 374fa3dc520a96579fc852934684ce010c1af977..2f6e6394dbc749d5947438ff958a4b1e342a5744 100644 --- a/thunar/thunar-standard-view-ui.xml +++ b/thunar/thunar-standard-view-ui.xml @@ -53,6 +53,12 @@ <menuitem action="properties" name="properties" /> </popup> + <popup action="folder-context-menu" name="folder-context-menu"> + <placeholder name="placeholder-view-items-actions" /> + <separator /> + <menuitem action="paste" name="paste" /> + </popup> + </ui> <!-- vi: set ts=2 sw=2 et ai nocindent syntax=xml: --> diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c index a00bb2f72f8fdf7883ac896b3bbb4ff71899518e..3af9ba54c940c913379fc237bfad0068471ddec2 100644 --- a/thunar/thunar-standard-view.c +++ b/thunar/thunar-standard-view.c @@ -111,7 +111,8 @@ struct _ThunarStandardViewPrivate static const GtkActionEntry action_entries[] = { - { "file-context-menu", NULL, N_ ("Context Menu"), NULL, NULL, NULL, }, + { "file-context-menu", NULL, N_ ("File Context Menu"), NULL, NULL, NULL, }, + { "folder-context-menu", NULL, N_ ("Folder Context Menu"), NULL, NULL, NULL, }, { "properties", GTK_STOCK_PROPERTIES, N_ ("_Properties"), "<alt>Return", N_ ("View the properties of the selected item"), G_CALLBACK (thunar_standard_view_action_properties), }, { "copy", GTK_STOCK_COPY, N_ ("_Copy files"), NULL, NULL, G_CALLBACK (thunar_standard_view_action_copy), }, { "cut", GTK_STOCK_CUT, N_ ("Cu_t files"), NULL, NULL, G_CALLBACK (thunar_standard_view_action_cut), }, @@ -199,6 +200,9 @@ thunar_standard_view_class_init (ThunarStandardViewClass *klass) gtkwidget_class->realize = thunar_standard_view_realize; gtkwidget_class->unrealize = thunar_standard_view_unrealize; + klass->connect_ui_manager = (gpointer) exo_noop; + klass->disconnect_ui_manager = (gpointer) exo_noop; + g_object_class_override_property (gobject_class, PROP_CURRENT_DIRECTORY, "current-directory"); @@ -627,6 +631,9 @@ thunar_standard_view_set_ui_manager (ThunarView *view, /* drop our action group from the previous UI manager */ gtk_ui_manager_remove_action_group (standard_view->ui_manager, standard_view->action_group); + /* unmerge the ui controls from derived classes */ + (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->disconnect_ui_manager) (standard_view, standard_view->ui_manager); + /* unmerge our ui controls from the previous UI manager */ gtk_ui_manager_remove_ui (standard_view->ui_manager, standard_view->ui_merge_id); @@ -654,6 +661,9 @@ thunar_standard_view_set_ui_manager (ThunarView *view, g_error ("Failed to merge ThunarStandardView menus: %s", error->message); g_error_free (error); } + + /* merge the ui controls from derived classes */ + (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->connect_ui_manager) (standard_view, ui_manager); } /* let others know that we have a new manager */ @@ -941,7 +951,7 @@ thunar_standard_view_loading_unbound (gpointer user_data) * @time : the event time. * * Invoked by derived classes (and only by derived classes!) whenever the user - * requests to open a context menu, e.g. by right-clicking on a file or by + * requests to open a context menu, e.g. by right-clicking on a file/folder or by * using one of the context menu shortcuts. **/ void @@ -951,12 +961,21 @@ thunar_standard_view_context_menu (ThunarStandardView *standard_view, { GMainLoop *loop; GtkWidget *menu; + GList *selected_items; guint id; g_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - /* take a reference on the file context menu */ - menu = gtk_ui_manager_get_widget (standard_view->ui_manager, "/file-context-menu"); + /* check if we need to popup the file or the folder context menu */ + selected_items = THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_selected_items (standard_view); + if (G_LIKELY (selected_items != NULL)) + menu = gtk_ui_manager_get_widget (standard_view->ui_manager, "/file-context-menu"); + else + menu = gtk_ui_manager_get_widget (standard_view->ui_manager, "/folder-context-menu"); + g_list_foreach (selected_items, (GFunc) gtk_tree_path_free, NULL); + g_list_free (selected_items); + + /* take a reference on the context menu */ g_object_ref (G_OBJECT (menu)); gtk_object_sink (GTK_OBJECT (menu)); diff --git a/thunar/thunar-standard-view.h b/thunar/thunar-standard-view.h index d929201445c2af7783893d2fee96519ad91dacec..a149f22ac1a688be21c2d7502807c85a30b02243 100644 --- a/thunar/thunar-standard-view.h +++ b/thunar/thunar-standard-view.h @@ -41,19 +41,27 @@ struct _ThunarStandardViewClass { GtkScrolledWindowClass __parent__; + /* Called by the ThunarStandardView class to let derived classes + * connect to and disconnect from the UI manager. + */ + void (*connect_ui_manager) (ThunarStandardView *standard_view, + GtkUIManager *ui_manager); + void (*disconnect_ui_manager) (ThunarStandardView *standard_view, + GtkUIManager *ui_manager); + /* Returns the list of currently selected GtkTreePath's, where * both the list and the items are owned by the caller. */ - GList *(*get_selected_items) (ThunarStandardView *standard_view); + GList *(*get_selected_items) (ThunarStandardView *standard_view); /* Selects all items in the view */ - void (*select_all) (ThunarStandardView *standard_view); + void (*select_all) (ThunarStandardView *standard_view); /* Unselects all items in the view */ - void (*unselect_all) (ThunarStandardView *standard_view); + void (*unselect_all) (ThunarStandardView *standard_view); /* Selects the given item */ - void (*select_path) (ThunarStandardView *standard_view, - GtkTreePath *path); + void (*select_path) (ThunarStandardView *standard_view, + GtkTreePath *path); }; struct _ThunarStandardView diff --git a/thunar/thunar-window-ui.xml b/thunar/thunar-window-ui.xml index 2d7bf30d59b36eaf7090225de585195dfc8cd91d..92c83f6abaea6c659838c3940ae69b98d47b05c9 100644 --- a/thunar/thunar-window-ui.xml +++ b/thunar/thunar-window-ui.xml @@ -34,10 +34,10 @@ <menuitem action="view-location-bar-entry" name="view-location-bar-entry" /> <menuitem action="view-location-bar-hidden" name="view-location-bar-hidden" /> </menu> - <separator /> - <placeholder name="placeholder-view-display-preferences" /> + <separator /> + <placeholder name="placeholder-view-items-actions" /> </menu> <menu action="go-menu" name="go-menu">