glade-popup.c 21.9 KB
Newer Older
Jose Maria Celorio's avatar
Jose Maria Celorio committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * 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
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Jose Maria Celorio's avatar
Jose Maria Celorio committed
17 18 19
 *
 * Authors:
 *   Chema Celorio <chema@celorio.com>
20
 *   Tristan Van Berkom <tvb@gnome.org>
Jose Maria Celorio's avatar
Jose Maria Celorio committed
21 22
 */

23 24 25 26 27 28
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <glib/gi18n-lib.h>

Jose Maria Celorio's avatar
Jose Maria Celorio committed
29 30
#include "glade.h"
#include "glade-widget.h"
31
#include "glade-widget-adaptor.h"
Jose Maria Celorio's avatar
Jose Maria Celorio committed
32
#include "glade-popup.h"
33
#include "glade-placeholder.h"
34 35
#include "glade-clipboard.h"
#include "glade-command.h"
Joaquín Cuenca Abela's avatar
Joaquín Cuenca Abela committed
36
#include "glade-project.h"
37
#include "glade-app.h"
38

39
static void
40
glade_popup_docs_cb (GtkMenuItem *item, GladeWidgetAdaptor *adaptor)
41 42 43
{
  g_return_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor));

44
  glade_app_search_docs (glade_widget_adaptor_get_book (adaptor),
45
                         glade_widget_adaptor_get_display_name (adaptor),
46
                         NULL);
47 48
}

49 50 51
/********************************************************
                      WIDGET POPUP
 *******************************************************/
Jose Maria Celorio's avatar
Jose Maria Celorio committed
52
static void
53
glade_popup_select_cb (GtkMenuItem *item, GladeWidget *widget)
Jose Maria Celorio's avatar
Jose Maria Celorio committed
54
{
55
  glade_project_selection_set (glade_widget_get_project (widget),
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
56
                               glade_widget_get_object (widget), TRUE);
57
}
58

59
typedef struct {
60
  GladeWidgetAdaptor *adaptor;
61 62 63 64
  GladeProject       *project;
  GladeWidget        *parent;
  GladePlaceholder   *placeholder;
} RootAddData;
65

66 67 68
static void
glade_popup_widget_add_cb (GtkMenuItem *item, RootAddData *data)
{
69 70 71
  gboolean use_group = FALSE;
  GObject *parent;

72
  g_return_if_fail (data->adaptor != NULL);
73

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
  parent = glade_widget_get_object (data->parent);

  if ((GTK_IS_BOX (parent) || GTK_IS_GRID (parent)) &&
      glade_util_count_placeholders (data->parent) == 0)
    {
      GladeProperty *prop;
      gint value;

      glade_command_push_group (_("Create %s"),
                                glade_widget_adaptor_get_name (data->adaptor));

      if (GTK_IS_BOX (parent))
        prop = glade_widget_get_property (data->parent, "size");
      else
        prop = glade_widget_get_property (data->parent, "n-columns");
89

90 91 92 93 94 95 96 97 98 99
      glade_property_get (prop, &value);
      glade_command_set_property (prop, ++value);

      use_group = TRUE;
    }

  if (glade_command_create (data->adaptor,
                            data->parent,
                            data->placeholder,
                            data->project))
100
    glade_project_set_add_item (data->project, NULL);
101 102 103

  if (use_group)
    glade_command_pop_group();
104 105 106
}

static void
107
glade_popup_root_add_cb (GtkMenuItem *item, RootAddData *data)
108
{
109 110
  if (glade_command_create (data->adaptor, NULL, NULL, data->project))
    glade_project_set_add_item (data->project, NULL);
111 112
}

