[gthumb/ext: 35/79] added a file list tools extension



commit c95579c63df886471315d53eef63631327dcbfd6
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Jul 5 00:14:40 2009 +0200

    added a file list tools extension

 configure.ac                                     |    1 +
 extensions/Makefile.am                           |    2 +-
 extensions/file_manager/callbacks.h              |    1 -
 extensions/list_tools/Makefile.am                |   30 ++
 extensions/list_tools/actions.c                  |   34 ++
 extensions/list_tools/actions.h                  |   32 ++
 extensions/list_tools/callbacks.c                |  121 ++++++
 extensions/list_tools/callbacks.h                |   31 ++
 extensions/list_tools/list_tools.extension.in.in |   10 +
 extensions/list_tools/main.c                     |   54 +++
 gthumb/Makefile.am                               |    2 +
 gthumb/gth-browser-ui.h                          |    1 -
 gthumb/gth-browser.c                             |    8 +
 gthumb/gth-browser.h                             |    1 +
 gthumb/gth-main.c                                |    2 +-
 gthumb/gth-toggle-menu-tool-button.c             |  426 ++++++++++++++++++++++
 gthumb/gth-toggle-menu-tool-button.h             |   64 ++++
 17 files changed, 816 insertions(+), 4 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 17ec69d..d216eb2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -235,6 +235,7 @@ extensions/file_viewer/Makefile
 extensions/image_viewer/Makefile
 extensions/image_viewer/data/Makefile
 extensions/image_viewer/data/ui/Makefile
+extensions/list_tools/Makefile
 extensions/search/Makefile
 extensions/search/data/Makefile
 extensions/search/data/ui/Makefile
diff --git a/extensions/Makefile.am b/extensions/Makefile.am
index 2bff7c9..25caf25 100644
--- a/extensions/Makefile.am
+++ b/extensions/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = catalogs comments exiv2 file_manager file_tools file_viewer image_viewer search
+SUBDIRS = catalogs comments exiv2 file_manager file_tools file_viewer image_viewer list_tools search
 
 -include $(top_srcdir)/git.mk
