Commit f69fe955 authored by Paolo Bacchilega's avatar Paolo Bacchilega
Browse files

added a gear menu and a manager to modify it dynamically

parent 78b9ba32
......@@ -122,6 +122,11 @@ static const char *browser_vfs_ui_info =
"</ui>";
static const GthMenuEntry browser_vfs_entries[] = {
{ N_("Create _Folder"), "win.create-folder", "<Ctrl><Shift>N" }
};
static const char *folder_popup_ui_info =
"<ui>"
" <popup name='FolderListPopup'>"
......@@ -701,6 +706,7 @@ file_manager_update_ui (BrowserData *data,
data->browser_merge_id = 0;
}
#if 0
if (GTH_IS_FILE_SOURCE_VFS (gth_browser_get_location_source (browser))
&& (gth_window_get_current_page (GTH_WINDOW (browser)) == GTH_BROWSER_PAGE_BROWSER))
{
......@@ -718,6 +724,21 @@ file_manager_update_ui (BrowserData *data,
gtk_ui_manager_remove_ui (gth_browser_get_ui_manager (browser), data->browser_vfs_merge_id);
data->browser_vfs_merge_id = 0;
}
#endif
if (GTH_IS_FILE_SOURCE_VFS (gth_browser_get_location_source (browser))
&& (gth_window_get_current_page (GTH_WINDOW (browser)) == GTH_BROWSER_PAGE_BROWSER))
{
if (data->browser_vfs_merge_id == 0) {
data->browser_vfs_merge_id = gth_menu_manager_append_entries (gth_browser_get_menu_manager (browser, GTH_BROWSER_MENU_MANAGER_GEARS_FOLDER_ACTIONS),
browser_vfs_entries,
G_N_ELEMENTS (browser_vfs_entries));
}
}
else if (data->browser_vfs_merge_id != 0) {
gth_menu_manager_remove_entries (gth_browser_get_menu_manager (browser, GTH_BROWSER_MENU_MANAGER_GEARS_FOLDER_ACTIONS), data->browser_vfs_merge_id);
data->browser_vfs_merge_id = 0;
}
}
......
......@@ -100,6 +100,16 @@ search__gth_browser_construct_cb (GthBrowser *browser)
g_error_free (error);
}
{
GtkWidget *button;
button = gtk_button_new_from_icon_name ("edit-find-symbolic", GTK_ICON_SIZE_MENU);
gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (button), FALSE);
gtk_activatable_set_related_action (GTK_ACTIVATABLE (button), gtk_action_group_get_action (data->find_action, "Edit_Find"));
gtk_widget_show (button);
gtk_box_pack_start (GTK_BOX (gth_browser_get_headerbar_section (browser, GTH_BROWSER_HEADER_SECTION_BROWSER_COMMANDS)), button, FALSE, FALSE, 0);
}
g_object_set_data_full (G_OBJECT (browser), BROWSER_DATA_KEY, data, (GDestroyNotify) browser_data_free);
}
......
......@@ -84,6 +84,7 @@ PUBLIC_HEADER_FILES = \
gth-main.h \
gth-menu-action.h \
gth-menu-button.h \
gth-menu-manager.h \
gth-metadata.h \
gth-metadata-chooser.h \
gth-metadata-provider.h \
......@@ -226,6 +227,7 @@ gthumb_SOURCES = \
gth-main-default-types.c \
gth-menu-action.c \
gth-menu-button.c \
gth-menu-manager.c \
gth-metadata.c \
gth-metadata-chooser.c \
gth-metadata-provider.c \
......
......@@ -467,3 +467,73 @@ gth_browser_activate_action_help_shortcuts (GtkAction *action,
{
show_help_dialog (GTK_WINDOW (data), "gthumb-shortcuts");
}
/* -- GAction callbacks -- */
void
gth_browser_activate_save (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GthBrowser *browser = user_data;
GtkWidget *viewer_page;
viewer_page = gth_browser_get_viewer_page (browser);
if (viewer_page == NULL)
return;
gth_viewer_page_save (GTH_VIEWER_PAGE (viewer_page), NULL, NULL, browser);
}
void
gth_browser_activate_save_as (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GthBrowser *browser = user_data;
GtkWidget *viewer_page;
viewer_page = gth_browser_get_viewer_page (browser);
if (viewer_page == NULL)
return;
gth_viewer_page_save_as (GTH_VIEWER_PAGE (viewer_page), NULL, NULL);
}
void
gth_browser_activate_revert_to_saved (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GthBrowser *browser = user_data;
GtkWidget *viewer_page;
viewer_page = gth_browser_get_viewer_page (browser);
if (viewer_page == NULL)
return;
gth_viewer_page_revert (GTH_VIEWER_PAGE (viewer_page));
}
void
gth_browser_activate_close (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GthBrowser *browser = user_data;
gth_window_close (GTH_WINDOW (browser));
}
void
gth_browser_activate_quit (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
}
......@@ -25,6 +25,7 @@
#include <gtk/gtk.h>
#define DEFINE_ACTION(x) void x (GtkAction *action, gpointer data);
#define ACTION_CALLBACK(x) void x (GSimpleAction *action, GVariant *parameter, gpointer user_data);
DEFINE_ACTION(gth_browser_activate_action_bookmarks_add)
DEFINE_ACTION(gth_browser_activate_action_bookmarks_edit)
......@@ -68,4 +69,10 @@ DEFINE_ACTION(gth_browser_activate_action_browser_tools)
DEFINE_ACTION(gth_browser_activate_action_viewer_tools)
DEFINE_ACTION(gth_browser_activate_action_view_shrink_wrap)
ACTION_CALLBACK (gth_browser_activate_save)
ACTION_CALLBACK (gth_browser_activate_save_as)
ACTION_CALLBACK (gth_browser_activate_revert_to_saved)
ACTION_CALLBACK (gth_browser_activate_close)
ACTION_CALLBACK (gth_browser_activate_quit)
#endif /* GTH_BROWSER_ACTIONS_CALLBACK_H */
......@@ -27,6 +27,15 @@
#include "gth-stock.h"
#include "gtk-utils.h"
static const GActionEntry gth_browser_actions[] = {
{ "save", gth_browser_activate_save },
{ "save-as", gth_browser_activate_save_as },
{ "revert-to-saved", gth_browser_activate_revert_to_saved },
{ "close", gth_browser_activate_close },
{ "quit", gth_browser_activate_quit },
};
static GthActionEntryExt gth_browser_action_entries[] = {
{ "FileMenu", NULL, N_("_File") },
{ "EditMenu", NULL, N_("_Edit") },
......
......@@ -119,6 +119,7 @@ struct _GthBrowserPrivate {
GtkWidget *list_extra_widget;
GtkWidget *file_properties;
GtkWidget *header_sections[GTH_BROWSER_N_HEADER_SECTIONS];
GthMenuManager *menu_managers[GTH_BROWSER_N_MENU_MANAGERS];
GtkWidget *thumbnail_list;
......@@ -306,6 +307,18 @@ monitor_event_data_unref (MonitorEventData *monitor_data)
/* -- gth_browser -- */
static void
_gth_browser_enable_action (GthBrowser *browser,
const char *action_name,
gboolean enabled)
{
GAction *action;
action = g_action_map_lookup_action (G_ACTION_MAP (browser), action_name);
g_object_set (action, "enabled", enabled, NULL);
}
static void
_gth_browser_set_action_sensitive (GthBrowser *browser,
const char *action_name,
......@@ -631,6 +644,10 @@ gth_browser_update_sensitivity (GthBrowser *browser)
_gth_browser_set_action_sensitive (browser, "View_Sidebar", gth_window_get_current_page (GTH_WINDOW (browser)) == GTH_BROWSER_PAGE_BROWSER);
_gth_browser_set_action_sensitive (browser, "View_Reload", gth_window_get_current_page (GTH_WINDOW (browser)) == GTH_BROWSER_PAGE_BROWSER);
_gth_browser_enable_action (browser, "save", viewer_can_save && modified);
_gth_browser_enable_action (browser, "save-as", viewer_can_save);
_gth_browser_enable_action (browser, "revert-to-saved", viewer_can_save && modified);
gth_sidebar_update_sensitivity (GTH_SIDEBAR (browser->priv->file_properties));
if (browser->priv->viewer_page != NULL)
......@@ -2715,7 +2732,10 @@ static void
gth_browser_finalize (GObject *object)
{
GthBrowser *browser = GTH_BROWSER (object);
int i;
for (i = 0; i < GTH_BROWSER_N_MENU_MANAGERS; i++)
_g_object_unref (browser->priv->menu_managers[i]);
browser_state_free (&browser->priv->state);
_g_object_unref (browser->priv->browser_settings);
_g_object_unref (browser->priv->messages_settings);
......@@ -4395,6 +4415,9 @@ gth_browser_init (GthBrowser *browser)
browser->priv->desktop_interface_settings = g_settings_new (GNOME_DESKTOP_INTERFACE_SCHEMA);
browser->priv->file_properties_on_the_right = g_settings_get_boolean (browser->priv->browser_settings, PREF_BROWSER_PROPERTIES_ON_THE_RIGHT);
for (i = 0; i < GTH_BROWSER_N_MENU_MANAGERS; i++)
browser->priv->menu_managers[i] = NULL;
browser_state_init (&browser->priv->state);
/* find a suitable size for the window */
......@@ -4601,6 +4624,25 @@ gth_browser_init (GthBrowser *browser)
gtk_header_bar_pack_end (GTK_HEADER_BAR (header_bar), browser->priv->header_sections[GTH_BROWSER_HEADER_SECTION_VIEWER_TOOLS]);
gtk_header_bar_pack_end (GTK_HEADER_BAR (header_bar), browser->priv->header_sections[GTH_BROWSER_HEADER_SECTION_VIEWER_PROPERTIES]);
/* gears menu */
{
GtkBuilder *builder;
GMenuModel *menu;
GtkWidget *gears_menu_button;
builder = _gtk_builder_new_from_resource ("gears-menu.ui");
menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
gears_menu_button = gtk_menu_button_new ();
gtk_container_add (GTK_CONTAINER (gears_menu_button), gtk_image_new_from_icon_name ("emblem-system-symbolic", GTK_ICON_SIZE_MENU));
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (gears_menu_button), menu);
gtk_widget_show_all (gears_menu_button);
gtk_header_bar_pack_end (GTK_HEADER_BAR (header_bar), gears_menu_button);
browser->priv->menu_managers[GTH_BROWSER_MENU_MANAGER_GEARS] = gth_menu_manager_new (G_MENU (menu));
browser->priv->menu_managers[GTH_BROWSER_MENU_MANAGER_GEARS_FOLDER_ACTIONS] = gth_menu_manager_new (G_MENU (gtk_builder_get_object (builder, "folder-actions")));
}
/* browser navigation */
button = gtk_button_new_from_icon_name ("go-previous-symbolic", GTK_ICON_SIZE_MENU);
......
......@@ -25,6 +25,7 @@
#include "gth-file-source.h"
#include "gth-file-store.h"
#include "gth-icon-cache.h"
#include "gth-menu-manager.h"
#include "gth-task.h"
#include "gth-window.h"
#include "typedefs.h"
......@@ -65,6 +66,12 @@ typedef enum { /*< skip >*/
GTH_BROWSER_N_HEADER_SECTIONS
} GthBrowserHeaderSection;
typedef enum { /*< skip >*/
GTH_BROWSER_MENU_MANAGER_GEARS,
GTH_BROWSER_MENU_MANAGER_GEARS_FOLDER_ACTIONS,
GTH_BROWSER_N_MENU_MANAGERS
} GthBrowserMenuManager;
typedef enum {
GTH_ACTION_GO_TO,
GTH_ACTION_GO_BACK,
......@@ -123,6 +130,9 @@ GtkWidget * gth_browser_get_statusbar (GthBrowser *browser);
GtkWidget * gth_browser_get_filterbar (GthBrowser *browser);
GtkWidget * gth_browser_get_headerbar_section (GthBrowser *browser,
GthBrowserHeaderSection section);
GthMenuManager * gth_browser_get_menu_manager (GthBrowser *browser,
GthBrowserMenuManager
manager);
GtkWidget * gth_browser_get_file_list (GthBrowser *browser);
GtkWidget * gth_browser_get_file_list_view (GthBrowser *browser);
GtkWidget * gth_browser_get_thumbnail_list (GthBrowser *browser);
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* GThumb
*
* Copyright (C) 2009 The Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <gtk/gtk.h>
#include "gtk-utils.h"
#include "glib-utils.h"
#include "gth-menu-manager.h"
/* Properties */
enum {
PROP_0,
PROP_MENU
};
struct _GthMenuManagerPrivate {
GMenu *menu;
guint last_id;
GHashTable *items;
};
G_DEFINE_TYPE (GthMenuManager, gth_menu_manager, G_TYPE_OBJECT)
static void
gth_menu_manager_finalize (GObject *object)
{
GthMenuManager *self;
self = GTH_MENU_MANAGER (object);
_g_object_unref (self->priv->menu);
g_hash_table_destroy (self->priv->items);
G_OBJECT_CLASS (gth_menu_manager_parent_class)->finalize (object);
}
static void
gth_menu_manager_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GthMenuManager *self;
self = GTH_MENU_MANAGER (object);
switch (property_id) {
case PROP_MENU:
_g_object_unref (self->priv->menu);
self->priv->menu = g_value_dup_object (value);
break;
default:
break;
}
}
static void
gth_menu_manager_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GthMenuManager *self;
self = GTH_MENU_MANAGER (object);
switch (property_id) {
case PROP_MENU:
g_value_set_object (value, self->priv->menu);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gth_menu_manager_class_init (GthMenuManagerClass *klass)
{
GObjectClass *object_class;
g_type_class_add_private (klass, sizeof (GthMenuManagerPrivate));
object_class = (GObjectClass*) klass;
object_class->set_property = gth_menu_manager_set_property;
object_class->get_property = gth_menu_manager_get_property;
object_class->finalize = gth_menu_manager_finalize;
/* properties */
g_object_class_install_property (object_class,
PROP_MENU,
g_param_spec_object ("menu",
"Menu",
"The menu to modify",
G_TYPE_MENU,
G_PARAM_READWRITE));
}
static void
gth_menu_manager_init (GthMenuManager *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_MENU_MANAGER, GthMenuManagerPrivate);
self->priv->items = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) _g_string_list_free);
self->priv->last_id = 1;
self->priv->menu = NULL;
}
GthMenuManager *
gth_menu_manager_new (GMenu *menu)
{
return g_object_new (GTH_TYPE_MENU_MANAGER, "menu", menu, NULL);
}
guint
gth_menu_manager_append_entries (GthMenuManager *menu_manager,
const GthMenuEntry *entries,
int n_entries)
{
guint merge_id;
GList *items;
int i;
merge_id = menu_manager->priv->last_id++;
items = NULL;
for (i = 0; i < n_entries; i++) {
const GthMenuEntry *entry = entries + i;
GMenuItem *item;
item = g_menu_item_new (_(entry->label), entry->detailed_action);
if (entry->accel != NULL)
g_menu_item_set_attribute (item, "accel", "s", entry->accel, NULL);
g_menu_append_item (menu_manager->priv->menu, item);
items = g_list_prepend (items, g_strdup (entry->detailed_action));
}
items = g_list_reverse (items);
g_hash_table_insert (menu_manager->priv->items, GINT_TO_POINTER (merge_id), items);
return merge_id;
}
static int
_g_menu_model_get_item_position_from_action (GMenuModel *model,
const char *action)
{
int i;
for (i = 0; i < g_menu_model_get_n_items (model); i++) {
char *item_action = NULL;
if (g_menu_model_get_item_attribute (model,
i,
G_MENU_ATTRIBUTE_ACTION,
"s",
&item_action))
{
if (g_strcmp0 (item_action, action) == 0) {
g_free (item_action);
return i;
}
}
g_free (item_action);
}
return -1;
}
void
gth_menu_manager_remove_entries (GthMenuManager *menu_manager,
guint merge_id)
{
GList *items;
GList *scan;
items = g_hash_table_lookup (menu_manager->priv->items, GINT_TO_POINTER (merge_id));
g_return_if_fail (items != NULL);
for (scan = items; scan; scan = scan->next) {
char *detailed_action = scan->data;
int pos;
pos = _g_menu_model_get_item_position_from_action (G_MENU_MODEL (menu_manager->priv->menu), detailed_action);
if (pos >= 0)
g_menu_remove (menu_manager->priv->menu, pos);
}
g_hash_table_remove (menu_manager->priv->items, GINT_TO_POINTER (merge_id));
}
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* GThumb
*
* Copyright (C) 2013 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GTH_MENU_MANAGER_H
#define GTH_MENU_MANAGER_H
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GTH_TYPE_MENU_MANAGER (gth_menu_manager_get_type ())
#define GTH_MENU_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTH_TYPE_MENU_MANAGER, GthMenuManager))
#define GTH_MENU_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTH_TYPE_MENU_MANAGER, GthMenuManagerClass))
#define GTH_IS_MENU_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTH_TYPE_MENU_MANAGER))
#define GTH_IS_MENU_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTH_TYPE_MENU_MANAGER))
#define GTH_MENU_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GTH_TYPE_MENU_MANAGER, GthMenuManagerClass))
typedef struct {
const char *label;
const char *detailed_action;
const char *accel;
} GthMenuEntry;
typedef struct _GthMenuManager GthMenuManager;
typedef struct _GthMenuManagerPrivate GthMenuManagerPrivate;
typedef struct _GthMenuManagerClass GthMenuManagerClass;
struct _GthMenuManager
{
GObject __parent;
GthMenuManagerPrivate *priv;
};
struct _GthMenuManagerClass
{
GObjectClass __parent_class;
};
GType gth_menu_manager_get_type (void) G_GNUC_CONST;
GthMenuManager * gth_menu_manager_new (GMenu *menu);
guint gth_menu_manager_append_entries (GthMenuManager *menu_manager,
const GthMenuEntry *entries,
int n_entries);
void gth_menu_manager_remove_entries (GthMenuManager *menu_manager,
guint merge_id);
G_END_DECLS
#endif /* GTH_MENU_MANAGER_H */
......@@ -2,6 +2,7 @@
<gresources>
<gresource prefix="/org/gnome/gThumb">
<file compressed="true">resources/app-menu.ui</file>
<file compressed="true">resources/gears-menu.ui</file>
<file compressed="true">resources/gthumb.css</file>
<file compressed="true">resources/message-dialog.ui</file>
</gresource>
......
EXTRA_DIST = \
app-menu.ui \
gears-menu.ui \
gthumb.css \
message-dialog.ui
......
<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<menu id="menu">
<section>
<item>
<attribute name="label" translatable="yes">_Save</attribute>
<attribute name="action">win.save</attribute>
<attribute name="accel"><![CDATA[<Ctrl>S]]></attribute>
</item>
<item>
<attribute name="label" translatable="yes">Save _As</attribute>
<attribute name="action">win.save-as</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Revert</attribute>
<attribute name="action">win.revert-to-saved</attribute>