[libgda/LIBGDA_4.2] Misc corrections
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda/LIBGDA_4.2] Misc corrections
- Date: Sun, 24 Jul 2011 21:23:44 +0000 (UTC)
commit 3b00c51c5b0f6154bf65616cabf2eccaa5d8d30a
Author: Vivien Malerba <malerba gnome-db org>
Date: Sun Jul 24 18:54:33 2011 +0200
Misc corrections
libgda-ui/gdaui-raw-form.c | 1 +
tools/browser/common/ui-formgrid.c | 61 +-
tools/browser/common/widget-overlay.c | 1045 +++++++++++++++++++++++++
tools/browser/query-exec/query-console-page.c | 5 +-
4 files changed, 1091 insertions(+), 21 deletions(-)
---
diff --git a/libgda-ui/gdaui-raw-form.c b/libgda-ui/gdaui-raw-form.c
index 60704e9..6b1bca8 100644
--- a/libgda-ui/gdaui-raw-form.c
+++ b/libgda-ui/gdaui-raw-form.c
@@ -557,6 +557,7 @@ iter_row_changed_cb (GdaDataModelIter *iter, gint row, GdauiRawForm *form)
param, !(attributes & GDA_VALUE_ATTR_NO_MODIF));
}
}
+ g_signal_emit_by_name (G_OBJECT (form), "selection-changed");
}
static void
diff --git a/tools/browser/common/ui-formgrid.c b/tools/browser/common/ui-formgrid.c
index 17134f5..f48e31d 100644
--- a/tools/browser/common/ui-formgrid.c
+++ b/tools/browser/common/ui-formgrid.c
@@ -197,6 +197,7 @@ ui_formgrid_show (GtkWidget *widget)
static void form_grid_autoupdate_cb (GtkToggleButton *button, UiFormGrid *formgrid);
static void form_grid_toggled_cb (GtkToggleButton *button, UiFormGrid *formgrid);
static void form_grid_populate_popup_cb (GtkWidget *wid, GtkMenu *menu, UiFormGrid *formgrid);
+static void selection_changed_cb (GdauiDataSelector *sel, UiFormGrid *formgrid);
static void
ui_formgrid_init (UiFormGrid *formgrid)
@@ -275,6 +276,35 @@ ui_formgrid_init (UiFormGrid *formgrid)
GDAUI_DATA_PROXY_INFO_CHUNCK_CHANGE_BUTTONS);
gtk_box_pack_start (GTK_BOX (hbox), formgrid->priv->info, TRUE, TRUE, 0);
gtk_widget_show (formgrid->priv->info);
+
+ /* keep data in sync */
+ g_signal_connect (formgrid->priv->raw_grid, "selection-changed",
+ G_CALLBACK (selection_changed_cb), formgrid);
+ g_signal_connect (formgrid->priv->raw_form, "selection-changed",
+ G_CALLBACK (selection_changed_cb), formgrid);
+}
+
+static void
+selection_changed_cb (GdauiDataSelector *sel, UiFormGrid *formgrid)
+{
+ GdaDataModelIter *iter;
+ GdauiDataSelector *tosel;
+ gint row;
+ if (sel == (GdauiDataSelector*) formgrid->priv->raw_grid)
+ tosel = (GdauiDataSelector*) formgrid->priv->raw_form;
+ else
+ tosel = (GdauiDataSelector*) formgrid->priv->raw_grid;
+
+ iter = gdaui_data_selector_get_data_set (sel);
+ g_assert (iter);
+ row = gda_data_model_iter_get_row (iter);
+ /*g_print ("Moved %s to row %d\n", sel == (GdauiDataSelector*) formgrid->priv->raw_grid ? "grid" : "form", row);*/
+ iter = gdaui_data_selector_get_data_set (tosel);
+ if (iter) {
+ g_signal_handlers_block_by_func (tosel, G_CALLBACK (selection_changed_cb), formgrid);
+ gda_data_model_iter_move_to_row (iter, row >= 0 ? row : 0);
+ g_signal_handlers_unblock_by_func (tosel, G_CALLBACK (selection_changed_cb), formgrid);
+ }
}
static void
@@ -286,9 +316,6 @@ form_grid_autoupdate_cb (GtkToggleButton *button, UiFormGrid *formgrid)
static void
form_grid_toggled_cb (GtkToggleButton *button, UiFormGrid *formgrid)
{
- GdaDataModelIter *iter;
- gint row;
-
if (!gtk_toggle_button_get_active (button)) {
/* switch to form view */
gtk_notebook_set_current_page (GTK_NOTEBOOK (formgrid->priv->nb), 1);
@@ -302,11 +329,6 @@ form_grid_toggled_cb (GtkToggleButton *button, UiFormGrid *formgrid)
GdkPixbuf *pixbuf = browser_get_pixbuf_icon (BROWSER_ICON_FORM);
gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_pixbuf (pixbuf));
-
- iter = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (formgrid->priv->raw_grid));
- if (iter)
- row = gda_data_model_iter_get_row (iter);
- iter = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (formgrid->priv->raw_form));
}
else {
/* switch to grid view */
@@ -321,15 +343,7 @@ form_grid_toggled_cb (GtkToggleButton *button, UiFormGrid *formgrid)
GdkPixbuf *pixbuf = browser_get_pixbuf_icon (BROWSER_ICON_GRID);
gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_pixbuf (pixbuf));
-
- iter = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (formgrid->priv->raw_form));
- if (iter)
- row = gda_data_model_iter_get_row (iter);
- iter = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (formgrid->priv->raw_grid));
}
-
- if (iter)
- gda_data_model_iter_move_to_row (iter, row >= 0 ? row : 0);
}
static BrowserConnection *
@@ -442,6 +456,9 @@ typedef struct {
guint exec_id;
guint timer_id;
} ActionExecutedData;
+
+static void action_executed_holder_changed_cb (G_GNUC_UNUSED GdaSet *params, G_GNUC_UNUSED GdaHolder *holder,
+ ActionExecutedData *aed);
static void
action_executed_data_free (ActionExecutedData *data)
{
@@ -450,7 +467,12 @@ action_executed_data_free (ActionExecutedData *data)
g_object_unref ((GObject*) data->formgrid);
g_free (data->name);
g_object_unref ((GObject*) data->stmt);
- g_object_unref ((GObject*) data->params);
+
+ if (data->params) {
+ g_signal_handlers_disconnect_by_func (data->params,
+ G_CALLBACK (action_executed_holder_changed_cb), data);
+ g_object_unref ((GObject*) data->params);
+ }
if (data->model)
g_object_unref ((GObject*) data->model);
if (data->timer_id)
@@ -542,6 +564,7 @@ statement_executed_cb (G_GNUC_UNUSED BrowserConnection *bcnc,
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (aed->formgrid));
g_object_unref (aed->formgrid);
aed->formgrid = NULL;
+
if (error)
browser_show_error (GTK_WINDOW (toplevel),
_("Error executing query:\n%s"),
@@ -599,7 +622,9 @@ statement_executed_cb (G_GNUC_UNUSED BrowserConnection *bcnc,
G_CALLBACK (gtk_widget_destroy), NULL);
g_signal_connect (dialog, "close",
G_CALLBACK (gtk_widget_destroy), NULL);
- aed = NULL;
+ g_object_set_data_full (G_OBJECT (dialog), "aed", aed,
+ (GDestroyNotify) action_executed_data_free);
+ aed = NULL; /* don't free it yet */
}
else if (BROWSER_IS_WINDOW (toplevel)) {
browser_window_show_notice_printf (BROWSER_WINDOW (toplevel),
diff --git a/tools/browser/common/widget-overlay.c b/tools/browser/common/widget-overlay.c
new file mode 100644
index 0000000..dc56405
--- /dev/null
+++ b/tools/browser/common/widget-overlay.c
@@ -0,0 +1,1045 @@
+/*
+ * Copyright (C) 2010 David King <davidk openismus com>
+ * Copyright (C) 2010 - 2011 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 Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "widget-overlay.h"
+#include <stdarg.h>
+#include <glib/gi18n-lib.h>
+
+#define SCALE_MIN .6
+#define SCALE_MAX 1.
+#define SCALE_MAX_SCALE 1.5
+#define SCALE_STEP ((SCALE_MAX - SCALE_MIN) / 20.)
+
+static void widget_overlay_realize (GtkWidget *widget);
+static void widget_overlay_unrealize (GtkWidget *widget);
+static void widget_overlay_get_preferred_width (GtkWidget *widget,
+ gint *minimum,
+ gint *natural);
+static void widget_overlay_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural);
+static void widget_overlay_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static gboolean widget_overlay_damage (GtkWidget *widget,
+ GdkEventExpose *event);
+static gboolean widget_overlay_draw (GtkWidget *widget,
+ cairo_t *cr);
+static void widget_overlay_add (GtkContainer *container,
+ GtkWidget *child);
+static void widget_overlay_remove (GtkContainer *container,
+ GtkWidget *widget);
+static void widget_overlay_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
+static void widget_overlay_show (GtkWidget *widget);
+static void widget_overlay_dispose (GObject *obj);
+static void widget_overlay_finalize (GObject *obj);
+
+static gboolean widget_overlay_event (GtkWidget *widget, GdkEvent *event);
+
+static void widget_overlay_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void widget_overlay_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static GdkWindow * pick_offscreen_child (GdkWindow *offscreen_window,
+ double widget_x, double widget_y,
+ WidgetOverlay *ovl);
+
+
+/* properties */
+enum
+{
+ PROP_0,
+ PROP_ADD_SCALE
+};
+
+G_DEFINE_TYPE (WidgetOverlay, widget_overlay, GTK_TYPE_CONTAINER);
+
+typedef struct {
+ WidgetOverlay *ovl;
+ GtkWidget *child;
+ GdkWindow *offscreen_window;
+ WidgetOverlayAlign halign;
+ WidgetOverlayAlign valign;
+ gint x, y;
+ gdouble alpha;
+ gboolean ignore_events;
+ gdouble scale;
+
+ gboolean is_tooltip;
+} ChildData;
+
+struct _WidgetOverlayPrivate
+{
+ GList *children;
+ ChildData *scale_child;
+ GtkRange *scale_range;
+
+ guint tooltip_ms;
+ guint idle_timer;
+};
+
+static GObjectClass *parent_class = NULL;
+
+/*
+static gint
+get_child_nb (WidgetOverlay *ovl, ChildData *cd)
+{
+ return g_list_index (ovl->priv->children, cd);
+}
+*/
+
+static void
+to_child (WidgetOverlay *ovl, GdkWindow *offscreen_window, double widget_x, double widget_y,
+ double *x_out, double *y_out)
+{
+ GList *list;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *lcd = (ChildData*) list->data;
+ if (lcd->offscreen_window == offscreen_window) {
+ *x_out = (widget_x - lcd->x) / lcd->scale;
+ *y_out = (widget_y - lcd->y) / lcd->scale;
+ return;
+ }
+ }
+
+ *x_out = -1;
+ *y_out = -1;
+}
+
+static void
+to_parent (WidgetOverlay *ovl, GdkWindow *offscreen_window, double offscreen_x, double offscreen_y,
+ double *x_out, double *y_out)
+{
+ GList *list;
+
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *lcd = (ChildData*) list->data;
+ if (lcd->offscreen_window == offscreen_window) {
+ *x_out = lcd->x * lcd->scale + offscreen_x;
+ *y_out = lcd->y * lcd->scale + offscreen_y;
+ return;
+ }
+ }
+
+ *x_out = offscreen_x;
+ *y_out = offscreen_y;
+}
+
+static void
+widget_overlay_class_init (WidgetOverlayClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ widget_class->realize = widget_overlay_realize;
+ widget_class->unrealize = widget_overlay_unrealize;
+ widget_class->get_preferred_width = widget_overlay_get_preferred_width;
+ widget_class->get_preferred_height = widget_overlay_get_preferred_height;
+ widget_class->size_allocate = widget_overlay_size_allocate;
+ widget_class->draw = widget_overlay_draw;
+ widget_class->event = widget_overlay_event;
+ widget_class->show = widget_overlay_show;
+
+ g_signal_override_class_closure (g_signal_lookup ("damage-event", GTK_TYPE_WIDGET),
+ WIDGET_OVERLAY_TYPE,
+ g_cclosure_new (G_CALLBACK (widget_overlay_damage),
+ NULL, NULL));
+
+ container_class->add = widget_overlay_add;
+ container_class->remove = widget_overlay_remove;
+ container_class->forall = widget_overlay_forall;
+ G_OBJECT_CLASS (klass)->dispose = widget_overlay_dispose;
+ G_OBJECT_CLASS (klass)->finalize = widget_overlay_finalize;
+
+ /* Properties */
+ G_OBJECT_CLASS (klass)->set_property = widget_overlay_set_property;
+ G_OBJECT_CLASS (klass)->get_property = widget_overlay_get_property;
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ADD_SCALE,
+ g_param_spec_boolean ("add-scale", NULL, NULL,
+ FALSE,
+ (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+}
+
+static void
+change_widget_scale (WidgetOverlay *ovl, ChildData *cd, gdouble new_scale)
+{
+ widget_overlay_set_child_props (ovl, cd->child, WIDGET_OVERLAY_CHILD_SCALE, new_scale, -1);
+ if (ovl->priv->scale_child)
+ gtk_range_set_value (ovl->priv->scale_range, new_scale);
+}
+
+static ChildData *
+get_first_child (WidgetOverlay *ovl)
+{
+ GList *list;
+
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *lcd;
+ lcd = (ChildData*) list->data;
+ if (lcd != ovl->priv->scale_child)
+ return lcd;
+ }
+ return NULL;
+}
+
+static void
+scale_value_changed_cb (GtkRange *range, WidgetOverlay *ovl)
+{
+ ChildData *cd;
+ cd = get_first_child (ovl);
+ if (!cd)
+ return;
+ change_widget_scale (ovl, cd, gtk_range_get_value (range));
+}
+
+static void
+scale_button_clicked_cb (GtkButton *button, WidgetOverlay *ovl)
+{
+ g_object_set (G_OBJECT (ovl), "add-scale", FALSE, NULL);
+}
+
+static void
+widget_overlay_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ WidgetOverlay *ovl = WIDGET_OVERLAY (object);
+ if (ovl->priv) {
+ switch (param_id) {
+ case PROP_ADD_SCALE: {
+ gboolean need_scale;
+ need_scale = g_value_get_boolean (value);
+ if (!need_scale && !ovl->priv->scale_child)
+ return;
+
+ if (need_scale && ovl->priv->scale_child) {
+ widget_overlay_set_child_props (ovl, ovl->priv->scale_child->child,
+ WIDGET_OVERLAY_CHILD_ALPHA, .6,
+ -1);
+ }
+ else if (need_scale) {
+ GtkWidget *box, *wid, *button, *image;
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ wid = gtk_vscale_new_with_range (SCALE_MIN, SCALE_MAX, SCALE_STEP);
+ ovl->priv->scale_range = GTK_RANGE (wid);
+ g_object_set (G_OBJECT (wid), "draw-value", FALSE, NULL);
+ gtk_box_pack_start (GTK_BOX (box), wid, TRUE, TRUE, 0);
+
+ button = gtk_button_new ();
+ image = gtk_image_new_from_stock (GTK_STOCK_CLOSE,
+ GTK_ICON_SIZE_MENU);
+ gtk_container_add (GTK_CONTAINER (button), image);
+ gtk_container_add (GTK_CONTAINER (box), button);
+ gtk_widget_set_name (button, "browser-tab-close-button");
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (scale_button_clicked_cb), ovl);
+
+ gtk_container_add (GTK_CONTAINER (ovl), box);
+ gtk_widget_show_all (box);
+
+ GList *list;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd = (ChildData*) list->data;
+ if (cd->child == box) {
+ ovl->priv->scale_child = cd;
+ break;
+ }
+ }
+ g_assert (ovl->priv->scale_child);
+
+ ChildData *cd;
+ cd = get_first_child (ovl);
+ if (cd)
+ gtk_range_set_value (ovl->priv->scale_range, cd->scale);
+ gtk_range_set_inverted (ovl->priv->scale_range, TRUE);
+
+ g_signal_connect (wid, "value-changed",
+ G_CALLBACK (scale_value_changed_cb), ovl);
+
+ widget_overlay_set_child_props (ovl, box,
+ WIDGET_OVERLAY_CHILD_VALIGN,
+ WIDGET_OVERLAY_ALIGN_FILL,
+ WIDGET_OVERLAY_CHILD_HALIGN,
+ WIDGET_OVERLAY_ALIGN_END,
+ WIDGET_OVERLAY_CHILD_SCALE, 1.,
+ WIDGET_OVERLAY_CHILD_ALPHA, .6,
+ -1);
+ }
+ else {
+ widget_overlay_set_child_props (ovl, ovl->priv->scale_child->child,
+ WIDGET_OVERLAY_CHILD_ALPHA, 0.,
+ -1);
+ }
+ break;
+ }
+ }
+ }
+}
+
+static void
+widget_overlay_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ WidgetOverlay *ovl = WIDGET_OVERLAY (object);
+ if (ovl->priv) {
+ switch (param_id) {
+ case PROP_ADD_SCALE: {
+ gboolean has_scale = FALSE;
+ if (ovl->priv->scale_child &&
+ (ovl->priv->scale_child->alpha > 0.))
+ has_scale = TRUE;
+ g_value_set_boolean (value, has_scale);
+ break;
+ }
+ }
+ }
+}
+
+static gboolean
+idle_timer_cb (WidgetOverlay *ovl)
+{
+ GList *list;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd;
+ cd = (ChildData*) list->data;
+ if (cd->is_tooltip) {
+ gtk_widget_show (cd->child);
+ gtk_widget_queue_draw (GTK_WIDGET (ovl));
+ /*
+ widget_overlay_set_child_props (ovl, cd->child,
+ WIDGET_OVERLAY_CHILD_ALPHA, 1.,
+ WIDGET_OVERLAY_CHILD_HAS_EVENTS, TRUE,
+ -1);
+ */
+ }
+ }
+ ovl->priv->idle_timer = 0;
+ return FALSE; /* remove timer */
+}
+
+static gboolean
+widget_overlay_event (GtkWidget *widget, GdkEvent *event)
+{
+ GdkEventScroll *ev = (GdkEventScroll *) event;
+ WidgetOverlay *ovl = WIDGET_OVERLAY (widget);
+ ChildData *cdevent = NULL;
+
+ /* find child */
+ GList *list;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd;
+ cd = (ChildData*) list->data;
+ if (cd->offscreen_window == ((GdkEventAny*)event)->window) {
+ cdevent = cd;
+ break;
+ }
+ }
+ /*g_print (" CH%d/%d", g_list_index (ovl->priv->children, cdevent), event->type);*/
+
+ /* tooltip widgets handling */
+ gboolean tooltip_event = FALSE;
+ if ((event->type == GDK_BUTTON_PRESS) ||
+ (event->type == GDK_2BUTTON_PRESS) ||
+ (event->type == GDK_3BUTTON_PRESS) ||
+ (event->type == GDK_BUTTON_RELEASE) ||
+ (event->type == GDK_MOTION_NOTIFY) ||
+ (event->type == GDK_KEY_PRESS) ||
+ (event->type == GDK_KEY_RELEASE) ||
+ (event->type == GDK_ENTER_NOTIFY) ||
+ (event->type == GDK_LEAVE_NOTIFY) ||
+ (event->type == GDK_SCROLL))
+ tooltip_event = TRUE;
+
+ if (tooltip_event) {
+ /*g_print (".");*/
+ gboolean need_tooltip = FALSE;
+ GList *list;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd;
+ cd = (ChildData*) list->data;
+ if (cd->is_tooltip) {
+ need_tooltip = TRUE;
+ break;
+ }
+ }
+
+ if (ovl->priv->idle_timer) {
+ g_source_remove (ovl->priv->idle_timer);
+ ovl->priv->idle_timer = 0;
+ }
+
+ if ((event->type != GDK_ENTER_NOTIFY) &&
+ (event->type != GDK_LEAVE_NOTIFY)) {
+ gboolean inc_timeout = FALSE;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd;
+ cd = (ChildData*) list->data;
+ if (cd->is_tooltip && gtk_widget_get_visible (cd->child)) {
+ inc_timeout = TRUE;
+ gtk_widget_hide (cd->child);
+ }
+ }
+ if (inc_timeout) {
+ GtkSettings *settings;
+ guint t;
+ settings = gtk_widget_get_settings (widget);
+ g_object_get (settings, "gtk-tooltip-timeout",
+ &t, NULL);
+ if ((ovl->priv->tooltip_ms * 2) < (t * 32))
+ ovl->priv->tooltip_ms = ovl->priv->tooltip_ms * 2;
+ }
+ }
+
+ if ((event->type == GDK_LEAVE_NOTIFY) &&
+ ((GdkEventAny*)event)->window == gtk_widget_get_window (GTK_WIDGET (ovl)))
+ need_tooltip = FALSE;
+
+ if (need_tooltip) {
+ if (ovl->priv->tooltip_ms == 0) {
+ GtkSettings *settings;
+ settings = gtk_widget_get_settings (widget);
+ g_object_get (settings, "gtk-tooltip-timeout",
+ &(ovl->priv->tooltip_ms), NULL);
+ }
+ ovl->priv->idle_timer = g_timeout_add (ovl->priv->tooltip_ms,
+ (GSourceFunc) idle_timer_cb, ovl);
+ }
+ }
+
+ if ((event->type != GDK_SCROLL) || !(ev->state & GDK_SHIFT_MASK))
+ return FALSE;
+
+ ChildData *cd = NULL;
+ cd = get_first_child (ovl);
+ if (!cd)
+ return FALSE;
+
+ gdouble scale;
+ scale = cd->scale;
+ if (ev->direction == GDK_SCROLL_UP)
+ scale += SCALE_STEP;
+ else
+ scale -= SCALE_STEP;
+ change_widget_scale (ovl, cd, scale);
+
+ return TRUE;
+}
+
+static void
+widget_overlay_init (WidgetOverlay *ovl)
+{
+ gtk_widget_set_has_window (GTK_WIDGET (ovl), TRUE);
+ ovl->priv = g_new0 (WidgetOverlayPrivate, 1);
+ ovl->priv->children = NULL;
+ ovl->priv->scale_child = NULL;
+ ovl->priv->tooltip_ms = 0;
+}
+
+GtkWidget *
+widget_overlay_new (void)
+{
+ return g_object_new (WIDGET_OVERLAY_TYPE, NULL);
+}
+
+static void
+widget_overlay_dispose (GObject *obj)
+{
+ WidgetOverlay *ovl = WIDGET_OVERLAY (obj);
+ if (ovl->priv) {
+ if (ovl->priv->idle_timer) {
+ g_source_remove (ovl->priv->idle_timer);
+ ovl->priv->idle_timer = 0;
+ }
+ }
+ if (G_OBJECT_CLASS (parent_class)->dispose)
+ G_OBJECT_CLASS (parent_class)->dispose (obj);
+}
+
+static void
+widget_overlay_finalize (GObject *obj)
+{
+ WidgetOverlay *ovl = WIDGET_OVERLAY (obj);
+ if (ovl->priv->children) {
+ GList *list;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd = (ChildData*) list->data;
+ g_free (cd);
+ }
+ g_list_free (ovl->priv->children);
+ }
+ g_free (ovl->priv);
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+static void
+widget_overlay_show (GtkWidget *widget)
+{
+ WidgetOverlay *ovl = WIDGET_OVERLAY (widget);
+ GList *list;
+
+ ((GtkWidgetClass *)parent_class)->show (widget);
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd;
+ cd = (ChildData*) list->data;
+ if (cd->is_tooltip)
+ gtk_widget_hide (cd->child);
+ }
+}
+
+static GdkWindow *
+pick_offscreen_child (G_GNUC_UNUSED GdkWindow *offscreen_window,
+ double widget_x, double widget_y,
+ WidgetOverlay *ovl)
+{
+ GList *list;
+ GdkWindow *retval = NULL;
+ gboolean ign_non_tooltip = FALSE;
+
+ //return ((ChildData*)ovl->priv->children)->offscreen_window;
+
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd = (ChildData*) list->data;
+ if (cd->is_tooltip && gtk_widget_get_visible (cd->child)) {
+ ign_non_tooltip = TRUE;
+ break;
+ }
+ }
+
+ for (list = g_list_last (ovl->priv->children); list; list = list->prev) {
+ ChildData *cd = (ChildData*) list->data;
+ if (!cd->ignore_events && gtk_widget_get_visible (cd->child) &&
+ (!ign_non_tooltip || (ign_non_tooltip && cd->is_tooltip))) {
+ GtkAllocation alloc;
+ double x, y;
+ to_child (ovl, cd->offscreen_window, widget_x, widget_y, &x, &y);
+ gtk_widget_get_allocation ((GtkWidget*) cd->child, &alloc);
+ if (x >= 0 && x < alloc.width &&
+ y >= 0 && y < alloc.height) {
+ retval = cd->offscreen_window;
+ break;
+ }
+ }
+ }
+
+ /*g_print ("%s() => %p\n", __FUNCTION__, retval);*/
+ return retval;
+}
+
+static void
+offscreen_window_to_parent (GdkWindow *offscreen_window,
+ double offscreen_x, double offscreen_y,
+ double *parent_x, double *parent_y,
+ WidgetOverlay *ovl)
+{
+ to_parent (ovl, offscreen_window, offscreen_x, offscreen_y, parent_x, parent_y);
+}
+
+static void
+offscreen_window_from_parent (GdkWindow *offscreen_window,
+ double parent_x, double parent_y,
+ double *offscreen_x, double *offscreen_y,
+ WidgetOverlay *ovl)
+{
+ to_child (ovl, offscreen_window, parent_x, parent_y, offscreen_x, offscreen_y);
+}
+
+static void
+widget_overlay_realize (GtkWidget *widget)
+{
+ WidgetOverlay *ovl = WIDGET_OVERLAY (widget);
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+ gint border_width;
+ GtkRequisition child_requisition;
+ GtkAllocation allocation;
+
+ gtk_widget_set_realized (widget, TRUE);
+
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+
+ gtk_widget_get_allocation (widget, &allocation);
+ attributes.x = allocation.x + border_width;
+ attributes.y = allocation.y + border_width;
+ attributes.width = allocation.width - 2 * border_width;
+ attributes.height = allocation.height - 2 * border_width;
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.event_mask = gtk_widget_get_events (widget)
+ | GDK_EXPOSURE_MASK
+ | GDK_POINTER_MOTION_MASK
+ | GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_SCROLL_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_LEAVE_NOTIFY_MASK;
+
+ attributes.visual = gtk_widget_get_visual (widget);
+ attributes.wclass = GDK_INPUT_OUTPUT;
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
+
+ GdkWindow *win;
+ win = gdk_window_new (gtk_widget_get_parent_window (widget),
+ &attributes, attributes_mask);
+ gtk_widget_set_window (widget, win);
+ gdk_window_set_user_data (win, widget);
+ g_signal_connect (win, "pick-embedded-child",
+ G_CALLBACK (pick_offscreen_child), ovl);
+
+ GtkStyle *style;
+ style = gtk_widget_get_style (widget);
+ style = gtk_style_attach (style, win);
+ gtk_widget_set_style (widget, style);
+
+ /* offscreen windows */
+ attributes.window_type = GDK_WINDOW_OFFSCREEN;
+
+ GList *list;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd = (ChildData*) list->data;
+ child_requisition.width = child_requisition.height = 0;
+ if (gtk_widget_get_visible (cd->child)) {
+ GtkAllocation allocation;
+ gtk_widget_get_allocation (cd->child, &allocation);
+ attributes.width = allocation.width;
+ attributes.height = allocation.height;
+ }
+
+ cd->offscreen_window = gdk_window_new (gtk_widget_get_root_window (widget),
+ &attributes, attributes_mask);
+ gdk_window_set_user_data (cd->offscreen_window, widget);
+ gtk_widget_set_parent_window (cd->child, cd->offscreen_window);
+ gdk_offscreen_window_set_embedder (cd->offscreen_window, win);
+ g_signal_connect (cd->offscreen_window, "to-embedder",
+ G_CALLBACK (offscreen_window_to_parent), ovl);
+ g_signal_connect (cd->offscreen_window, "from-embedder",
+ G_CALLBACK (offscreen_window_from_parent), ovl);
+
+ //gtk_style_set_background (style, win, GTK_STATE_NORMAL);
+ gtk_style_set_background (style, cd->offscreen_window, GTK_STATE_NORMAL);
+ gdk_window_show (cd->offscreen_window);
+ }
+}
+
+static void
+widget_overlay_unrealize (GtkWidget *widget)
+{
+ WidgetOverlay *ovl = WIDGET_OVERLAY (widget);
+
+ GList *list;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd = (ChildData*) list->data;
+ gdk_window_set_user_data (cd->offscreen_window, NULL);
+ gdk_window_destroy (cd->offscreen_window);
+ cd->offscreen_window = NULL;
+ }
+
+ GTK_WIDGET_CLASS (widget_overlay_parent_class)->unrealize (widget);
+}
+
+static void
+widget_overlay_add (GtkContainer *container, GtkWidget *widget)
+{
+ WidgetOverlay *ovl = WIDGET_OVERLAY (container);
+ ChildData *cd;
+
+ cd = g_new0 (ChildData, 1);
+ gtk_widget_set_parent (widget, GTK_WIDGET (ovl));
+ cd->ovl = ovl;
+ cd->child = widget;
+ cd->halign = WIDGET_OVERLAY_ALIGN_CENTER;
+ cd->valign = WIDGET_OVERLAY_ALIGN_END;
+ cd->alpha = 1.;
+ cd->scale = 1.;
+ cd->ignore_events = FALSE;
+ cd->is_tooltip = FALSE;
+
+ ovl->priv->children = g_list_append (ovl->priv->children, cd);
+
+ if (ovl->priv->scale_child) {
+ ChildData *fcd;
+ fcd = get_first_child (ovl);
+ if (cd == fcd)
+ gtk_range_set_value (ovl->priv->scale_range, cd->scale);
+
+ ovl->priv->children = g_list_remove (ovl->priv->children, ovl->priv->scale_child);
+ ovl->priv->children = g_list_append (ovl->priv->children, ovl->priv->scale_child);
+ }
+}
+
+static void
+widget_overlay_remove (GtkContainer *container, GtkWidget *widget)
+{
+ WidgetOverlay *ovl = WIDGET_OVERLAY (container);
+ gboolean was_visible;
+
+ was_visible = gtk_widget_get_visible (widget);
+ GList *list;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd = (ChildData*) list->data;
+ if (cd->child == widget) {
+ gtk_widget_unparent (widget);
+ ovl->priv->children = g_list_remove (ovl->priv->children, cd);
+ g_free (cd);
+ if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container)))
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ break;
+ }
+ }
+}
+
+static void
+widget_overlay_forall (GtkContainer *container,
+ G_GNUC_UNUSED gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ WidgetOverlay *ovl = WIDGET_OVERLAY (container);
+
+ g_return_if_fail (callback != NULL);
+ GList *list, *copy;
+ copy = g_list_copy (ovl->priv->children);
+ for (list = copy; list; list = list->next) {
+ ChildData *cd = (ChildData*) list->data;
+ (*callback) (cd->child, callback_data);
+ }
+ g_list_free (copy);
+}
+
+static void
+widget_overlay_size_request (GtkWidget *widget, GtkRequisition *req_min, GtkRequisition *req_nat)
+{
+ WidgetOverlay *ovl = WIDGET_OVERLAY (widget);
+ guint border_width;
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+ req_min->width = 1;
+ req_min->height = 1;
+ req_nat->width = 1;
+ req_nat->height = 1;
+
+ GList *list;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd = (ChildData*) list->data;
+ if (gtk_widget_get_visible (cd->child)) {
+ GtkRequisition child_req_min, child_req_nat;
+ gtk_widget_get_preferred_size (cd->child, &child_req_min, &child_req_nat);
+ if (cd->halign == WIDGET_OVERLAY_ALIGN_FILL) {
+ req_min->width = MAX (border_width * 2 + child_req_min.width,
+ req_min->width);
+ req_nat->width = MAX (border_width * 2 + child_req_nat.width,
+ req_nat->width);
+ }
+ else {
+ req_min->width = MAX (border_width * 2 + child_req_min.width * cd->scale,
+ req_min->width);
+ req_nat->width = MAX (border_width * 2 + child_req_nat.width * cd->scale,
+ req_nat->width);
+ }
+
+ if (cd->valign == WIDGET_OVERLAY_ALIGN_FILL) {
+ req_min->height = MAX (border_width * 2 + child_req_min.height,
+ req_min->height);
+
+ req_nat->height = MAX (border_width * 2 + child_req_nat.height,
+ req_nat->height);
+ }
+ else {
+ req_min->height = MAX (border_width * 2 + child_req_min.height * cd->scale,
+ req_min->height);
+
+ req_nat->height = MAX (border_width * 2 + child_req_nat.height * cd->scale,
+ req_nat->height);
+ }
+ }
+ }
+}
+
+static void
+widget_overlay_get_preferred_width (GtkWidget *widget, gint *minimum, gint *natural)
+{
+ GtkRequisition req_min, req_nat;
+ widget_overlay_size_request (widget, &req_min, &req_nat);
+ *minimum = req_min.width;
+ *natural = req_nat.width;
+}
+
+static void
+widget_overlay_get_preferred_height (GtkWidget *widget, gint *minimum, gint *natural)
+{
+ GtkRequisition req_min, req_nat;
+ widget_overlay_size_request (widget, &req_min, &req_nat);
+ *minimum = req_min.height;
+ *natural = req_nat.height;
+}
+
+static void
+widget_overlay_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+ WidgetOverlay *ovl = WIDGET_OVERLAY (widget);
+ gint border_width;
+ gint w, h;
+
+ gtk_widget_set_allocation (widget, allocation);
+
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+
+ w = allocation->width - border_width * 2;
+ h = allocation->height - border_width * 2;
+
+ if (gtk_widget_get_realized (widget)) {
+ GdkWindow *win;
+ win = gtk_widget_get_window (widget);
+ gdk_window_move_resize (win,
+ allocation->x + border_width,
+ allocation->y + border_width,
+ w, h);
+ }
+
+ GList *list;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd = (ChildData*) list->data;
+ if (gtk_widget_get_visible (cd->child)){
+ GtkRequisition child_requisition;
+ GtkAllocation child_allocation;
+
+ gtk_widget_get_preferred_size (cd->child, &child_requisition, NULL);
+ child_allocation.x = 0;
+ child_allocation.y = 0;
+ child_allocation.height = child_requisition.height;
+ child_allocation.width = child_requisition.width;
+
+ if (cd->halign == WIDGET_OVERLAY_ALIGN_FILL)
+ child_allocation.width = w / cd->scale;
+ if ((cd->valign == WIDGET_OVERLAY_ALIGN_FILL) ||
+ (cd == ovl->priv->scale_child))
+ child_allocation.height = h / cd->scale;
+
+ if (gtk_widget_get_realized (widget))
+ gdk_window_move_resize (cd->offscreen_window,
+ child_allocation.x,
+ child_allocation.y,
+ child_allocation.width,
+ child_allocation.height);
+
+ child_allocation.x = child_allocation.y = 0;
+
+ gtk_widget_size_allocate (cd->child, &child_allocation);
+ }
+ }
+}
+
+static gboolean
+widget_overlay_damage (GtkWidget *widget,
+ G_GNUC_UNUSED GdkEventExpose *event)
+{
+ gdk_window_invalidate_rect (gtk_widget_get_window (widget), NULL, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+widget_overlay_draw (GtkWidget *widget, cairo_t *cr)
+{
+ WidgetOverlay *ovl = WIDGET_OVERLAY (widget);
+ GdkWindow *window;
+
+ GtkAllocation area;
+ gtk_widget_get_allocation (widget, &area);
+
+ window = gtk_widget_get_window (widget);
+ if (gtk_cairo_should_draw_window (cr, window)) {
+ GList *list;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd = (ChildData*) list->data;
+ if (gtk_widget_get_visible (cd->child)) {
+ cairo_surface_t *surface;
+ GtkAllocation child_area;
+ double x, y;
+
+ gtk_widget_get_allocation (cd->child, &child_area);
+ child_area.width *= cd->scale;
+ child_area.height *= cd->scale;
+ switch (cd->halign) {
+ case WIDGET_OVERLAY_ALIGN_FILL:
+ case WIDGET_OVERLAY_ALIGN_START:
+ x = 0;
+ break;
+ case WIDGET_OVERLAY_ALIGN_END:
+ x = area.width - child_area.width;
+ break;
+ case WIDGET_OVERLAY_ALIGN_CENTER:
+ x = (area.width - child_area.width) / 2.;
+ break;
+ }
+ switch (cd->valign) {
+ case WIDGET_OVERLAY_ALIGN_FILL:
+ case WIDGET_OVERLAY_ALIGN_START:
+ y = 0;
+ break;
+ case WIDGET_OVERLAY_ALIGN_END:
+ y = area.height - child_area.height;
+ break;
+ case WIDGET_OVERLAY_ALIGN_CENTER:
+ y = (area.height - child_area.height) / 2.;
+ break;
+ }
+
+ surface = gdk_offscreen_window_get_surface (cd->offscreen_window);
+ if (cd->scale == 1.) {
+ cairo_set_source_surface (cr, surface, x, y);
+ cairo_paint_with_alpha (cr, cd->alpha);
+ }
+ else {
+ cairo_save (cr);
+ cairo_scale (cr, cd->scale, cd->scale);
+ cairo_set_source_surface (cr, surface, x/cd->scale, y/cd->scale);
+ cairo_paint_with_alpha (cr, cd->alpha);
+ cairo_restore (cr);
+ }
+
+ cd->x = x;
+ cd->y = y;
+ }
+
+ if (list->next &&
+ ((ChildData*) list->next->data == ovl->priv->scale_child) &&
+ (ovl->priv->scale_child->alpha > 0.)) {
+ cairo_set_source_rgba (cr, 0., 0., 0., .3);
+ cairo_rectangle (cr, 0, 0,
+ area.width, area.height);
+ cairo_fill (cr);
+ }
+ }
+ }
+ else {
+ GList *list;
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd = (ChildData*) list->data;
+ if (gtk_cairo_should_draw_window (cr, cd->offscreen_window))
+ gtk_container_propagate_draw (GTK_CONTAINER (widget), cd->child, cr);
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * widget_overlay_set_child_props:
+ *
+ * @...: (WidgetOverlayChildProperty, value) terminated by -1
+ */
+void
+widget_overlay_set_child_props (WidgetOverlay *ovl, GtkWidget *child, ...)
+{
+ GList *list;
+ g_return_if_fail (IS_WIDGET_OVERLAY (ovl));
+
+ for (list = ovl->priv->children; list; list = list->next) {
+ ChildData *cd = (ChildData*) list->data;
+ if (cd->child == child) {
+ va_list args;
+ WidgetOverlayChildProperty prop;
+ GtkAllocation area;
+ gtk_widget_get_allocation (GTK_WIDGET (ovl), &area);
+ if (gtk_widget_get_has_window (GTK_WIDGET (ovl)))
+ area.x = area.y = 0;
+
+ va_start (args, child);
+ for (prop = va_arg (args, WidgetOverlayChildProperty); prop != -1;
+ prop = va_arg (args, WidgetOverlayChildProperty)) {
+ switch (prop) {
+ case WIDGET_OVERLAY_CHILD_VALIGN:
+ cd->valign = va_arg (args, WidgetOverlayAlign);
+ break;
+ case WIDGET_OVERLAY_CHILD_HALIGN:
+ cd->halign = va_arg (args, WidgetOverlayAlign);
+ break;
+ case WIDGET_OVERLAY_CHILD_ALPHA:
+ cd->alpha = va_arg (args, gdouble);
+ if (cd->alpha > 1.)
+ cd->alpha = 1;
+ else if (cd->alpha < 0.)
+ cd->alpha = 0.;
+
+ if (cd != ovl->priv->scale_child) {
+ gtk_widget_get_allocation (cd->child, &area);
+ area.x = cd->x;
+ area.y = cd->y;
+ }
+ break;
+ case WIDGET_OVERLAY_CHILD_HAS_EVENTS:
+ cd->ignore_events = ! (va_arg (args, gboolean));
+ break;
+ case WIDGET_OVERLAY_CHILD_SCALE: {
+ GtkAllocation alloc;
+ gdouble current, max;
+ current = cd->scale;
+ gtk_widget_get_allocation (cd->child, &alloc);
+
+ cd->scale = va_arg (args, gdouble);
+ if (cd->scale < SCALE_MIN)
+ cd->scale = SCALE_MIN;
+ max = SCALE_MAX;
+ if (cd == ovl->priv->scale_child)
+ max = SCALE_MAX_SCALE;
+ if (cd->scale > max)
+ cd->scale = max;
+
+ if (current >= cd->scale) {
+ area.x = cd->x;
+ area.y = cd->y;
+ area.width = alloc.width;
+ area.height = alloc.height;
+ }
+ if ((cd->halign == WIDGET_OVERLAY_ALIGN_FILL) ||
+ (cd->valign == WIDGET_OVERLAY_ALIGN_FILL)) {
+ /*gtk_widget_queue_resize (GTK_WIDGET (ovl));*/
+ gtk_widget_queue_resize (cd->child);
+ }
+ break;
+ }
+ case WIDGET_OVERLAY_CHILD_TOOLTIP:
+ cd->is_tooltip = va_arg (args, gboolean);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
+ va_end (args);
+ /*g_print ("Queue draw %dx%d %dx%d\n", area.x, area.y, area.width, area.height);*/
+ gtk_widget_queue_draw_area (GTK_WIDGET (ovl), area.x, area.y, area.width, area.height);
+
+ return;
+ }
+ }
+}
diff --git a/tools/browser/query-exec/query-console-page.c b/tools/browser/query-exec/query-console-page.c
index b0422a1..4ac1265 100644
--- a/tools/browser/query-exec/query-console-page.c
+++ b/tools/browser/query-exec/query-console-page.c
@@ -307,7 +307,7 @@ query_console_page_new (BrowserConnection *bcnc)
gtk_box_pack_start (GTK_BOX (hbox), hpaned, TRUE, TRUE, 0);
vbox = gtk_vbox_new (FALSE, 0);
- gtk_paned_pack1 (GTK_PANED (hpaned), vbox, TRUE, FALSE);
+ gtk_paned_pack1 (GTK_PANED (hpaned), vbox, TRUE, TRUE);
wid = gtk_label_new ("");
str = g_strdup_printf ("<b>%s</b>", _("SQL code to execute:"));
@@ -324,11 +324,10 @@ query_console_page_new (BrowserConnection *bcnc)
G_CALLBACK (editor_changed_cb), tconsole);
g_signal_connect (wid, "execute-request",
G_CALLBACK (editor_execute_request_cb), tconsole);
- gtk_widget_set_size_request (wid, -1, 200);
vbox = gtk_vbox_new (FALSE, 0);
tconsole->priv->params_top = vbox;
- gtk_paned_pack2 (GTK_PANED (hpaned), vbox, FALSE, TRUE);
+ gtk_paned_pack2 (GTK_PANED (hpaned), vbox, TRUE, TRUE);
wid = gtk_label_new ("");
str = g_strdup_printf ("<b>%s</b>", _("Variables' values:"));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]