diff --git a/extensions/file_manager/callbacks.h b/extensions/file_manager/callbacks.h
index 7e244cb..bf8bc01 100644
--- a/extensions/file_manager/callbacks.h
+++ b/extensions/file_manager/callbacks.h
@@ -34,7 +34,6 @@ void fm__gth_browser_load_location_after_cb      (GthBrowser    *browser,
 void fm__gth_browser_folder_tree_popup_before_cb (GthBrowser    *browser,
 						  GthFileSource *file_source,
 					          GFile         *folder);
-void fm__gth_browser_update_sensitivity_cb       (GthBrowser    *browser);
 void fm__gth_browser_selection_changed_cb        (GthBrowser    *browser);
 void fm__gth_browser_realize_cb                  (GthBrowser    *browser);
 void fm__gth_browser_unrealize_cb                (GthBrowser    *browser);
diff --git a/extensions/list_tools/Makefile.am b/extensions/list_tools/Makefile.am
new file mode 100644
index 0000000..f3520a2
--- /dev/null
+++ b/extensions/list_tools/Makefile.am
@@ -0,0 +1,30 @@
+extensiondir = $(libdir)/gthumb-2.0/extensions
+extension_LTLIBRARIES = liblist_tools.la
+
+liblist_tools_la_SOURCES = 		\
+	actions.c			\
+	actions.h			\
+	callbacks.c			\
+	callbacks.h			\
+	main.c
+
+liblist_tools_la_CFLAGS = $(GTHUMB_CFLAGS) $(DISABLE_DEPRECATED) $(WARNINGS) -I$(top_srcdir) -I$(top_builddir)/gthumb 
+liblist_tools_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
+liblist_tools_la_LIBADD = $(GTHUMB_LIBS)
+liblist_tools_la_DEPENDENCIES = $(top_builddir)/gthumb/gthumb$(EXEEXT)
+
+extensioninidir = $(extensiondir)
+extensionini_in_files = list_tools.extension.in.in
+extensionini_DATA = $(extensionini_in_files:.extension.in.in=.extension)
+
+%.extension.in: %.extension.in.in $(extension_LTLIBRARIES)
+	sed -e "s|%LIBRARY%|`. ./$(extension_LTLIBRARIES) && echo $$dlname`|" \
+	$< > $@
+
+%.extension: %.extension.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
+
+EXTRA_DIST = $(extensionini_in_files) 
+
+DISTCLEANFILES = $(extensionini_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/list_tools/actions.c b/extensions/list_tools/actions.c
new file mode 100644
index 0000000..3973897
--- /dev/null
+++ b/extensions/list_tools/actions.c
@@ -0,0 +1,34 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <gthumb.h>
+
+
+void
+gth_browser_action_list_tools_edit_scripts (GtkAction  *action,
+			       GthBrowser *browser)
+{
+	/* FIXME */
+}
diff --git a/extensions/list_tools/actions.h b/extensions/list_tools/actions.h
new file mode 100644
index 0000000..e082239
--- /dev/null
+++ b/extensions/list_tools/actions.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef ACTIONS_H
+#define ACTIONS_H
+
+#include <gtk/gtk.h>
+
+#define DEFINE_ACTION(x) void x (GtkAction *action, gpointer data);
+
+DEFINE_ACTION(gth_browser_action_list_tools_edit_scripts)
+
+#endif /* ACTIONS_H */
diff --git a/extensions/list_tools/callbacks.c b/extensions/list_tools/callbacks.c
new file mode 100644
index 0000000..1593d4e
--- /dev/null
+++ b/extensions/list_tools/callbacks.c
@@ -0,0 +1,121 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gthumb.h>
+#include "actions.h"
+
+
+#define BROWSER_DATA_KEY "list-tools-browser-data"
+
+
+static const char *fixed_ui_info =
+"<ui>"
+"  <popup name='ListToolsPopup'>"
+"    <placeholder name='Tools'/>"
+"    <separator/>"
+"    <placeholder name='Scripts'/>"
+"    <separator/>"
+"    <menuitem action='ListTools_EditScripts'/>"
+"  </popup>"
+"</ui>";
+
+
+static GtkActionEntry action_entries[] = {
+	{ "ListTools_EditScripts", GTK_STOCK_EDIT,
+	  N_("Personalize..."), NULL,
+	  NULL,
+	  G_CALLBACK (gth_browser_action_list_tools_edit_scripts) }
+};
+
+
+typedef struct {
+	GtkToolItem    *tool_item;
+	GtkActionGroup *action_group;
+} BrowserData;
+
+
+static void
+browser_data_free (BrowserData *data)
+{
+	g_free (data);
+}
+
+
+void
+list_tools__gth_browser_construct_cb (GthBrowser *browser)
+{
+	BrowserData *data;
+	GError      *error = NULL;
+
+	g_return_if_fail (GTH_IS_BROWSER (browser));
+
+	data = g_new0 (BrowserData, 1);
+
+	data->action_group = gtk_action_group_new ("List Tools Manager Actions");
+	gtk_action_group_set_translation_domain (data->action_group, NULL);
+	gtk_action_group_add_actions (data->action_group,
+				      action_entries,
+				      G_N_ELEMENTS (action_entries),
+				      browser);
+	gtk_ui_manager_insert_action_group (gth_browser_get_ui_manager (browser), data->action_group, 0);
+
+	if (! gtk_ui_manager_add_ui_from_string (gth_browser_get_ui_manager (browser), fixed_ui_info, -1, &error)) {
+		g_message ("building menus failed: %s", error->message);
+		g_clear_error (&error);
+	}
+
+	/* tools menu button */
+
+	data->tool_item = gth_toggle_menu_tool_button_new ();
+	gtk_tool_button_set_label (GTK_TOOL_BUTTON (data->tool_item), _("Tools"));
+	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (data->tool_item), GTK_STOCK_EXECUTE);
+	gth_toggle_menu_tool_button_set_menu (GTH_TOGGLE_MENU_TOOL_BUTTON (data->tool_item), gtk_ui_manager_get_widget (gth_browser_get_ui_manager (browser), "/ListToolsPopup"));
+	gtk_widget_show (GTK_WIDGET (data->tool_item));
+	gtk_toolbar_insert (GTK_TOOLBAR (gth_browser_get_browser_toolbar (browser)), data->tool_item, -1);
+
+	g_object_set_data_full (G_OBJECT (browser), BROWSER_DATA_KEY, data, (GDestroyNotify) browser_data_free);
+}
+
+
+void
+list_tools__gth_browser_update_sensitivity_cb (GthBrowser *browser)
+{
+	/*
+	BrowserData   *data;
+	GthFileSource *file_source;
+	int            n_selected;
+	gboolean       sensitive;
+
+	data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY);
+	g_return_if_fail (data != NULL);
+
+	file_source = gth_browser_get_location_source (browser);
+	n_selected = gth_file_selection_get_n_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
+
+	sensitive = (n_selected > 0) && (file_source != NULL) && gth_file_source_can_cut (file_source);
+	gtk_widget_set_sensitive (GTK_WIDGET (data->tool_item), sensitive);
+	*/
+}
diff --git a/extensions/list_tools/callbacks.h b/extensions/list_tools/callbacks.h
new file mode 100644
index 0000000..765ca7a
--- /dev/null
+++ b/extensions/list_tools/callbacks.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CALLBACKS_H
+#define CALLBACKS_H
+
+#include <gthumb.h>
+
+void list_tools__gth_browser_construct_cb          (GthBrowser *browser);
+void list_tools__gth_browser_update_sensitivity_cb (GthBrowser *browser);
+
+#endif /* CALLBACKS_H */
diff --git a/extensions/list_tools/list_tools.extension.in.in b/extensions/list_tools/list_tools.extension.in.in
new file mode 100644
index 0000000..949d694
--- /dev/null
+++ b/extensions/list_tools/list_tools.extension.in.in
@@ -0,0 +1,10 @@
+[Extension]
+_Name=File list tools
+_Description=Allow to add tools to operate on files.
+_Authors=gthumb development team
+Copyright=Copyright © 2009 The Free Software Foundation, Inc.
+Version=1.0
+
+[Loader]
+Type=module
+File=%LIBRARY%
diff --git a/extensions/list_tools/main.c b/extensions/list_tools/main.c
new file mode 100644
index 0000000..d84c379
--- /dev/null
+++ b/extensions/list_tools/main.c
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include <gthumb.h>
+#include "callbacks.h"
+
+
+G_MODULE_EXPORT void
+gthumb_extension_activate (void)
+{
+	gth_hook_add_callback ("gth-browser-construct", 10, G_CALLBACK (list_tools__gth_browser_construct_cb), NULL);
+	gth_hook_add_callback ("gth-browser-update-sensitivity", 10, G_CALLBACK (list_tools__gth_browser_update_sensitivity_cb), NULL);
+}
+
+
+G_MODULE_EXPORT void
+gthumb_extension_deactivate (void)
+{
+}
+
+
+G_MODULE_EXPORT gboolean
+gthumb_extension_is_configurable (void)
+{
+	return FALSE;
+}
+
+
+G_MODULE_EXPORT void
+gthumb_extension_configure (GtkWindow *parent)
+{
+}
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index adbe63a..a04421e 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -85,6 +85,7 @@ PUBLIC_HEADER_FILES = 					\
 	gth-test-simple.h				\
 	gth-thumb-loader.h				\
 	gth-time.h					\
+	gth-toggle-menu-tool-button.h			\
 	gth-toolbox.h					\
 	gth-uri-list.h					\
 	gth-user-dir.h					\
@@ -191,6 +192,7 @@ gthumb_SOURCES = 					\
 	gth-test-simple.c				\
 	gth-thumb-loader.c				\
 	gth-time.c					\
+	gth-toggle-menu-tool-button.c			\
 	gth-toolbox.c					\
 	gth-uri-list.c					\
 	gth-user-dir.c					\
diff --git a/gthumb/gth-browser-ui.h b/gthumb/gth-browser-ui.h
index 33e8f4c..fdbfe51 100644
--- a/gthumb/gth-browser-ui.h
+++ b/gthumb/gth-browser-ui.h
@@ -107,7 +107,6 @@ static const char *fixed_ui_info =
 "    <separator/>"
 "    <placeholder name='BrowserCommands'/>"
 "    <separator/>"
-"    <toolitem action='File_CloseWindow'/>"
 "  </toolbar>"
 
 "  <toolbar name='ViewerToolBar'>"
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index ae21c09..8156b38 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -47,6 +47,7 @@
 #include "gth-preferences.h"
 #include "gth-sidebar.h"
 #include "gth-statusbar.h"
+#include "gth-toggle-menu-tool-button.h"
 #include "gth-viewer-page.h"
 #include "gth-window.h"
 #include "gth-window-actions-callbacks.h"
@@ -3161,6 +3162,13 @@ gth_browser_get_menu_icon_cache (GthBrowser *browser)
 
 
 GtkWidget *
+gth_browser_get_browser_toolbar (GthBrowser *browser)
+{
+	return browser->priv->browser_toolbar;
+}
+
+
+GtkWidget *
 gth_browser_get_statusbar (GthBrowser *browser)
 {
 	return browser->priv->statusbar;
diff --git a/gthumb/gth-browser.h b/gthumb/gth-browser.h
index 1a015b1..7c7b5cd 100644
--- a/gthumb/gth-browser.h
+++ b/gthumb/gth-browser.h
@@ -89,6 +89,7 @@ GtkWidget *      gth_browser_get_dialog             (GthBrowser       *browser,
 						     const char       *dialog_name);
 GtkUIManager *   gth_browser_get_ui_manager         (GthBrowser       *browser);
 GthIconCache *   gth_browser_get_menu_icon_cache    (GthBrowser       *browser);
+GtkWidget *      gth_browser_get_browser_toolbar    (GthBrowser       *browser);
 GtkWidget *      gth_browser_get_statusbar          (GthBrowser       *browser);
 GtkWidget *      gth_browser_get_file_list          (GthBrowser       *browser);
 GtkWidget *      gth_browser_get_file_list_view     (GthBrowser       *browser);
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index c5385ea..8fff5ce 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -1034,7 +1034,7 @@ void
 gth_main_activate_extensions (void)
 {
 	const char *mandatory_extensions[] = { "file_viewer", NULL };
-	const char *default_extensions[] = { "catalogs", "comments", "exiv2", "file_manager", "file_tools", "image_viewer", "search", NULL };
+	const char *default_extensions[] = { "catalogs", "comments", "exiv2", "file_manager", "file_tools", "image_viewer", "list_tools", "search", NULL };
 	int         i;
 	GSList     *active_extensions;
 	GSList     *scan;
diff --git a/gthumb/gth-toggle-menu-tool-button.c b/gthumb/gth-toggle-menu-tool-button.c
new file mode 100644
index 0000000..1112286
--- /dev/null
+++ b/gthumb/gth-toggle-menu-tool-button.c
@@ -0,0 +1,426 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include "gth-toggle-menu-tool-button.h"
+
+struct _GthToggleMenuToolButtonPrivate {
+	GtkWidget *toggle_button;
+	GtkMenu   *menu;
+};
+
+enum {
+	SHOW_MENU,
+	LAST_SIGNAL
+};
+
+enum {
+	PROP_0,
+	PROP_MENU
+};
+
+static gpointer parent_class = NULL;
+static int signals[LAST_SIGNAL];
+
+
+static void
+gth_toggle_menu_tool_button_state_changed (GtkWidget    *widget,
+					   GtkStateType  previous_state)
+{
+	GthToggleMenuToolButton *button = GTH_TOGGLE_MENU_TOOL_BUTTON (widget);
+
+	if (! GTK_WIDGET_IS_SENSITIVE (widget) && (button->priv->menu != NULL))
+		gtk_menu_shell_deactivate (GTK_MENU_SHELL (button->priv->menu));
+}
+
+
+static void
+gth_toggle_menu_tool_button_set_property (GObject      *object,
+					  guint         prop_id,
+					  const GValue *value,
+					  GParamSpec   *pspec)
+{
+	GthToggleMenuToolButton *button = GTH_TOGGLE_MENU_TOOL_BUTTON (object);
+
+	switch (prop_id) {
+	case PROP_MENU:
+		gth_toggle_menu_tool_button_set_menu (button, g_value_get_object (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+
+static void
+gth_toggle_menu_tool_button_get_property (GObject    *object,
+					  guint       prop_id,
+					  GValue     *value,
+					  GParamSpec *pspec)
+{
+	GthToggleMenuToolButton *button = GTH_TOGGLE_MENU_TOOL_BUTTON (object);
+
+	switch (prop_id) {
+	case PROP_MENU:
+		g_value_set_object (value, button->priv->menu);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+
+/* Callback for the "deactivate" signal on the pop-up menu.
+ * This is used so that we unset the state of the toggle button
+ * when the pop-up menu disappears.
+ */
+static int
+menu_deactivate_cb (GtkMenuShell            *menu_shell,
+		    GthToggleMenuToolButton *button)
+{
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->priv->toggle_button), FALSE);
+	return TRUE;
+}
+
+
+static void
+menu_position_func (GtkMenu                 *menu,
+                    int                     *x,
+                    int                     *y,
+                    gboolean                *push_in,
+                    GthToggleMenuToolButton *button)
+{
+	GtkWidget        *widget = GTK_WIDGET (button);
+	GtkRequisition    req;
+	GtkRequisition    menu_req;
+	GtkOrientation    orientation;
+	GtkTextDirection  direction;
+	GdkRectangle      monitor;
+	int               monitor_num;
+	GdkScreen        *screen;
+
+	gtk_widget_size_request (GTK_WIDGET (button->priv->menu), &menu_req);
+
+	orientation = gtk_tool_item_get_orientation (GTK_TOOL_ITEM (button));
+	direction = gtk_widget_get_direction (widget);
+
+	screen = gtk_widget_get_screen (GTK_WIDGET (menu));
+	monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
+	if (monitor_num < 0)
+		monitor_num = 0;
+	gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+
+	if (orientation == GTK_ORIENTATION_HORIZONTAL) {
+		gdk_window_get_origin (widget->window, x, y);
+		*x += widget->allocation.x;
+		*y += widget->allocation.y;
+
+		if (direction == GTK_TEXT_DIR_LTR)
+			*x += MAX (widget->allocation.width - menu_req.width, 0);
+		else if (menu_req.width > widget->allocation.width)
+			*x -= menu_req.width - widget->allocation.width;
+
+		if ((*y + widget->allocation.height + menu_req.height) <= monitor.y + monitor.height)
+			*y += widget->allocation.height;
+		else if ((*y - menu_req.height) >= monitor.y)
+			*y -= menu_req.height;
+		else if (monitor.y + monitor.height - (*y + widget->allocation.height) > *y)
+			*y += widget->allocation.height;
+		else
+			*y -= menu_req.height;
+	}
+	else {
+		gdk_window_get_origin (GTK_BUTTON (widget)->event_window, x, y);
+		gtk_widget_size_request (widget, &req);
+
+		if (direction == GTK_TEXT_DIR_LTR)
+			*x += widget->allocation.width;
+		else
+			*x -= menu_req.width;
+
+		if ((*y + menu_req.height > monitor.y + monitor.height) &&
+		    (*y + widget->allocation.height - monitor.y > monitor.y + monitor.height - *y))
+		{
+			*y += widget->allocation.height - menu_req.height;
+		}
+	}
+
+	*push_in = FALSE;
+}
+
+
+static void
+popup_menu_under_button (GthToggleMenuToolButton *button,
+                         GdkEventButton          *event)
+{
+	g_signal_emit (button, signals[SHOW_MENU], 0);
+
+	if (button->priv->menu == NULL)
+		return;
+
+	gtk_menu_popup (button->priv->menu, NULL, NULL,
+			(GtkMenuPositionFunc) menu_position_func,
+			button,
+			event ? event->button : 0,
+			event ? event->time : gtk_get_current_event_time ());
+}
+
+
+static gboolean
+real_button_toggled_cb (GtkToggleButton         *togglebutton,
+                        GthToggleMenuToolButton *button)
+{
+
+	if (button->priv->menu == NULL)
+		return FALSE;
+
+	if (gtk_toggle_button_get_active (togglebutton) && ! GTK_WIDGET_VISIBLE (button->priv->menu)) {
+		/* we get here only when the menu is activated by a key
+		 * press, so that we can select the first menu item */
+		popup_menu_under_button (button, NULL);
+		gtk_menu_shell_select_first (GTK_MENU_SHELL (button->priv->menu), FALSE);
+	}
+
+	return FALSE;
+}
+
+
+static gboolean
+real_button_button_press_event_cb (GtkWidget               *widget,
+                                   GdkEventButton          *event,
+                                   GthToggleMenuToolButton *button)
+{
+	if ((event->button == 1) && (button->priv->menu != NULL))  {
+		popup_menu_under_button (button, event);
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+
+		return TRUE;
+	}
+	else
+		return FALSE;
+}
+
+
+static void
+gth_toggle_menu_tool_button_destroy (GtkObject *object)
+{
+	GthToggleMenuToolButton *button;
+
+	button = GTH_TOGGLE_MENU_TOOL_BUTTON (object);
+
+	if (button->priv->menu != NULL) {
+		g_signal_handlers_disconnect_by_func (button->priv->menu,
+						      menu_deactivate_cb,
+						      button);
+		gtk_menu_detach (button->priv->menu);
+
+		g_signal_handlers_disconnect_by_func (button->priv->toggle_button,
+						      real_button_toggled_cb,
+						      button);
+		g_signal_handlers_disconnect_by_func (button->priv->toggle_button,
+						      real_button_button_press_event_cb,
+						      button);
+	}
+
+	GTK_OBJECT_CLASS (parent_class)->destroy (object);
+}
+
+
+static void
+gth_toggle_menu_tool_button_class_init (GthToggleMenuToolButtonClass *klass)
+{
+	GObjectClass     *object_class;
+	GtkObjectClass   *gtk_object_class;
+	GtkWidgetClass   *widget_class;
+	/*GtkToolItemClass *toolitem_class;*/
+
+	parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (GthToggleMenuToolButtonPrivate));
+
+	object_class = (GObjectClass *)klass;
+	object_class->set_property = gth_toggle_menu_tool_button_set_property;
+	object_class->get_property = gth_toggle_menu_tool_button_get_property;
+
+	gtk_object_class = (GtkObjectClass *)klass;
+	gtk_object_class->destroy = gth_toggle_menu_tool_button_destroy;
+
+	widget_class = (GtkWidgetClass *)klass;
+	widget_class->state_changed = gth_toggle_menu_tool_button_state_changed;
+
+	/*toolitem_class = (GtkToolItemClass *)klass;
+	toolitem_class->toolbar_reconfigured = gth_toggle_menu_tool_button_toolbar_reconfigured;*/
+
+	/**
+	 * GthToggleMenuToolButton::show-menu:
+	 * @button: the object on which the signal is emitted
+	 *
+	 * The ::show-menu signal is emitted before the menu is shown.
+	 *
+	 * It can be used to populate the menu on demand, using
+	 * gth_toggle_menu_tool_button_get_menu().
+
+	 * Note that even if you populate the menu dynamically in this way,
+	 * you must set an empty menu on the #GthToggleMenuToolButton beforehand,
+	 * since the arrow is made insensitive if the menu is not set.
+	 */
+	signals[SHOW_MENU] =
+		g_signal_new ("show-menu",
+			      G_OBJECT_CLASS_TYPE (klass),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (GthToggleMenuToolButtonClass, show_menu),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0);
+
+	g_object_class_install_property (object_class,
+                                        PROP_MENU,
+                                        g_param_spec_object ("menu",
+                                                             "Menu",
+                                                             "The dropdown menu",
+                                                             GTK_TYPE_MENU,
+                                                             G_PARAM_READABLE | G_PARAM_WRITABLE));
+}
+
+
+static void
+gth_toggle_menu_tool_button_init (GthToggleMenuToolButton *button)
+{
+	button->priv = G_TYPE_INSTANCE_GET_PRIVATE (button, GTH_TYPE_TOGGLE_MENU_TOOL_BUTTON, GthToggleMenuToolButtonPrivate);
+	button->priv->menu = NULL;
+
+	button->priv->toggle_button = gtk_bin_get_child (GTK_BIN (button));
+	g_signal_connect (button->priv->toggle_button,
+			  "toggled",
+			  G_CALLBACK (real_button_toggled_cb),
+			  button);
+	g_signal_connect (button->priv->toggle_button,
+			  "button-press-event",
+		          G_CALLBACK (real_button_button_press_event_cb),
+		          button);
+}
+
+
+GType
+gth_toggle_menu_tool_button_get_type (void)
+{
+        static GType type = 0;
+
+        if (! type) {
+                GTypeInfo type_info = {
+			sizeof (GthToggleMenuToolButtonClass),
+			NULL,
+			NULL,
+			(GClassInitFunc) gth_toggle_menu_tool_button_class_init,
+			NULL,
+			NULL,
+			sizeof (GthToggleMenuToolButton),
+			0,
+			(GInstanceInitFunc) gth_toggle_menu_tool_button_init
+		};
+		type = g_type_register_static (GTK_TYPE_TOGGLE_TOOL_BUTTON,
+					       "GthToggleMenuToolButton",
+					       &type_info,
+					       0);
+	}
+
+        return type;
+}
+
+
+GtkToolItem *
+gth_toggle_menu_tool_button_new (void)
+{
+	return (GtkToolItem *) g_object_new (GTH_TYPE_TOGGLE_MENU_TOOL_BUTTON, NULL);
+}
+
+
+GtkToolItem *
+gth_toggle_menu_tool_button_new_from_stock (const gchar *stock_id)
+{
+	g_return_val_if_fail (stock_id != NULL, NULL);
+
+	return (GtkToolItem *) g_object_new (GTH_TYPE_TOGGLE_MENU_TOOL_BUTTON,
+					     "stock-id", stock_id,
+					     NULL);
+}
+
+
+static void
+menu_detacher (GtkWidget *widget,
+               GtkMenu   *menu)
+{
+	GthToggleMenuToolButton *button = GTH_TOGGLE_MENU_TOOL_BUTTON (widget);
+
+	g_return_if_fail (button->priv->menu == menu);
+
+	button->priv->menu = NULL;
+}
+
+
+void
+gth_toggle_menu_tool_button_set_menu (GthToggleMenuToolButton *button,
+				      GtkWidget               *menu)
+{
+	g_return_if_fail (GTH_IS_TOGGLE_MENU_TOOL_BUTTON (button));
+	g_return_if_fail (GTK_IS_MENU (menu) || menu == NULL);
+
+	if (button->priv->menu != GTK_MENU (menu)) {
+		if ((button->priv->menu != NULL) && GTK_WIDGET_VISIBLE (button->priv->menu))
+			gtk_menu_shell_deactivate (GTK_MENU_SHELL (button->priv->menu));
+
+		if (button->priv->menu != NULL) {
+			g_signal_handlers_disconnect_by_func (button->priv->menu,
+							      menu_deactivate_cb,
+							      button);
+			gtk_menu_detach (button->priv->menu);
+		}
+
+		button->priv->menu = GTK_MENU (menu);
+
+		if (button->priv->menu != NULL) {
+			gtk_menu_attach_to_widget (button->priv->menu,
+						   GTK_WIDGET (button),
+						   menu_detacher);
+
+			gtk_widget_set_sensitive (button->priv->toggle_button, TRUE);
+
+			g_signal_connect (button->priv->menu,
+					  "deactivate",
+					  G_CALLBACK (menu_deactivate_cb),
+					  button);
+		}
+		else
+			gtk_widget_set_sensitive (button->priv->toggle_button, FALSE);
+	}
+
+	g_object_notify (G_OBJECT (button), "menu");
+}
+
+
+GtkWidget *
+gth_toggle_menu_tool_button_get_menu (GthToggleMenuToolButton *button)
+{
+	g_return_val_if_fail (GTH_IS_TOGGLE_MENU_TOOL_BUTTON (button), NULL);
+
+	return GTK_WIDGET (button->priv->menu);
+}
diff --git a/gthumb/gth-toggle-menu-tool-button.h b/gthumb/gth-toggle-menu-tool-button.h
new file mode 100644
index 0000000..a006feb
--- /dev/null
+++ b/gthumb/gth-toggle-menu-tool-button.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_TOGGLE_MENU_TOOL_BUTTON_H
+#define GTH_TOGGLE_MENU_TOOL_BUTTON_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_TOGGLE_MENU_TOOL_BUTTON            (gth_toggle_menu_tool_button_get_type ())
+#define GTH_TOGGLE_MENU_TOOL_BUTTON(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_TOGGLE_MENU_TOOL_BUTTON, GthToggleMenuToolButton))
+#define GTH_TOGGLE_MENU_TOOL_BUTTON_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_TOGGLE_MENU_TOOL_BUTTON, GthToggleMenuToolButtonClass))
+#define GTH_IS_TOGGLE_MENU_TOOL_BUTTON(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_TOGGLE_MENU_TOOL_BUTTON))
+#define GTH_IS_TOGGLE_MENU_TOOL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_TOGGLE_MENU_TOOL_BUTTON))
+#define GTH_TOGGLE_MENU_TOOL_BUTTON_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_TOGGLE_MENU_TOOL_BUTTON, GthToggleMenuToolButtonClass))
+
+typedef struct _GthToggleMenuToolButton        GthToggleMenuToolButton;
+typedef struct _GthToggleMenuToolButtonClass   GthToggleMenuToolButtonClass;
+typedef struct _GthToggleMenuToolButtonPrivate GthToggleMenuToolButtonPrivate;
+
+struct _GthToggleMenuToolButton
+{
+	GtkToggleToolButton parent;
+	GthToggleMenuToolButtonPrivate *priv;
+};
+
+struct _GthToggleMenuToolButtonClass
+{
+	GtkToggleToolButtonClass parent_class;
+
+	void (*show_menu) (GthToggleMenuToolButton *button);
+};
+
+GType         gth_toggle_menu_tool_button_get_type       (void) G_GNUC_CONST;
+GtkToolItem * gth_toggle_menu_tool_button_new            (void);
+GtkToolItem * gth_toggle_menu_tool_button_new_from_stock (const char              *stock_id);
+void          gth_toggle_menu_tool_button_set_menu       (GthToggleMenuToolButton *button,
+							  GtkWidget               *menu);
+GtkWidget *   gth_toggle_menu_tool_button_get_menu       (GthToggleMenuToolButton *button);
+
+G_END_DECLS
+
+#endif /* GTH_TOGGLE_MENU_TOOL_BUTTON_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]