113
static void
114
glade_popup_cut_cb (GtkMenuItem *item, GladeWidget *widget)
115
{
116
  GladeProject *project = glade_widget_get_project (widget);
117

118 119 120 121 122 123
  /* Assign selection first only if its not already assigned (it may be a delete
   * of multiple widgets) */
  if (!glade_project_is_selected (project, glade_widget_get_object (widget)))
    glade_project_selection_set (project, glade_widget_get_object (widget), FALSE);

  glade_project_command_cut (project);
Jose Maria Celorio's avatar
Jose Maria Celorio committed
124 125 126
}

static void
127
glade_popup_copy_cb (GtkMenuItem *item, GladeWidget *widget)
Jose Maria Celorio's avatar
Jose Maria Celorio committed
128
{
129
  GladeProject *project = glade_widget_get_project (widget);
130

131
  /* Assign selection first */
132
  if (!glade_project_is_selected (project, glade_widget_get_object (widget)))
133
    glade_project_selection_set (project, glade_widget_get_object (widget), FALSE);
134

135
  glade_project_copy_selection (project);
136
}
Jose Maria Celorio's avatar
Jose Maria Celorio committed
137

138
static void
139
glade_popup_paste_cb (GtkMenuItem *item, gpointer data)
140
{
141 142 143 144 145 146 147 148 149 150 151 152 153
  GladeWidget  *widget = NULL;
  GladeProject *project;

  if (GLADE_IS_WIDGET (data))
    {
      widget  = GLADE_WIDGET (data);
      project = glade_widget_get_project (widget);
    }
  else if (GLADE_IS_PROJECT (data))
    project = GLADE_PROJECT (data);
  else
    g_return_if_reached ();

154 155
  /* The selected widget is the paste destination */
  if (widget)
156
    glade_project_selection_set (project, glade_widget_get_object (widget), FALSE);
157
  else
158
    glade_project_selection_clear (project, FALSE);
159

160
  glade_project_command_paste (project, NULL);
161
}
Jose Maria Celorio's avatar
Jose Maria Celorio committed
162

163
static void
164
glade_popup_delete_cb (GtkMenuItem *item, GladeWidget *widget)
165
{
166
  GladeProject *project = glade_widget_get_project (widget);
167

168 169 170
  /* Assign selection first */
  if (glade_project_is_selected
      (project, glade_widget_get_object (widget)) == FALSE)
171
    glade_project_selection_set (project, glade_widget_get_object (widget), FALSE);
172

173
  glade_project_command_delete (project);
Jose Maria Celorio's avatar
Jose Maria Celorio committed
174
}
175

176 177 178
/********************************************************
                  PLACEHOLDER POPUP
 *******************************************************/
179
static void
180
glade_popup_placeholder_paste_cb (GtkMenuItem      *item, 
181
                                  GladePlaceholder *placeholder)
182
{
183
  GladeProject *project;
184

185
  project = glade_placeholder_get_project (placeholder);
186

187
  glade_project_selection_clear (project, FALSE);
188

189
  glade_project_command_paste (project, placeholder);
190 191
}

192 193 194
/********************************************************
                    POPUP BUILDING
 *******************************************************/
195
static GtkWidget *
196
glade_popup_append_item (GtkWidget   *popup_menu,
197
                         const gchar *label,
198 199 200
                         gboolean     sensitive,
                         gpointer     callback,
                         gpointer     data)
Jose Maria Celorio's avatar
Jose Maria Celorio committed
201
{
202
  GtkWidget *menu_item = gtk_menu_item_new_with_mnemonic (label);
203 204 205 206 207 208 209 210 211 212

  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;
Jose Maria Celorio's avatar
Jose Maria Celorio committed
213 214
}

215

Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
216
static void
217
glade_popup_menuitem_activated (GtkMenuItem *item, const gchar *action_path)
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
218
{
219 220 221
  GladeWidget *widget;

  if ((widget = g_object_get_data (G_OBJECT (item), "gwa-data")))
222 223
    glade_widget_adaptor_action_activate (glade_widget_get_adaptor (widget),
                                          glade_widget_get_object (widget), action_path);
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
224 225
}

