[libgda] Improved again the UI when dealing with binary data
- From: Vivien Malerba <vivien src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [libgda] Improved again the UI when dealing with binary data
- Date: Sun, 13 Sep 2009 13:26:01 +0000 (UTC)
commit 2127bbad14c7036f809a48deea554cca554b3e4b
Author: Vivien Malerba <malerba gnome-db org>
Date: Sat Sep 12 10:14:25 2009 +0200
Improved again the UI when dealing with binary data
now display the data's size and type (if GIO is available)
libgda-ui/data-entries/common-bin.c | 185 +++++++++---
libgda-ui/data-entries/common-bin.h | 13 +-
.../data-entries/gdaui-data-cell-renderer-bin.c | 48 +++-
libgda-ui/data-entries/gdaui-entry-bin.c | 47 ++-
libgda-ui/internal/Makefile.am | 2 +
libgda-ui/internal/popup-container.c | 313 +++++++++++++++++++
libgda-ui/internal/popup-container.h | 57 ++++
tools/browser/common/popup-container.c | 319 +-------------------
tools/browser/common/popup-container.h | 58 +----
9 files changed, 603 insertions(+), 439 deletions(-)
---
diff --git a/libgda-ui/data-entries/common-bin.c b/libgda-ui/data-entries/common-bin.c
index 8be009a..69a3004 100644
--- a/libgda-ui/data-entries/common-bin.c
+++ b/libgda-ui/data-entries/common-bin.c
@@ -19,6 +19,7 @@
#include <libgda/gda-value.h>
#include "common-bin.h"
+#include "../internal/popup-container.h"
#include <string.h>
#include <gtk/gtk.h>
#include <glib/gi18n-lib.h>
@@ -33,6 +34,7 @@ file_load_cb (GtkWidget *button, BinMenu *menu)
{
GtkWidget *dlg;
+ gtk_widget_hide (menu->popup);
dlg = gtk_file_chooser_dialog_new (_("Select file to load"),
GTK_WINDOW (gtk_widget_get_toplevel (button)),
GTK_FILE_CHOOSER_ACTION_OPEN,
@@ -62,23 +64,6 @@ file_load_cb (GtkWidget *button, BinMenu *menu)
gda_value_take_binary (nvalue, bin);
menu->loaded_value_cb (menu->loaded_value_cb_data, nvalue);
-
-#ifdef HAVE_GIO
- /* Open with... using GIO */
- gchar *tmp;
- tmp = g_content_type_guess (NULL, bin->data, (gsize) bin->binary_length, NULL);
- g_print ("Content type: %s\n", tmp);
-
- GList *list;
- list = g_app_info_get_all_for_type (tmp);
- for (; list; list = list->next) {
- GAppInfo *ai;
- ai = (GAppInfo*) list->data;
- g_print ("\t open with %s (%s)\n", g_app_info_get_name (ai),
- g_app_info_get_executable (ai));
- }
- g_free (tmp);
-#endif
}
else {
GtkWidget *msg;
@@ -113,6 +98,7 @@ file_save_cb (GtkWidget *button, BinMenu *menu)
{
GtkWidget *dlg;
+ gtk_widget_hide (menu->popup);
dlg = gtk_file_chooser_dialog_new (_("Select a file to save data to"),
GTK_WINDOW (gtk_widget_get_toplevel (button)),
GTK_FILE_CHOOSER_ACTION_SAVE,
@@ -175,34 +161,70 @@ file_save_cb (GtkWidget *button, BinMenu *menu)
}
void
-common_bin_create_menu (BinMenu *binmenu, GtkWidget *attach_to, GType entry_type,
+common_bin_create_menu (BinMenu *binmenu, PopupContainerPositionFunc pos_func, GType entry_type,
BinCallback loaded_value_cb, gpointer loaded_value_cb_data)
{
- GtkWidget *menu, *mitem;
+ GtkWidget *popup, *vbox, *hbox, *bbox, *button, *label;
+ gchar *str;
binmenu->entry_type = entry_type;
binmenu->loaded_value_cb = loaded_value_cb;
binmenu->loaded_value_cb_data = loaded_value_cb_data;
- menu = gtk_menu_new ();
- g_signal_connect (menu, "deactivate",
- G_CALLBACK (gtk_widget_hide), NULL);
- binmenu->menu = menu;
+ popup = popup_container_new_with_func (pos_func);
+ binmenu->popup = popup;
- mitem = gtk_menu_item_new_with_mnemonic (_("_Load from file"));
- gtk_container_add (GTK_CONTAINER (menu), mitem);
- g_signal_connect (mitem, "activate",
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (popup), vbox);
+
+ label = gtk_label_new ("");
+ str = g_strdup_printf ("<b>%s:</b>", _("Properties"));
+ gtk_label_set_markup (GTK_LABEL (label), str);
+ g_free (str);
+ gtk_misc_set_alignment (GTK_MISC (label), 0., -1);
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new (FALSE, 0); /* HIG */
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
+ gtk_widget_show (hbox);
+ label = gtk_label_new (" ");
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ label = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (label), 0., -1);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ binmenu->props_label = label;
+
+ bbox = gtk_hbutton_box_new ();
+ gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
+
+ button = gtk_button_new_from_stock (GTK_STOCK_OPEN);
+ gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+ g_signal_connect (button, "clicked",
G_CALLBACK (file_load_cb), binmenu);
- binmenu->load_mitem = mitem;
+ binmenu->load_button = button;
- mitem = gtk_menu_item_new_with_mnemonic (_("_Save to file"));
- gtk_container_add (GTK_CONTAINER (menu), mitem);
- g_signal_connect (mitem, "activate",
+ button = gtk_button_new_from_stock (GTK_STOCK_SAVE_AS);
+ gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+ g_signal_connect (button, "clicked",
G_CALLBACK (file_save_cb), binmenu);
- binmenu->save_mitem = mitem;
-
- gtk_menu_attach_to_widget (GTK_MENU (menu), attach_to, NULL);
- gtk_widget_show_all (menu);
+ binmenu->save_button = button;
+
+ gtk_widget_show_all (vbox);
+}
+
+static gchar *
+format_size (gulong size)
+{
+ if (size < 1024)
+ return g_strdup_printf (ngettext ("%lu Byte", "%lu Bytes", size), size);
+ else if (size < 1048576)
+ return g_strdup_printf ("%.1f Kio", (gfloat) (size / 1024));
+ else if (size < 1073741824)
+ return g_strdup_printf ("%.1f Mio", (gfloat) (size / 1048576));
+ else
+ return g_strdup_printf ("%.1f Gio", (gfloat) (size / 1073741824));
}
/*
@@ -211,17 +233,100 @@ common_bin_create_menu (BinMenu *binmenu, GtkWidget *attach_to, GType entry_type
void
common_bin_adjust_menu (BinMenu *binmenu, gboolean editable, const GValue *value)
{
- if (!binmenu || !binmenu->menu)
+ gchar *size;
+ GString *string;
+#ifdef HAVE_GIO
+ gchar *ctype = NULL;
+#endif
+
+ if (!binmenu || !binmenu->popup)
return;
if (binmenu->tmpvalue) {
gda_value_free (binmenu->tmpvalue);
binmenu->tmpvalue = NULL;
}
- if (value)
+ string = g_string_new ("");
+ if (value) {
binmenu->tmpvalue = gda_value_copy (value);
- gtk_widget_set_sensitive (binmenu->load_mitem, editable);
- gtk_widget_set_sensitive (binmenu->save_mitem, (value && !gda_value_is_null (value)) ? TRUE : FALSE);
+ if (G_VALUE_TYPE (value) == GDA_TYPE_NULL)
+ g_string_append_printf (string, "<i>%s</i>", _("No data"));
+ else if (G_VALUE_TYPE (value) == GDA_TYPE_BINARY) {
+ const GdaBinary *bin;
+ bin = gda_value_get_binary (value);
+ size = format_size (bin->binary_length);
+ g_string_append_printf (string, "%s: %s", _("Data size"), size);
+ g_free (size);
+#ifdef HAVE_GIO
+ ctype = g_content_type_guess (NULL, bin->data, (gsize) bin->binary_length, NULL);
+#endif
+ }
+ else if (G_VALUE_TYPE (value) == GDA_TYPE_BLOB) {
+ const GdaBlob *blob;
+ GdaBinary *bin;
+ blob = gda_value_get_blob (value);
+ bin = (GdaBinary *) blob;
+ if (blob->op) {
+ glong len;
+ len = gda_blob_op_get_length (blob->op);
+ if (len >= 0) {
+ size = format_size (len);
+ g_string_append_printf (string, "%s: %s", _("Data size"), size);
+ g_free (size);
+#ifdef HAVE_GIO
+ GdaBlob *b2;
+ glong read;
+ b2 = gda_blob_copy (blob);
+ read = gda_blob_op_read (b2->op, b2, 0, 1024);
+ bin = (GdaBinary *) b2;
+ ctype = g_content_type_guess (NULL, bin->data, (gsize) bin->binary_length, NULL);
+#endif
+ }
+ else
+ g_string_append_printf (string, "%s: %s", _("Data size"), _("Unknown"));
+ }
+ else {
+ size = format_size (bin->binary_length);
+ g_string_append_printf (string, "%s: %s", _("Data size"), size);
+ g_free (size);
+#ifdef HAVE_GIO
+ ctype = g_content_type_guess (NULL, bin->data, (gsize) bin->binary_length, NULL);
+#endif
+ }
+ }
+ else
+ g_assert_not_reached ();
+ }
+ else
+ g_string_append_printf (string, "<i>%s</i>", _("No data"));
+
+#ifdef HAVE_GIO
+ if (ctype) {
+ GList *list;
+ gchar *descr, *tmp;
+ descr = g_content_type_get_description (ctype);
+ tmp = g_markup_printf_escaped (descr);
+ g_free (descr);
+ g_string_append_printf (string, "\n%s: %s", _("Data type"), tmp);
+ g_free (tmp);
+
+ list = g_app_info_get_all_for_type (ctype);
+ for (; list; list = list->next) {
+ GAppInfo *ai;
+ ai = (GAppInfo*) list->data;
+ g_print ("\t open with %s (%s)\n", g_app_info_get_name (ai),
+ g_app_info_get_executable (ai));
+ }
+ g_free (ctype);
+ }
+#endif
+
+
+ gtk_label_set_markup (GTK_LABEL (binmenu->props_label), string->str);
+ g_string_free (string, TRUE);
+
+ gtk_widget_set_sensitive (binmenu->load_button, editable);
+ gtk_widget_set_sensitive (binmenu->save_button, (value && !gda_value_is_null (value)) ? TRUE : FALSE);
}
/*
@@ -232,8 +337,8 @@ common_bin_reset (BinMenu *binmenu)
{
if (binmenu->tmpvalue)
gda_value_free (binmenu->tmpvalue);
- if (binmenu->menu)
- gtk_widget_destroy (binmenu->menu);
+ if (binmenu->popup)
+ gtk_widget_destroy (binmenu->popup);
memset (binmenu, 0, sizeof (BinMenu));
}
diff --git a/libgda-ui/data-entries/common-bin.h b/libgda-ui/data-entries/common-bin.h
index 0243876..2784bea 100644
--- a/libgda-ui/data-entries/common-bin.h
+++ b/libgda-ui/data-entries/common-bin.h
@@ -21,22 +21,25 @@
#define __COMMON_BIN_H__
#include <gtk/gtk.h>
+#include "../internal/popup-container.h"
typedef void (*BinCallback) (gpointer, GValue *);
typedef struct {
- GtkWidget *menu; /* popup menu */
- GtkWidget *load_mitem;
- GtkWidget *save_mitem;
+ GtkWidget *popup; /* PopupContainer popup window */
+ GtkWidget *load_button;
+ GtkWidget *save_button;
+ GtkWidget *props_label;
GType entry_type;
- const GValue *tmpvalue;
+ GValue *tmpvalue;
BinCallback loaded_value_cb;
gpointer loaded_value_cb_data;
} BinMenu;
-void common_bin_create_menu (BinMenu *binmenu, GtkWidget *attach_to, GType entry_type, BinCallback loaded_value_cb, gpointer loaded_value_cb_data);
+void common_bin_create_menu (BinMenu *binmenu, PopupContainerPositionFunc pos_func, GType entry_type,
+ BinCallback loaded_value_cb, gpointer loaded_value_cb_data);
void common_bin_adjust_menu (BinMenu *binmenu, gboolean editable, const GValue *value);
void common_bin_reset (BinMenu *binmenu);
diff --git a/libgda-ui/data-entries/gdaui-data-cell-renderer-bin.c b/libgda-ui/data-entries/gdaui-data-cell-renderer-bin.c
index a363baf..7120031 100644
--- a/libgda-ui/data-entries/gdaui-data-cell-renderer-bin.c
+++ b/libgda-ui/data-entries/gdaui-data-cell-renderer-bin.c
@@ -381,6 +381,41 @@ bin_data_changed_cb (GdauiDataCellRendererBin *bincell, GValue *value)
gda_value_free (value);
}
+static void
+popup_position (PopupContainer *container, gint *out_x, gint *out_y)
+{
+ GtkWidget *poswidget;
+ GdkEvent *event;
+ GdkRectangle *rect;
+ gint x, y;
+
+ poswidget = g_object_get_data (G_OBJECT (container), "__poswidget");
+ event = g_object_get_data (G_OBJECT (container), "__event");
+ rect = g_object_get_data (G_OBJECT (container), "__rect");
+
+ if (event && (event->type == GDK_BUTTON_PRESS)) {
+ GdkEventButton *rev = (GdkEventButton*) event;
+ gdk_window_get_origin (rev->window, &x, &y);
+ x += (gint) rev->x;
+ y += (gint) rev->y;
+ }
+ else {
+ g_assert (rect);
+ gdk_window_get_origin (gtk_tree_view_get_bin_window (GTK_TREE_VIEW (poswidget)), &x, &y);
+ x += rect->x;
+ y += rect->y;
+ }
+
+ if (x < 0)
+ x = 0;
+
+ if (y < 0)
+ y = 0;
+
+ *out_x = x;
+ *out_y = y;
+}
+
static gboolean
gdaui_data_cell_renderer_bin_activate (GtkCellRenderer *cell,
GdkEvent *event,
@@ -396,12 +431,13 @@ gdaui_data_cell_renderer_bin_activate (GtkCellRenderer *cell,
GtkTreeIter iter;
bincell = GDAUI_DATA_CELL_RENDERER_BIN (cell);
- int event_time;
g_object_set_data_full (G_OBJECT (bincell), "last_path", g_strdup (path), g_free);
- if (!bincell->priv->menu.menu)
- common_bin_create_menu (&(bincell->priv->menu), widget, bincell->priv->type,
+ if (!bincell->priv->menu.popup) {
+ common_bin_create_menu (&(bincell->priv->menu), popup_position, bincell->priv->type,
(BinCallback) bin_data_changed_cb, bincell);
+ g_object_set_data (G_OBJECT (bincell->priv->menu.popup), "__poswidget", widget);
+ }
model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
tpath = gtk_tree_path_new_from_string (path);
@@ -415,9 +451,9 @@ gdaui_data_cell_renderer_bin_activate (GtkCellRenderer *cell,
model_col, &value, -1);
common_bin_adjust_menu (&(bincell->priv->menu), bincell->priv->editable,
value);
- event_time = gtk_get_current_event_time ();
- gtk_menu_popup (GTK_MENU (bincell->priv->menu.menu), NULL, NULL, NULL, NULL,
- 0, event_time);
+ g_object_set_data (G_OBJECT (bincell->priv->menu.popup), "__event", event);
+ g_object_set_data (G_OBJECT (bincell->priv->menu.popup), "__rect", cell_area);
+ gtk_widget_show (bincell->priv->menu.popup);
}
gtk_tree_path_free (tpath);
diff --git a/libgda-ui/data-entries/gdaui-entry-bin.c b/libgda-ui/data-entries/gdaui-entry-bin.c
index 4ae2f9d..a5af886 100644
--- a/libgda-ui/data-entries/gdaui-entry-bin.c
+++ b/libgda-ui/data-entries/gdaui-entry-bin.c
@@ -184,10 +184,7 @@ gdaui_entry_bin_dispose (GObject * object)
gda_value_free (gdaui_entry_bin->priv->current_data);
gdaui_entry_bin->priv->current_data = NULL;
}
- if (gdaui_entry_bin->priv->menu.menu) {
- gtk_widget_destroy (gdaui_entry_bin->priv->menu.menu);
- gdaui_entry_bin->priv->menu.menu = NULL;
- }
+ common_bin_reset (&(gdaui_entry_bin->priv->menu));
if (gdaui_entry_bin->priv->button_label) {
g_object_unref (gdaui_entry_bin->priv->button_label);
@@ -325,19 +322,44 @@ value_loaded_cb (GdauiEntryBin *dbin, GValue *new_value)
}
static void
+popup_position (PopupContainer *container, gint *out_x, gint *out_y)
+{
+ GtkWidget *poswidget;
+ poswidget = g_object_get_data (G_OBJECT (container), "__poswidget");
+
+ gint x, y;
+ GtkRequisition req;
+
+ gtk_widget_size_request (poswidget, &req);
+
+ gdk_window_get_origin (poswidget->window, &x, &y);
+
+ x += poswidget->allocation.x;
+ y += poswidget->allocation.y;
+ y += poswidget->allocation.height;
+
+ if (x < 0)
+ x = 0;
+
+ if (y < 0)
+ y = 0;
+
+ *out_x = x;
+ *out_y = y;
+}
+
+static void
button_clicked_cb (GtkWidget *button, GdauiEntryBin *dbin)
{
- if (!dbin->priv->menu.menu)
- common_bin_create_menu (&(dbin->priv->menu), button,
+ if (!dbin->priv->menu.popup) {
+ common_bin_create_menu (&(dbin->priv->menu), popup_position,
gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (dbin)),
(BinCallback) value_loaded_cb, dbin);
+ g_object_set_data (G_OBJECT (dbin->priv->menu.popup), "__poswidget", button);
+ }
common_bin_adjust_menu (&(dbin->priv->menu), dbin->priv->editable, dbin->priv->current_data);
-
- int event_time;
- event_time = gtk_get_current_event_time ();
- gtk_menu_popup (GTK_MENU (dbin->priv->menu.menu), NULL, NULL, NULL, NULL,
- 0, event_time);
+ gtk_widget_show (dbin->priv->menu.popup);
}
static void
@@ -369,8 +391,7 @@ set_editable (GdauiEntryWrapper *mgwrap, gboolean editable)
g_return_if_fail (dbin->priv);
dbin->priv->editable = editable;
- if (dbin->priv->menu.load_mitem)
- gtk_widget_set_sensitive (dbin->priv->menu.load_mitem, dbin->priv->editable);
+ common_bin_adjust_menu (&(dbin->priv->menu), editable, dbin->priv->current_data);
}
static void
diff --git a/libgda-ui/internal/Makefile.am b/libgda-ui/internal/Makefile.am
index e723a9e..dc58b46 100644
--- a/libgda-ui/internal/Makefile.am
+++ b/libgda-ui/internal/Makefile.am
@@ -16,5 +16,7 @@ libgda_ui_internal_la_SOURCES = \
gdaui-provider-auth-editor.h \
gdaui-provider-spec-editor.c \
gdaui-provider-spec-editor.h \
+ popup-container.h \
+ popup-container.c \
utility.h \
utility.c
diff --git a/libgda-ui/internal/popup-container.c b/libgda-ui/internal/popup-container.c
new file mode 100644
index 0000000..8726d09
--- /dev/null
+++ b/libgda-ui/internal/popup-container.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2009 The GNOME Foundation
+ *
+ * AUTHORS:
+ * Vivien Malerba <malerba gnome-db org>
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "popup-container.h"
+#include <gdk/gdkkeysyms.h>
+
+struct _PopupContainerPrivate {
+ PopupContainerPositionFunc position_func;
+};
+
+static void popup_container_class_init (PopupContainerClass *klass);
+static void popup_container_init (PopupContainer *container,
+ PopupContainerClass *klass);
+static void popup_container_dispose (GObject *object);
+static void popup_container_show (GtkWidget *widget);
+static void popup_container_hide (GtkWidget *widget);
+
+static GObjectClass *parent_class = NULL;
+
+/*
+ * PopupContainer class implementation
+ */
+
+static void
+popup_container_class_init (PopupContainerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->dispose = popup_container_dispose;
+ widget_class->show = popup_container_show;
+ widget_class->hide = popup_container_hide;
+}
+
+static gboolean
+delete_popup (GtkWidget *widget, PopupContainer *container)
+{
+ gtk_widget_hide (GTK_WIDGET (container));
+ gtk_grab_remove (GTK_WIDGET (container));
+ return TRUE;
+}
+
+static gboolean
+key_press_popup (GtkWidget *widget, GdkEventKey *event, PopupContainer *container)
+{
+ if (event->keyval != GDK_Escape)
+ return FALSE;
+
+ g_signal_stop_emission_by_name (widget, "key_press_event");
+ gtk_widget_hide (GTK_WIDGET (container));
+ gtk_grab_remove (GTK_WIDGET (container));
+ return TRUE;
+}
+
+static gboolean
+button_press_popup (GtkWidget *widget, GdkEventButton *event, PopupContainer *container)
+{
+ GtkWidget *child;
+
+ child = gtk_get_event_widget ((GdkEvent *) event);
+
+ /* We don't ask for button press events on the grab widget, so
+ * if an event is reported directly to the grab widget, it must
+ * be on a window outside the application (and thus we remove
+ * the popup window). Otherwise, we check if the widget is a child
+ * of the grab widget, and only remove the popup window if it
+ * is not.
+ */
+ if (child != widget) {
+ while (child) {
+ if (child == widget)
+ return FALSE;
+ child = child->parent;
+ }
+ }
+ gtk_widget_hide (GTK_WIDGET (container));
+ gtk_grab_remove (GTK_WIDGET (container));
+ return TRUE;
+}
+
+static void
+popup_container_init (PopupContainer *container, PopupContainerClass *klass)
+{
+ container->priv = g_new0 (PopupContainerPrivate, 1);
+ container->priv->position_func = NULL;
+
+ gtk_widget_set_events (GTK_WIDGET (container),
+ gtk_widget_get_events (GTK_WIDGET (container)) | GDK_KEY_PRESS_MASK);
+ gtk_window_set_resizable (GTK_WINDOW (container), FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (container), 5);
+ g_signal_connect (G_OBJECT (container), "delete_event",
+ G_CALLBACK (delete_popup), container);
+ g_signal_connect (G_OBJECT (container), "key_press_event",
+ G_CALLBACK (key_press_popup), container);
+ g_signal_connect (G_OBJECT (container), "button_press_event",
+ G_CALLBACK (button_press_popup), container);
+
+}
+
+/* FIXME:
+ * - implement the show() virtual method with popup_grab_on_window()...
+ * - implement the position_popup()
+ */
+
+static void
+popup_container_dispose (GObject *object)
+{
+ PopupContainer *container = (PopupContainer *) object;
+
+ /* free memory */
+ if (container->priv) {
+ g_free (container->priv);
+ container->priv = NULL;
+ }
+
+ parent_class->dispose (object);
+}
+
+static void
+default_position_func (PopupContainer *container, gint *out_x, gint *out_y)
+{
+ gdk_display_get_pointer (gdk_display_get_default (), NULL,
+ out_x, out_y, NULL);
+}
+
+static gboolean
+popup_grab_on_window (GdkWindow *window, guint32 activate_time)
+{
+ if ((gdk_pointer_grab (window, TRUE,
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK,
+ NULL, NULL, activate_time) == 0)) {
+ if (gdk_keyboard_grab (window, TRUE,
+ activate_time) == 0)
+ return TRUE;
+ else {
+ gdk_pointer_ungrab (activate_time);
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+static void
+popup_container_show (GtkWidget *widget)
+{
+ PopupContainer *container = (PopupContainer *) widget;
+ gint x, y;
+
+ GTK_WIDGET_CLASS (parent_class)->show (widget);
+ if (container->priv->position_func)
+ container->priv->position_func (container, &x, &y);
+ else
+ default_position_func (container, &x, &y);
+ gtk_window_move (GTK_WINDOW (widget), x + 1, y + 1);
+ gtk_window_move (GTK_WINDOW (widget), x, y);
+
+ gtk_grab_add (widget);
+
+ GdkScreen *screen;
+ gint swidth, sheight;
+ gint root_x, root_y;
+ gint wwidth, wheight;
+ gboolean do_move = FALSE;
+ screen = gtk_window_get_screen (GTK_WINDOW (widget));
+ if (screen) {
+ swidth = gdk_screen_get_width (screen);
+ sheight = gdk_screen_get_height (screen);
+ }
+ else {
+ swidth = gdk_screen_width ();
+ sheight = gdk_screen_height ();
+ }
+ gtk_window_get_position (GTK_WINDOW (widget), &root_x, &root_y);
+ gtk_window_get_size (GTK_WINDOW (widget), &wwidth, &wheight);
+ if (root_x + wwidth > swidth) {
+ do_move = TRUE;
+ root_x = swidth - wwidth;
+ }
+ else if (root_x < 0) {
+ do_move = TRUE;
+ root_x = 0;
+ }
+ if (root_y + wheight > sheight) {
+ do_move = TRUE;
+ root_y = sheight - wheight;
+ }
+ else if (root_y < 0) {
+ do_move = TRUE;
+ root_y = 0;
+ }
+ if (do_move)
+ gtk_window_move (GTK_WINDOW (widget), root_x, root_y);
+
+ popup_grab_on_window (widget->window,
+ gtk_get_current_event_time ());
+}
+
+static void
+popup_container_hide (GtkWidget *widget)
+{
+ GTK_WIDGET_CLASS (parent_class)->hide (widget);
+ gtk_grab_remove (widget);
+}
+
+GType
+popup_container_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo info = {
+ sizeof (PopupContainerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) popup_container_class_init,
+ NULL,
+ NULL,
+ sizeof (PopupContainer),
+ 0,
+ (GInstanceInitFunc) popup_container_init
+ };
+ type = g_type_register_static (GTK_TYPE_WINDOW, "PopupContainer",
+ &info, 0);
+ }
+ return type;
+}
+
+static void
+popup_position (PopupContainer *container, gint *out_x, gint *out_y)
+{
+ GtkWidget *poswidget;
+ poswidget = g_object_get_data (G_OBJECT (container), "__poswidget");
+
+ gint x, y;
+ GtkRequisition req;
+
+ gtk_widget_size_request (poswidget, &req);
+
+ gdk_window_get_origin (poswidget->window, &x, &y);
+
+ x += poswidget->allocation.x;
+ y += poswidget->allocation.y;
+ y += poswidget->allocation.height;
+
+ if (x < 0)
+ x = 0;
+
+ if (y < 0)
+ y = 0;
+
+ *out_x = x;
+ *out_y = y;
+}
+
+/**
+ * popup_container_new_with_func
+ *
+ * Returns:
+ */
+GtkWidget *
+popup_container_new (GtkWidget *position_widget)
+{
+ PopupContainer *container;
+ g_return_val_if_fail (GTK_IS_WIDGET (position_widget), NULL);
+
+ container = POPUP_CONTAINER (g_object_new (POPUP_CONTAINER_TYPE, "type", GTK_WINDOW_POPUP,
+ NULL));
+ g_object_set_data (G_OBJECT (container), "__poswidget", position_widget);
+ container->priv->position_func = popup_position;
+ return (GtkWidget*) container;
+}
+
+
+/**
+ * popup_container_new_with_func
+ *
+ * Returns:
+ */
+GtkWidget *
+popup_container_new_with_func (PopupContainerPositionFunc pos_func)
+{
+ PopupContainer *container;
+
+ container = POPUP_CONTAINER (g_object_new (POPUP_CONTAINER_TYPE, "type", GTK_WINDOW_POPUP,
+ NULL));
+
+ container->priv->position_func = pos_func;
+ return (GtkWidget*) container;
+}
diff --git a/libgda-ui/internal/popup-container.h b/libgda-ui/internal/popup-container.h
new file mode 100644
index 0000000..836225b
--- /dev/null
+++ b/libgda-ui/internal/popup-container.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 The GNOME Foundation
+ *
+ * AUTHORS:
+ * Vivien Malerba <malerba gnome-db org>
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __POPUP_CONTAINER_H__
+#define __POPUP_CONTAINER_H__
+
+#include <gtk/gtkwindow.h>
+
+G_BEGIN_DECLS
+
+#define POPUP_CONTAINER_TYPE (popup_container_get_type())
+#define POPUP_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, POPUP_CONTAINER_TYPE, PopupContainer))
+#define POPUP_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST (klass, POPUP_CONTAINER_TYPE, PopupContainerClass))
+#define IS_POPUP_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, POPUP_CONTAINER_TYPE))
+#define IS_POPUP_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), POPUP_CONTAINER_TYPE))
+
+typedef struct _PopupContainer PopupContainer;
+typedef struct _PopupContainerClass PopupContainerClass;
+typedef struct _PopupContainerPrivate PopupContainerPrivate;
+
+typedef void (*PopupContainerPositionFunc) (PopupContainer *cont, gint *out_x, gint *out_y);
+
+struct _PopupContainer {
+ GtkWindow parent;
+ PopupContainerPrivate *priv;
+};
+
+struct _PopupContainerClass {
+ GtkWindowClass parent_class;
+};
+
+GType popup_container_get_type (void) G_GNUC_CONST;
+GtkWidget *popup_container_new (GtkWidget *position_widget);
+GtkWidget *popup_container_new_with_func (PopupContainerPositionFunc pos_func);
+
+G_END_DECLS
+
+#endif
diff --git a/tools/browser/common/popup-container.c b/tools/browser/common/popup-container.c
deleted file mode 100644
index e259f32..354fef4
--- a/tools/browser/common/popup-container.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2009 The GNOME Foundation
- *
- * AUTHORS:
- * Vivien Malerba <malerba gnome-db org>
- *
- * This Library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This Library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "popup-container.h"
-#include <gdk/gdkkeysyms.h>
-
-struct _PopupContainerPrivate {
- PopupContainerPositionFunc position_func;
-};
-
-static void popup_container_class_init (PopupContainerClass *klass);
-static void popup_container_init (PopupContainer *container,
- PopupContainerClass *klass);
-static void popup_container_dispose (GObject *object);
-static void popup_container_show (GtkWidget *widget);
-static void popup_container_hide (GtkWidget *widget);
-
-static GObjectClass *parent_class = NULL;
-
-/*
- * PopupContainer class implementation
- */
-
-static void
-popup_container_class_init (PopupContainerClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- object_class->dispose = popup_container_dispose;
- widget_class->show = popup_container_show;
- widget_class->hide = popup_container_hide;
-}
-
-static gboolean
-delete_popup (GtkWidget *widget, PopupContainer *container)
-{
- gtk_widget_hide (GTK_WIDGET (container));
- gtk_grab_remove (GTK_WIDGET (container));
- return TRUE;
-}
-
-static gboolean
-key_press_popup (GtkWidget *widget, GdkEventKey *event, PopupContainer *container)
-{
- if (event->keyval != GDK_Escape)
- return FALSE;
-
- g_signal_stop_emission_by_name (widget, "key_press_event");
- gtk_widget_hide (GTK_WIDGET (container));
- gtk_grab_remove (GTK_WIDGET (container));
- return TRUE;
-}
-
-static gboolean
-button_press_popup (GtkWidget *widget, GdkEventButton *event, PopupContainer *container)
-{
- GtkWidget *child;
-
- child = gtk_get_event_widget ((GdkEvent *) event);
-
- /* We don't ask for button press events on the grab widget, so
- * if an event is reported directly to the grab widget, it must
- * be on a window outside the application (and thus we remove
- * the popup window). Otherwise, we check if the widget is a child
- * of the grab widget, and only remove the popup window if it
- * is not.
- */
- if (child != widget) {
- while (child) {
- if (child == widget)
- return FALSE;
- child = child->parent;
- }
- }
- gtk_widget_hide (GTK_WIDGET (container));
- gtk_grab_remove (GTK_WIDGET (container));
- return TRUE;
-}
-
-static void
-popup_container_init (PopupContainer *container, PopupContainerClass *klass)
-{
- container->priv = g_new0 (PopupContainerPrivate, 1);
- container->priv->position_func = NULL;
-
- gtk_widget_set_events (GTK_WIDGET (container),
- gtk_widget_get_events (GTK_WIDGET (container)) | GDK_KEY_PRESS_MASK);
- gtk_window_set_resizable (GTK_WINDOW (container), FALSE);
- gtk_container_set_border_width (GTK_CONTAINER (container), 5);
- g_signal_connect (G_OBJECT (container), "delete_event",
- G_CALLBACK (delete_popup), container);
- g_signal_connect (G_OBJECT (container), "key_press_event",
- G_CALLBACK (key_press_popup), container);
- g_signal_connect (G_OBJECT (container), "button_press_event",
- G_CALLBACK (button_press_popup), container);
-
-}
-
-/* FIXME:
- * - implement the show() virtual method with popup_grab_on_window()...
- * - implement the position_popup()
- */
-
-static void
-popup_container_dispose (GObject *object)
-{
- PopupContainer *container = (PopupContainer *) object;
-
- /* free memory */
- if (container->priv) {
- g_free (container->priv);
- container->priv = NULL;
- }
-
- parent_class->dispose (object);
-}
-
-static void
-default_position_func (PopupContainer *container, gint *out_x, gint *out_y)
-{
- gdk_display_get_pointer (gdk_display_get_default (), NULL,
- out_x, out_y, NULL);
-}
-
-static gboolean
-popup_grab_on_window (GdkWindow *window, guint32 activate_time)
-{
- if ((gdk_pointer_grab (window, TRUE,
- GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
- GDK_POINTER_MOTION_MASK,
- NULL, NULL, activate_time) == 0)) {
- if (gdk_keyboard_grab (window, TRUE,
- activate_time) == 0)
- return TRUE;
- else {
- gdk_pointer_ungrab (activate_time);
- return FALSE;
- }
- }
- return FALSE;
-}
-
-static void
-popup_container_show (GtkWidget *widget)
-{
- PopupContainer *container = (PopupContainer *) widget;
- gint x, y;
-
- GTK_WIDGET_CLASS (parent_class)->show (widget);
- if (container->priv->position_func)
- container->priv->position_func (container, &x, &y);
- else
- default_position_func (container, &x, &y);
- gtk_window_move (GTK_WINDOW (widget), x + 1, y + 1);
- gtk_window_move (GTK_WINDOW (widget), x, y);
-
- gtk_grab_add (widget);
-
- GdkScreen *screen;
- gint swidth, sheight;
- gint root_x, root_y;
- gint wwidth, wheight;
- gboolean do_move = FALSE;
- screen = gtk_window_get_screen (GTK_WINDOW (widget));
- if (screen) {
- swidth = gdk_screen_get_width (screen);
- sheight = gdk_screen_get_height (screen);
- }
- else {
- swidth = gdk_screen_width ();
- sheight = gdk_screen_height ();
- }
- gtk_window_get_position (GTK_WINDOW (widget), &root_x, &root_y);
- gtk_window_get_size (GTK_WINDOW (widget), &wwidth, &wheight);
- if (root_x + wwidth > swidth) {
- do_move = TRUE;
- root_x = swidth - wwidth;
- }
- else if (root_x < 0) {
- do_move = TRUE;
- root_x = 0;
- }
- if (root_y + wheight > sheight) {
- do_move = TRUE;
- root_y = sheight - wheight;
- }
- else if (root_y < 0) {
- do_move = TRUE;
- root_y = 0;
- }
- if (do_move)
- gtk_window_move (GTK_WINDOW (widget), root_x, root_y);
-
- popup_grab_on_window (widget->window,
- gtk_get_current_event_time ());
-}
-
-static void
-popup_container_hide (GtkWidget *widget)
-{
- GTK_WIDGET_CLASS (parent_class)->hide (widget);
- gtk_grab_remove (widget);
-}
-
-GType
-popup_container_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo info = {
- sizeof (PopupContainerClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) popup_container_class_init,
- NULL,
- NULL,
- sizeof (PopupContainer),
- 0,
- (GInstanceInitFunc) popup_container_init
- };
- type = g_type_register_static (GTK_TYPE_WINDOW, "PopupContainer",
- &info, 0);
- }
- return type;
-}
-
-static void
-popup_position (PopupContainer *container, gint *out_x, gint *out_y)
-{
- GtkWidget *poswidget;
- poswidget = g_object_get_data (G_OBJECT (container), "__poswidget");
-
- gint x, y;
- gint bwidth, bheight;
- GtkRequisition req;
-
- gtk_widget_size_request (poswidget, &req);
-
- gdk_window_get_origin (poswidget->window, &x, &y);
-
- x += poswidget->allocation.x;
- y += poswidget->allocation.y;
- bwidth = poswidget->allocation.width;
- bheight = poswidget->allocation.height;
-
- x += bwidth - req.width;
- y += bheight;
-
- if (x < 0)
- x = 0;
-
- if (y < 0)
- y = 0;
-
- *out_x = x;
- *out_y = y;
-}
-
-/**
- * popup_container_new_with_func
- *
- * Returns:
- */
-GtkWidget *
-popup_container_new (GtkWidget *position_widget)
-{
- PopupContainer *container;
- g_return_val_if_fail (GTK_IS_WIDGET (position_widget), NULL);
-
- container = POPUP_CONTAINER (g_object_new (POPUP_CONTAINER_TYPE, "type", GTK_WINDOW_POPUP,
- NULL));
- g_object_set_data (G_OBJECT (container), "__poswidget", position_widget);
- container->priv->position_func = popup_position;
- return (GtkWidget*) container;
-}
-
-
-/**
- * popup_container_new_with_func
- *
- * Returns:
- */
-GtkWidget *
-popup_container_new_with_func (PopupContainerPositionFunc pos_func)
-{
- PopupContainer *container;
-
- container = POPUP_CONTAINER (g_object_new (POPUP_CONTAINER_TYPE, "type", GTK_WINDOW_POPUP,
- NULL));
-
- container->priv->position_func = pos_func;
- return (GtkWidget*) container;
-}
diff --git a/tools/browser/common/popup-container.c b/tools/browser/common/popup-container.c
new file mode 120000
index e259f32..354fef4
--- /dev/null
+++ b/tools/browser/common/popup-container.c
@@ -0,0 +1 @@
+../../../libgda-ui/internal/popup-container.c
\ No newline at end of file
diff --git a/tools/browser/common/popup-container.h b/tools/browser/common/popup-container.h
deleted file mode 100644
index 836225b..cfcd232
--- a/tools/browser/common/popup-container.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2009 The GNOME Foundation
- *
- * AUTHORS:
- * Vivien Malerba <malerba gnome-db org>
- *
- * This Library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This Library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __POPUP_CONTAINER_H__
-#define __POPUP_CONTAINER_H__
-
-#include <gtk/gtkwindow.h>
-
-G_BEGIN_DECLS
-
-#define POPUP_CONTAINER_TYPE (popup_container_get_type())
-#define POPUP_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, POPUP_CONTAINER_TYPE, PopupContainer))
-#define POPUP_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST (klass, POPUP_CONTAINER_TYPE, PopupContainerClass))
-#define IS_POPUP_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, POPUP_CONTAINER_TYPE))
-#define IS_POPUP_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), POPUP_CONTAINER_TYPE))
-
-typedef struct _PopupContainer PopupContainer;
-typedef struct _PopupContainerClass PopupContainerClass;
-typedef struct _PopupContainerPrivate PopupContainerPrivate;
-
-typedef void (*PopupContainerPositionFunc) (PopupContainer *cont, gint *out_x, gint *out_y);
-
-struct _PopupContainer {
- GtkWindow parent;
- PopupContainerPrivate *priv;
-};
-
-struct _PopupContainerClass {
- GtkWindowClass parent_class;
-};
-
-GType popup_container_get_type (void) G_GNUC_CONST;
-GtkWidget *popup_container_new (GtkWidget *position_widget);
-GtkWidget *popup_container_new_with_func (PopupContainerPositionFunc pos_func);
-
-G_END_DECLS
-
-#endif
diff --git a/tools/browser/common/popup-container.h b/tools/browser/common/popup-container.h
new file mode 120000
index 836225b..cfcd232
--- /dev/null
+++ b/tools/browser/common/popup-container.h
@@ -0,0 +1 @@
+../../../libgda-ui/internal/popup-container.h
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]