/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2001 Ximian, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Authors:
* Chema Celorio <chema@celorio.com>
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <glib/gi18n-lib.h>
#include "glade.h"
#include "glade-widget.h"
#include "glade-widget-adaptor.h"
#include "glade-popup.h"
#include "glade-placeholder.h"
#include "glade-clipboard.h"
#include "glade-command.h"
#include "glade-project.h"
#include "glade-app.h"
/********************************************************
WIDGET POPUP
*******************************************************/
static void
glade_popup_select_cb (GtkMenuItem *item, GladeWidget *widget)
{
glade_util_clear_selection ();
glade_app_selection_set
(glade_widget_get_object (widget), TRUE);
}
static void
glade_popup_cut_cb (GtkMenuItem *item, GladeWidget *widget)
{
GladeProject *project = glade_app_get_project ();
glade_util_clear_selection ();
/* Assign selection first */
if (glade_project_is_selected
(project, glade_widget_get_object (widget)) == FALSE)
{
glade_app_selection_set
(glade_widget_get_object (widget), FALSE);
}
glade_app_command_cut ();
}
static void
glade_popup_copy_cb (GtkMenuItem *item, GladeWidget *widget)
{
GladeProject *project = glade_app_get_project ();
glade_util_clear_selection ();
/* Assign selection first */
if (glade_project_is_selected
(project, glade_widget_get_object (widget)) == FALSE)
glade_app_selection_set
(glade_widget_get_object (widget), FALSE);
glade_app_command_copy ();
}
static void
glade_popup_paste_cb (GtkMenuItem *item, GladeWidget *widget)
{
glade_util_clear_selection ();
/* The selected widget is the paste destination */
glade_app_selection_set (glade_widget_get_object (widget), FALSE);
glade_app_command_paste (NULL);
}
static void
glade_popup_delete_cb (GtkMenuItem *item, GladeWidget *widget)
{
GladeProject *project = glade_app_get_project ();
/* Assign selection first */
if (glade_project_is_selected
(project, glade_widget_get_object (widget)) == FALSE)
glade_app_selection_set
(glade_widget_get_object (widget), FALSE);
glade_app_command_delete ();
}
/********************************************************
PLACEHOLDER POPUP
*******************************************************/
static void
glade_popup_placeholder_paste_cb (GtkMenuItem *item,
GladePlaceholder *placeholder)
{
glade_util_clear_selection ();
glade_app_selection_clear (FALSE);
glade_app_command_paste (placeholder);
}
/********************************************************
CLIPBOARD POPUP
*******************************************************/
static void
glade_popup_clipboard_paste_cb (GtkMenuItem *item,
GladeWidget *widget)
{
glade_util_clear_selection ();
glade_app_selection_clear (FALSE);
glade_app_command_paste (NULL);
}
static void
glade_popup_clipboard_delete_cb (GtkMenuItem *item, GladeWidget *widget)
{
glade_app_command_delete_clipboard ();
}
/********************************************************
POPUP BUILDING
*******************************************************/
static GtkWidget *
glade_popup_append_item (GtkWidget *popup_menu,
const gchar *stock_id,
const gchar *label,
gboolean sensitive,
gpointer callback,
gpointer data)
{
GtkWidget *menu_item;
if (stock_id && label)
{
menu_item = gtk_image_menu_item_new_with_mnemonic (label);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU));
}
else if (stock_id)
menu_item = gtk_image_menu_item_new_from_stock (stock_id, NULL);
else
menu_item = gtk_menu_item_new_with_mnemonic (label);
if (callback)
g_signal_connect (G_OBJECT (menu_item), "activate",
G_CALLBACK (callback), data);
gtk_widget_set_sensitive (menu_item, sensitive);
gtk_widget_show (menu_item);
gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);
return menu_item;
}
static void
glade_popup_menuitem_activated (GtkMenuItem *item, const gchar *action_path)
{
GladeWidget *widget;
if ((widget = g_object_get_data (G_OBJECT (item), "gwa-data")))
glade_widget_adaptor_action_activate (widget->adaptor,
widget->object,
action_path);
}
static void
glade_popup_menuitem_packing_activated (GtkMenuItem *item, const gchar *action_path)
{
GladeWidget *widget;
if ((widget = g_object_get_data (G_OBJECT (item), "gwa-data")))
glade_widget_adaptor_child_action_activate (widget->parent->adaptor,
widget->parent->object,
widget->object,
action_path);
}
static void
glade_popup_menuitem_ph_packing_activated (GtkMenuItem *item, const gchar *action_path)
{
GladePlaceholder *ph;
GladeWidget *parent;
if ((ph = g_object_get_data (G_OBJECT (item), "gwa-data")))
{
parent = glade_placeholder_get_parent (ph);
glade_widget_adaptor_child_action_activate (parent->adaptor,
parent->object,
G_OBJECT (ph),
action_path);
}
}
static gint
glade_popup_action_populate_menu_real (GtkWidget *menu,
GList *actions,
GCallback callback,
gpointer data)
{
GtkWidget *item;
GList *list;
gint n = 0;
for (list = actions; list; list = g_list_next (list))
{
GladeWidgetAction *a = list->data;
GtkWidget *submenu = NULL;
if (a->actions)
{
submenu = gtk_menu_new ();
n += glade_popup_action_populate_menu_real (submenu,
a->actions,
callback,
data);
}
item = glade_popup_append_item (menu,
a->klass->stock,
a->klass->label, TRUE,
(a->actions) ? NULL : callback,
(a->actions) ? NULL : a->klass->path);
g_object_set_data (G_OBJECT (item), "gwa-data", data);
gtk_widget_set_sensitive (item, a->sensitive);
if (submenu)
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
n++;
}
return n;
}
/*
* glade_popup_action_populate_menu:
* @menu: a GtkMenu to put the actions menu items.
* @widget: A #GladeWidget
* @action: a @widget subaction or NULL to include all actions.
* @packing: TRUE to include packing actions
*
* Populate a GtkMenu with widget's actions
*
* Returns the number of action appended to the menu.
*/
gint
glade_popup_action_populate_menu (GtkWidget *menu,
GladeWidget *widget,
GladeWidgetAction *action,
gboolean packing)
{
gint n;
g_return_val_if_fail (GTK_IS_MENU (menu), 0);
g_return_val_if_fail (GLADE_IS_WIDGET (widget), 0);
if (action)
{
g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (action), 0);
if (glade_widget_get_action (widget, action->klass->path))
return glade_popup_action_populate_menu_real (menu,
action->actions,
G_CALLBACK (glade_popup_menuitem_activated),
widget);
if (glade_widget_get_pack_action (widget, action->klass->path))
return glade_popup_action_populate_menu_real (menu,
action->actions,
G_CALLBACK (glade_popup_menuitem_packing_activated),
widget);
return 0;
}
n = glade_popup_action_populate_menu_real (menu,
widget->actions,
G_CALLBACK (glade_popup_menuitem_activated),
widget);
if (packing && widget->packing_actions)
{
if (n)
{
GtkWidget *separator = gtk_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (menu), separator);
gtk_widget_show (separator);
}
n += glade_popup_action_populate_menu_real (menu,
widget->packing_actions,
G_CALLBACK (glade_popup_menuitem_packing_activated),
widget);
}
return n;
}
static GtkWidget *
glade_popup_create_menu (GladeWidget *widget,
GladePlaceholder *placeholder,
gboolean packing)
{
GtkWidget *popup_menu;
gboolean sensitive;
popup_menu = gtk_menu_new ();
glade_popup_append_item (popup_menu, NULL, _("_Select"), TRUE,
glade_popup_select_cb, widget);
glade_popup_append_item (popup_menu, GTK_STOCK_CUT, NULL, TRUE,
glade_popup_cut_cb, widget);
glade_popup_append_item (popup_menu, GTK_STOCK_COPY, NULL, TRUE,
glade_popup_copy_cb, widget);
/* paste is placholder specific when the popup is on a placeholder */
sensitive = glade_clipboard_get_has_selection (glade_app_get_clipboard ());
if (placeholder)
glade_popup_append_item (popup_menu, GTK_STOCK_PASTE, NULL, sensitive,
glade_popup_placeholder_paste_cb, placeholder);
else
glade_popup_append_item (popup_menu, GTK_STOCK_PASTE, NULL, sensitive,
glade_popup_paste_cb, widget);
glade_popup_append_item (popup_menu, GTK_STOCK_DELETE, NULL, TRUE,
glade_popup_delete_cb, widget);
/* packing actions are a little different on placholders */
if (placeholder)
{
if (widget->actions)
{
GtkWidget *separator = gtk_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), separator);
gtk_widget_show (separator);
glade_popup_action_populate_menu_real
(popup_menu,
widget->actions,
G_CALLBACK (glade_popup_menuitem_activated),
widget);
}
if (placeholder->packing_actions)
{
GtkWidget *separator = gtk_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), separator);
gtk_widget_show (separator);
glade_popup_action_populate_menu_real
(popup_menu,
placeholder->packing_actions,
G_CALLBACK (glade_popup_menuitem_ph_packing_activated),
placeholder);
}
}
else if (widget->actions || (packing && widget->packing_actions))
{
GtkWidget *separator = gtk_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), separator);
gtk_widget_show (separator);
glade_popup_action_populate_menu (popup_menu, widget, NULL, packing);
}
return popup_menu;
}
static GtkWidget *
glade_popup_create_clipboard_menu (GladeWidget *widget)
{
GtkWidget *popup_menu;
popup_menu = gtk_menu_new ();
if (GTK_WIDGET_TOPLEVEL (glade_widget_get_object (widget)))
{
glade_popup_append_item (popup_menu, GTK_STOCK_PASTE,
NULL, TRUE,
glade_popup_clipboard_paste_cb, NULL);
}
glade_popup_append_item (popup_menu, GTK_STOCK_DELETE, NULL, TRUE,
glade_popup_clipboard_delete_cb, widget);
return popup_menu;
}
void
glade_popup_widget_pop (GladeWidget *widget,
GdkEventButton *event,
gboolean packing)
{
GtkWidget *popup_menu;
gint button;
gint event_time;
g_return_if_fail (GLADE_IS_WIDGET (widget));
popup_menu = glade_popup_create_menu (widget, NULL, packing);
if (event)
{
button = event->button;
event_time = event->time;
}
else
{
button = 0;
event_time = gtk_get_current_event_time ();
}
gtk_menu_popup (GTK_MENU (popup_menu), NULL, NULL,
NULL, NULL, button, event_time);
}
void
glade_popup_placeholder_pop (GladePlaceholder *placeholder,
GdkEventButton *event)
{
GladeWidget *widget;
GtkWidget *popup_menu;
gint button;
gint event_time;
g_return_if_fail (GLADE_IS_PLACEHOLDER (placeholder));
widget = glade_placeholder_get_parent (placeholder);
popup_menu = glade_popup_create_menu (widget, placeholder, TRUE);
if (event)
{
button = event->button;
event_time = event->time;
}
else
{
button = 0;
event_time = gtk_get_current_event_time ();
}
gtk_menu_popup (GTK_MENU (popup_menu), NULL, NULL,
NULL, NULL, button, event_time);
}
void
glade_popup_clipboard_pop (GladeWidget *widget,
GdkEventButton *event)
{
GtkWidget *popup_menu;
gint button;
gint event_time;
g_return_if_fail (GLADE_IS_WIDGET (widget));
popup_menu = glade_popup_create_clipboard_menu (widget);
if (event)
{
button = event->button;
event_time = event->time;
}
else
{
button = 0;
event_time = gtk_get_current_event_time ();
}
gtk_menu_popup (GTK_MENU (popup_menu), NULL, NULL,
NULL, NULL, button, event_time);
}
syntax highlighted by Code2HTML, v. 0.9.1