226
static void
227 228
glade_popup_menuitem_packing_activated (GtkMenuItem *item,
                                        const gchar *action_path)
229
{
230
  GladeWidget *widget, *parent;
231 232

  if ((widget = g_object_get_data (G_OBJECT (item), "gwa-data")))
233 234 235
    {
      parent = glade_widget_get_parent (widget);
      glade_widget_adaptor_child_action_activate (glade_widget_get_adaptor (parent),
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
236 237
                                                  glade_widget_get_object (parent),
                                                  glade_widget_get_object (widget), action_path);
238
    }
239 240
}

241
static void
242 243
glade_popup_menuitem_ph_packing_activated (GtkMenuItem *item,
                                           const gchar *action_path)
244
{
245 246 247 248 249 250
  GladePlaceholder *ph;
  GladeWidget *parent;

  if ((ph = g_object_get_data (G_OBJECT (item), "gwa-data")))
    {
      parent = glade_placeholder_get_parent (ph);
251 252
      glade_widget_adaptor_child_action_activate (glade_widget_get_adaptor (parent),
                                                  glade_widget_get_object (parent),
253 254
                                                  G_OBJECT (ph), action_path);
    }
255 256
}

257
static gint
258
glade_popup_action_populate_menu_real (GtkWidget   *menu,
259
                                       GladeWidget *gwidget,
260 261 262
                                       GList       *actions,
                                       GCallback    callback,
                                       gpointer     data)
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
263
{
264 265 266 267 268 269
  GtkWidget *item;
  GList *list;
  gint n = 0;

  for (list = actions; list; list = g_list_next (list))
    {
270 271 272 273
      GladeWidgetAction    *action = list->data;
      GladeWidgetActionDef *adef = glade_widget_action_get_def (action);
      GList                *children = glade_widget_action_get_children (action);
      GtkWidget            *submenu = NULL;
274

275
      if (!glade_widget_action_get_visible (action))
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
276
        continue;
277 278

      if (children)
279 280 281 282
        {
          submenu = gtk_menu_new ();
          n += glade_popup_action_populate_menu_real (submenu,
                                                      gwidget,
283
                                                      children,
284 285 286
                                                      callback, data);
        }
      else
287 288
        submenu = glade_widget_adaptor_action_submenu (glade_widget_get_adaptor (gwidget),
                                                       glade_widget_get_object (gwidget),
289
                                                       adef->path);
290 291


292
      item = glade_popup_append_item (menu, adef->label, TRUE,
293
                                      (children) ? NULL : callback,
294
                                      (children) ? NULL : adef->path);
295 296 297

      g_object_set_data (G_OBJECT (item), "gwa-data", data);

298
      gtk_widget_set_sensitive (item, glade_widget_action_get_sensitive (action));
299 300 301 302 303 304 305 306

      if (submenu)
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);

      n++;
    }

  return n;
307 308
}

309 310 311 312 313
/*
 * 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.
314
 * @packing: TRUE to include packing actions
315 316 317 318 319 320
 *
 * Populate a GtkMenu with widget's actions
 *
 * Returns the number of action appended to the menu.
 */
gint
321 322
glade_popup_action_populate_menu (GtkWidget         *menu,
                                  GladeWidget       *widget,
323
                                  GladeWidgetAction *action,
324
                                  gboolean           packing)
