SF.net SVN: geany-plugins:[1462] trunk/geany-plugins/geanygendoc

colombanw at users.sourceforge.net colombanw at xxxxx
Mon Jun 14 19:57:39 UTC 2010


Revision: 1462
          http://geany-plugins.svn.sourceforge.net/geany-plugins/?rev=1462&view=rev
Author:   colombanw
Date:     2010-06-14 19:57:38 +0000 (Mon, 14 Jun 2010)

Log Message:
-----------
GeanyGenDoc: Add a popup menu to the documentation type selector

Modified Paths:
--------------
    trunk/geany-plugins/geanygendoc/ChangeLog
    trunk/geany-plugins/geanygendoc/src/ggd-widget-doctype-selector.c

Modified: trunk/geany-plugins/geanygendoc/ChangeLog
===================================================================
--- trunk/geany-plugins/geanygendoc/ChangeLog	2010-06-14 19:57:15 UTC (rev 1461)
+++ trunk/geany-plugins/geanygendoc/ChangeLog	2010-06-14 19:57:38 UTC (rev 1462)
@@ -7,6 +7,8 @@
   * src/ggd-tag-utils.c:
     Use Geany's symbols_get_context_separator() and not a copied version since
     it is now exported to the plugin API since 185.
+  * src/ggd-widget-doctype-selector.c:
+    Add a popup menu.
 
 
 2010-06-12  Colomban Wendling  <ban(at)herbesfolles(dot)org>

Modified: trunk/geany-plugins/geanygendoc/src/ggd-widget-doctype-selector.c
===================================================================
--- trunk/geany-plugins/geanygendoc/src/ggd-widget-doctype-selector.c	2010-06-14 19:57:15 UTC (rev 1461)
+++ trunk/geany-plugins/geanygendoc/src/ggd-widget-doctype-selector.c	2010-06-14 19:57:38 UTC (rev 1462)
@@ -25,30 +25,42 @@
 #include "ggd-plugin.h"
 
 
-static void   ggd_doctype_selector_finalize     (GObject *object);
-static void   ggd_doctype_selector_constructed  (GObject *object);
-static void   doctype_column_edited_handler     (GtkCellRendererText *renderer,
-                                                 gchar               *path,
-                                                 gchar               *new_text,
-                                                 GtkListStore        *store);
-static gint   sort_language_column              (GtkTreeModel *model,
-                                                 GtkTreeIter  *a,
-                                                 GtkTreeIter  *b,
-                                                 gpointer      user_data);
+static void     ggd_doctype_selector_finalize     (GObject *object);
+static void     ggd_doctype_selector_constructed  (GObject *object);
+static void     doctype_column_edited_handler     (GtkCellRendererText *renderer,
+                                                   gchar               *path,
+                                                   gchar               *new_text,
+                                                   GtkListStore        *store);
+static gint     sort_language_column              (GtkTreeModel *model,
+                                                   GtkTreeIter  *a,
+                                                   GtkTreeIter  *b,
+                                                   gpointer      user_data);
+static gboolean tree_view_button_press_event      (GtkTreeView         *view,
+                                                   GdkEventButton      *event,
+                                                   GgdDoctypeSelector  *selector);
+static gboolean tree_view_popup_menu              (GtkTreeView         *view,
+                                                   GgdDoctypeSelector  *selector);
+static void     tree_view_popup_clear_handler     (GtkMenuItem        *item,
+                                                   GgdDoctypeSelector *selector);
+static void     tree_view_popup_edit_handler      (GtkMenuItem        *item,
+                                                   GgdDoctypeSelector *selector);
 
 
 struct _GgdDoctypeSelectorPrivate
 {
   GtkListStore   *store;
   GtkWidget      *view;
+  GtkWidget      *popup_menu;
 };
 
 enum
 {
+  /* Sort model column IDs in the order they are shown in the view for them to
+   * correspond to tree view's columns. Inivisible column at the end. */
+  COLUMN_LANGUAGE,
+  COLUMN_DOCTYPE,
   COLUMN_ID,
-  COLUMN_LANGUAGE,
   COLUMN_TOOLTIP,
-  COLUMN_DOCTYPE,
   
   N_COLUMNS
 };
