From: Jim Evins Date: Tue, 20 Oct 2009 03:59:02 +0000 (-0400) Subject: Create new glFieldButton widget family X-Git-Tag: glabels-2_3_0~156 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=797627cec95e55d0305a0b7aa81811cd5be291a4;p=glabels Create new glFieldButton widget family Created new glFieldButton widget family modelled after glFontCombo. This widget is for inserting merge fields into text. This button will pop-up a menu containing possible field keys. The button attempts to place the menu intelligently, rather than simply where the button was pressed. Renamed glWdgtMergeMenu to glFieldButtonMenu. --- diff --git a/data/builder/object-editor.builder b/data/builder/object-editor.builder index 5cfb9002..365f4267 100644 --- a/data/builder/object-editor.builder +++ b/data/builder/object-editor.builder @@ -86,12 +86,12 @@ True 12 - - Insert merge field + True - True - False - True + vertical + + + False diff --git a/po/POTFILES.in b/po/POTFILES.in index de755fa9..e0c51d34 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -38,6 +38,10 @@ src/critical-error-handler.c src/critical-error-handler.h src/debug.c src/debug.h +src/field-button.c +src/field-button.h +src/field-button-menu.c +src/field-button-menu.h src/file.c src/file.h src/file-util.c @@ -167,8 +171,6 @@ src/wdgt-chain-button.c src/wdgt-chain-button.h src/wdgt-media-select.c src/wdgt-media-select.h -src/wdgt-merge-menu.c -src/wdgt-merge-menu.h src/window.c src/window.h src/xml-label-04.c diff --git a/src/Makefile.am b/src/Makefile.am index 2c312744..6008dee8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -179,8 +179,10 @@ glabels_SOURCES = \ rotate-label-button.h \ wdgt-chain-button.c \ wdgt-chain-button.h \ - wdgt-merge-menu.c \ - wdgt-merge-menu.h \ + field-button.c \ + field-button.h \ + field-button-menu.c \ + field-button-menu.h \ color-combo.c \ color-combo.h \ color-combo-button.c \ diff --git a/src/debug.c b/src/debug.c index ce53820a..97972e55 100644 --- a/src/debug.c +++ b/src/debug.c @@ -91,8 +91,8 @@ gl_debug_init (void) debug_flags |= GLABELS_DEBUG_WDGT; if (g_getenv ("GLABELS_DEBUG_PATH") != NULL) debug_flags |= GLABELS_DEBUG_PATH; - if (g_getenv ("GLABELS_DEBUG_MERGE_MENU") != NULL) - debug_flags |= GLABELS_DEBUG_MERGE_MENU; + if (g_getenv ("GLABELS_DEBUG_FIELD_BUTTON") != NULL) + debug_flags |= GLABELS_DEBUG_FIELD_BUTTON; } diff --git a/src/debug.h b/src/debug.h index 6dced6d4..b8bed985 100644 --- a/src/debug.h +++ b/src/debug.h @@ -62,7 +62,7 @@ typedef enum { GLABELS_DEBUG_EDITOR = 1 << 19, GLABELS_DEBUG_WDGT = 1 << 20, GLABELS_DEBUG_PATH = 1 << 21, - GLABELS_DEBUG_MERGE_MENU = 1 << 22, + GLABELS_DEBUG_FIELD_BUTTON = 1 << 22, } glDebugSection; @@ -92,7 +92,7 @@ typedef enum { #define DEBUG_EDITOR GLABELS_DEBUG_EDITOR, __FILE__, __LINE__, __FUNCTION__ #define DEBUG_WDGT GLABELS_DEBUG_WDGT, __FILE__, __LINE__, __FUNCTION__ #define DEBUG_PATH GLABELS_DEBUG_PATH, __FILE__, __LINE__, __FUNCTION__ -#define DEBUG_MERGE_MENU GLABELS_DEBUG_MERGE_MENU, __FILE__, __LINE__, __FUNCTION__ +#define DEBUG_FIELD_BUTTON GLABELS_DEBUG_FIELD_BUTTON, __FILE__, __LINE__, __FUNCTION__ void gl_debug_init (void); diff --git a/src/field-button-menu.c b/src/field-button-menu.c new file mode 100644 index 00000000..a59bb3b2 --- /dev/null +++ b/src/field-button-menu.c @@ -0,0 +1,222 @@ +/* + * field-button-menu.c + * Copyright (C) 2008-2009 Jim Evins . + * + * This file is part of gLabels. + * + * gLabels 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 3 of the License, or + * (at your option) any later version. + * + * gLabels 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 gLabels. If not, see . + */ + +#include + +#include "field-button-menu.h" + +#include +#include + +#include "marshal.h" + +#include "debug.h" + + +/*===========================================*/ +/* Private types */ +/*===========================================*/ + + +struct _glFieldButtonMenuPrivate { + + GList *menu_items; +}; + +enum { + KEY_SELECTED, + LAST_SIGNAL +}; + +typedef void (*glFieldButtonMenuSignal) (GObject * object, gpointer data); + + +/*===========================================*/ +/* Private globals */ +/*===========================================*/ + +static gint signals[LAST_SIGNAL] = { 0 }; + + +/*===========================================*/ +/* Local function prototypes */ +/*===========================================*/ + +static void gl_field_button_menu_finalize (GObject *object); + + +/****************************************************************************/ +/* Boilerplate Object stuff. */ +/****************************************************************************/ +G_DEFINE_TYPE (glFieldButtonMenu, gl_field_button_menu, GTK_TYPE_MENU); + + +static void +gl_field_button_menu_class_init (glFieldButtonMenuClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + gl_debug (DEBUG_FIELD_BUTTON, "START"); + + gl_field_button_menu_parent_class = g_type_class_peek_parent (class); + + object_class->finalize = gl_field_button_menu_finalize; + + signals[KEY_SELECTED] = + g_signal_new ("key_selected", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (glFieldButtonMenuClass, key_selected), + NULL, NULL, + gl_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + gl_debug (DEBUG_FIELD_BUTTON, "END"); +} + + +static void +gl_field_button_menu_init (glFieldButtonMenu *merge_menu) +{ + gl_debug (DEBUG_FIELD_BUTTON, "START"); + + merge_menu->priv = g_new0 (glFieldButtonMenuPrivate, 1); + + gl_debug (DEBUG_FIELD_BUTTON, "END"); +} + + +static void +gl_field_button_menu_finalize (GObject *object) +{ + glFieldButtonMenu *merge_menu = GL_FIELD_BUTTON_MENU (object); + GList *p; + GtkWidget *menu_item; + gchar *field; + + gl_debug (DEBUG_FIELD_BUTTON, "START"); + + g_return_if_fail (object != NULL); + g_return_if_fail (GL_IS_FIELD_BUTTON_MENU (object)); + + for ( p = merge_menu->priv->menu_items; p != NULL; p = p->next ) + { + menu_item = GTK_WIDGET (p->data); + field = g_object_get_data (G_OBJECT (menu_item), "field"); + g_free (field); + } + g_list_free (merge_menu->priv->menu_items); + g_free (merge_menu->priv); + + G_OBJECT_CLASS (gl_field_button_menu_parent_class)->finalize (object); + + gl_debug (DEBUG_FIELD_BUTTON, "END"); +} + + +GtkWidget * +gl_field_button_menu_new (void) +{ + glFieldButtonMenu *merge_menu; + + gl_debug (DEBUG_FIELD_BUTTON, "START"); + + merge_menu = g_object_new (gl_field_button_menu_get_type (), NULL); + + gl_debug (DEBUG_FIELD_BUTTON, "END"); + + return GTK_WIDGET (merge_menu); +} + + +/*--------------------------------------------------------------------------*/ +/* PRIVATE. Menu item activation callback. */ +/*--------------------------------------------------------------------------*/ +static void +activate_cb (GtkMenuItem *menu_item, + glFieldButtonMenu *merge_menu) +{ + gchar *key; + + gl_debug (DEBUG_FIELD_BUTTON, "START"); + + key = g_object_get_data (G_OBJECT (menu_item), "key"); + gl_debug (DEBUG_FIELD_BUTTON, "Key activated: \"%s\"\n", key ); + + g_signal_emit (G_OBJECT (merge_menu), signals[KEY_SELECTED], 0, key); + + gl_debug (DEBUG_FIELD_BUTTON, "END"); +} + + +/****************************************************************************/ +/* set key names. */ +/****************************************************************************/ +void +gl_field_button_menu_set_keys (glFieldButtonMenu *merge_menu, + GList *key_list) +{ + GList *p; + GtkWidget *menu_item; + gchar *key; + + gl_debug (DEBUG_FIELD_BUTTON, "START"); + + /* + * Remove all old menu items. + */ + for ( p = merge_menu->priv->menu_items; p != NULL; p = p->next ) + { + menu_item = GTK_WIDGET (p->data); + key = g_object_get_data (G_OBJECT (menu_item), "key"); + g_free (key); + gtk_widget_destroy (menu_item); + } + g_list_free (merge_menu->priv->menu_items); + merge_menu->priv->menu_items = NULL; + + /* + * Add new menu items. + */ + for ( p = key_list; p != NULL; p = p->next ) + { + gl_debug (DEBUG_FIELD_BUTTON, "Adding key: %s", p->data); + menu_item = gtk_menu_item_new_with_label (p->data); + g_object_set_data (G_OBJECT (menu_item), "key", g_strdup (p->data)); + g_signal_connect (G_OBJECT (menu_item), "activate", + G_CALLBACK (activate_cb), merge_menu); + gtk_menu_shell_append (GTK_MENU_SHELL (merge_menu), menu_item); + merge_menu->priv->menu_items = + g_list_append (merge_menu->priv->menu_items, menu_item); + } + + gl_debug (DEBUG_FIELD_BUTTON, "END"); +} + + + +/* + * Local Variables: -- emacs + * mode: C -- emacs + * c-basic-offset: 8 -- emacs + * tab-width: 8 -- emacs + * indent-tabs-mode: nil -- emacs + * End: -- emacs + */ diff --git a/src/field-button-menu.h b/src/field-button-menu.h new file mode 100644 index 00000000..cdb2a261 --- /dev/null +++ b/src/field-button-menu.h @@ -0,0 +1,82 @@ +/* + * field-button-menu.h + * Copyright (C) 2008-2009 Jim Evins . + * + * This file is part of gLabels. + * + * gLabels 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 3 of the License, or + * (at your option) any later version. + * + * gLabels 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 gLabels. If not, see . + */ + +#ifndef __FIELD_BUTTON_MENU_H__ +#define __FIELD_BUTTON_MENU_H__ + +#include + +G_BEGIN_DECLS + +#define GL_TYPE_FIELD_BUTTON_MENU (gl_field_button_menu_get_type ()) +#define GL_FIELD_BUTTON_MENU(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), GL_TYPE_FIELD_BUTTON_MENU, glFieldButtonMenu )) +#define GL_FIELD_BUTTON_MENU_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_FIELD_BUTTON_MENU, glFieldButtonMenuClass)) +#define GL_IS_FIELD_BUTTON_MENU(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_FIELD_BUTTON_MENU)) +#define GL_IS_FIELD_BUTTON_MENU_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_FIELD_BUTTON_MENU)) + + +typedef struct _glFieldButtonMenu glFieldButtonMenu; +typedef struct _glFieldButtonMenuClass glFieldButtonMenuClass; + +typedef struct _glFieldButtonMenuPrivate glFieldButtonMenuPrivate; + + +struct _glFieldButtonMenu { + GtkMenu parent_widget; + + glFieldButtonMenuPrivate *priv; +}; + + +struct _glFieldButtonMenuClass { + GtkMenuClass parent_class; + + void (*key_selected) (glFieldButtonMenu *merge_menu, + gchar *key, + gpointer user_data); +}; + + +GType gl_field_button_menu_get_type (void) G_GNUC_CONST; + +GtkWidget *gl_field_button_menu_new (void); + +void gl_field_button_menu_set_keys (glFieldButtonMenu *merge_menu, + GList *key_list); + + +G_END_DECLS + +#endif + + + +/* + * Local Variables: -- emacs + * mode: C -- emacs + * c-basic-offset: 8 -- emacs + * tab-width: 8 -- emacs + * indent-tabs-mode: nil -- emacs + * End: -- emacs + */ diff --git a/src/field-button.c b/src/field-button.c new file mode 100644 index 00000000..e307bfb5 --- /dev/null +++ b/src/field-button.c @@ -0,0 +1,294 @@ +/* + * field-button.c + * Copyright (C) 2009 Jim Evins . + * + * This file is part of gLabels. + * + * gLabels 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 3 of the License, or + * (at your option) any later version. + * + * gLabels 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 gLabels. If not, see . + */ + +#include + +#include "field-button.h" + +#include +#include + +#include "field-button-menu.h" +#include "marshal.h" + + + +/*========================================================*/ +/* Private types. */ +/*========================================================*/ + +/** GL_FIELD_BUTTON Private fields */ +struct _glFieldButtonPrivate { + + GtkWidget *label; + + GtkWidget *menu; +}; + +enum { + KEY_SELECTED, + LAST_SIGNAL +}; + + +/*========================================================*/ +/* Private globals. */ +/*========================================================*/ + +static guint signals[LAST_SIGNAL] = {0}; + + +/*========================================================*/ +/* Private function prototypes. */ +/*========================================================*/ + +static void gl_field_button_finalize (GObject *object); + +static gboolean +button_press_event_cb (GtkWidget *widget, + GdkEventButton *event, + glFieldButton *this); + +static void +menu_key_selected_cb (glFieldButtonMenu *menu, + gchar *key, + glFieldButton *this); + +static void +menu_selection_done_cb (GtkMenuShell *object, + glFieldButton *this); + + +/*****************************************************************************/ +/* Object infrastructure. */ +/*****************************************************************************/ +G_DEFINE_TYPE (glFieldButton, gl_field_button, GTK_TYPE_TOGGLE_BUTTON); + + +/*****************************************************************************/ +/* Class Init Function. */ +/*****************************************************************************/ +static void +gl_field_button_class_init (glFieldButtonClass *class) +{ + GObjectClass *gobject_class = (GObjectClass *) class; + + gl_field_button_parent_class = g_type_class_peek_parent (class); + + gobject_class->finalize = gl_field_button_finalize; + + signals[KEY_SELECTED] = + g_signal_new ("key_selected", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (glFieldButtonClass, key_selected), + NULL, NULL, + gl_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); +} + + +/*****************************************************************************/ +/* Object Instance Init Function. */ +/*****************************************************************************/ +static void +gl_field_button_init (glFieldButton *this) +{ + GtkWidget *hbox; + GtkWidget *arrow; + + this->priv = g_new0 (glFieldButtonPrivate, 1); + + hbox = gtk_hbox_new (FALSE, 3); + gtk_container_add (GTK_CONTAINER (this), hbox); + + this->priv->label = gtk_label_new (""); + gtk_misc_set_alignment (GTK_MISC (this->priv->label), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (hbox), this->priv->label, TRUE, TRUE, 0); + + arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN); + gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0); + + g_signal_connect (this, "button_press_event", + G_CALLBACK(button_press_event_cb), this); +} + + +/*****************************************************************************/ +/* Finalize Method. */ +/*****************************************************************************/ +static void +gl_field_button_finalize (GObject *object) +{ + glFieldButton *this; + + g_return_if_fail (object && IS_GL_FIELD_BUTTON (object)); + this = GL_FIELD_BUTTON (object); + + g_object_ref_sink (this->priv->menu); + g_free (this->priv); + + G_OBJECT_CLASS (gl_field_button_parent_class)->finalize (object); +} + + +/*****************************************************************************/ +/** New Object Generator. */ +/*****************************************************************************/ +GtkWidget * +gl_field_button_new (const gchar *name) +{ + glFieldButton *this; + + this = g_object_new (TYPE_GL_FIELD_BUTTON, NULL); + + gtk_label_set_text (GTK_LABEL (this->priv->label), name); + + this->priv->menu = gl_field_button_menu_new (); + + gtk_widget_show_all (this->priv->menu); + + g_signal_connect (this->priv->menu, "key_selected", + G_CALLBACK (menu_key_selected_cb), this); + g_signal_connect (this->priv->menu, "selection_done", + G_CALLBACK (menu_selection_done_cb), this); + + return GTK_WIDGET (this); +} + + +/*****************************************************************************/ +/* Set key list. */ +/*****************************************************************************/ +void +gl_field_button_set_keys (glFieldButton *this, + GList *key_list) +{ + gl_field_button_menu_set_keys (GL_FIELD_BUTTON_MENU (this->priv->menu), + key_list); + + gtk_widget_show_all (this->priv->menu); +} + + +/*****************************************************************************/ +/* Menu positioning function. */ +/*****************************************************************************/ +static void +menu_position_function (GtkMenu *menu, + gint *x, + gint *y, + gboolean *push_in, + gpointer user_data) +{ + glFieldButton *this = GL_FIELD_BUTTON (user_data); + GdkWindow *window; + gint x1, y1; + gint menu_h, menu_w; + + window = gtk_widget_get_window (GTK_WIDGET (this)); + + gdk_window_get_origin (window, &x1, &y1); + *x = x1 + GTK_WIDGET (this)->allocation.x; + *y = y1 + GTK_WIDGET (this)->allocation.y + + GTK_WIDGET (this)->allocation.height; + + menu_h = this->priv->menu->allocation.height; + menu_w = this->priv->menu->allocation.width; + + if ((*y + menu_h) > gdk_screen_height ()) + { + *y = y1 + GTK_WIDGET (this)->allocation.y - menu_h; + if ( *y < 0 ) + { + *y = gdk_screen_height () - menu_h; + } + } + + if ((*x + menu_w) > gdk_screen_width ()) + { + *x = gdk_screen_width () - menu_w; + } + + *push_in = TRUE; +} + + +/*****************************************************************************/ +/* Button "button_press_event" callback. */ +/*****************************************************************************/ +static gboolean +button_press_event_cb (GtkWidget *widget, + GdkEventButton *event, + glFieldButton *this) +{ + switch (event->button) + { + + case 1: + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this), TRUE); + + gtk_menu_popup (GTK_MENU (this->priv->menu), + NULL, NULL, + menu_position_function, this, + event->button, event->time); + break; + + default: + break; + + } + + return FALSE; +} + + +/*****************************************************************************/ +/* Menu "key selected" callback. */ +/*****************************************************************************/ +static void +menu_key_selected_cb (glFieldButtonMenu *menu, + gchar *field, + glFieldButton *this) +{ + g_signal_emit (this, signals[KEY_SELECTED], 0, field); +} + + +/*****************************************************************************/ +/* Menu "selection done" callback. */ +/*****************************************************************************/ +static void +menu_selection_done_cb (GtkMenuShell *object, + glFieldButton *this) +{ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this), FALSE); +} + + + +/* + * Local Variables: -- emacs + * mode: C -- emacs + * c-basic-offset: 8 -- emacs + * tab-width: 8 -- emacs + * indent-tabs-mode: nil -- emacs + * End: -- emacs + */ diff --git a/src/field-button.h b/src/field-button.h new file mode 100644 index 00000000..883558dd --- /dev/null +++ b/src/field-button.h @@ -0,0 +1,82 @@ +/* + * field-button.h + * Copyright (C) 2009 Jim Evins . + * + * This file is part of gLabels. + * + * gLabels 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 3 of the License, or + * (at your option) any later version. + * + * gLabels 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 gLabels. If not, see . + */ + +#ifndef __GL_FIELD_BUTTON_H__ +#define __GL_FIELD_BUTTON_H__ + + +#include + + +G_BEGIN_DECLS + +#define TYPE_GL_FIELD_BUTTON (gl_field_button_get_type ()) +#define GL_FIELD_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_GL_FIELD_BUTTON, glFieldButton)) +#define GL_FIELD_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_GL_FIELD_BUTTON, glFieldButtonClass)) +#define IS_GL_FIELD_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_GL_FIELD_BUTTON)) +#define IS_GL_FIELD_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_GL_FIELD_BUTTON)) +#define GL_FIELD_BUTTON_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), TYPE_GL_FIELD_BUTTON, glFieldButtonClass)) + + +typedef struct _glFieldButton glFieldButton; +typedef struct _glFieldButtonPrivate glFieldButtonPrivate; +typedef struct _glFieldButtonClass glFieldButtonClass; + + +struct _glFieldButton { + GtkToggleButton parent; + + glFieldButtonPrivate *priv; +}; + +struct _glFieldButtonClass { + GtkToggleButtonClass parent_class; + + /* + * Signals + */ + void (*key_selected) (glFieldButton *object, + gchar *key, + gpointer user_data); + +}; + + +GType gl_field_button_get_type (void) G_GNUC_CONST; + +GtkWidget *gl_field_button_new (const gchar *name); + +void gl_field_button_set_keys (glFieldButton *this, + GList *key_list); + +G_END_DECLS + +#endif /* __GL_COLOR_COMBO_H__ */ + + + +/* + * Local Variables: -- emacs + * mode: C -- emacs + * c-basic-offset: 8 -- emacs + * tab-width: 8 -- emacs + * indent-tabs-mode: nil -- emacs + * End: -- emacs + */ diff --git a/src/object-editor-edit-page.c b/src/object-editor-edit-page.c index 0e52015a..949f0239 100644 --- a/src/object-editor-edit-page.c +++ b/src/object-editor-edit-page.c @@ -28,7 +28,7 @@ #include "prefs.h" #include "color.h" -#include "wdgt-merge-menu.h" +#include "field-button.h" #include "builder-util.h" #include "object-editor-private.h" @@ -55,9 +55,7 @@ /* Local function prototypes */ /*===========================================*/ -static void insert_button_cb (glObjectEditor *editor); - -static void field_selected_cb (glObjectEditor *editor, gchar *field); +static void key_selected_cb (glObjectEditor *editor, gchar *key); /*--------------------------------------------------------------------------*/ @@ -72,22 +70,20 @@ gl_object_editor_prepare_edit_page (glObjectEditor *editor) gl_builder_util_get_widgets (editor->priv->builder, "edit_page_vbox", &editor->priv->edit_page_vbox, "edit_text_view", &editor->priv->edit_text_view, - "edit_insert_field_button", &editor->priv->edit_insert_field_button, + "edit_insert_field_vbox", &editor->priv->edit_insert_field_vbox, NULL); - editor->priv->edit_insert_field_menu = gl_wdgt_merge_menu_new (); + editor->priv->edit_insert_field_button = gl_field_button_new (_("Insert merge field")); + gtk_box_pack_start (GTK_BOX (editor->priv->edit_insert_field_vbox), + editor->priv->edit_insert_field_button, FALSE, FALSE, 0); /* Un-hide */ gtk_widget_show_all (editor->priv->edit_page_vbox); /* Connect signals */ g_signal_connect_swapped (G_OBJECT (editor->priv->edit_insert_field_button), - "clicked", - G_CALLBACK (insert_button_cb), - G_OBJECT (editor)); - g_signal_connect_swapped (G_OBJECT (editor->priv->edit_insert_field_menu), - "field_selected", - G_CALLBACK (field_selected_cb), + "key_selected", + G_CALLBACK (key_selected_cb), G_OBJECT (editor)); gl_debug (DEBUG_EDITOR, "END"); @@ -98,14 +94,14 @@ gl_object_editor_prepare_edit_page (glObjectEditor *editor) /* PRIVATE. Menu item activated callback. */ /*--------------------------------------------------------------------------*/ static void -field_selected_cb (glObjectEditor *editor, gchar *field) +key_selected_cb (glObjectEditor *editor, gchar *key) { GtkTextBuffer *buffer; gchar *field_string; gl_debug (DEBUG_EDITOR, "START"); - field_string = g_strdup_printf ("${%s}", field); + field_string = g_strdup_printf ("${%s}", key); gl_debug (DEBUG_WDGT, "Inserting %s", field_string); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->priv->edit_text_view)); @@ -117,22 +113,6 @@ field_selected_cb (glObjectEditor *editor, gchar *field) } -/*--------------------------------------------------------------------------*/ -/* PRIVATE. Insert button callback. */ -/*--------------------------------------------------------------------------*/ -static void -insert_button_cb (glObjectEditor *editor) -{ - gl_debug (DEBUG_EDITOR, "START"); - - gtk_widget_show_all (editor->priv->edit_insert_field_menu); - gtk_menu_popup (GTK_MENU (editor->priv->edit_insert_field_menu), - NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ()); - - gl_debug (DEBUG_EDITOR, "END"); -} - - /*****************************************************************************/ /* Set text buffer as model for text view/editor. */ /*****************************************************************************/ diff --git a/src/object-editor-private.h b/src/object-editor-private.h index 68580759..d585f310 100644 --- a/src/object-editor-private.h +++ b/src/object-editor-private.h @@ -113,8 +113,8 @@ struct _glObjectEditorPrivate { GtkWidget *edit_page_vbox; GtkWidget *edit_text_view; + GtkWidget *edit_insert_field_vbox; GtkWidget *edit_insert_field_button; - GtkWidget *edit_insert_field_menu; GtkWidget *bc_page_vbox; GtkWidget *bc_style_combo; diff --git a/src/object-editor.c b/src/object-editor.c index 3edf5815..e63831ad 100644 --- a/src/object-editor.c +++ b/src/object-editor.c @@ -30,7 +30,7 @@ #include "color-combo.h" #include "color.h" #include "wdgt-chain-button.h" -#include "wdgt-merge-menu.h" +#include "field-button.h" #include "marshal.h" #include "combo-util.h" #include "builder-util.h" @@ -386,7 +386,7 @@ gl_object_editor_set_key_names (glObjectEditor *editor, { GList *keys; GtkWidget *combo; - GtkWidget *menu; + GtkWidget *button; gboolean fixed_flag; gboolean state; @@ -529,9 +529,9 @@ gl_object_editor_set_key_names (glObjectEditor *editor, gl_combo_util_set_strings (GTK_COMBO_BOX (combo), keys); } - menu = editor->priv->edit_insert_field_menu; - if (menu) { - gl_wdgt_merge_menu_set_fields (GL_WDGT_MERGE_MENU(menu), keys); + button = editor->priv->edit_insert_field_button; + if (button) { + gl_field_button_set_keys (GL_FIELD_BUTTON(button), keys); } combo = editor->priv->data_key_combo; diff --git a/src/wdgt-merge-menu.c b/src/wdgt-merge-menu.c deleted file mode 100644 index 9f0d132e..00000000 --- a/src/wdgt-merge-menu.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * wdgt-merge-menu.c - * Copyright (C) 2008-2009 Jim Evins . - * - * This file is part of gLabels. - * - * gLabels 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 3 of the License, or - * (at your option) any later version. - * - * gLabels 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 gLabels. If not, see . - */ - -#include - -#include "wdgt-merge-menu.h" - -#include -#include - -#include "marshal.h" - -#include "debug.h" - - -/*===========================================*/ -/* Private types */ -/*===========================================*/ - - -struct _glWdgtMergeMenuPrivate { - - GList *menu_items; -}; - -enum { - FIELD_SELECTED, - LAST_SIGNAL -}; - -typedef void (*glWdgtMergeMenuSignal) (GObject * object, gpointer data); - - -/*===========================================*/ -/* Private globals */ -/*===========================================*/ - -static gint signals[LAST_SIGNAL] = { 0 }; - - -/*===========================================*/ -/* Local function prototypes */ -/*===========================================*/ - -static void gl_wdgt_merge_menu_finalize (GObject *object); - - -/****************************************************************************/ -/* Boilerplate Object stuff. */ -/****************************************************************************/ -G_DEFINE_TYPE (glWdgtMergeMenu, gl_wdgt_merge_menu, GTK_TYPE_MENU); - - -static void -gl_wdgt_merge_menu_class_init (glWdgtMergeMenuClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - gl_debug (DEBUG_MERGE_MENU, "START"); - - gl_wdgt_merge_menu_parent_class = g_type_class_peek_parent (class); - - object_class->finalize = gl_wdgt_merge_menu_finalize; - - signals[FIELD_SELECTED] = - g_signal_new ("field_selected", - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (glWdgtMergeMenuClass, field_selected), - NULL, NULL, - gl_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - gl_debug (DEBUG_MERGE_MENU, "END"); -} - - -static void -gl_wdgt_merge_menu_init (glWdgtMergeMenu *merge_menu) -{ - gl_debug (DEBUG_MERGE_MENU, "START"); - - merge_menu->priv = g_new0 (glWdgtMergeMenuPrivate, 1); - - gl_debug (DEBUG_MERGE_MENU, "END"); -} - - -static void -gl_wdgt_merge_menu_finalize (GObject *object) -{ - glWdgtMergeMenu *merge_menu = GL_WDGT_MERGE_MENU (object); - GList *p; - GtkWidget *menu_item; - gchar *field; - - gl_debug (DEBUG_MERGE_MENU, "START"); - - g_return_if_fail (object != NULL); - g_return_if_fail (GL_IS_WDGT_MERGE_MENU (object)); - - for ( p = merge_menu->priv->menu_items; p != NULL; p = p->next ) - { - menu_item = GTK_WIDGET (p->data); - field = g_object_get_data (G_OBJECT (menu_item), "field"); - g_free (field); - } - g_list_free (merge_menu->priv->menu_items); - g_free (merge_menu->priv); - - G_OBJECT_CLASS (gl_wdgt_merge_menu_parent_class)->finalize (object); - - gl_debug (DEBUG_MERGE_MENU, "END"); -} - - -GtkWidget * -gl_wdgt_merge_menu_new (void) -{ - glWdgtMergeMenu *merge_menu; - - gl_debug (DEBUG_MERGE_MENU, "START"); - - merge_menu = g_object_new (gl_wdgt_merge_menu_get_type (), NULL); - - gl_debug (DEBUG_MERGE_MENU, "END"); - - return GTK_WIDGET (merge_menu); -} - - -/*--------------------------------------------------------------------------*/ -/* PRIVATE. Menu item activation callback. */ -/*--------------------------------------------------------------------------*/ -static void -activate_cb (GtkMenuItem *menu_item, - glWdgtMergeMenu *merge_menu) -{ - gchar *field; - - gl_debug (DEBUG_MERGE_MENU, "START"); - - field = g_object_get_data (G_OBJECT (menu_item), "field"); - gl_debug (DEBUG_MERGE_MENU, "Field activated: \"%s\"\n", field ); - - g_signal_emit (G_OBJECT (merge_menu), signals[FIELD_SELECTED], 0, field); - - gl_debug (DEBUG_MERGE_MENU, "END"); -} - - -/****************************************************************************/ -/* set field names. */ -/****************************************************************************/ -void -gl_wdgt_merge_menu_set_fields (glWdgtMergeMenu *merge_menu, - GList *field_list) -{ - GList *p; - GtkWidget *menu_item; - gchar *field; - - gl_debug (DEBUG_MERGE_MENU, "START"); - - /* - * Remove all old menu items. - */ - for ( p = merge_menu->priv->menu_items; p != NULL; p = p->next ) - { - menu_item = GTK_WIDGET (p->data); - field = g_object_get_data (G_OBJECT (menu_item), "field"); - g_free (field); - gtk_widget_destroy (menu_item); - } - g_list_free (merge_menu->priv->menu_items); - merge_menu->priv->menu_items = NULL; - - /* - * Add new menu items. - */ - for ( p = field_list; p != NULL; p = p->next ) - { - menu_item = gtk_menu_item_new_with_label (p->data); - g_object_set_data (G_OBJECT (menu_item), "field", g_strdup (p->data)); - g_signal_connect (G_OBJECT (menu_item), "activate", - G_CALLBACK (activate_cb), merge_menu); - gtk_menu_shell_append (GTK_MENU_SHELL (merge_menu), menu_item); - merge_menu->priv->menu_items = - g_list_append (merge_menu->priv->menu_items, menu_item); - } - - gl_debug (DEBUG_MERGE_MENU, "END"); -} - - - -/* - * Local Variables: -- emacs - * mode: C -- emacs - * c-basic-offset: 8 -- emacs - * tab-width: 8 -- emacs - * indent-tabs-mode: nil -- emacs - * End: -- emacs - */ diff --git a/src/wdgt-merge-menu.h b/src/wdgt-merge-menu.h deleted file mode 100644 index 2c406dcd..00000000 --- a/src/wdgt-merge-menu.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * wdgt-merge-menu.h - * Copyright (C) 2008-2009 Jim Evins . - * - * This file is part of gLabels. - * - * gLabels 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 3 of the License, or - * (at your option) any later version. - * - * gLabels 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 gLabels. If not, see . - */ - -#ifndef __WDGT_MERGE_MENU_H__ -#define __WDGT_MERGE_MENU_H__ - -#include - -G_BEGIN_DECLS - -#define GL_TYPE_WDGT_MERGE_MENU (gl_wdgt_merge_menu_get_type ()) -#define GL_WDGT_MERGE_MENU(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GL_TYPE_WDGT_MERGE_MENU, glWdgtMergeMenu )) -#define GL_WDGT_MERGE_MENU_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_WDGT_MERGE_MENU, glWdgtMergeMenuClass)) -#define GL_IS_WDGT_MERGE_MENU(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_WDGT_MERGE_MENU)) -#define GL_IS_WDGT_MERGE_MENU_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_WDGT_MERGE_MENU)) - - -typedef struct _glWdgtMergeMenu glWdgtMergeMenu; -typedef struct _glWdgtMergeMenuClass glWdgtMergeMenuClass; - -typedef struct _glWdgtMergeMenuPrivate glWdgtMergeMenuPrivate; - - -struct _glWdgtMergeMenu { - GtkMenu parent_widget; - - glWdgtMergeMenuPrivate *priv; -}; - - -struct _glWdgtMergeMenuClass { - GtkMenuClass parent_class; - - void (*field_selected) (glWdgtMergeMenu *merge_menu, - gchar *field, - gpointer user_data); -}; - - -GType gl_wdgt_merge_menu_get_type (void) G_GNUC_CONST; - -GtkWidget *gl_wdgt_merge_menu_new (void); - -void gl_wdgt_merge_menu_set_fields (glWdgtMergeMenu *merge_menu, - GList *field_list); - - -G_END_DECLS - -#endif - - - -/* - * Local Variables: -- emacs - * mode: C -- emacs - * c-basic-offset: 8 -- emacs - * tab-width: 8 -- emacs - * indent-tabs-mode: nil -- emacs - * End: -- emacs - */