325
{
326 327 328 329 330
  gint n;

  g_return_val_if_fail (GTK_IS_MENU (menu), 0);
  g_return_val_if_fail (GLADE_IS_WIDGET (widget), 0);

331 332
  g_return_val_if_fail (action == NULL || GLADE_IS_WIDGET_ACTION (action), 0);

333 334
  if (action)
    {
335 336
      GladeWidgetActionDef *adef = glade_widget_action_get_def (action);
      GList                *children = glade_widget_action_get_children (action);
337
      
338
      if (glade_widget_get_action (widget, adef->path) &&
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
339
          glade_widget_action_get_visible (action))
340 341
        return glade_popup_action_populate_menu_real (menu,
                                                      widget,
342
                                                      children,
343 344 345 346
                                                      G_CALLBACK
                                                      (glade_popup_menuitem_activated),
                                                      widget);

347
      if (glade_widget_get_pack_action (widget, adef->path) &&
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
348
          glade_widget_action_get_visible (action))
349 350
        return glade_popup_action_populate_menu_real (menu,
                                                      glade_widget_get_parent
351
                                                      (widget), children,
352 353 354 355 356 357 358 359 360
                                                      G_CALLBACK
                                                      (glade_popup_menuitem_packing_activated),
                                                      widget);

      return 0;
    }

  n = glade_popup_action_populate_menu_real (menu,
                                             widget,
361
                                             glade_widget_get_actions (widget),
362 363 364 365
                                             G_CALLBACK
                                             (glade_popup_menuitem_activated),
                                             widget);

366
  if (packing && glade_widget_get_pack_actions (widget))
367 368 369
    {
      if (n)
        {
370
          GtkWidget *separator = gtk_separator_menu_item_new ();
371 372 373
          gtk_menu_shell_append (GTK_MENU_SHELL (menu), separator);
          gtk_widget_show (separator);
        }
374

375
      n += glade_popup_action_populate_menu_real 
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
376 377 378
        (menu, glade_widget_get_parent (widget),
         glade_widget_get_pack_actions (widget),
         G_CALLBACK (glade_popup_menuitem_packing_activated), widget);
379 380 381
    }

  return n;
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
382
}
383

384
static GtkWidget *
385 386
glade_popup_create_menu (GladeWidget      *widget,
                         GladePlaceholder *placeholder, 
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
387 388
                         GladeProject     *project,
                         gboolean          packing)
Jose Maria Celorio's avatar
Jose Maria Celorio committed
389
{
390 391 392 393
  GtkWidget          *popup_menu;
  GtkWidget          *separator;
  gboolean            sensitive;
  GladeWidgetAdaptor *adaptor;
394 395 396

  popup_menu = gtk_menu_new ();

397 398 399
  adaptor = glade_project_get_add_item (project);

  if (adaptor)
400
    {
401
      RootAddData *data = g_new (RootAddData, 1);
402
      
403 404
      data->adaptor = adaptor;
      data->project = project;
405 406 407
      data->parent = placeholder ? glade_placeholder_get_parent (placeholder) : widget;
      data->placeholder = placeholder;
      
408
      g_object_set_data_full (G_OBJECT (popup_menu), "root-data-destroy-me", 
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
409
                              data, (GDestroyNotify)g_free);
410

411 412
      glade_popup_append_item (popup_menu, _("_Add widget here"),
                               data->parent != NULL,
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
413 414
                               glade_popup_widget_add_cb,
                               data);
415

416 417
      glade_popup_append_item (popup_menu, _("Add widget as _toplevel"), TRUE,
                               glade_popup_root_add_cb, data);
418

419
      separator = gtk_separator_menu_item_new ();
420 421 422 423 424 425
      gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), separator);
      gtk_widget_show (separator);
    }

  sensitive = (widget != NULL);

426
  glade_popup_append_item (popup_menu, _("_Select"), sensitive,
427
                           glade_popup_select_cb, widget);
428
  glade_popup_append_item (popup_menu, _("Cu_t"), sensitive,
429
                           glade_popup_cut_cb, widget);
430
  glade_popup_append_item (popup_menu, _("_Copy"), sensitive,
431 432 433 434 435 436
                           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)
437
    glade_popup_append_item (popup_menu, _("_Paste"), sensitive,
438 439
                             glade_popup_placeholder_paste_cb, placeholder);
  else if (widget)