@@ -83,6 +95,7 @@
 {
   GtkCellRenderer    *renderer;
   GtkTreeViewColumn  *column;
+  GtkWidget          *item;
   
   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
                                             GGD_DOCTYPE_SELECTOR_TYPE,
@@ -94,8 +107,9 @@
                                        GTK_SHADOW_IN);
   
   /* Model */
-  self->priv->store = gtk_list_store_new (N_COLUMNS, G_TYPE_UINT, G_TYPE_STRING,
-                                          G_TYPE_STRING, G_TYPE_STRING);
+  self->priv->store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING,
+                                          G_TYPE_STRING, G_TYPE_UINT,
+                                          G_TYPE_STRING);
   gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (self->priv->store),
                                    COLUMN_LANGUAGE, sort_language_column,
                                    NULL, NULL);
@@ -122,6 +136,34 @@
                                                      "text", COLUMN_DOCTYPE,
                                                      NULL);
   gtk_tree_view_append_column (GTK_TREE_VIEW (self->priv->view), column);
+  
+  /* create popup menu */
+  self->priv->popup_menu = gtk_menu_new ();
+  g_signal_connect (self->priv->popup_menu, "deactivate",
+                    G_CALLBACK (gtk_widget_hide), NULL);
+  gtk_menu_attach_to_widget (GTK_MENU (self->priv->popup_menu),
+                             self->priv->view, NULL);
+  item = gtk_image_menu_item_new_with_mnemonic (_("_Change associated documentation type"));
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
+                                 gtk_image_new_from_stock (GTK_STOCK_EDIT,
+                                                           GTK_ICON_SIZE_MENU));
+  g_signal_connect (item, "activate",
+                    G_CALLBACK (tree_view_popup_edit_handler), self);
+  gtk_menu_shell_append (GTK_MENU_SHELL (self->priv->popup_menu), item);
+  gtk_widget_show (item);
+  item = gtk_image_menu_item_new_with_mnemonic (_("_Disassociate documentation type"));
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
+                                 gtk_image_new_from_stock (GTK_STOCK_CLEAR,
+                                                           GTK_ICON_SIZE_MENU));
+  g_signal_connect (item, "activate",
+                    G_CALLBACK (tree_view_popup_clear_handler), self);
+  gtk_menu_shell_append (GTK_MENU_SHELL (self->priv->popup_menu), item);
+  gtk_widget_show (item);
+  /* connect signals for popping the menu up */
+  g_signal_connect (self->priv->view, "button-press-event",
+                    G_CALLBACK (tree_view_button_press_event), self);
+  g_signal_connect (self->priv->view, "popup-menu",
+                    G_CALLBACK (tree_view_popup_menu), self);
 }
 
 static void
@@ -157,6 +199,151 @@
   }
 }
 