440
    glade_popup_append_item (popup_menu, _("_Paste"), sensitive,
441 442
                             glade_popup_paste_cb, widget);
  else
443
    glade_popup_append_item (popup_menu, _("_Paste"), sensitive,
444 445 446
                             glade_popup_paste_cb, NULL);


447 448
  glade_popup_append_item (popup_menu, _("_Delete"), (widget != NULL),
                           glade_popup_delete_cb, widget);
449 450 451 452 453


  /* packing actions are a little different on placholders */
  if (placeholder)
    {
454
      if (widget && glade_widget_get_actions (widget))
455
        {
456
          GtkWidget *separator = gtk_separator_menu_item_new ();
457 458 459 460 461 462
          gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), separator);
          gtk_widget_show (separator);

          glade_popup_action_populate_menu_real
              (popup_menu,
               widget,
463
               glade_widget_get_actions (widget),
464 465 466
               G_CALLBACK (glade_popup_menuitem_activated), widget);
        }

467
      if (glade_placeholder_packing_actions (placeholder))
468
        {
469
          GtkWidget *separator = gtk_separator_menu_item_new ();
470 471 472 473 474 475
          gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), separator);
          gtk_widget_show (separator);

          glade_popup_action_populate_menu_real
              (popup_menu,
               widget,
476
               glade_placeholder_packing_actions (placeholder),
477 478 479 480
               G_CALLBACK (glade_popup_menuitem_ph_packing_activated),
               placeholder);
        }
    }
481
  else if (widget && (glade_widget_get_actions (widget) || 
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
482
                      (packing && glade_widget_get_pack_actions (widget))))
483
    {
484
      GtkWidget *separator = gtk_separator_menu_item_new ();
485 486 487 488 489 490 491
      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;
Jose Maria Celorio's avatar
Jose Maria Celorio committed
492 493 494
}

void
495
glade_popup_widget_pop (GladeWidget    *widget,
496
                        GdkEventButton *event,
497
                        gboolean        packing)
Jose Maria Celorio's avatar
Jose Maria Celorio committed
498
{
499 500 501 502 503 504
  GtkWidget *popup_menu;
  gint button;
  gint event_time;

  g_return_if_fail (GLADE_IS_WIDGET (widget) || widget == NULL);

505
  popup_menu = glade_popup_create_menu (widget, NULL, glade_widget_get_project (widget), packing);
506 507 508 509 510 511 512 513 514 515 516 517 518

  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);
Jose Maria Celorio's avatar
Jose Maria Celorio committed
519
}
520 521

void
522
glade_popup_placeholder_pop (GladePlaceholder *placeholder,
523
                             GdkEventButton   *event)
524
{
525 526 527 528 529 530 531 532 533
  GladeWidget *widget;
  GtkWidget *popup_menu;
  gint button;
  gint event_time;

  g_return_if_fail (GLADE_IS_PLACEHOLDER (placeholder));

  widget = glade_placeholder_get_parent (placeholder);

534
  popup_menu = glade_popup_create_menu (widget, placeholder, 
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
535
                                        glade_widget_get_project (widget), TRUE);
536 537 538 539 540 541 542 543 544 545 546 547 548 549

  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);
550
}
551

552
void
553
glade_popup_palette_pop (GladePalette       *palette, 
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
554 555
                         GladeWidgetAdaptor *adaptor, 
                         GdkEventButton     *event)
556
{
557 558 559 560
  GladeProject *project;
  GtkWidget *popup_menu;
  gint button;
  gint event_time;
561
  RootAddData *data;
562 563 564 565 566

  g_return_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor));

  popup_menu = gtk_menu_new ();

567
  project = glade_palette_get_project (palette);
568

569 570 571 572
  data = g_new (RootAddData, 1);
  data->adaptor = adaptor;
  data->project = project;
  g_object_set_data_full (G_OBJECT (popup_menu), "root-data-destroy-me", 
Juan Pablo Ugarte's avatar
Juan Pablo Ugarte committed
573
                          data, (GDestroyNotify)g_free);
574

575 576
  glade_popup_append_item (popup_menu, _("Add widget as _toplevel"), TRUE,
                           glade_popup_root_add_cb, data);
577

578
  if (glade_widget_adaptor_get_book (adaptor) && glade_util_have_devhelp ())
579 580
    glade_popup_append_item (popup_menu, _("Read _documentation"), TRUE,
                             glade_popup_docs_cb, adaptor);
581 582 583 584 585 586 587 588 589 590 591 592 593 594

  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);
595 596
}

597
static void
598
glade_popup_clear_property_cb (GtkMenuItem *item, GladeProperty *property)
599
{
600
  GValue value = { 0, };
601

602 603 604
  glade_property_get_default (property, &value);
  glade_command_set_property_value (property, &value);
  g_value_unset (&value);
605 606 607
}

static void
608
glade_popup_property_docs_cb (GtkMenuItem *item, GladeProperty *property)
609
{
610
  GladeWidgetAdaptor *adaptor, *prop_adaptor;
611
  GladePropertyDef   *pdef;
612
  GParamSpec         *pspec;
613
  gchar              *search;
614

615 616 617
  pdef         = glade_property_get_def (property);
  pspec        = glade_property_def_get_pspec (pdef);
  prop_adaptor = glade_property_def_get_adaptor (pdef);
618
  adaptor      = glade_widget_adaptor_from_pspec (prop_adaptor, pspec);
619
  search       = g_strdup_printf ("The \"%s\" property", glade_property_def_id (pdef));
620

621 622
  glade_app_search_docs (glade_widget_adaptor_get_book (adaptor),
                         g_type_name (pspec->owner_type), search);
623

624
  g_free (search);
625 626 627
}

void
628
glade_popup_property_pop (GladeProperty *property, GdkEventButton *event)
629 630
{

631
  GladeWidgetAdaptor *adaptor, *prop_adaptor;
632
  GladePropertyDef   *pdef;
633
  GParamSpec         *pspec;
634 635 636 637
  GtkWidget *popup_menu;
  gint button;
  gint event_time;

638 639 640
  pdef         = glade_property_get_def (property);
  pspec        = glade_property_def_get_pspec (pdef);
  prop_adaptor = glade_property_def_get_adaptor (pdef);
641
  adaptor      = glade_widget_adaptor_from_pspec (prop_adaptor, pspec);
642 643 644 645 646

  g_return_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor));

  popup_menu = gtk_menu_new ();

647 648
  glade_popup_append_item (popup_menu, _("Set default value"), TRUE,
                           glade_popup_clear_property_cb, property);
649

650
  if (!glade_property_def_get_virtual (pdef) &&
651 652
      glade_widget_adaptor_get_book (adaptor) &&
      glade_util_have_devhelp ())
653
    {
654 655
      glade_popup_append_item (popup_menu, _("Read _documentation"), TRUE,
                               glade_popup_property_docs_cb, property);
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
    }

  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);
671 672
}

673
void
674
glade_popup_simple_pop (GladeProject *project, GdkEventButton *event)
675
{
676 677 678 679
  GtkWidget *popup_menu;
  gint button;
  gint event_time;

680
  popup_menu = glade_popup_create_menu (NULL, NULL, project, FALSE);
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695
  if (!popup_menu)
    return;

  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);
696 697
}

698
gboolean
699
glade_popup_is_popup_event (GdkEventButton *event)
700
{
701
  g_return_val_if_fail (event, FALSE);
702

703
#ifdef __APPLE__
704 705
  return (event->type == GDK_BUTTON_PRESS && event->button == 1 &&
          ((event->state & GDK_MOD1_MASK) != 0));
706
#else
707
  return (event->type == GDK_BUTTON_PRESS && event->button == 3);
708 709
#endif
}