+/* clears documentation type on the selected row */
+static void
+tree_view_popup_clear_handler (GtkMenuItem        *item,
+                               GgdDoctypeSelector *selector)
+{
+  GtkTreeIter       iter;
+  GtkTreeSelection *selection;
+  
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (selector->priv->view));
+  if (gtk_tree_selection_get_selected (selection, NULL, &iter)) {
+    gtk_list_store_set (selector->priv->store, &iter, COLUMN_DOCTYPE, "", -1);
+  }
+}
+
+/* starts editing of the documentation type on the selected row */
+static void
+tree_view_popup_edit_handler (GtkMenuItem        *item,
+                              GgdDoctypeSelector *selector)
+{
+  GtkTreeIter       iter;
+  GtkTreeSelection *selection;
+  GtkTreeModel     *model;
+  GtkTreeView      *view = GTK_TREE_VIEW (selector->priv->view);
+  
+  selection = gtk_tree_view_get_selection (view);
+  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+    GtkTreePath        *path;
+    GtkTreeViewColumn  *column;
+    
+    path = gtk_tree_model_get_path (model, &iter);
+    column = gtk_tree_view_get_column (view, COLUMN_DOCTYPE);
+    gtk_tree_view_set_cursor_on_cell (view, path, column, NULL, TRUE);
+    gtk_tree_path_free (path);
+  }
+}
+
+static void
+tree_view_popup_menu_position_func (GtkMenu   *menu,
+                                    gint      *x,
+                                    gint      *y,
+                                    gboolean  *push_in,
+                                    gpointer   user_data)
+{
+  GgdDoctypeSelector *selector = user_data;
+  GtkTreeView        *view = GTK_TREE_VIEW (selector->priv->view);
+  GdkScreen          *screen = gtk_widget_get_screen (selector->priv->view);
+  gint                monitor_id;
+  GtkTreeModel       *model;
+  GtkTreeViewColumn  *column;
+  GtkTreeSelection   *selection;
+  GtkTreePath        *path;
+  GtkTreeIter         iter;
+  GdkWindow          *window;
+  GdkRectangle        cell;
+  GdkRectangle        monitor;
+  GtkRequisition      req;
+  
+  g_return_if_fail (gtk_widget_get_realized (selector->priv->view));
+
+  window = gtk_widget_get_window (GTK_WIDGET (view));
+  gdk_window_get_origin (window, x, y);
+  /* ensure there is a row selected */
+  selection = gtk_tree_view_get_selection (view);
+  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+    path = gtk_tree_model_get_path (model, &iter);
+  } else {
+    gtk_tree_view_get_cursor (view, &path, NULL);
+    gtk_tree_selection_select_path (selection, path);
+  }
+  column = gtk_tree_view_get_column (view, COLUMN_DOCTYPE);
+  gtk_tree_view_scroll_to_cell (view, path, column, FALSE, 0.0, 0.0);
+  gtk_tree_view_get_cell_area (view, path, column, &cell);
+  gtk_tree_path_free (path);
+  gtk_tree_view_convert_bin_window_to_widget_coords (view,
+                                                     *x + cell.x, *y + cell.y,
+                                                     x, y);
+  gtk_widget_size_request (GTK_WIDGET (menu), &req);
+  monitor_id = gdk_screen_get_monitor_at_point (screen, *x, *y);
+  gtk_menu_set_monitor (menu, monitor_id);
+  gdk_screen_get_monitor_geometry (screen, monitor_id, &monitor);
+  if (*y + cell.height + req.height <= monitor.height) {
+    *y += cell.height;
+  } else {
+    *y -= req.height;
+  }
+  *x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width));
+  *y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height));
+  *push_in = FALSE;
+}
+
+static void
+do_popup_menu (GgdDoctypeSelector *self,
+               GdkEventButton     *event)
+{
+  guint               event_button;
+  guint32             event_time;
+  GtkMenuPositionFunc menu_position_func;
+  
+  if (event) {
+    event_button = event->button;
+    event_time = event->time;
+    menu_position_func = NULL;
+  } else {
+    event_button = 0;
+    event_time = gtk_get_current_event_time ();
+    menu_position_func = tree_view_popup_menu_position_func;
+  }
+  gtk_menu_popup (GTK_MENU (self->priv->popup_menu), NULL, NULL,
+                  menu_position_func, self, event_button, event_time);
+}
+
+static gboolean
+tree_view_button_press_event (GtkTreeView        *view,
+                              GdkEventButton     *event,
+                              GgdDoctypeSelector *selector)
+{
+  gboolean handled = FALSE;
+  
+  /* Ignore double-clicks and triple-clicks */
+  if (event->button == 3 && event->type == GDK_BUTTON_PRESS) {
+    GtkTreePath *path;
+    
+    /* select row under the cursor before poping the menu up */
+    if (gtk_tree_view_get_path_at_pos (view, (gint)event->x, (gint)event->y,
+                                       &path, NULL, NULL, NULL)) {
+      gtk_tree_selection_select_path (gtk_tree_view_get_selection (view), path);
+      gtk_tree_view_scroll_to_cell (view, path, NULL, FALSE, 0.0, 0.0);
+      gtk_tree_path_free (path);
+    }
+    do_popup_menu (selector, event);
+    handled = TRUE;
+  }
+
+  return handled;
+}
+
+static gboolean
+tree_view_popup_menu (GtkTreeView        *view,
+                      GgdDoctypeSelector *selector)
+{
+  do_popup_menu (selector, NULL);
+  
+  return TRUE;
+}
+
 /* Gets the row having @language_id as language ID.
  * Returns: %TRUE if @iter was set, %FALSE otherwise */
 static gboolean


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Plugins-Commits mailing list