[libgda] Major rework of the data entries
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] Major rework of the data entries
- Date: Sun, 29 Nov 2015 13:53:32 +0000 (UTC)
commit 4a9f615d887def93ccfb109611d100d8ab7e0bd1
Author: Vivien Malerba <malerba gnome-db org>
Date: Sun Nov 29 14:44:13 2015 +0100
Major rework of the data entries
doc/C/libgda-sections.txt | 1 +
libgda-ui/data-entries/common-bin.c | 500 +++++++---
libgda-ui/data-entries/common-bin.h | 19 +-
.../data-entries/gdaui-data-cell-renderer-bin.c | 51 +-
libgda-ui/data-entries/gdaui-entry-bin.c | 207 ++---
libgda-ui/data-entries/gdaui-entry-boolean.c | 76 +-
libgda-ui/data-entries/gdaui-entry-combo.c | 56 +-
libgda-ui/data-entries/gdaui-entry-common-time.c | 1112 ++++++++------------
libgda-ui/data-entries/gdaui-entry-integer.xml.in | 4 +-
libgda-ui/data-entries/gdaui-entry-none.c | 13 +-
libgda-ui/data-entries/gdaui-entry-number.c | 30 +-
libgda-ui/data-entries/gdaui-entry-number.xml.in | 6 +-
libgda-ui/data-entries/gdaui-entry-shell.c | 603 +++++++----
libgda-ui/data-entries/gdaui-entry-shell.h | 17 +-
libgda-ui/data-entries/gdaui-entry-string.c | 37 +-
libgda-ui/data-entries/gdaui-entry-string.xml.in | 8 +-
libgda-ui/data-entries/gdaui-entry-wrapper.c | 288 +++---
libgda-ui/data-entries/gdaui-entry.c | 87 ++-
libgda-ui/data-entries/gdaui-formatted-entry.c | 2 +-
libgda-ui/data-entries/gdaui-numeric-entry.c | 34 +-
libgda-ui/data-entries/plugins/gdaui-entry-cidr.c | 6 +-
.../data-entries/plugins/gdaui-entry-filesel.c | 10 +-
.../data-entries/plugins/gdaui-entry-format.c | 6 +-
.../data-entries/plugins/gdaui-entry-password.c | 10 +-
libgda-ui/data-entries/plugins/gdaui-entry-rt.c | 10 +-
libgda-ui/data-entries/plugins/gdaui-entry-text.c | 9 +-
libgda-ui/data/Makefile.am | 3 +-
libgda-ui/data/bin-attachment-16x16.png | Bin 649 -> 0 bytes
libgda-ui/data/mime-types-extensions | 413 ++++++++
libgda-ui/gdaui-basic-form.c | 254 ++---
libgda-ui/gdaui-cloud.c | 3 +-
libgda-ui/gdaui-data-entry.h | 4 +-
libgda-ui/gdaui-enums.h | 8 +
libgda-ui/gdaui-form.c | 3 +-
libgda-ui/gdaui-raw-form.c | 14 -
libgda-ui/gdaui.css | 12 -
libgda-ui/gdaui.gresource.xml | 4 +-
libgda-ui/internal/utility.c | 4 +-
libgda-ui/libgda-ui.symbols | 3 +-
libgda/gda-enums.h | 17 +-
libgda/gda-value.c | 95 ++-
libgda/gda-value.h | 3 +-
libgda/handlers/gda-handler-time.c | 62 ++-
libgda/handlers/gda-handler-time.h | 2 +
libgda/libgda.symbols | 2 +
testing/gdaui-test-data-entries.c | 147 ++-
testing/gdaui-test-errors.c | 11 +-
testing/gdaui-test-widget-entry.c | 45 +-
48 files changed, 2496 insertions(+), 1815 deletions(-)
---
diff --git a/doc/C/libgda-sections.txt b/doc/C/libgda-sections.txt
index a9d17a0..64aa99b 100644
--- a/doc/C/libgda-sections.txt
+++ b/doc/C/libgda-sections.txt
@@ -943,6 +943,7 @@ gda_time_valid
gda_time_change_timezone
gda_value_get_time
gda_value_set_time
+gda_value_new_time_from_timet
<SUBSECTION>
GdaTimestamp
gda_timestamp_copy
diff --git a/libgda-ui/data-entries/common-bin.c b/libgda-ui/data-entries/common-bin.c
index 25e92d5..638d793 100644
--- a/libgda-ui/data-entries/common-bin.c
+++ b/libgda-ui/data-entries/common-bin.c
@@ -19,9 +19,9 @@
* Boston, MA 02110-1301, USA.
*/
+#include <glib/gstdio.h>
#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>
@@ -32,11 +32,30 @@
#endif
static void
+show_and_clear_error (BinMenu *binmenu, const gchar *context, GError **error)
+{
+ if (!error)
+ return;
+
+ GtkWidget *msg, *relative_to;
+ relative_to = gtk_popover_get_relative_to (GTK_POPOVER (binmenu->popover));
+ msg = gtk_message_dialog_new_with_markup (relative_to ? GTK_WINDOW (gtk_widget_get_toplevel
(relative_to)) : NULL,
+ GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "<b>%s:</b>\n%s: %s",
+ _("Error"), context,
+ *error && (*error)->message ? (*error)->message : _("No
detail"));
+ gtk_dialog_run (GTK_DIALOG (msg));
+ gtk_widget_destroy (msg);
+ g_clear_error (error);
+}
+
+static void
file_load_cb (GtkWidget *button, BinMenu *menu)
{
GtkWidget *dlg;
- gtk_widget_hide (menu->popup);
+ gtk_widget_hide (menu->popover);
dlg = gtk_file_chooser_dialog_new (_("Select file to load"),
GTK_WINDOW (gtk_widget_get_toplevel (button)),
GTK_FILE_CHOOSER_ACTION_OPEN,
@@ -71,22 +90,13 @@ file_load_cb (GtkWidget *button, BinMenu *menu)
menu->loaded_value_cb (menu->loaded_value_cb_data, nvalue);
}
else {
- GtkWidget *msg;
+ gtk_widget_destroy (dlg);
+ dlg = NULL;
+
gchar *tmp;
tmp = g_strdup_printf (_("Could not load the contents of '%s'"), filename);
- msg = gtk_message_dialog_new_with_markup (GTK_WINDOW (gtk_widget_get_toplevel
(button)),
- GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "<b>%s:</b>\n%s: %s",
- _("Error"), tmp,
- error && error->message ?
error->message : _("No detail"));
+ show_and_clear_error (menu, tmp, &error);
g_free (tmp);
- g_clear_error (&error);
- gtk_widget_destroy (dlg);
- dlg = NULL;
-
- gtk_dialog_run (GTK_DIALOG (msg));
- gtk_widget_destroy (msg);
}
}
else
@@ -102,12 +112,51 @@ file_load_cb (GtkWidget *button, BinMenu *menu)
}
}
+static gboolean
+export_data (BinMenu *menu, const gchar *filename, GError **error)
+{
+ gboolean allok;
+ if (menu->entry_type == GDA_TYPE_BINARY) {
+ const GdaBinary *bin;
+ bin = gda_value_get_binary (menu->tmpvalue);
+ allok = g_file_set_contents (filename, (gchar *) bin->data,
+ bin->binary_length, error);
+ }
+ else if (menu->entry_type == GDA_TYPE_BLOB) {
+ GdaBlob *blob;
+ blob = (GdaBlob*) gda_value_get_blob (menu->tmpvalue);
+ if (blob->op) {
+ GValue *dest_value;
+ GdaBlob *dest_blob;
+
+ dest_value = gda_value_new_blob_from_file (filename);
+ dest_blob = (GdaBlob*) gda_value_get_blob (dest_value);
+ allok = gda_blob_op_write_all (dest_blob->op, (GdaBlob*) blob);
+ gda_value_free (dest_value);
+ }
+ else
+ allok = g_file_set_contents (filename, (gchar *) ((GdaBinary*)blob)->data,
+ ((GdaBinary*)blob)->binary_length, error);
+ }
+ else
+ g_assert_not_reached ();
+ if (allok) {
+#ifdef G_OS_WIN32
+ SetFileAttributes (filename, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED |
+ FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_TEMPORARY);
+#else
+ g_chmod (filename, 0400);
+#endif
+ }
+ return allok;
+}
+
static void
file_save_cb (GtkWidget *button, BinMenu *menu)
{
GtkWidget *dlg;
- gtk_widget_hide (menu->popup);
+ gtk_widget_hide (menu->popover);
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,
@@ -120,36 +169,10 @@ file_save_cb (GtkWidget *button, BinMenu *menu)
if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_ACCEPT) {
char *filename;
- gboolean allok = TRUE;
GError *error = NULL;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
- if (menu->entry_type == GDA_TYPE_BINARY) {
- const GdaBinary *bin;
- bin = gda_value_get_binary (menu->tmpvalue);
- allok = g_file_set_contents (filename, (gchar *) bin->data,
- bin->binary_length, &error);
- }
- else if (menu->entry_type == GDA_TYPE_BLOB) {
- GdaBlob *blob;
- blob = (GdaBlob*) gda_value_get_blob (menu->tmpvalue);
- if (blob->op) {
-
- GValue *dest_value;
- GdaBlob *dest_blob;
-
- dest_value = gda_value_new_blob_from_file (filename);
- dest_blob = (GdaBlob*) gda_value_get_blob (dest_value);
- allok = gda_blob_op_write_all (dest_blob->op, (GdaBlob*) blob);
- gda_value_free (dest_value);
- }
- else
- allok = g_file_set_contents (filename, (gchar *) ((GdaBinary*)blob)->data,
- ((GdaBinary*)blob)->binary_length, &error);
- }
- else
- g_assert_not_reached ();
- if (!allok) {
+ if (! export_data (menu, filename, &error)) {
GtkWidget *msg;
gchar *tmp;
tmp = g_strdup_printf (_("Could not save data to '%s'"), filename);
@@ -174,62 +197,73 @@ file_save_cb (GtkWidget *button, BinMenu *menu)
g_free (menu->current_folder);
menu->current_folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dlg));
gtk_widget_destroy (dlg);
-
}
}
+static void
+clear_data_cb (GtkWidget *button, BinMenu *menu)
+{
+ menu->loaded_value_cb (menu->loaded_value_cb_data, NULL);
+}
+
+#ifdef HAVE_GIO
+static void
+open_data_cb (GtkWidget *button, BinMenu *menu)
+{
+ g_return_if_fail (menu->open_menu);
+ gtk_menu_popup (GTK_MENU (menu->open_menu), NULL, NULL, NULL, NULL,
+ 0, gtk_get_current_event_time ());
+}
+#endif
+
void
-common_bin_create_menu (BinMenu *binmenu, PopupContainerPositionFunc pos_func, GType entry_type,
+common_bin_create_menu (GtkWidget *relative_to, BinMenu *binmenu, GType entry_type,
BinCallback loaded_value_cb, gpointer loaded_value_cb_data)
{
- GtkWidget *popup, *vbox, *hbox, *bbox, *button, *label;
+ GtkWidget *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;
- popup = popup_container_new_with_func (pos_func);
- binmenu->popup = popup;
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 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_widget_set_halign (label, GTK_ALIGN_START);
- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 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_widget_set_halign (label, GTK_ALIGN_START);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- binmenu->props_label = label;
+ binmenu->popover = gtk_popover_new (relative_to);
+ gtk_popover_set_modal (GTK_POPOVER (binmenu->popover), TRUE);
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
- gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (binmenu->popover), bbox);
- button = gtk_button_new_from_icon_name ("document-open", GTK_ICON_SIZE_BUTTON);
+ button = gtk_button_new_from_icon_name ("document-open-symbolic", GTK_ICON_SIZE_MENU);
+ gtk_widget_set_tooltip_text (button, _("Load data from file"));
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
g_signal_connect (button, "clicked",
G_CALLBACK (file_load_cb), binmenu);
binmenu->load_button = button;
- button = gtk_button_new_from_icon_name ("document-save-as", GTK_ICON_SIZE_BUTTON);
+ button = gtk_button_new_from_icon_name ("document-save-as-symbolic", GTK_ICON_SIZE_MENU);
+ gtk_widget_set_tooltip_text (button, _("Save data to file"));
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
g_signal_connect (button, "clicked",
G_CALLBACK (file_save_cb), binmenu);
binmenu->save_button = button;
- gtk_widget_show_all (vbox);
+ button = gtk_button_new_from_icon_name ("edit-clear-symbolic", GTK_ICON_SIZE_MENU);
+ gtk_widget_set_tooltip_text (button, _("Clear data"));
+ gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (clear_data_cb), binmenu);
+ binmenu->clear_button = button;
+
+#ifdef HAVE_GIO
+ button = gtk_button_new_from_icon_name ("open-menu-symbolic", GTK_ICON_SIZE_MENU);
+ gtk_widget_set_tooltip_text (button, _("Open with..."));
+ gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (open_data_cb), binmenu);
+ binmenu->open_button = button;
+#endif
+
+ gtk_widget_show_all (bbox);
}
static gchar *
@@ -245,39 +279,27 @@ format_size (gulong size)
return g_strdup_printf ("%.1f Gio", (gfloat) (size / 1073741824));
}
-/*
- * adjust the sensitiveness of the menu items in the popup menu
+/**
+ * common_bin_get_description:
*/
-void
-common_bin_adjust_menu (BinMenu *binmenu, gboolean editable, const GValue *value)
+gchar *
+common_bin_get_description (BinMenu *binmenu)
{
gchar *size;
- GString *string;
-#ifdef HAVE_GIO
- gchar *ctype = NULL;
-#endif
+ GString *string = NULL;
- if (!binmenu || !binmenu->popup)
- return;
-
- if (binmenu->tmpvalue) {
- gda_value_free (binmenu->tmpvalue);
- binmenu->tmpvalue = NULL;
- }
- string = g_string_new ("");
+ const GValue *value = binmenu->tmpvalue;
if (value) {
- binmenu->tmpvalue = gda_value_copy (value);
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) {
+ return NULL;
+
+ string = g_string_new ("");
+ 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_string_append (string, 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;
@@ -289,67 +311,276 @@ common_bin_adjust_menu (BinMenu *binmenu, gboolean editable, const GValue *value
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_string_append (string, size);
g_free (size);
-#ifdef HAVE_GIO
- GdaBlob *blob2;
- blob2 = (GdaBlob*) gda_blob_copy ((gpointer) blob);
- gda_blob_op_read (blob2->op, blob2, 0, 1024);
- bin = (GdaBinary *) blob2;
- ctype = g_content_type_guess (NULL, bin->data,
- (gsize) bin->binary_length, NULL);
- gda_blob_free ((gpointer) blob2);
-#endif
}
else
- g_string_append_printf (string, "%s: %s", _("Data size"),
_("Unknown"));
+ g_string_append (string, _("Unknown size"));
}
else {
size = format_size (bin->binary_length);
- g_string_append_printf (string, "%s: %s", _("Data size"), size);
+ g_string_append (string, 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"));
+ return NULL;
#ifdef HAVE_GIO
- if (ctype) {
- GList *list;
- gchar *descr, *tmp;
- descr = g_content_type_get_description (ctype);
- tmp = g_markup_escape_text (descr, -1);
- g_free (descr);
- g_string_append_printf (string, "\n%s: %s", _("Data type"), tmp);
+ if (binmenu->ctype) {
+ gchar *tmp;
+ tmp = g_content_type_get_description (binmenu->ctype);
+ g_string_append_printf (string, " (%s)", tmp);
+ g_free (tmp);
+ }
+#endif
+ return g_string_free (string, FALSE);
+}
+
+#ifdef HAVE_GIO
+
+typedef struct {
+ gchar *dirname;
+ gchar *filename;
+} LaunchData;
+
+static gboolean
+launch_cleanups (LaunchData *data)
+{
+ g_assert (data);
+
+ if (data->filename) {
+#ifndef G_OS_WIN32
+ if (g_unlink (data->filename))
+ g_warning ("Error removing temporary file %s", data->filename);
+#endif
+ g_free (data->filename);
+ }
+
+ if (data->dirname) {
+#ifndef G_OS_WIN32
+ if (g_rmdir (data->dirname))
+ g_warning ("Error removing temporary directory %s", data->dirname);
+#endif
+ g_free (data->dirname);
+ }
+ g_free (data);
+
+ return G_SOURCE_REMOVE;
+}
+
+static gchar *
+get_file_extension_for_mime_type (const gchar *mime_type)
+{
+ g_return_val_if_fail (mime_type && *mime_type, NULL);
+ size_t length;
+ length = strlen (mime_type);
+ g_return_val_if_fail (length > 0, NULL);
+ GBytes *css_data;
+ css_data = g_resources_lookup_data ("/gdaui/data/mime-types-extensions",
+ G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
+ if (css_data) {
+ gchar *ext = NULL;
+ const gchar *data;
+ const gchar *sol;
+ data = (gchar*) g_bytes_get_data (css_data, NULL);
+ for (sol = data; *sol; ) {
+ const gchar *eol;
+ for (eol = sol; *eol && (*eol != '\n'); eol++);
+ if (((size_t) (eol - sol) > length) &&
+ (sol[length] == '.') &&
+ !strncmp (sol, mime_type, length)) {
+ ext = g_strndup (sol + length + 1, eol - sol - length - 1);
+ break;
+ }
+ sol = eol;
+ if (*sol)
+ sol++;
+ }
+ g_bytes_unref (css_data);
+ return ext;
+ }
+ else
+ return NULL;
+}
+
+static void
+open_activate_cb (GtkMenuItem *mitem, BinMenu *binmenu)
+{
+ GAppInfo *ai;
+ ai = g_object_get_data (G_OBJECT (mitem), "ai");
+ g_print ("OPENING With %s\n", g_app_info_get_name (ai));
+
+ GError *error = NULL;
+
+ /* Save data to a TMP file */
+ gchar *tmpdir;
+ tmpdir = g_dir_make_tmp (NULL, &error);
+ if (!tmpdir) {
+ show_and_clear_error (binmenu, _("Could not create temporary directory"), &error);
+ return;
+ }
+
+ /* filename */
+#define BASE_EXP_NAME "exported-data"
+ gchar *filename;
+ gchar *ext;
+ ext = get_file_extension_for_mime_type (binmenu->ctype);
+ if (ext) {
+ gchar *tmp;
+ tmp = g_strdup_printf ("%s.%s", BASE_EXP_NAME, ext);
+ filename = g_build_filename (tmpdir, tmp, NULL);
g_free (tmp);
+ g_free (ext);
+ }
+ else
+ filename = g_build_filename (tmpdir, BASE_EXP_NAME, NULL);
+ g_print ("TMP file is: %s\n", filename);
+
+ LaunchData *data;
+ data = g_new (LaunchData, 1);
+ data->dirname = tmpdir;
+ data->filename = filename;
+
+ if (export_data (binmenu, filename, &error)) {
+ g_print ("Exported, now runinng opener program\n");
+ GList *files_list;
+ GFile *file;
+ file = g_file_new_for_path (filename);
+ files_list = g_list_append (NULL, file);
+
+ if (g_app_info_launch (ai, files_list, NULL, &error)) {
+ g_print ("Ok, running...\n");
+ g_timeout_add_seconds (30, (GSourceFunc) launch_cleanups, data);
+ }
+ else {
+ show_and_clear_error (binmenu, _("Could not run selected application"), &error);
+ launch_cleanups (data);
+ }
+ g_list_free (files_list);
+ g_object_unref (file);
+ }
+ else {
+ show_and_clear_error (binmenu, _("Could not export data"), &error);
+ launch_cleanups (data);
+ }
+}
+
+static void
+adjust_ctype (BinMenu *binmenu)
+{
+ g_free (binmenu->ctype);
+ binmenu->ctype = NULL;
+ if (binmenu->open_menu) {
+ gtk_widget_destroy (binmenu->open_menu);
+ binmenu->open_menu = NULL;
+ }
+ if (! binmenu->tmpvalue)
+ return;
+
+ const GValue *value = binmenu->tmpvalue;
+ if (value && (G_VALUE_TYPE (value) != GDA_TYPE_NULL)) {
+ if (G_VALUE_TYPE (value) == GDA_TYPE_BINARY) {
+ const GdaBinary *bin;
+ bin = gda_value_get_binary (value);
+ binmenu->ctype = g_content_type_guess (NULL, bin->data, (gsize) bin->binary_length,
NULL);
+ }
+ 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) {
+ GdaBlob *blob2;
+ blob2 = (GdaBlob*) gda_blob_copy ((gpointer) blob);
+ gda_blob_op_read (blob2->op, blob2, 0, 1024);
+ bin = (GdaBinary *) blob2;
+ binmenu->ctype = g_content_type_guess (NULL, bin->data,
+ (gsize) bin->binary_length, NULL);
+ gda_blob_free ((gpointer) blob2);
+ }
+ }
+ else
+ binmenu->ctype = g_content_type_guess (NULL, bin->data,
+ (gsize) bin->binary_length, NULL);
+ }
+ else
+ g_assert_not_reached ();
+ }
+ if (binmenu->ctype) {
+ GList *list;
+ list = g_app_info_get_all_for_type (binmenu->ctype);
+ for (; list; ) {
+ GAppInfo *ai = (GAppInfo *) list->data;
+ if (!binmenu->open_menu)
+ binmenu->open_menu = gtk_menu_new ();
- 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));
+ gchar *tmp;
+ tmp = g_strdup_printf ("%s %s", _("Open with"), g_app_info_get_name (ai));
+ GtkWidget *mitem;
+ mitem = gtk_menu_item_new_with_label (tmp);
+ g_free (tmp);
+ g_object_set_data_full (G_OBJECT (mitem), "ai", ai, g_object_unref);
+ g_signal_connect (mitem, "activate",
+ G_CALLBACK (open_activate_cb), binmenu);
+ gtk_menu_shell_append (GTK_MENU_SHELL (binmenu->open_menu), mitem);
+ gtk_widget_show (mitem);
+
+ list = g_list_delete_link (list, list);
}
- g_free (ctype);
}
+}
#endif
+/*
+ * adjust the sensitiveness of the menu items in the popup menu
+ */
+void
+common_bin_adjust (BinMenu *binmenu, gboolean editable, const GValue *value)
+{
+ gchar *size;
+ GString *string;
- gtk_label_set_markup (GTK_LABEL (binmenu->props_label), string->str);
- g_string_free (string, TRUE);
+ if (!binmenu || !binmenu->popover)
+ return;
+ if (value != binmenu->tmpvalue) {
+ if (binmenu->tmpvalue) {
+ gda_value_free (binmenu->tmpvalue);
+ binmenu->tmpvalue = NULL;
+ }
+ if (value)
+ binmenu->tmpvalue = gda_value_copy (value);
+ }
+#ifdef HAVE_GIO
+ adjust_ctype (binmenu);
+#endif
gtk_widget_set_sensitive (binmenu->load_button, editable);
gtk_widget_set_sensitive (binmenu->save_button, (value && !gda_value_is_null (value)) ? TRUE : FALSE);
+ gtk_widget_set_sensitive (binmenu->clear_button, (editable && value && !gda_value_is_null (value)) ?
TRUE : FALSE);
+#ifdef HAVE_GIO
+ gtk_widget_set_sensitive (binmenu->open_button, binmenu->open_menu ? TRUE : FALSE);
+#endif
+}
+
+/*
+ * Initialize @binmenu's contents
+ */
+void
+common_bin_init (BinMenu *binmenu)
+{
+ g_assert (binmenu);
+ memset (binmenu, 0, sizeof (BinMenu));
}
/*
- * Reset @bonmenu's contents
+ * Reset @binmenu's contents
*/
void
common_bin_reset (BinMenu *binmenu)
@@ -358,9 +589,14 @@ common_bin_reset (BinMenu *binmenu)
gda_value_free (binmenu->tmpvalue);
binmenu->tmpvalue = NULL;
}
- if (binmenu->popup)
- gtk_widget_destroy (binmenu->popup);
+ if (binmenu->popover)
+ gtk_widget_destroy (binmenu->popover);
g_free (binmenu->current_folder);
+#ifdef HAVE_GIO
+ if (binmenu->open_menu)
+ gtk_widget_destroy (binmenu->open_menu);
+ g_free (binmenu->ctype);
+#endif
memset (binmenu, 0, sizeof (BinMenu));
}
diff --git a/libgda-ui/data-entries/common-bin.h b/libgda-ui/data-entries/common-bin.h
index fbdb6c6..6b3c13a 100644
--- a/libgda-ui/data-entries/common-bin.h
+++ b/libgda-ui/data-entries/common-bin.h
@@ -25,15 +25,20 @@
#define __COMMON_BIN_H__
#include <gtk/gtk.h>
-#include "../internal/popup-container.h"
typedef void (*BinCallback) (gpointer, GValue *);
typedef struct {
- GtkWidget *popup; /* PopupContainer popup window */
+ GtkWidget *popover; /* GtkPopover popup window */
GtkWidget *load_button;
GtkWidget *save_button;
+ GtkWidget *clear_button;
+#ifdef HAVE_GIO
+ GtkWidget *open_button;
+ gchar *ctype;
+ GtkWidget *open_menu;
+#endif
+
gchar *current_folder;
- GtkWidget *props_label;
GType entry_type;
GValue *tmpvalue;
@@ -43,9 +48,11 @@ typedef struct {
} BinMenu;
-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_init (BinMenu *binmenu);
void common_bin_reset (BinMenu *binmenu);
+gchar *common_bin_get_description (BinMenu *binmenu);
+void common_bin_create_menu (GtkWidget *relative_to, BinMenu *binmenu, GType entry_type,
+ BinCallback loaded_value_cb, gpointer loaded_value_cb_data);
+void common_bin_adjust (BinMenu *binmenu, gboolean editable, const GValue *value);
#endif
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 5f2a4aa..be078c8 100644
--- a/libgda-ui/data-entries/gdaui-data-cell-renderer-bin.c
+++ b/libgda-ui/data-entries/gdaui-data-cell-renderer-bin.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 - 2014 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2009 - 2015 Vivien Malerba <malerba gnome-db org>
* Copyright (C) 2010 David King <davidk openismus com>
* Copyright (C) 2011 Murray Cumming <murrayc murrayc com>
*
@@ -391,41 +391,6 @@ 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,
@@ -443,11 +408,9 @@ gdaui_data_cell_renderer_bin_activate (GtkCellRenderer *cell,
bincell = GDAUI_DATA_CELL_RENDERER_BIN (cell);
g_object_set_data_full (G_OBJECT (bincell), "last-path", g_strdup (path), g_free);
- if (!bincell->priv->menu.popup) {
- common_bin_create_menu (&(bincell->priv->menu), popup_position, bincell->priv->type,
+ if (!bincell->priv->menu.popover)
+ common_bin_create_menu (widget, &(bincell->priv->menu), 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);
@@ -459,11 +422,9 @@ gdaui_data_cell_renderer_bin_activate (GtkCellRenderer *cell,
gtk_tree_model_get (model, &iter,
model_col, &value, -1);
- common_bin_adjust_menu (&(bincell->priv->menu), bincell->priv->editable,
- value);
- g_object_set_data (G_OBJECT (bincell->priv->menu.popup), "__event", event);
- g_object_set_data (G_OBJECT (bincell->priv->menu.popup), "__rect", (GdkRectangle*)cell_area);
- gtk_widget_show (bincell->priv->menu.popup);
+ common_bin_adjust (&(bincell->priv->menu), bincell->priv->editable,
+ value);
+ gtk_widget_show (bincell->priv->menu.popover);
}
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 5cea961..62de305 100644
--- a/libgda-ui/data-entries/gdaui-entry-bin.c
+++ b/libgda-ui/data-entries/gdaui-entry-bin.c
@@ -39,24 +39,17 @@ static void connect_signals(GdauiEntryWrapper *mgwrap, GCallback modify_cb
static void set_editable (GdauiEntryWrapper *mgwrap, gboolean editable);
static void grab_focus (GdauiEntryWrapper *mgwrap);
-static void show (GtkWidget *widget);
-
/* get a pointer to the parents to be able to call their destructor */
static GObjectClass *parent_class = NULL;
-static GdkPixbuf *attach_pixbuf = NULL;
/* private structure */
struct _GdauiEntryBinPrivate
{
- GtkWidget *button;
- GtkWidget *button_hbox;
- GtkWidget *button_label; /* ref held! */
- GtkWidget *button_image; /* ref held! */
+ GtkWidget *label;
- BinMenu menu;
+ BinMenu commonbin;
+ GtkWidget *entry_widget;
gboolean editable;
-
- GValue *current_data;
};
@@ -100,45 +93,15 @@ gdaui_entry_bin_class_init (GdauiEntryBinClass *class)
GDAUI_ENTRY_WRAPPER_CLASS (class)->connect_signals = connect_signals;
GDAUI_ENTRY_WRAPPER_CLASS (class)->set_editable = set_editable;
GDAUI_ENTRY_WRAPPER_CLASS (class)->grab_focus = grab_focus;
-
- GTK_WIDGET_CLASS (class)->show = show;
-
- if (! attach_pixbuf) {
- #define ICON_FILE "/gdaui/images/data/bin-attachment-16x16.png"
- attach_pixbuf = gdk_pixbuf_new_from_resource (ICON_FILE, NULL);
- if (!attach_pixbuf)
- g_warning ("Could not find icon file %s in resources please report error to "
- "http://bugzilla.gnome.org/ for the \"libgda\" product", ICON_FILE);
- }
}
static void
gdaui_entry_bin_init (GdauiEntryBin * gdaui_entry_bin)
{
gdaui_entry_bin->priv = g_new0 (GdauiEntryBinPrivate, 1);
- gdaui_entry_bin->priv->button = NULL;
- gdaui_entry_bin->priv->current_data = NULL;
+ gdaui_entry_bin->priv->label = NULL;
gdaui_entry_bin->priv->editable = TRUE;
-}
-
-static void
-show (GtkWidget *widget)
-{
- GValue *value;
- GdauiEntryBin *dbin;
-
- ((GtkWidgetClass *)parent_class)->show (widget);
-
- dbin = GDAUI_ENTRY_BIN (widget);
- value = dbin->priv->current_data;
- if (value && (G_VALUE_TYPE (value) != GDA_TYPE_NULL)) {
- gtk_widget_show (dbin->priv->button_image);
- gtk_widget_hide (dbin->priv->button_label);
- }
- else {
- gtk_widget_hide (dbin->priv->button_image);
- gtk_widget_show (dbin->priv->button_label);
- }
+ common_bin_init (&(gdaui_entry_bin->priv->commonbin));
}
/**
@@ -176,23 +139,8 @@ gdaui_entry_bin_dispose (GObject * object)
g_return_if_fail (GDAUI_IS_ENTRY_BIN (object));
gdaui_entry_bin = GDAUI_ENTRY_BIN (object);
- if (gdaui_entry_bin->priv) {
- if (gdaui_entry_bin->priv->current_data) {
- gda_value_free (gdaui_entry_bin->priv->current_data);
- gdaui_entry_bin->priv->current_data = 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);
- gdaui_entry_bin->priv->button_label = NULL;
- }
-
- if (gdaui_entry_bin->priv->button_image) {
- g_object_unref (gdaui_entry_bin->priv->button_image);
- gdaui_entry_bin->priv->button_image = NULL;
- }
- }
+ if (gdaui_entry_bin->priv)
+ common_bin_reset (&(gdaui_entry_bin->priv->commonbin));
/* parent class */
parent_class->dispose (object);
@@ -208,7 +156,6 @@ gdaui_entry_bin_finalize (GObject * object)
gdaui_entry_bin = GDAUI_ENTRY_BIN (object);
if (gdaui_entry_bin->priv) {
-
g_free (gdaui_entry_bin->priv);
gdaui_entry_bin->priv = NULL;
}
@@ -217,10 +164,42 @@ gdaui_entry_bin_finalize (GObject * object)
parent_class->finalize (object);
}
+/*
+ * Steals @value
+ *
+ * WARNING:
+ * Does NOT emit any signal
+ */
+static void
+take_as_current_value (GdauiEntryBin *dbin, GValue *value)
+{
+ common_bin_adjust (&(dbin->priv->commonbin), dbin->priv->editable, value);
+
+ gchar *str;
+ str = common_bin_get_description (&(dbin->priv->commonbin));
+ gchar *markup;
+ if (str) {
+ markup = g_markup_printf_escaped ("<a href=''>%s</a>", str);
+ g_free (str);
+ }
+ else
+ markup = g_markup_printf_escaped ("<a href=''><i>%s</i></a>", _("No data"));
+ gtk_label_set_markup (GTK_LABEL (dbin->priv->label), markup);
+ g_free (markup);
+}
+
+static void
+event_after_cb (GtkWidget *widget, GdkEvent *event, GdauiEntryBin *dbin)
+{
+ /* don't "forward" event if popover is shown */
+ if (!dbin->priv->commonbin.popover || !gtk_widget_is_visible (dbin->priv->commonbin.popover))
+ g_signal_emit_by_name (dbin->priv->entry_widget, "event-after", event);
+}
+
static GtkWidget *
create_entry (GdauiEntryWrapper *mgwrap)
{
- GtkWidget *button, *arrow, *label, *img;
+ GtkWidget *label;
GdauiEntryBin *dbin;
GtkWidget *hbox;
@@ -228,56 +207,21 @@ create_entry (GdauiEntryWrapper *mgwrap)
dbin = GDAUI_ENTRY_BIN (mgwrap);
g_return_val_if_fail (dbin->priv, NULL);
- button = gtk_button_new ();
- dbin->priv->button = button;
-
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_container_add (GTK_CONTAINER (button), hbox);
- dbin->priv->button_hbox = hbox;
+ dbin->priv->entry_widget = hbox;
label = gtk_label_new ("");
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- dbin->priv->button_label = g_object_ref (G_OBJECT (label));
-
- img = gtk_image_new_from_pixbuf (attach_pixbuf);
- gtk_box_pack_start (GTK_BOX (hbox), img, FALSE, FALSE, 0);
- dbin->priv->button_image = g_object_ref (G_OBJECT (img));
-
- arrow = gtk_image_new_from_icon_name ("go-down-symbolic", GTK_ICON_SIZE_MENU);
- gtk_widget_set_halign (arrow, GTK_ALIGN_START);
- gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+ gtk_widget_show (label);
+ dbin->priv->label = label;
- gtk_widget_show_all (hbox);
- gtk_widget_hide (dbin->priv->button_label);
-
- return button;
-}
-
-/*
- * WARNING:
- * Does NOT emit any signal
- */
-static void
-take_current_value (GdauiEntryBin *dbin, GValue *value)
-{
- /* clear previous situation */
- if (dbin->priv->current_data) {
- gda_value_free (dbin->priv->current_data);
- dbin->priv->current_data = NULL;
- }
+ g_signal_connect (label, "event-after",
+ G_CALLBACK (event_after_cb), dbin);
- /* new situation */
- dbin->priv->current_data = value;
- if (value && (G_VALUE_TYPE (value) != GDA_TYPE_NULL)) {
- gtk_widget_show (dbin->priv->button_image);
- gtk_widget_hide (dbin->priv->button_label);
- }
- else {
- gtk_widget_hide (dbin->priv->button_image);
- gtk_widget_show (dbin->priv->button_label);
- }
+ take_as_current_value (dbin, NULL);
- common_bin_adjust_menu (&(dbin->priv->menu), dbin->priv->editable, value);
+ return hbox;
}
static void
@@ -289,7 +233,7 @@ real_set_value (GdauiEntryWrapper *mgwrap, const GValue *value)
dbin = GDAUI_ENTRY_BIN (mgwrap);
g_return_if_fail (dbin->priv);
- take_current_value (dbin, value ? gda_value_copy (value) : NULL);
+ take_as_current_value (dbin, value ? gda_value_copy (value) : NULL);
}
static GValue *
@@ -301,8 +245,8 @@ real_get_value (GdauiEntryWrapper *mgwrap)
dbin = GDAUI_ENTRY_BIN (mgwrap);
g_return_val_if_fail (dbin->priv, NULL);
- if (dbin->priv->current_data)
- return gda_value_copy (dbin->priv->current_data);
+ if (dbin->priv->commonbin.tmpvalue)
+ return gda_value_copy (dbin->priv->commonbin.tmpvalue);
else
return gda_value_new_null ();
}
@@ -311,7 +255,7 @@ real_get_value (GdauiEntryWrapper *mgwrap)
static void
value_loaded_cb (GdauiEntryBin *dbin, GValue *new_value)
{
- take_current_value (dbin, new_value);
+ take_as_current_value (dbin, new_value);
/* signal changes */
gdaui_entry_wrapper_contents_changed (GDAUI_ENTRY_WRAPPER (dbin));
@@ -319,41 +263,15 @@ 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;
- gdk_window_get_origin (gtk_widget_get_window (poswidget), &x, &y);
- GtkAllocation alloc;
- gtk_widget_get_allocation (poswidget, &alloc);
- x += alloc.x;
- y += alloc.y;
- y += alloc.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)
+link_activated_cb (GdauiEntryBin *dbin, const gchar *uri, GtkWidget *label)
{
- if (!dbin->priv->menu.popup) {
- common_bin_create_menu (&(dbin->priv->menu), popup_position,
+ if (!dbin->priv->commonbin.popover)
+ common_bin_create_menu (GTK_WIDGET (label), &(dbin->priv->commonbin),
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);
- gtk_widget_show (dbin->priv->menu.popup);
+ common_bin_adjust (&(dbin->priv->commonbin), dbin->priv->editable, dbin->priv->commonbin.tmpvalue);
+ gtk_widget_show (dbin->priv->commonbin.popover);
}
static void
@@ -366,8 +284,9 @@ connect_signals (GdauiEntryWrapper *mgwrap, G_GNUC_UNUSED GCallback modify_cb,
dbin = GDAUI_ENTRY_BIN (mgwrap);
g_return_if_fail (dbin->priv);
- g_signal_connect (G_OBJECT (dbin->priv->button), "clicked",
- G_CALLBACK (button_clicked_cb), dbin);
+ g_assert (dbin->priv->label);
+ g_signal_connect_swapped (G_OBJECT (dbin->priv->label), "activate-link",
+ G_CALLBACK (link_activated_cb), dbin);
}
static void
@@ -380,7 +299,7 @@ set_editable (GdauiEntryWrapper *mgwrap, gboolean editable)
g_return_if_fail (dbin->priv);
dbin->priv->editable = editable;
- common_bin_adjust_menu (&(dbin->priv->menu), editable, dbin->priv->current_data);
+ common_bin_adjust (&(dbin->priv->commonbin), editable, dbin->priv->commonbin.tmpvalue);
}
static void
@@ -392,5 +311,5 @@ grab_focus (GdauiEntryWrapper *mgwrap)
dbin = GDAUI_ENTRY_BIN (mgwrap);
g_return_if_fail (dbin->priv);
- gtk_widget_grab_focus (dbin->priv->button);
+ gtk_widget_grab_focus (dbin->priv->label);
}
diff --git a/libgda-ui/data-entries/gdaui-entry-boolean.c b/libgda-ui/data-entries/gdaui-entry-boolean.c
index a15df78..2dc2c99 100644
--- a/libgda-ui/data-entries/gdaui-entry-boolean.c
+++ b/libgda-ui/data-entries/gdaui-entry-boolean.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 - 2012 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2009 - 2015 Vivien Malerba <malerba gnome-db org>
* Copyright (C) 2010 David King <davidk openismus com>
* Copyright (C) 2011 Murray Cumming <murrayc murrayc com>
*
@@ -43,8 +43,7 @@ static GObjectClass *parent_class = NULL;
/* private structure */
struct _GdauiEntryBooleanPrivate
{
- GtkWidget *hbox;
- GtkWidget *check;
+ GtkWidget *switchw;
};
@@ -94,8 +93,7 @@ static void
gdaui_entry_boolean_init (GdauiEntryBoolean * gdaui_entry_boolean)
{
gdaui_entry_boolean->priv = g_new0 (GdauiEntryBooleanPrivate, 1);
- gdaui_entry_boolean->priv->hbox = NULL;
- gdaui_entry_boolean->priv->check = NULL;
+ gdaui_entry_boolean->priv->switchw = NULL;
}
/**
@@ -160,25 +158,31 @@ gdaui_entry_boolean_finalize (GObject * object)
parent_class->finalize (object);
}
+static void
+event_after_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+ g_signal_emit_by_name (widget, "event-after", event);
+}
+
static GtkWidget *
create_entry (GdauiEntryWrapper *mgwrap)
{
- GtkWidget *hbox, *cb;
GdauiEntryBoolean *mgbool;
g_return_val_if_fail (GDAUI_IS_ENTRY_BOOLEAN (mgwrap), NULL);
mgbool = GDAUI_ENTRY_BOOLEAN (mgwrap);
g_return_val_if_fail (mgbool->priv, NULL);
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
- mgbool->priv->hbox = hbox;
-
- cb = gtk_check_button_new ();
- mgbool->priv->check = cb;
- gtk_box_pack_start (GTK_BOX (hbox), cb, FALSE, FALSE, 0);
- gtk_widget_show (cb);
+ GtkWidget *wid, *box;
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ wid = gtk_switch_new ();
+ gtk_box_pack_start (GTK_BOX (box), wid, FALSE, FALSE, 0);
+ gtk_widget_show (wid);
+ mgbool->priv->switchw = wid;
+ g_signal_connect_swapped (wid, "event-after",
+ G_CALLBACK (event_after_cb), box);
- return hbox;
+ return box;
}
static void
@@ -191,22 +195,13 @@ real_set_value (GdauiEntryWrapper *mgwrap, const GValue *value)
g_return_if_fail (mgbool->priv);
if (value) {
- if (gda_value_is_null ((GValue *) value)) {
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mgbool->priv->check), FALSE);
- gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (mgbool->priv->check), TRUE);
- }
- else {
- gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (mgbool->priv->check), FALSE);
- if (g_value_get_boolean ((GValue *) value))
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mgbool->priv->check), TRUE);
- else
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mgbool->priv->check), FALSE);
- }
- }
- else {
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mgbool->priv->check), FALSE);
- gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (mgbool->priv->check), TRUE);
+ if (gda_value_is_null ((GValue *) value))
+ gtk_switch_set_active (GTK_SWITCH (mgbool->priv->switchw), FALSE);
+ else
+ gtk_switch_set_active (GTK_SWITCH (mgbool->priv->switchw), g_value_get_boolean
((GValue *) value));
}
+ else
+ gtk_switch_set_active (GTK_SWITCH (mgbool->priv->switchw), FALSE);
}
static GValue *
@@ -222,7 +217,7 @@ real_get_value (GdauiEntryWrapper *mgwrap)
g_return_val_if_fail (mgbool->priv, NULL);
dh = gdaui_data_entry_get_handler (GDAUI_DATA_ENTRY (mgwrap));
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (mgbool->priv->check)))
+ if (gtk_switch_get_active (GTK_SWITCH (mgbool->priv->switchw)))
str = "TRUE";
else
str = "FALSE";
@@ -231,7 +226,6 @@ real_get_value (GdauiEntryWrapper *mgwrap)
return value;
}
-static void check_toggled_cb (GtkToggleButton *toggle, GdauiEntryBoolean *mgbool);
static void
connect_signals(GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activate_cb)
{
@@ -241,18 +235,10 @@ connect_signals(GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activa
mgbool = GDAUI_ENTRY_BOOLEAN (mgwrap);
g_return_if_fail (mgbool->priv);
- g_signal_connect (G_OBJECT (mgbool->priv->check), "toggled",
- modify_cb, mgwrap);
- g_signal_connect (G_OBJECT (mgbool->priv->check), "toggled",
- activate_cb, mgwrap);
- g_signal_connect (G_OBJECT (mgbool->priv->check), "toggled",
- G_CALLBACK (check_toggled_cb), mgwrap);
-}
-
-static void
-check_toggled_cb (GtkToggleButton *toggle, G_GNUC_UNUSED GdauiEntryBoolean *mgbool)
-{
- gtk_toggle_button_set_inconsistent (toggle, FALSE);
+ g_signal_connect_swapped (G_OBJECT (mgbool->priv->switchw), "notify::active",
+ modify_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgbool->priv->switchw), "notify::active",
+ activate_cb, mgwrap);
}
static void
@@ -264,7 +250,7 @@ set_editable (GdauiEntryWrapper *mgwrap, gboolean editable)
mgbool = GDAUI_ENTRY_BOOLEAN (mgwrap);
g_return_if_fail (mgbool->priv);
- gtk_widget_set_sensitive (mgbool->priv->check, editable);
+ gtk_widget_set_sensitive (mgbool->priv->switchw, editable);
}
static void
@@ -276,5 +262,5 @@ grab_focus (GdauiEntryWrapper *mgwrap)
mgbool = GDAUI_ENTRY_BOOLEAN (mgwrap);
g_return_if_fail (mgbool->priv);
- gtk_widget_grab_focus (mgbool->priv->check);
+ gtk_widget_grab_focus (mgbool->priv->switchw);
}
diff --git a/libgda-ui/data-entries/gdaui-entry-combo.c b/libgda-ui/data-entries/gdaui-entry-combo.c
index 309eceb..b2bcfd1 100644
--- a/libgda-ui/data-entries/gdaui-entry-combo.c
+++ b/libgda-ui/data-entries/gdaui-entry-combo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 - 2013 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2009 - 2015 Vivien Malerba <malerba gnome-db org>
* Copyright (C) 2010 David King <davidk openismus com>
* Copyright (C) 2011 Murray Cumming <murrayc murrayc com>
* Copyright (C) 2013 Daniel Espinosa <esodan gmail com>
@@ -91,10 +91,10 @@ struct _GdauiEntryComboPriv {
gboolean data_valid;
gboolean null_forced;
gboolean default_forced;
+ gboolean invalid;
gboolean null_possible;
gboolean default_possible;
-
- gboolean show_actions;
+
gboolean set_default_if_invalid; /* use first entry when provided value is not found ?
*/
};
@@ -185,13 +185,7 @@ real_combo_unblock_signals (GdauiEntryCombo *wid)
static void
gdaui_entry_combo_emit_signal (GdauiEntryCombo *combo)
{
-#ifdef debug_signal
- g_print (">> 'CONTENTS_MODIFIED' from %s\n", __FUNCTION__);
-#endif
g_signal_emit_by_name (G_OBJECT (combo), "contents-modified");
-#ifdef debug_signal
- g_print ("<< 'CONTENTS_MODIFIED' from %s\n", __FUNCTION__);
-#endif
}
static void
@@ -203,11 +197,11 @@ gdaui_entry_combo_init (GdauiEntryCombo *combo)
combo->priv->set_default_if_invalid = FALSE;
combo->priv->combo_entry = NULL;
combo->priv->data_valid = FALSE;
+ combo->priv->invalid = FALSE;
combo->priv->null_forced = FALSE;
combo->priv->default_forced = FALSE;
combo->priv->null_possible = TRUE;
combo->priv->default_possible = FALSE;
- combo->priv->show_actions = TRUE;
combo->priv->paramlist = NULL;
combo->priv->source = NULL;
@@ -909,22 +903,11 @@ gdaui_entry_combo_set_attributes (GdauiDataEntry *iface, guint attrs, guint mask
}
}
- /* Actions buttons ? */
- if (mask & GDA_VALUE_ATTR_ACTIONS_SHOWN) {
- GValue *gval;
- combo->priv->show_actions = (attrs & GDA_VALUE_ATTR_ACTIONS_SHOWN) ? TRUE : FALSE;
-
- gval = g_new0 (GValue, 1);
- g_value_init (gval, G_TYPE_BOOLEAN);
- g_value_set_boolean (gval, combo->priv->show_actions);
- g_object_set_property (G_OBJECT (combo), "actions", gval);
- g_free (gval);
- }
+ /* invalid data */
+ if (mask & GDA_VALUE_ATTR_DATA_NON_VALID)
+ combo->priv->invalid = attrs & GDA_VALUE_ATTR_DATA_NON_VALID;
/* NON WRITABLE attributes */
- if (mask & GDA_VALUE_ATTR_DATA_NON_VALID)
- g_warning ("Can't force a GdauiDataEntry to be invalid!");
-
if (mask & GDA_VALUE_ATTR_HAS_VALUE_ORIG)
g_warning ("Having an original value is not a write attribute on GdauiDataEntry!");
@@ -980,31 +963,26 @@ gdaui_entry_combo_get_attributes (GdauiDataEntry *iface)
}
if (isunchanged)
- retval = retval | GDA_VALUE_ATTR_IS_UNCHANGED;
+ retval |= GDA_VALUE_ATTR_IS_UNCHANGED;
if (isnull || combo->priv->null_forced)
- retval = retval | GDA_VALUE_ATTR_IS_NULL;
+ retval |= GDA_VALUE_ATTR_IS_NULL;
/* can be NULL? */
if (combo->priv->null_possible)
- retval = retval | GDA_VALUE_ATTR_CAN_BE_NULL;
+ retval |= GDA_VALUE_ATTR_CAN_BE_NULL;
/* is default */
if (combo->priv->default_forced)
- retval = retval | GDA_VALUE_ATTR_IS_DEFAULT;
+ retval |= GDA_VALUE_ATTR_IS_DEFAULT;
/* can be default? */
if (combo->priv->default_possible)
- retval = retval | GDA_VALUE_ATTR_CAN_BE_DEFAULT;
+ retval |= GDA_VALUE_ATTR_CAN_BE_DEFAULT;
-
- /* actions shown */
- if (combo->priv->show_actions)
- retval = retval | GDA_VALUE_ATTR_ACTIONS_SHOWN;
-
/* data valid? */
- if (! combo->priv->data_valid)
- retval = retval | GDA_VALUE_ATTR_DATA_NON_VALID;
+ if ((! combo->priv->data_valid) || combo->priv->invalid)
+ retval |= GDA_VALUE_ATTR_DATA_NON_VALID;
else {
GSList *nodes;
gboolean allnull = TRUE;
@@ -1021,13 +999,13 @@ gdaui_entry_combo_get_attributes (GdauiDataEntry *iface)
if ((allnull && !combo->priv->null_possible) ||
(combo->priv->null_forced && !combo->priv->null_possible))
- retval = retval | GDA_VALUE_ATTR_DATA_NON_VALID;
+ retval |= GDA_VALUE_ATTR_DATA_NON_VALID;
}
/* has original value? */
list2 = gdaui_entry_combo_get_reference_values (combo);
if (list2) {
- retval = retval | GDA_VALUE_ATTR_HAS_VALUE_ORIG;
+ retval |= GDA_VALUE_ATTR_HAS_VALUE_ORIG;
g_slist_free (list2);
}
@@ -1051,5 +1029,5 @@ static void
gdaui_entry_combo_set_unknown_color (GdauiDataEntry *de, gdouble red, gdouble green,
gdouble blue, gdouble alpha)
{
- gdaui_entry_shell_set_ucolor (GDAUI_ENTRY_SHELL (de), red, green, blue, alpha);
+ gdaui_entry_shell_set_invalid_color (GDAUI_ENTRY_SHELL (de), red, green, blue, alpha);
}
diff --git a/libgda-ui/data-entries/gdaui-entry-common-time.c
b/libgda-ui/data-entries/gdaui-entry-common-time.c
index 90306b2..6a35ab7 100644
--- a/libgda-ui/data-entries/gdaui-entry-common-time.c
+++ b/libgda-ui/data-entries/gdaui-entry-common-time.c
@@ -25,9 +25,15 @@
#include <gdk/gdkkeysyms.h>
#include <string.h>
#include "gdaui-formatted-entry.h"
+#include "gdaui-numeric-entry.h"
#include <libgda/gda-debug-macros.h>
-/*
+/*
+ * REM:
+ * Times are displayed relative to localtime
+ */
+
+/*
* Main static functions
*/
static void gdaui_entry_common_time_class_init (GdauiEntryCommonTimeClass * class);
@@ -71,21 +77,14 @@ static GObjectClass *parent_class = NULL;
/* private structure */
struct _GdauiEntryCommonTimePrivate
{
- /* for date */
- GtkWidget *entry_date;
- GtkWidget *date;
- GtkWidget *window;
- GtkWidget *date_button;
- gboolean editing_canceled;
-
- /* for time */
- GtkWidget *entry_time;
-
- /* for timestamp */
- GtkWidget *hbox;
+ GtkWidget *entry;
+ GtkWidget *cal_popover;
+ GtkWidget *calendar;
+ gulong displayed_tz;
+ gulong value_tz;
+ gulong value_fraction;
- /* Last value set */
- GValue *last_value_set;
+ gboolean editing_canceled;
};
static void
@@ -162,19 +161,82 @@ key_press_event_cb (GdauiEntryCommonTime *mgtim, GdkEventKey *key_event, G_GNUC_
return FALSE;
}
+static glong
+compute_tz_offset (struct tm *gmttm, struct tm *loctm)
+{
+ if (! gmttm || !loctm)
+ return G_MAXLONG;
+
+ struct tm cgmttm, cloctm;
+ cgmttm = *gmttm;
+ cloctm = *loctm;
+
+ time_t lt, gt;
+ cgmttm.tm_isdst = 0;
+ cloctm.tm_isdst = 0;
+
+ lt = mktime (&cloctm);
+ if (lt == -1)
+ return G_MAXLONG;
+ gt = mktime (&cgmttm);
+ if (gt == -1)
+ return G_MAXLONG;
+ glong off;
+ off = lt - gt;
+
+ if ((off >= 24 * 3600) || (off <= - 24 * 3600))
+ return G_MAXLONG;
+ else
+ return off;
+}
+
+static gulong
+compute_localtime_tz (void)
+{
+ time_t val;
+ val = time (NULL);
+ glong tz = 0;
+
+#ifdef HAVE_LOCALTIME_R
+ struct tm gmttm, loctm;
+ tzset ();
+ localtime_r ((const time_t *) &val, &loctm);
+ tz = compute_tz_offset (gmtime_r ((const time_t *) &val, &gmttm), &loctm);
+#elif HAVE_LOCALTIME_S
+ struct tm gmttm, loctm;
+ if ((localtime_s (&loctm, (const time_t *) &val) == 0) &&
+ (gmtime_s (&gmttm, (const time_t *) &val) == 0)) {
+ tz = compute_tz_offset (&gmttm, &loctm);
+ }
+#else
+ struct tm gmttm, loctm;
+ struct tm *ltm;
+ ltm = gmtime ((const time_t *) &val);
+ if (ltm) {
+ gmttm = *ltm;
+ ltm = localtime ((const time_t *) &val);
+ if (ltm) {
+ loctm = *ltm;
+ tz = compute_tz_offset (&gmttm, &loctm);
+ }
+ }
+#endif
+ if (tz == G_MAXLONG)
+ tz = 0;
+ return tz;
+}
+
static void
-gdaui_entry_common_time_init (GdauiEntryCommonTime *gdaui_entry_common_time)
+gdaui_entry_common_time_init (GdauiEntryCommonTime *mgtim)
{
- gdaui_entry_common_time->priv = g_new0 (GdauiEntryCommonTimePrivate, 1);
- gdaui_entry_common_time->priv->entry_date = NULL;
- gdaui_entry_common_time->priv->entry_time = NULL;
- gdaui_entry_common_time->priv->date = NULL;
- gdaui_entry_common_time->priv->window = NULL;
- gdaui_entry_common_time->priv->date_button = NULL;
- gdaui_entry_common_time->priv->hbox = NULL;
- gdaui_entry_common_time->priv->last_value_set = NULL;
- gdaui_entry_common_time->priv->editing_canceled = FALSE;
- g_signal_connect (gdaui_entry_common_time, "key-press-event",
+ mgtim->priv = g_new0 (GdauiEntryCommonTimePrivate, 1);
+ mgtim->priv->entry = NULL;
+ mgtim->priv->calendar = NULL;
+ mgtim->priv->editing_canceled = FALSE;
+ mgtim->priv->value_tz = 0; /* safe init value */
+ mgtim->priv->value_fraction = 0; /* safe init value */
+ mgtim->priv->displayed_tz = compute_localtime_tz ();
+ g_signal_connect (mgtim, "key-press-event",
G_CALLBACK (key_press_event_cb), NULL);
}
@@ -214,10 +276,6 @@ gdaui_entry_common_time_dispose (GObject * object)
gdaui_entry_common_time = GDAUI_ENTRY_COMMON_TIME (object);
if (gdaui_entry_common_time->priv) {
- if (gdaui_entry_common_time->priv->window) {
- gtk_widget_destroy (gdaui_entry_common_time->priv->window);
- gdaui_entry_common_time->priv->window = NULL;
- }
}
/* parent class */
@@ -234,9 +292,6 @@ gdaui_entry_common_time_finalize (GObject * object)
gdaui_entry_common_time = GDAUI_ENTRY_COMMON_TIME (object);
if (gdaui_entry_common_time->priv) {
- if (gdaui_entry_common_time->priv->last_value_set)
- gda_value_free (gdaui_entry_common_time->priv->last_value_set);
-
g_free (gdaui_entry_common_time->priv);
gdaui_entry_common_time->priv = NULL;
}
@@ -293,33 +348,278 @@ gdaui_entry_common_time_get_property (GObject *object,
}
}
-static GtkWidget *create_entry_date (GdauiEntryCommonTime *mgtim);
-static GtkWidget *create_entry_time (GdauiEntryCommonTime *mgtim);
-static GtkWidget *create_entry_ts (GdauiEntryCommonTime *mgtim);
+static void date_day_selected (GtkCalendar *calendar, GdauiEntryCommonTime *mgtim);
+static void date_day_selected_double_click (GtkCalendar *calendar, GdauiEntryCommonTime *mgtim);
+
+static void
+icon_press_cb (GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event, GdauiEntryCommonTime *mgtim)
+{
+ if (icon_pos == GTK_ENTRY_ICON_PRIMARY) {
+ if (! mgtim->priv->cal_popover) {
+ /* calendar */
+ GtkWidget *wid;
+ wid = gtk_calendar_new ();
+ mgtim->priv->calendar = wid;
+ gtk_widget_show (wid);
+ g_signal_connect (G_OBJECT (wid), "day-selected",
+ G_CALLBACK (date_day_selected), mgtim);
+ g_signal_connect (G_OBJECT (wid), "day-selected-double-click",
+ G_CALLBACK (date_day_selected_double_click), mgtim);
+
+ /* popover */
+ GtkWidget *popover;
+ popover = gtk_popover_new (mgtim->priv->entry);
+ gtk_container_add (GTK_CONTAINER (popover), mgtim->priv->calendar);
+ mgtim->priv->cal_popover = popover;
+ }
+
+ /* set calendar to current value */
+ GValue *value;
+ guint year=0, month=0, day=0;
+ gboolean unset = TRUE;
+
+ /* setting the calendar to the displayed date */
+ value = gdaui_data_entry_get_value (GDAUI_DATA_ENTRY (mgtim));
+
+ if (value && !gda_value_is_null (value)) {
+ GType type;
+ type = gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (mgtim));
+ if (type == G_TYPE_DATE) {
+ const GDate *date;
+ date = (GDate*) g_value_get_boxed (value);
+ if (date) {
+ month = g_date_get_month (date);
+ year = g_date_get_year (date);
+ day = g_date_get_day (date);
+ if ((month != G_DATE_BAD_MONTH) &&
+ (day != G_DATE_BAD_DAY) &&
+ (year != G_DATE_BAD_YEAR)) {
+ month -= 1;
+ unset = FALSE;
+ }
+ }
+ }
+ else if (type == GDA_TYPE_TIMESTAMP) {
+ const GdaTimestamp *ts;
+ ts = gda_value_get_timestamp (value);
+ if (ts) {
+ year = ts->year;
+ month = ts->month - 1;
+ day = ts->day;
+ unset = FALSE;
+ }
+ }
+ else
+ g_assert_not_reached ();
+ }
+
+ if (unset) {
+ time_t now;
+ struct tm *stm;
+
+ now = time (NULL);
+#ifdef HAVE_LOCALTIME_R
+ struct tm tmpstm;
+ stm = localtime_r (&now, &tmpstm);
+#elif HAVE_LOCALTIME_S
+ struct tm tmpstm;
+ g_assert (localtime_s (&tmpstm, &now) == 0);
+ stm = &tmpstm;
+#else
+ stm = localtime (&now);
+#endif
+ year = stm->tm_year + 1900;
+ month = stm->tm_mon;
+ day = stm->tm_mday;
+ }
+
+ if (! unset) {
+ g_signal_handlers_block_by_func (G_OBJECT (mgtim->priv->calendar),
+ G_CALLBACK (date_day_selected), mgtim);
+ g_signal_handlers_block_by_func (G_OBJECT (mgtim->priv->calendar),
+ G_CALLBACK (date_day_selected_double_click), mgtim);
+ }
+ gtk_calendar_select_month (GTK_CALENDAR (mgtim->priv->calendar), month, year);
+ gtk_calendar_select_day (GTK_CALENDAR (mgtim->priv->calendar), day);
+ if (! unset) {
+ g_signal_handlers_unblock_by_func (G_OBJECT (mgtim->priv->calendar),
+ G_CALLBACK (date_day_selected), mgtim);
+ g_signal_handlers_unblock_by_func (G_OBJECT (mgtim->priv->calendar),
+ G_CALLBACK (date_day_selected_double_click),
mgtim);
+ }
+
+ gtk_widget_show (mgtim->priv->cal_popover);
+ }
+}
+
+static void
+date_day_selected (GtkCalendar *calendar, GdauiEntryCommonTime *mgtim)
+{
+ char buffer [256];
+ guint year, month, day;
+ struct tm mtm = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ GType type;
+ type = gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (mgtim));
+
+ gtk_calendar_get_date (calendar, &year, &month, &day);
+
+ mtm.tm_mday = day;
+ mtm.tm_mon = month;
+ if (year > 1900)
+ mtm.tm_year = year - 1900;
+ else
+ mtm.tm_year = year;
+
+ if (type == GDA_TYPE_TIMESTAMP) {
+ /* get the time part back from current value */
+ GValue *value = NULL;
+ gchar *tmpstr;
+ GdaDataHandler *dh;
+ dh = gdaui_data_entry_get_handler (GDAUI_DATA_ENTRY (mgtim));
+ tmpstr = gdaui_formatted_entry_get_text (GDAUI_FORMATTED_ENTRY (mgtim->priv->entry));
+ if (tmpstr) {
+ value = gda_data_handler_get_value_from_str (dh, tmpstr, type);
+ g_free (tmpstr);
+ }
+
+ if (value && (G_VALUE_TYPE (value) != GDA_TYPE_NULL)) {
+ /* copy the 'fraction' and 'timezone' parts, we have not modified */
+ const GdaTimestamp *ets = gda_value_get_timestamp (value);
+ mtm.tm_hour = ets->hour;
+ mtm.tm_min = ets->minute;
+ mtm.tm_sec = ets->second;
+ }
+ gda_value_free (value);
+ }
+
+ guint bufsize;
+ bufsize = sizeof (buffer) / sizeof (char);
+ if (strftime (buffer, bufsize, "%x", &mtm) == 0)
+ buffer [0] = 0;
+ else if (type == GDA_TYPE_TIMESTAMP) {
+ char buffer2 [128];
+ if (strftime (buffer2, bufsize, "%X", &mtm) == 0)
+ buffer [0] = 0;
+ else {
+ gchar *tmp;
+ tmp = g_strdup_printf ("%s %s", buffer, buffer2);
+ if (strlen (tmp) < bufsize)
+ strcpy (buffer, tmp);
+ else
+ buffer [0] = 0;
+ g_free (tmp);
+ }
+ }
+
+ g_print ("BUFFER:[%s]\n", buffer);
+
+ if (buffer [0]) {
+ char *str_utf8;
+ str_utf8 = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
+ gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry), str_utf8);
+ g_free (str_utf8);
+ }
+ else
+ gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry), "");
+}
+
+static void
+date_day_selected_double_click (GtkCalendar *calendar, GdauiEntryCommonTime *mgtim)
+{
+ gtk_widget_hide (mgtim->priv->cal_popover);
+}
+
+static glong
+fit_tz (glong tz)
+{
+ tz = tz % 86400;
+ if (tz > 43200)
+ tz -= 86400;
+ else if (tz < -43200)
+ tz += 86400;
+ return tz;
+}
+
+static void entry_insert_func (GdauiFormattedEntry *fentry, gunichar insert_char, gint virt_pos, gpointer
data);
+
+static void
+event_after_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+ g_signal_emit_by_name (widget, "event-after", event);
+}
+
static GtkWidget *
create_entry (GdauiEntryWrapper *mgwrap)
{
GdauiEntryCommonTime *mgtim;
- GtkWidget *entry = NULL;
- GType type;
-
- g_return_val_if_fail (mgwrap && GDAUI_IS_ENTRY_COMMON_TIME (mgwrap), NULL);
+ g_return_val_if_fail (GDAUI_IS_ENTRY_COMMON_TIME (mgwrap), NULL);
mgtim = GDAUI_ENTRY_COMMON_TIME (mgwrap);
- g_return_val_if_fail (mgtim->priv, NULL);
+ GtkWidget *wid, *hb;
+ GdaDataHandler *dh;
+ GType type;
type = gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (mgtim));
- if (type == G_TYPE_DATE)
- entry = create_entry_date (mgtim);
- else if (type == GDA_TYPE_TIME)
- entry = create_entry_time (mgtim);
- else if (type == GDA_TYPE_TIMESTAMP)
- entry = create_entry_ts (mgtim);
+
+ /* top widget */
+ hb = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
+
+ /* text entry */
+ dh = gdaui_data_entry_get_handler (GDAUI_DATA_ENTRY (mgtim));
+ if (GDA_IS_HANDLER_TIME (dh)) {
+ gchar *str, *mask, *ptr;
+ str = gda_handler_time_get_format (GDA_HANDLER_TIME (dh), type);
+ mask = g_strdup (str);
+ for (ptr = mask; *ptr; ptr++) {
+ if (*ptr == '0')
+ *ptr = '-';
+ }
+ wid = gdaui_formatted_entry_new (str, mask);
+ gdaui_entry_set_suffix (GDAUI_ENTRY (wid), "");
+ g_free (str);
+ g_free (mask);
+
+ gchar *tmp;
+ gulong tz;
+ tz = mgtim->priv->displayed_tz;
+ if (tz == 0)
+ tmp = g_strdup ("GMT");
+ else if ((tz % 3600) == 0)
+ tmp = g_strdup_printf ("GMT %+03d", (gint) tz / 3600);
+ else if ((tz % 60) == 0)
+ tmp = g_strdup_printf ("GMT %+02d min", (gint) tz / 60);
+ else
+ tmp = g_strdup_printf ("GMT %+02d sec", (gint) tz);
+
+ gchar *hint;
+ gdaui_formatted_entry_set_insert_func (GDAUI_FORMATTED_ENTRY (wid), entry_insert_func, mgtim);
+ str = gda_handler_time_get_hint (GDA_HANDLER_TIME (dh), type);
+ hint = g_strdup_printf (_("Expected format is %s\nTime is relative to local time (%s)"), str,
tmp);
+ g_free (str);
+ g_free (tmp);
+ gtk_widget_set_tooltip_text (wid, hint);
+ g_free (hint);
+ }
else
- g_assert_not_reached ();
-
- return entry;
+ wid = gdaui_entry_new (NULL, NULL);
+ gtk_box_pack_start (GTK_BOX (hb), wid, FALSE, FALSE, 0);
+ gtk_widget_show (wid);
+ mgtim->priv->entry = wid;
+ g_signal_connect_swapped (wid, "event-after",
+ G_CALLBACK (event_after_cb), hb);
+
+ if ((type == G_TYPE_DATE) || (type == GDA_TYPE_TIMESTAMP))
+ gtk_entry_set_icon_from_icon_name (GTK_ENTRY (wid),
+ GTK_ENTRY_ICON_PRIMARY, "x-office-calendar-symbolic");
+
+ g_signal_connect (wid, "icon-press",
+ G_CALLBACK (icon_press_cb), mgtim);
+
+ return hb;
}
+/*
+ * NB: the displayed value is relative to mgtim->priv->displayed_tz
+ */
static void
real_set_value (GdauiEntryWrapper *mgwrap, const GValue *value)
{
@@ -327,7 +627,7 @@ real_set_value (GdauiEntryWrapper *mgwrap, const GValue *value)
GType type;
GdaDataHandler *dh;
- g_return_if_fail (mgwrap && GDAUI_IS_ENTRY_COMMON_TIME (mgwrap));
+ g_return_if_fail (GDAUI_IS_ENTRY_COMMON_TIME (mgwrap));
mgtim = GDAUI_ENTRY_COMMON_TIME (mgwrap);
g_return_if_fail (mgtim->priv);
@@ -337,65 +637,84 @@ real_set_value (GdauiEntryWrapper *mgwrap, const GValue *value)
if (type == G_TYPE_DATE) {
if (value) {
if (gda_value_is_null ((GValue *) value))
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_date), NULL);
+ gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry), NULL);
else {
gchar *str;
str = gda_data_handler_get_str_from_value (dh, value);
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_date), str);
+ gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry), str);
g_free (str);
}
}
else
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_date), NULL);
+ gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry), NULL);
}
else if (type == GDA_TYPE_TIME) {
if (value) {
- if (gda_value_is_null ((GValue *) value))
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_time), NULL);
+ if (gda_value_is_null ((GValue *) value)) {
+ gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry), NULL);
+ mgtim->priv->value_tz = mgtim->priv->displayed_tz;
+ mgtim->priv->value_fraction = 0;
+ }
else {
+ const GdaTime *gtim;
+ GdaTime copy;
+ gtim = gda_value_get_time (value);
+ mgtim->priv->value_tz = fit_tz (gtim->timezone);
+ mgtim->priv->value_fraction = gtim->fraction;
+
+ copy = *gtim;
+ gda_time_change_timezone (©, mgtim->priv->displayed_tz);
+
+ GValue *copy_value;
+ copy_value = g_new0 (GValue, 1);
+ gda_value_set_time (copy_value, ©);
+
gchar *str;
-
- str = gda_data_handler_get_str_from_value (dh, value);
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_time), str);
+ str = gda_data_handler_get_str_from_value (dh, copy_value);
+ gda_value_free (copy_value);
+
+ gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry), str);
g_free (str);
}
}
else
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_time), NULL);
+ gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry), NULL);
}
else if (type == GDA_TYPE_TIMESTAMP) {
if (value) {
if (gda_value_is_null ((GValue *) value)) {
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_date), NULL);
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_time), NULL);
+ gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry), NULL);
+ mgtim->priv->value_tz = mgtim->priv->displayed_tz;
+ mgtim->priv->value_fraction = 0;
}
else {
- gchar *str, *ptr;
-
- str = gda_data_handler_get_str_from_value (dh, value);
- ptr = strtok (str, " ");
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_date), ptr);
- ptr = strtok (NULL, " ");
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_time), ptr);
+ const GdaTimestamp *gts;
+ GdaTimestamp copy;
+ gts = gda_value_get_timestamp (value);
+ mgtim->priv->value_tz = fit_tz (gts->timezone);
+ mgtim->priv->value_fraction = gts->fraction;
+
+ copy = *gts;
+ gda_timestamp_change_timezone (©, mgtim->priv->displayed_tz);
+
+ GValue *copy_value;
+ copy_value = g_new0 (GValue, 1);
+ gda_value_set_timestamp (copy_value, ©);
+
+ gchar *str;
+ str = gda_data_handler_get_str_from_value (dh, copy_value);
+ gda_value_free (copy_value);
+
+ gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry), str);
g_free (str);
}
}
- else {
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_date), NULL);
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_time), NULL);
- }
+ else
+ gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry), NULL);
}
else
g_assert_not_reached ();
-
- /* keep track of the last value set */
- if (mgtim->priv->last_value_set) {
- gda_value_free (mgtim->priv->last_value_set);
- mgtim->priv->last_value_set = NULL;
- }
- if (value)
- mgtim->priv->last_value_set = gda_value_copy ((GValue *) value);
}
static GValue *
@@ -415,52 +734,44 @@ real_get_value (GdauiEntryWrapper *mgwrap)
dh = gdaui_data_entry_get_handler (GDAUI_DATA_ENTRY (mgwrap));
if (type == G_TYPE_DATE) {
- str2 = gdaui_formatted_entry_get_text (GDAUI_FORMATTED_ENTRY (mgtim->priv->entry_date));
+ str2 = gdaui_formatted_entry_get_text (GDAUI_FORMATTED_ENTRY (mgtim->priv->entry));
if (str2) {
value = gda_data_handler_get_value_from_str (dh, str2, type);
g_free (str2);
}
}
else if (type == GDA_TYPE_TIME) {
- str2 = gdaui_formatted_entry_get_text (GDAUI_FORMATTED_ENTRY (mgtim->priv->entry_time));
+ str2 = gdaui_formatted_entry_get_text (GDAUI_FORMATTED_ENTRY (mgtim->priv->entry));
if (str2) {
value = gda_data_handler_get_value_from_str (dh, str2, type);
g_free (str2);
}
- if (value && (G_VALUE_TYPE (value) != GDA_TYPE_NULL) &&
- mgtim->priv->last_value_set &&
- gda_value_isa (mgtim->priv->last_value_set, GDA_TYPE_TIME)) {
- /* copy the 'timezone' part, we we have not modified */
- const GdaTime *dgatime_set = gda_value_get_time (mgtim->priv->last_value_set);
+ if (value && (G_VALUE_TYPE (value) != GDA_TYPE_NULL)) {
GdaTime *gdatime = g_new (GdaTime, 1);
*gdatime = *(gda_value_get_time (value));
- gdatime->timezone = dgatime_set->timezone;
+ gdatime->timezone = mgtim->priv->displayed_tz;
+ gda_time_change_timezone (gdatime, mgtim->priv->value_tz);
gda_value_set_time (value, gdatime);
g_free (gdatime);
}
}
else if (type == GDA_TYPE_TIMESTAMP) {
- gchar *tmpstr, *tmpstr2;
+ gchar *tmpstr;
- tmpstr = gdaui_formatted_entry_get_text (GDAUI_FORMATTED_ENTRY (mgtim->priv->entry_time));
- tmpstr2 = gdaui_formatted_entry_get_text (GDAUI_FORMATTED_ENTRY (mgtim->priv->entry_date));
- if (tmpstr && tmpstr2) {
- str2 = g_strdup_printf ("%s %s", tmpstr2, tmpstr);
- value = gda_data_handler_get_value_from_str (dh, str2, type);
- g_free (str2);
+ tmpstr = gdaui_formatted_entry_get_text (GDAUI_FORMATTED_ENTRY (mgtim->priv->entry));
+ if (tmpstr) {
+ value = gda_data_handler_get_value_from_str (dh, tmpstr, type);
+ g_free (tmpstr);
}
- g_free (tmpstr);
- g_free (tmpstr2);
- if (value && (G_VALUE_TYPE (value) != GDA_TYPE_NULL) &&
- mgtim->priv->last_value_set &&
- gda_value_isa (mgtim->priv->last_value_set, GDA_TYPE_TIMESTAMP)) {
- /* copy the 'fraction' and 'timezone' parts, we have not modified */
- const GdaTimestamp *dgatime_set = gda_value_get_timestamp
(mgtim->priv->last_value_set);
+
+ if (value && (G_VALUE_TYPE (value) != GDA_TYPE_NULL)) {
+ /* copy the 'fraction' part, we have not modified */
GdaTimestamp *gdatime = g_new (GdaTimestamp, 1);
*gdatime = *(gda_value_get_timestamp (value));
- gdatime->fraction = dgatime_set->fraction;
- gdatime->timezone = dgatime_set->timezone;
+ gdatime->fraction = mgtim->priv->value_fraction;
+ gdatime->timezone = mgtim->priv->displayed_tz;
+ gda_timestamp_change_timezone (gdatime, mgtim->priv->value_tz);
gda_value_set_timestamp (value, gdatime);
g_free (gdatime);
}
@@ -481,27 +792,13 @@ static void
connect_signals (GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activate_cb)
{
GdauiEntryCommonTime *mgtim;
- GType type;
-
- g_return_if_fail (mgwrap && GDAUI_IS_ENTRY_COMMON_TIME (mgwrap));
+ g_return_if_fail (GDAUI_IS_ENTRY_COMMON_TIME (mgwrap));
mgtim = GDAUI_ENTRY_COMMON_TIME (mgwrap);
- g_return_if_fail (mgtim->priv);
-
- type = gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (mgtim));
- if ((type == G_TYPE_DATE) || (type == GDA_TYPE_TIMESTAMP)) {
- g_signal_connect (G_OBJECT (mgtim->priv->entry_date), "changed",
+ g_signal_connect_swapped (G_OBJECT (mgtim->priv->entry), "changed",
modify_cb, mgwrap);
- g_signal_connect (G_OBJECT (mgtim->priv->entry_date), "activate",
+ g_signal_connect_swapped (G_OBJECT (mgtim->priv->entry), "activate",
activate_cb, mgwrap);
- }
-
- if ((type == GDA_TYPE_TIME) || (type == GDA_TYPE_TIMESTAMP)) {
- g_signal_connect (G_OBJECT (mgtim->priv->entry_time), "changed",
- modify_cb, mgwrap);
- g_signal_connect (G_OBJECT (mgtim->priv->entry_time), "activate",
- activate_cb, mgwrap);
- }
}
static void
@@ -509,16 +806,14 @@ set_editable (GdauiEntryWrapper *mgwrap, gboolean editable)
{
GdauiEntryCommonTime *mgtim;
- g_return_if_fail (mgwrap && GDAUI_IS_ENTRY_COMMON_TIME (mgwrap));
+ g_return_if_fail (GDAUI_IS_ENTRY_COMMON_TIME (mgwrap));
mgtim = GDAUI_ENTRY_COMMON_TIME (mgwrap);
- g_return_if_fail (mgtim->priv);
- if (mgtim->priv->entry_date)
- gtk_editable_set_editable (GTK_EDITABLE (mgtim->priv->entry_date), editable);
- if (mgtim->priv->entry_time)
- gtk_editable_set_editable (GTK_EDITABLE (mgtim->priv->entry_time), editable);
- if (mgtim->priv->date_button)
- gtk_widget_set_sensitive (mgtim->priv->date_button, editable);
+ if (mgtim->priv->entry)
+ gtk_editable_set_editable (GTK_EDITABLE (mgtim->priv->entry), editable);
+
+ gtk_entry_set_icon_sensitive (GTK_ENTRY (mgtim->priv->entry), GTK_ENTRY_ICON_PRIMARY, editable);
+ gtk_entry_set_icon_sensitive (GTK_ENTRY (mgtim->priv->entry), GTK_ENTRY_ICON_SECONDARY, editable);
}
static void
@@ -526,105 +821,15 @@ grab_focus (GdauiEntryWrapper *mgwrap)
{
GdauiEntryCommonTime *mgtim;
- g_return_if_fail (mgwrap && GDAUI_IS_ENTRY_COMMON_TIME (mgwrap));
+ g_return_if_fail (GDAUI_IS_ENTRY_COMMON_TIME (mgwrap));
mgtim = GDAUI_ENTRY_COMMON_TIME (mgwrap);
- g_return_if_fail (mgtim->priv);
-
- if (mgtim->priv->entry_date)
- gtk_widget_grab_focus (mgtim->priv->entry_date);
- if (mgtim->priv->entry_time)
- gtk_widget_grab_focus (mgtim->priv->entry_time);
-}
-
-
-
-/*
- * callbacks for the date
- */
-static gint date_delete_popup (GtkWidget *widget, GdauiEntryCommonTime *mgtim);
-static gint date_key_press_popup (GtkWidget *widget, GdkEventKey *event, GdauiEntryCommonTime *mgtim);
-static gint date_button_press_popup (GtkWidget *widget, GdkEventButton *event, GdauiEntryCommonTime *mgtim);
-static void date_day_selected (GtkCalendar *calendar, GdauiEntryCommonTime *mgtim);
-static void date_day_selected_double_click (GtkCalendar *calendar, GdauiEntryCommonTime *mgtim);
-static void date_calendar_choose_cb (GtkWidget *button, GdauiEntryCommonTime *mgtim);
-
-static void entry_date_insert_func (GdauiFormattedEntry *fentry, gunichar insert_char, gint virt_pos,
gpointer data);
-
-static GtkWidget *
-create_entry_date (GdauiEntryCommonTime *mgtim)
-{
- GtkWidget *wid, *hb, *window, *arrow;
- GdaDataHandler *dh;
-
- /* top widget */
- hb = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
-
- /* text entry */
- dh = gdaui_data_entry_get_handler (GDAUI_DATA_ENTRY (mgtim));
- if (GDA_IS_HANDLER_TIME (dh)) {
- gchar *str, *mask, *ptr;
- str = gda_handler_time_get_format (GDA_HANDLER_TIME (dh), G_TYPE_DATE);
- mask = g_strdup (str);
- for (ptr = mask; *ptr; ptr++) {
- if (*ptr == '0')
- *ptr = '-';
- }
- wid = gdaui_formatted_entry_new (str, mask);
- g_free (str);
- g_free (mask);
- gdaui_formatted_entry_set_insert_func (GDAUI_FORMATTED_ENTRY (wid), entry_date_insert_func,
- mgtim);
- }
- else
- wid = gdaui_entry_new (NULL, NULL);
- gtk_box_pack_start (GTK_BOX (hb), wid, FALSE, FALSE, 0);
- gtk_widget_show (wid);
- mgtim->priv->entry_date = wid;
-
- /* window to hold the calendar popup */
- window = gtk_window_new (GTK_WINDOW_POPUP);
- gtk_widget_set_events (window, gtk_widget_get_events (window) | GDK_KEY_PRESS_MASK);
- gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
- g_signal_connect (G_OBJECT (window), "delete-event",
- G_CALLBACK (date_delete_popup), mgtim);
- g_signal_connect (G_OBJECT (window), "key-press-event",
- G_CALLBACK (date_key_press_popup), mgtim);
- g_signal_connect (G_OBJECT (window), "button-press-event",
- G_CALLBACK (date_button_press_popup), mgtim);
- mgtim->priv->window = window;
-
- /* calendar */
- wid = gtk_calendar_new ();
- mgtim->priv->date = wid;
- gtk_container_add (GTK_CONTAINER (window), wid);
- gtk_widget_show (wid);
- g_signal_connect (G_OBJECT (wid), "day-selected",
- G_CALLBACK (date_day_selected), mgtim);
- g_signal_connect (G_OBJECT (wid), "day-selected-double-click",
- G_CALLBACK (date_day_selected_double_click), mgtim);
-
- /* button to pop up the calendar */
- wid = gtk_button_new ();
- arrow = gtk_image_new_from_icon_name ("go-down-symbolic", GTK_ICON_SIZE_MENU);
- gtk_container_add (GTK_CONTAINER (wid), arrow);
- gtk_box_pack_start (GTK_BOX (hb), wid, FALSE, FALSE, 0);
- gtk_widget_show_all (wid);
- g_signal_connect (G_OBJECT (wid), "clicked",
- G_CALLBACK (date_calendar_choose_cb), mgtim);
- mgtim->priv->date_button = wid;
-
- /* padding */
- wid = gtk_label_new ("");
- gtk_box_pack_start (GTK_BOX (hb), wid, TRUE, TRUE, 0);
- gtk_widget_show (wid);
-
- return hb;
+ gtk_widget_grab_focus (mgtim->priv->entry);
}
static void
-entry_date_insert_func (G_GNUC_UNUSED GdauiFormattedEntry *fentry, gunichar insert_char,
- G_GNUC_UNUSED gint virt_pos, gpointer data)
+entry_insert_func (G_GNUC_UNUSED GdauiFormattedEntry *fentry, gunichar insert_char,
+ G_GNUC_UNUSED gint virt_pos, gpointer data)
{
GValue *value;
GType type;
@@ -634,31 +839,42 @@ entry_date_insert_func (G_GNUC_UNUSED GdauiFormattedEntry *fentry, gunichar inse
if (!value)
return;
- if (G_VALUE_TYPE (value) == GDA_TYPE_NULL) {
+ /* current value is NULL and we are not entering a digit */
+ if ((G_VALUE_TYPE (value) == GDA_TYPE_NULL) && (insert_char == g_utf8_get_char (" "))) {
+ gda_value_reset_with_type (value, type);
if (type == G_TYPE_DATE) {
- /* set current date, whatever @insert_char is */
+ /* set current date */
GDate *ndate;
ndate = g_new0 (GDate, 1);
g_date_set_time_t (ndate, time (NULL));
- gda_value_reset_with_type (value, type);
g_value_take_boxed (value, ndate);
real_set_value (GDAUI_ENTRY_WRAPPER (data), value);
}
+ else if (type == GDA_TYPE_TIME) {
+ /* set current time */
+ GValue *timvalue;
+ GdauiEntryCommonTime *mgtim = GDAUI_ENTRY_COMMON_TIME (data);
+ timvalue = gda_value_new_time_from_timet (time (NULL));
+ real_set_value (GDAUI_ENTRY_WRAPPER (data), timvalue);
+ gda_value_free (timvalue);
+ }
else if (type == GDA_TYPE_TIMESTAMP) {
+ /* set current date and time */
GValue *tsvalue;
- gchar *str;
+ //gchar *str;
GdauiEntryCommonTime *mgtim = GDAUI_ENTRY_COMMON_TIME (data);
- str = gdaui_formatted_entry_get_text (GDAUI_FORMATTED_ENTRY
(mgtim->priv->entry_time));
+ //str = gdaui_formatted_entry_get_text (GDAUI_FORMATTED_ENTRY (mgtim->priv->entry));
tsvalue = gda_value_new_timestamp_from_timet (time (NULL));
real_set_value (GDAUI_ENTRY_WRAPPER (data), tsvalue);
gda_value_free (tsvalue);
- if (str && g_ascii_isdigit (*str))
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_time), str);
- g_free (str);
+ //if (str && g_ascii_isdigit (*str))
+ // gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry), str);
+ //g_free (str);
}
}
- else {
+ else if ((G_VALUE_TYPE (value) != GDA_TYPE_NULL)) {
+ /* REM: if (type == GDA_TYPE_TIME) we have nothing to do */
GDate *date = NULL;
if (type == G_TYPE_DATE) {
date = (GDate*) g_value_get_boxed (value);
@@ -708,399 +924,6 @@ entry_date_insert_func (G_GNUC_UNUSED GdauiFormattedEntry *fentry, gunichar inse
gda_value_free (value);
}
-static void
-hide_popup (GdauiEntryCommonTime *mgtim)
-{
- gtk_widget_hide (mgtim->priv->window);
- gtk_grab_remove (mgtim->priv->window);
-}
-
-static gint
-date_delete_popup (G_GNUC_UNUSED GtkWidget *widget, GdauiEntryCommonTime *mgtim)
-{
- hide_popup (mgtim);
- return TRUE;
-}
-
-static gint
-date_key_press_popup (GtkWidget *widget, GdkEventKey *event, GdauiEntryCommonTime *mgtim)
-{
- if (event->keyval != GDK_KEY_Escape)
- return FALSE;
-
- g_signal_stop_emission_by_name (widget, "key-press-event");
- hide_popup (mgtim);
-
- return TRUE;
-}
-
-static gint
-date_button_press_popup (GtkWidget *widget, GdkEventButton *event, GdauiEntryCommonTime *mgtim)
-{
- 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 = gtk_widget_get_parent (child);
- }
- }
-
- hide_popup (mgtim);
-
- return TRUE;
-}
-
-static void
-date_day_selected (GtkCalendar *calendar, GdauiEntryCommonTime *mgtim)
-{
- char buffer [256];
- guint year, month, day;
- struct tm mtm = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- char *str_utf8;
-
- gtk_calendar_get_date (calendar, &year, &month, &day);
-
- mtm.tm_mday = day;
- mtm.tm_mon = month;
- if (year > 1900)
- mtm.tm_year = year - 1900;
- else
- mtm.tm_year = year;
-
- if (strftime (buffer, sizeof (buffer), "%x", &mtm) == 0)
- strcpy (buffer, "???");
- buffer[sizeof(buffer)-1] = '\0';
-
- str_utf8 = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
- gdaui_entry_set_text (GDAUI_ENTRY (mgtim->priv->entry_date), str_utf8);
- g_free (str_utf8);
-}
-
-static void
-date_day_selected_double_click (G_GNUC_UNUSED GtkCalendar *calendar, GdauiEntryCommonTime *mgtim)
-{
- hide_popup (mgtim);
-}
-
-
-static gboolean popup_grab_on_window (GtkWidget *widget, guint32 activate_time);
-static void position_popup (GdauiEntryCommonTime *mgtim);
-static void
-date_calendar_choose_cb (GtkWidget *button, GdauiEntryCommonTime *mgtim)
-{
- GValue *value;
- guint year=0, month=0, day=0;
- gboolean unset = TRUE;
-
- /* setting the calendar to the latest displayed date */
- value = gdaui_data_entry_get_value (GDAUI_DATA_ENTRY (mgtim));
-
- if (value && !gda_value_is_null (value)) {
- const GDate *date;
- const GdaTimestamp *ts;
- GType type;
-
- type = gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (mgtim));
- if (type == G_TYPE_DATE) {
- date = (GDate*) g_value_get_boxed (value);
- if (date) {
- month = g_date_get_month (date);
- year = g_date_get_year (date);
- day = g_date_get_day (date);
- if ((month != G_DATE_BAD_MONTH) &&
- (day != G_DATE_BAD_DAY) &&
- (year != G_DATE_BAD_YEAR)) {
- month -= 1;
- unset = FALSE;
- }
- }
- }
- else if (type == GDA_TYPE_TIMESTAMP) {
- ts = gda_value_get_timestamp (value);
- if (ts) {
- year = ts->year;
- month = ts->month - 1;
- day = ts->day;
- unset = FALSE;
- }
- }
- else
- g_assert_not_reached ();
- }
-
- if (unset) {
- time_t now;
- struct tm *stm;
-
- now = time (NULL);
-#ifdef HAVE_LOCALTIME_R
- struct tm tmpstm;
- stm = localtime_r (&now, &tmpstm);
-#elif HAVE_LOCALTIME_S
- struct tm tmpstm;
- g_assert (localtime_s (&tmpstm, &now) == 0);
- stm = &tmpstm;
-#else
- stm = localtime (&now);
-#endif
- year = stm->tm_year + 1900;
- month = stm->tm_mon;
- day = stm->tm_mday;
- }
-
- gtk_calendar_select_month (GTK_CALENDAR (mgtim->priv->date), month, year);
- gtk_calendar_select_day (GTK_CALENDAR (mgtim->priv->date), day);
-
- /* popup window */
- /* Temporarily grab pointer and keyboard, copied from GnomeDateEdit */
- if (!popup_grab_on_window (button, gtk_get_current_event_time ()))
- return;
-
- position_popup (mgtim);
- gtk_widget_show (mgtim->priv->window);
- gtk_grab_add (mgtim->priv->window);
-
- GdkScreen *screen;
- gint swidth, sheight;
- gint root_x, root_y;
- gint wwidth, wheight;
- gboolean do_move = FALSE;
- screen = gtk_window_get_screen (GTK_WINDOW (mgtim->priv->window));
- 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 (mgtim->priv->window), &root_x, &root_y);
- gtk_window_get_size (GTK_WINDOW (mgtim->priv->window), &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 (mgtim->priv->window), root_x, root_y);
-
- gtk_widget_grab_focus (mgtim->priv->date);
- popup_grab_on_window (mgtim->priv->window,
- gtk_get_current_event_time ());
-}
-
-static gboolean
-popup_grab_on_window (GtkWidget *widget, guint32 activate_time)
-{
- GdkDeviceManager *manager;
- GdkDevice *pointer;
- GdkWindow *window;
- window = gtk_widget_get_window (widget);
- manager = gdk_display_get_device_manager (gtk_widget_get_display (widget));
- pointer = gdk_device_manager_get_client_pointer (manager);
- if (gdk_device_grab (pointer, window, GDK_OWNERSHIP_WINDOW, TRUE,
- GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
- GDK_POINTER_MOTION_MASK,
- NULL, activate_time) == GDK_GRAB_SUCCESS) {
- GdkDevice *keyb;
- keyb = gdk_device_get_associated_device (pointer);
- if (gdk_device_grab (keyb, window, GDK_OWNERSHIP_WINDOW, TRUE,
- GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK, NULL, activate_time) ==
- GDK_GRAB_SUCCESS)
- return TRUE;
- else {
- gdk_device_ungrab (pointer, activate_time);
- return FALSE;
- }
- }
- return FALSE;
-}
-
-static void
-position_popup (GdauiEntryCommonTime *mgtim)
-{
- gint x, y;
- gint bwidth, bheight;
- GtkRequisition req_minimum, req_natural;
-
- gtk_widget_get_preferred_size (mgtim->priv->window, &req_minimum,
- &req_natural);
-
- gdk_window_get_origin (gtk_widget_get_window (mgtim->priv->date_button), &x, &y);
- GtkAllocation alloc;
- gtk_widget_get_allocation (mgtim->priv->date_button, &alloc);
- x += alloc.x;
- y += alloc.y;
- bwidth = alloc.width;
- bheight = alloc.height;
-
- x += bwidth - req_natural.width;
- y += bheight;
-
- if (x < 0)
- x = 0;
-
- if (y < 0)
- y = 0;
-
- gtk_window_move (GTK_WINDOW (mgtim->priv->window), x, y);
-}
-
-
-
-
-/*
- * callbacks for the time
- */
-static void entry_time_insert_func (GdauiFormattedEntry *fentry, gunichar insert_char, gint virt_pos,
gpointer data);
-
-static GtkWidget *
-create_entry_time (GdauiEntryCommonTime *mgtim)
-{
- GtkWidget *wid;
- GdaDataHandler *dh;
-
- /* text entry */
- dh = gdaui_data_entry_get_handler (GDAUI_DATA_ENTRY (mgtim));
- if (GDA_IS_HANDLER_TIME (dh)) {
- gchar *str, *mask, *ptr;
- str = gda_handler_time_get_format (GDA_HANDLER_TIME (dh), GDA_TYPE_TIME);
- mask = g_strdup (str);
- for (ptr = mask; *ptr; ptr++) {
- if (*ptr == '0')
- *ptr = '-';
- }
- wid = gdaui_formatted_entry_new (str, mask);
- g_free (str);
- g_free (mask);
-
- gdaui_formatted_entry_set_insert_func (GDAUI_FORMATTED_ENTRY (wid), entry_time_insert_func,
- mgtim);
- }
- else
- wid = gdaui_entry_new (NULL, NULL);
- mgtim->priv->entry_time = wid;
-
- /* format tooltip */
- gtk_widget_set_tooltip_text (wid, _("Format is hh:mm:ss"));
-
- return wid;
-}
-
-static void
-entry_time_insert_func (G_GNUC_UNUSED GdauiFormattedEntry *fentry, gunichar insert_char,
- G_GNUC_UNUSED gint virt_pos, gpointer data)
-{
- GValue *value;
- GType type;
-
- type = gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (data));
- value = real_get_value (GDAUI_ENTRY_WRAPPER (data));
- if (!value)
- return;
-
- if (insert_char != g_utf8_get_char (" "))
- return;
-
- if (type == GDA_TYPE_TIME) {
- /* set current time */
- gda_value_reset_with_type (value, type);
- struct tm *ltm;
- time_t val;
-
- val = time (NULL);
- ltm = localtime ((const time_t *) &val);
- if (ltm) {
- GdaTime tim;
- memset (&tim, 0, sizeof (GdaTime));
- tim.hour = ltm->tm_hour;
- tim.minute = ltm->tm_min;
- tim.second = ltm->tm_sec;
- tim.fraction = 0;
- tim.timezone = GDA_TIMEZONE_INVALID;
- gda_value_set_time (value, (const GdaTime *) &tim);
- real_set_value (GDAUI_ENTRY_WRAPPER (data), value);
- }
- }
- else if (type == GDA_TYPE_TIMESTAMP && (G_VALUE_TYPE (value) == GDA_TYPE_TIMESTAMP)) {
- const GdaTimestamp *ts;
- ts = gda_value_get_timestamp (value);
- if (ts) {
- struct tm *ltm;
- time_t val;
-
- val = time (NULL);
- ltm = localtime ((const time_t *) &val);
- if (ltm) {
- GdaTimestamp tim;
- tim = *ts;
- tim.hour = ltm->tm_hour;
- tim.minute = ltm->tm_min;
- tim.second = ltm->tm_sec;
- tim.fraction = 0;
- tim.timezone = GDA_TIMEZONE_INVALID;
- gda_value_set_timestamp (value, (const GdaTimestamp *) &tim);
- real_set_value (GDAUI_ENTRY_WRAPPER (data), value);
- }
- }
- }
- else if (type == GDA_TYPE_TIMESTAMP) {
- /* value is GDA_TYPE_NULL */
- entry_date_insert_func (NULL, insert_char, 0, data);
- }
-
- gda_value_free (value);
-}
-
-/*
- * callbacks for the timestamp
- */
-static GtkWidget *
-create_entry_ts (GdauiEntryCommonTime *mgtim)
-{
- GtkWidget *hb, *wid;
-
- hb = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-
- /* date part */
- wid = create_entry_date (mgtim);
- gtk_box_pack_start (GTK_BOX (hb), wid, FALSE, FALSE, 0);
- gtk_widget_show (wid);
-
- /* time part */
- wid = create_entry_time (mgtim);
- gtk_box_pack_start (GTK_BOX (hb), wid, FALSE, FALSE, 0);
- gtk_widget_show (wid);
-
- mgtim->priv->hbox = hb;
-
- return hb;
-}
-
-
-
/*
* GtkCellEditable interface
*/
@@ -1126,39 +949,16 @@ gdaui_entry_common_time_start_editing (GtkCellEditable *iface, GdkEvent *event)
g_return_if_fail (mgtim->priv);
mgtim->priv->editing_canceled = FALSE;
- if (mgtim->priv->date_button) {
- gtk_widget_destroy (mgtim->priv->date_button);
- mgtim->priv->date_button = NULL;
- }
-
- if (mgtim->priv->hbox) {
- gtk_box_set_spacing (GTK_BOX (mgtim->priv->hbox), 0);
- gtk_container_set_border_width (GTK_CONTAINER (mgtim->priv->hbox), 0);
- }
- if (mgtim->priv->entry_date) {
- g_object_set (G_OBJECT (mgtim->priv->entry_date), "has-frame", FALSE, NULL);
- gtk_cell_editable_start_editing (GTK_CELL_EDITABLE (mgtim->priv->entry_date), event);
- g_signal_connect (G_OBJECT (mgtim->priv->entry_date), "editing-done",
+ if (mgtim->priv->entry) {
+ g_object_set (G_OBJECT (mgtim->priv->entry), "has-frame", FALSE, NULL);
+ gtk_cell_editable_start_editing (GTK_CELL_EDITABLE (mgtim->priv->entry), event);
+ g_signal_connect (G_OBJECT (mgtim->priv->entry), "editing-done",
G_CALLBACK (gtk_cell_editable_entry_editing_done_cb), mgtim);
- g_signal_connect (G_OBJECT (mgtim->priv->entry_date), "remove-widget",
+ g_signal_connect (G_OBJECT (mgtim->priv->entry), "remove-widget",
G_CALLBACK (gtk_cell_editable_entry_remove_widget_cb), mgtim);
}
- if (mgtim->priv->entry_time) {
- g_object_set (G_OBJECT (mgtim->priv->entry_time), "has-frame", FALSE, NULL);
- gtk_cell_editable_start_editing (GTK_CELL_EDITABLE (mgtim->priv->entry_time), event);
- g_signal_connect (G_OBJECT (mgtim->priv->entry_time), "editing-done",
- G_CALLBACK (gtk_cell_editable_entry_editing_done_cb), mgtim);
- g_signal_connect (G_OBJECT (mgtim->priv->entry_time), "remove-widget",
- G_CALLBACK (gtk_cell_editable_entry_remove_widget_cb), mgtim);
- }
-
- gdaui_entry_shell_refresh (GDAUI_ENTRY_SHELL (mgtim));
-
- if (mgtim->priv->entry_date)
- gtk_widget_grab_focus (mgtim->priv->entry_date);
- else
- gtk_widget_grab_focus (mgtim->priv->entry_time);
- gtk_widget_queue_draw (GTK_WIDGET (mgtim));
+ gtk_widget_grab_focus (mgtim->priv->entry);
+ //gtk_widget_queue_draw (GTK_WIDGET (mgtim)); useful ?
}
diff --git a/libgda-ui/data-entries/gdaui-entry-integer.xml.in
b/libgda-ui/data-entries/gdaui-entry-integer.xml.in
index f46ff21..04d7a01 100644
--- a/libgda-ui/data-entries/gdaui-entry-integer.xml.in
+++ b/libgda-ui/data-entries/gdaui-entry-integer.xml.in
@@ -1,10 +1,10 @@
<?xml version="1.0"?>
<data-set-spec>
<parameters>
- <parameter id="THOUSAND_SEP" _name="Use 1000s separators" _descr="Use thousands separator as specified
by current locale" gdatype="gboolean">
+ <parameter id="THOUSAND_SEP" _name="Use 1000s separators" _descr="Use thousands separator as specified
by current locale" gdatype="gboolean" nullok="TRUE">
<gda_value>FALSE</gda_value>
</parameter>
- <parameter id="CURRENCY" _name="Currency symbol" _descr="A currency symbol" source="currencies:0"
gdatype="gchararray"/>
+ <parameter id="CURRENCY" _name="Currency symbol" _descr="A currency symbol" source="currencies:0"
gdatype="gchararray" nullok="TRUE"/>
</parameters>
<sources>
<gda_array name="currencies">
diff --git a/libgda-ui/data-entries/gdaui-entry-none.c b/libgda-ui/data-entries/gdaui-entry-none.c
index bbf7834..aa05b89 100644
--- a/libgda-ui/data-entries/gdaui-entry-none.c
+++ b/libgda-ui/data-entries/gdaui-entry-none.c
@@ -156,23 +156,24 @@ gdaui_entry_none_finalize (GObject * object)
static GtkWidget *
create_entry (GdauiEntryWrapper *mgwrap)
{
- GtkWidget *frame, *label;
+ GtkWidget *evbox, *label;
GdauiEntryNone *entry;
g_return_val_if_fail (mgwrap && GDAUI_IS_ENTRY_NONE (mgwrap), NULL);
entry = GDAUI_ENTRY_NONE (mgwrap);
g_return_val_if_fail (entry->priv, NULL);
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
-
+ evbox = gtk_event_box_new ();
+ gtk_widget_add_events (evbox, GDK_FOCUS_CHANGE_MASK);
+ gtk_widget_set_can_focus (evbox, TRUE);
label = gtk_label_new ("");
+ gtk_widget_set_name (label, "invalid-label");
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
- gtk_container_add (GTK_CONTAINER (frame), label);
+ gtk_container_add (GTK_CONTAINER (evbox), label);
gtk_widget_show (label);
- return frame;
+ return evbox;
}
static void
diff --git a/libgda-ui/data-entries/gdaui-entry-number.c b/libgda-ui/data-entries/gdaui-entry-number.c
index 84f6564..b0383be 100644
--- a/libgda-ui/data-entries/gdaui-entry-number.c
+++ b/libgda-ui/data-entries/gdaui-entry-number.c
@@ -78,8 +78,6 @@ struct _GdauiEntryNumberPrivate
guchar thousand_sep;
guint16 nb_decimals;
gchar *currency;
-
- gulong entry_change_sig;
};
static void
@@ -165,8 +163,6 @@ gdaui_entry_number_init (GdauiEntryNumber *mgstr)
mgstr->priv->nb_decimals = G_MAXUINT16; /* unlimited number of decimals */
mgstr->priv->currency = NULL;
- mgstr->priv->entry_change_sig = 0;
-
g_signal_connect (mgstr, "key-press-event",
G_CALLBACK (key_press_event_cb), NULL);
}
@@ -187,8 +183,9 @@ gdaui_entry_number_is_type_numeric (GType type)
* gdaui_entry_number_new:
* @dh: the data handler to be used by the new widget
* @type: the requested data type (compatible with @dh)
+ * @options: (allow-none): some options formatting the new entry, or %NULL
*
- * Creates a new data entry widget
+ * Creates a new data entry widget. Known options are: THOUSAND_SEP, NB_DECIMALS and CURRENCY
*
* Returns: (transfer full): the new widget
*/
@@ -293,18 +290,30 @@ gdaui_entry_number_get_property (GObject *object,
}
}
+static void
+event_after_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+ g_signal_emit_by_name (widget, "event-after", event);
+}
+
static GtkWidget *
create_entry (GdauiEntryWrapper *mgwrap)
{
+ GtkWidget *hb;
GdauiEntryNumber *mgstr;
g_return_val_if_fail (GDAUI_IS_ENTRY_NUMBER (mgwrap), NULL);
mgstr = GDAUI_ENTRY_NUMBER (mgwrap);
+ hb = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
mgstr->priv->entry = gdaui_numeric_entry_new (gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY
(mgwrap)));
sync_entry_options (mgstr);
- return mgstr->priv->entry;
+ gtk_container_add (GTK_CONTAINER (hb), mgstr->priv->entry);
+ gtk_widget_show (mgstr->priv->entry);
+ g_signal_connect_swapped (mgstr->priv->entry, "event-after",
+ G_CALLBACK (event_after_cb), hb);
+ return hb;
}
static void
@@ -361,10 +370,10 @@ connect_signals (GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activ
mgstr = GDAUI_ENTRY_NUMBER (mgwrap);
g_return_if_fail (mgstr->priv);
- mgstr->priv->entry_change_sig = g_signal_connect (G_OBJECT (mgstr->priv->entry), "changed",
- modify_cb, mgwrap);
- g_signal_connect (G_OBJECT (mgstr->priv->entry), "activate",
- activate_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgstr->priv->entry), "changed",
+ modify_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgstr->priv->entry), "activate",
+ activate_cb, mgwrap);
}
static void
@@ -420,7 +429,6 @@ gdaui_entry_number_start_editing (GtkCellEditable *iface, GdkEvent *event)
G_CALLBACK (gtk_cell_editable_entry_editing_done_cb), mgstr);
g_signal_connect (G_OBJECT (mgstr->priv->entry), "remove-widget",
G_CALLBACK (gtk_cell_editable_entry_remove_widget_cb), mgstr);
- gdaui_entry_shell_refresh (GDAUI_ENTRY_SHELL (mgstr));
gtk_widget_grab_focus (mgstr->priv->entry);
gtk_widget_queue_draw (GTK_WIDGET (mgstr));
diff --git a/libgda-ui/data-entries/gdaui-entry-number.xml.in
b/libgda-ui/data-entries/gdaui-entry-number.xml.in
index 4dcdeba..dc86769 100644
--- a/libgda-ui/data-entries/gdaui-entry-number.xml.in
+++ b/libgda-ui/data-entries/gdaui-entry-number.xml.in
@@ -1,13 +1,13 @@
<?xml version="1.0"?>
<data-set-spec>
<parameters>
- <parameter id="THOUSAND_SEP" _name="Use 1000s separators" _descr="Use thousands separator as specified
by current locale" gdatype="gboolean">
+ <parameter id="THOUSAND_SEP" _name="Use 1000s separators" _descr="Use thousands separator as specified
by current locale" gdatype="gboolean" nullok="TRUE">
<gda_value>FALSE</gda_value>
</parameter>
- <parameter id="NB_DECIMALS" _name="Decimals" _descr="Number of decimals" gdatype="guint">
+ <parameter id="NB_DECIMALS" _name="Decimals" _descr="Number of decimals" gdatype="guint" nullok="TRUE">
<gda_value>2</gda_value>
</parameter>
- <parameter id="CURRENCY" _name="Currency symbol" _descr="A currency symbol" source="currencies:0"
gdatype="gchararray"/>
+ <parameter id="CURRENCY" _name="Currency symbol" _descr="A currency symbol" source="currencies:0"
gdatype="gchararray" nullok="TRUE"/>
</parameters>
<sources>
<gda_array name="currencies">
diff --git a/libgda-ui/data-entries/gdaui-entry-shell.c b/libgda-ui/data-entries/gdaui-entry-shell.c
index ccee60b..2ac2b00 100644
--- a/libgda-ui/data-entries/gdaui-entry-shell.c
+++ b/libgda-ui/data-entries/gdaui-entry-shell.c
@@ -19,13 +19,16 @@
* Boston, MA 02110-1301, USA.
*/
-#include <gdk/gdkkeysyms.h>
+#include <gdk/gdk.h>
#include "gdaui-entry-shell.h"
#include "gdaui-entry-none.h"
#include <libgda/gda-data-handler.h>
#include <libgda-ui/internal/utility.h>
#include <glib/gi18n-lib.h>
-#include "widget-embedder.h"
+#include <libgda/gda-debug-macros.h>
+
+/*#define DEBUG*/
+
static void gdaui_entry_shell_class_init (GdauiEntryShellClass *class);
static void gdaui_entry_shell_init (GdauiEntryShell *wid);
static void gdaui_entry_shell_dispose (GObject *object);
@@ -38,36 +41,72 @@ static void gdaui_entry_shell_get_property (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec);
+/*
+ * This widget displays a GValue and its attributes (GValueAttribute) in the following way:
+ * - if GDA_VALUE_ATTR_DATA_NON_VALID, then:
+ * - if GDA_VALUE_ATTR_READ_ONLY: then a "Invalid" label is shown, and no action is possible
+ * else
+ * - an entry widget is shown
+ * NB: in both cases, the widget is outlined (or colored) in the "invalid color", which can be changed
+ * using gdaui_entry_shell_set_invalid_color()
+ * else
+ * - if GDA_VALUE_ATTR_IS_NULL or GDA_VALUE_ATTR_IS_DEFAULT then
+ * - a "value is NULL" or "value is default" or "Value is default (NULL)" is shown.
+ * If not GDA_VALUE_ATTR_READ_ONLY, then an "edit" action is possible, which (at least up to when
+ * the focus is lost), displays an entry widget
+ * else
+ * - an entry widget is shown. If not GDA_VALUE_ATTR_READ_ONLY then, depending on
+ * GDA_VALUE_ATTR_CAN_BE_NULL, GDA_VALUE_ATTR_CAN_BE_DEFAULT, or GDA_VALUE_ATTR_HAS_VALUE_ORIG, the
+ * following respective actions are possible: "set to NULL", "set to default" and "reset" (this last
one
+ * if not GDA_VALUE_ATTR_IS_UNCHANGED)
+ */
+#define PAGE_LABEL "L"
+#define PAGE_ENTRY "E"
+
+typedef enum {
+ MESSAGE_NONE,
+ MESSAGE_NULL,
+ MESSAGE_DEFAULT,
+ MESSAGE_DEFAULT_AND_NULL,
+ MESSAGE_INVALID
+} MessageType;
+
+static const gchar *raw_messages[] = {
+ "",
+ N_("NULL value"),
+ N_("Default value"),
+ N_("Default value (NULL)"),
+ N_("Invalid value"),
+};
-static gint event_cb (GtkWidget *widget, GdkEvent *event, GdauiEntryShell *shell);
-static void show_all (GtkWidget *widget);
-static void contents_modified_cb (GdauiEntryShell *shell, gpointer unused);
-static void gdaui_entry_shell_refresh_status_display (GdauiEntryShell *shell);
+static gchar **messages = NULL;
/* properties */
enum {
PROP_0,
PROP_HANDLER,
- PROP_ACTIONS,
PROP_IS_CELL_RENDERER
};
+#define value_is_null(attr) ((attr) & GDA_VALUE_ATTR_IS_NULL)
+#define value_is_modified(attr) (!((attr) & GDA_VALUE_ATTR_IS_UNCHANGED))
+#define value_is_default(attr) ((attr) & GDA_VALUE_ATTR_IS_DEFAULT)
+#define value_is_valid(attr) (!((attr) & GDA_VALUE_ATTR_DATA_NON_VALID))
struct _GdauiEntryShellPriv {
- GtkWidget *embedder;
- GtkWidget *hbox;
- GtkWidget *button;
- GdaDataHandler *data_handler;
+ GtkWidget *stack;
+ GtkWidget *button; /* "..." button */
+ GtkWidget *label;
+ GdaDataHandler *data_handler; /* FIXME: to remove if unused elsewhere */
gboolean show_actions;
-
- gboolean value_is_null;
- gboolean value_is_modified;
- gboolean value_is_default;
- gboolean value_is_non_valid;
-
gboolean is_cell_renderer;
+ gboolean editable;
+ gboolean being_edited;
};
+static void show_or_hide_actions_button (GdauiEntryShell *shell, GdaValueAttribute attr);
+static guint compute_nb_possible_actions (GdauiEntryShell *shell, GdaValueAttribute attr);
+
/* get a pointer to the parents to be able to call their destructor */
static GObjectClass *parent_class = NULL;
@@ -97,7 +136,7 @@ gdaui_entry_shell_get_type (void)
0
};
- type = g_type_register_static (GTK_TYPE_VIEWPORT, "GdauiEntryShell", &info, 0);
+ type = g_type_register_static (GTK_TYPE_BOX, "GdauiEntryShell", &info, 0);
}
return type;
}
@@ -112,7 +151,6 @@ gdaui_entry_shell_class_init (GdauiEntryShellClass * class)
parent_class = g_type_class_peek_parent (class);
object_class->dispose = gdaui_entry_shell_dispose;
- widget_class->show_all = show_all;
/* Properties */
object_class->set_property = gdaui_entry_shell_set_property;
@@ -120,9 +158,6 @@ gdaui_entry_shell_class_init (GdauiEntryShellClass * class)
g_object_class_install_property (object_class, PROP_HANDLER,
g_param_spec_object ("handler", NULL, NULL, GDA_TYPE_DATA_HANDLER,
(G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property (object_class, PROP_ACTIONS,
- g_param_spec_boolean ("actions", NULL, NULL, TRUE,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
g_object_class_install_property (object_class, PROP_IS_CELL_RENDERER,
g_param_spec_boolean ("is-cell-renderer", NULL, NULL, TRUE,
@@ -130,65 +165,233 @@ gdaui_entry_shell_class_init (GdauiEntryShellClass * class)
}
static void
-show_all (GtkWidget *widget)
+destroy_popover (GtkWidget *child)
+{
+ /* destroy GtkPopover in which @child is */
+ GtkWidget *pop;
+ pop = gtk_widget_get_ancestor (GTK_WIDGET (child), GTK_TYPE_POPOVER);
+ if (pop)
+ gtk_widget_destroy (pop);
+}
+
+static void
+action_edit_value_cb (GtkButton *button, GdauiEntryShell *shell)
+{
+ GdaValueAttribute attr;
+ attr = gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (shell));
+ if (! (attr & GDA_VALUE_ATTR_READ_ONLY)) {
+ gtk_stack_set_visible_child_name (GTK_STACK (shell->priv->stack), PAGE_ENTRY);
+ gdaui_data_entry_grab_focus (GDAUI_DATA_ENTRY (shell));
+ show_or_hide_actions_button (shell, attr);
+ shell->priv->being_edited = TRUE;
+ }
+ if (button)
+ destroy_popover (GTK_WIDGET (button));
+}
+
+static void
+action_set_value_to_null_cb (GtkButton *button, GdauiEntryShell *shell)
+{
+ GdaValueAttribute attr;
+ attr = gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (shell));
+ if (attr & GDA_VALUE_ATTR_CAN_BE_NULL) {
+ gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (shell),
+ GDA_VALUE_ATTR_IS_NULL, GDA_VALUE_ATTR_IS_NULL);
+ show_or_hide_actions_button (shell, attr);
+ shell->priv->being_edited = FALSE;
+ }
+ destroy_popover (GTK_WIDGET (button));
+}
+
+static void
+action_set_value_to_default_cb (GtkButton *button, GdauiEntryShell *shell)
+{
+ GdaValueAttribute attr;
+ attr = gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (shell));
+ if (attr & GDA_VALUE_ATTR_CAN_BE_DEFAULT) {
+ gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (shell),
+ GDA_VALUE_ATTR_IS_DEFAULT, GDA_VALUE_ATTR_IS_DEFAULT);
+ show_or_hide_actions_button (shell, attr);
+ shell->priv->being_edited = FALSE;
+ }
+ destroy_popover (GTK_WIDGET (button));
+}
+
+static void
+action_reset_value_cb (GtkButton *button, GdauiEntryShell *shell)
{
- if (((GdauiEntryShell*) widget)->priv->show_actions)
- gtk_widget_show (((GdauiEntryShell*) widget)->priv->button);
+ GdaValueAttribute attr;
+ attr = gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (shell));
+ if (attr & GDA_VALUE_ATTR_HAS_VALUE_ORIG) {
+ gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (shell),
+ GDA_VALUE_ATTR_IS_UNCHANGED, GDA_VALUE_ATTR_IS_UNCHANGED);
+ shell->priv->being_edited = FALSE;
+ }
+ destroy_popover (GTK_WIDGET (button));
+}
+
+static void
+show_or_hide_actions_button (GdauiEntryShell *shell, GdaValueAttribute attr)
+{
+ gboolean visible = FALSE;
+ if (shell->priv->editable) {
+ guint nb;
+ nb = compute_nb_possible_actions (shell, attr);
+ if (nb > 0)
+ visible = TRUE;
+ }
+ gtk_widget_set_visible (shell->priv->button, visible);
+}
+
+static guint
+compute_nb_possible_actions (GdauiEntryShell *shell, GdaValueAttribute attr)
+{
+ guint nb = 0;
+
+ if (attr & GDA_VALUE_ATTR_READ_ONLY)
+ return 0; /* no action possible */
+
+ if (!strcmp (gtk_stack_get_visible_child_name (GTK_STACK (shell->priv->stack)), PAGE_LABEL))
+ nb ++; /* "edit value" action */
+
+ if ((attr & GDA_VALUE_ATTR_CAN_BE_NULL) && !(attr & GDA_VALUE_ATTR_IS_NULL))
+ nb++;
+ if ((attr & GDA_VALUE_ATTR_CAN_BE_DEFAULT) && !(attr & GDA_VALUE_ATTR_IS_DEFAULT))
+ nb++;
+ if ((attr & GDA_VALUE_ATTR_HAS_VALUE_ORIG) && ! (attr & GDA_VALUE_ATTR_IS_UNCHANGED))
+ nb ++;
+ return nb;
+}
+
+static void
+actions_button_clicked_cb (G_GNUC_UNUSED GtkButton *button, GdauiEntryShell *shell)
+{
+ GdaValueAttribute attr;
+ attr = gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (shell));
+
+ if (attr & GDA_VALUE_ATTR_READ_ONLY)
+ g_assert_not_reached ();
+
+ shell->priv->being_edited = FALSE;
+ g_assert (compute_nb_possible_actions (shell, attr) != 0);
+
+ GtkWidget *pop;
+ pop = gtk_popover_new (GTK_WIDGET (button));
+ GtkWidget *box;
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_container_add (GTK_CONTAINER (pop), box);
+
+ GtkWidget *action_button;
+ if (!strcmp (gtk_stack_get_visible_child_name (GTK_STACK (shell->priv->stack)), PAGE_LABEL)) {
+ action_button = gtk_button_new_with_label (_("Edit value"));
+ g_signal_connect (action_button, "clicked",
+ G_CALLBACK (action_edit_value_cb), shell);
+ gtk_box_pack_start (GTK_BOX (box), action_button, FALSE, FALSE, 0);
+ }
+
+ if ((attr & GDA_VALUE_ATTR_CAN_BE_NULL) && !(attr & GDA_VALUE_ATTR_IS_NULL)) {
+ action_button = gtk_button_new_with_label (_("Set value to NULL"));
+ g_signal_connect (action_button, "clicked",
+ G_CALLBACK (action_set_value_to_null_cb), shell);
+ gtk_box_pack_start (GTK_BOX (box), action_button, FALSE, FALSE, 0);
+ }
+
+ if ((attr & GDA_VALUE_ATTR_CAN_BE_DEFAULT) && !(attr & GDA_VALUE_ATTR_IS_DEFAULT)) {
+ action_button = gtk_button_new_with_label (_("Set value to default"));
+ g_signal_connect (action_button, "clicked",
+ G_CALLBACK (action_set_value_to_default_cb), shell);
+ gtk_box_pack_start (GTK_BOX (box), action_button, FALSE, FALSE, 0);
+ }
+
+ if ((attr & GDA_VALUE_ATTR_HAS_VALUE_ORIG) && ! (attr & GDA_VALUE_ATTR_IS_UNCHANGED)) {
+ action_button = gtk_button_new_with_label (_("Reset value"));
+ g_signal_connect (action_button, "clicked",
+ G_CALLBACK (action_reset_value_cb), shell);
+ gtk_box_pack_start (GTK_BOX (box), action_button, FALSE, FALSE, 0);
+ }
+
+ g_signal_connect (pop, "closed", G_CALLBACK (gtk_widget_destroy), NULL);
+ gtk_widget_show_all (pop);
+}
+
+static void
+event_after_cb (GtkWidget *widget, GdkEvent *event, GdauiEntryShell *shell)
+{
+ if (((event->type == GDK_KEY_RELEASE) && (((GdkEventKey*) event)->keyval == GDK_KEY_Escape)) ||
+ ((event->type == GDK_FOCUS_CHANGE) && (((GdkEventFocus*) event)->in == FALSE))) {
+ shell->priv->being_edited = FALSE;
+#ifdef DEBUG
+ g_print ("EVENT AFTER: %s!\n", event->type == GDK_FOCUS_CHANGE ? "FOCUS" : "KEY RELEASE");
+#endif
+ if (!strcmp (gtk_stack_get_visible_child_name (GTK_STACK (shell->priv->stack)), PAGE_ENTRY)) {
+ GdaValueAttribute attr;
+ attr = gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (shell));
+ _gdaui_entry_shell_attrs_changed (shell, attr);
+ }
+ }
+}
+
+static gboolean
+label_event_cb (GtkWidget *widget, GdkEvent *event, GdauiEntryShell *shell)
+{
+ action_edit_value_cb (NULL, shell);
+ return FALSE;
}
static void
gdaui_entry_shell_init (GdauiEntryShell *shell)
{
- GtkWidget *button, *hbox, *arrow;
GValue *gval;
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (shell), GTK_ORIENTATION_HORIZONTAL);
+
/* Private structure */
shell->priv = g_new0 (GdauiEntryShellPriv, 1);
- shell->priv->embedder = NULL;
- shell->priv->button = NULL;
shell->priv->show_actions = TRUE;
shell->priv->data_handler = NULL;
-
- shell->priv->value_is_null = FALSE;
- shell->priv->value_is_modified = FALSE;
- shell->priv->value_is_default = FALSE;
- shell->priv->value_is_non_valid = FALSE;
+ shell->priv->editable = TRUE;
+ shell->priv->being_edited = FALSE;
shell->priv->is_cell_renderer = FALSE;
/* Setting the initial layout */
- gtk_viewport_set_shadow_type (GTK_VIEWPORT (shell), GTK_SHADOW_NONE);
+ shell->priv->stack = gtk_stack_new ();
+ gtk_box_pack_start (GTK_BOX (shell), shell->priv->stack, TRUE, TRUE, 0);
+ gtk_widget_show (shell->priv->stack);
gtk_container_set_border_width (GTK_CONTAINER (shell), 0);
- /* hbox */
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_container_add (GTK_CONTAINER (shell), hbox);
- gtk_widget_show (hbox);
- shell->priv->hbox = hbox;
-
- /* vbox to insert the real widget to edit data */
- shell->priv->embedder = widget_embedder_new ();
- gtk_box_pack_start (GTK_BOX (hbox), shell->priv->embedder, TRUE, TRUE, 0);
- gtk_widget_show (shell->priv->embedder);
-
- /* button to change the entry's state and to display that state */
- arrow = gtk_image_new_from_icon_name ("go-down-symbolic", GTK_ICON_SIZE_MENU);
- button = gtk_button_new ();
- gtk_style_context_add_class (gtk_widget_get_style_context (button), "action-entry");
- gtk_container_add (GTK_CONTAINER (button), arrow);
- gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
- shell->priv->button = button;
- gtk_widget_show_all (button);
-
- g_signal_connect (G_OBJECT (button), "event",
- G_CALLBACK (event_cb), shell);
-
- /* focus */
- gval = g_new0 (GValue, 1);
- g_value_init (gval, G_TYPE_BOOLEAN);
- g_value_set_boolean (gval, TRUE);
- g_object_set_property (G_OBJECT (button), "can-focus", gval);
- g_free (gval);
+ /* button */
+ shell->priv->button = gtk_button_new_with_label ("...");
+ gtk_button_set_relief (GTK_BUTTON (shell->priv->button), GTK_RELIEF_NONE);
+ gtk_style_context_add_class (gtk_widget_get_style_context (shell->priv->button), "action-entry");
+ g_object_set (G_OBJECT (shell->priv->button), "no-show-all", TRUE, NULL);
+ gtk_box_pack_start (GTK_BOX (shell), shell->priv->button, FALSE, FALSE, 0);
+ gtk_widget_show (shell->priv->button);
+ g_signal_connect (shell->priv->button, "clicked",
+ G_CALLBACK (actions_button_clicked_cb), shell);
+
+ /* label */
+ if (!messages) {
+ guint size, i;
+ size = G_N_ELEMENTS (raw_messages);
+ messages = g_new (gchar *, size);
+ for (i = 0; i < size; i++)
+ messages[i] = g_markup_printf_escaped ("<i>%s</i>", raw_messages[i]);
+ }
+ shell->priv->label = gtk_label_new ("");
+ gtk_widget_set_name (shell->priv->label, "invalid-label");
+ gtk_label_set_markup (GTK_LABEL (shell->priv->label), messages[MESSAGE_INVALID]);
+ gtk_widget_set_halign (shell->priv->label, GTK_ALIGN_START);
+ GtkWidget *evbox;
+ evbox = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (evbox), shell->priv->label);
+ gtk_widget_show_all (evbox);
+ gtk_stack_add_named (GTK_STACK (shell->priv->stack), evbox, PAGE_LABEL);
+
+ gdaui_entry_shell_set_invalid_color (shell, 1.0, 0., 0., 0.9);
+
+ g_signal_connect (evbox, "button-press-event",
+ G_CALLBACK (label_event_cb), shell);
}
static void
@@ -240,13 +443,6 @@ gdaui_entry_shell_set_property (GObject *object,
"(to be set using the 'handler' property) expect some
mis-behaviours"),
G_OBJECT_TYPE_NAME (object));
break;
- case PROP_ACTIONS:
- shell->priv->show_actions = g_value_get_boolean (value);
- if (shell->priv->show_actions)
- gtk_widget_show (shell->priv->button);
- else
- gtk_widget_hide (shell->priv->button);
- break;
case PROP_IS_CELL_RENDERER:
if (GTK_IS_CELL_EDITABLE (shell) &&
(g_value_get_boolean (value) != shell->priv->is_cell_renderer)) {
@@ -274,9 +470,6 @@ gdaui_entry_shell_get_property (GObject *object,
case PROP_HANDLER:
g_value_set_object (value, shell->priv->data_handler);
break;
- case PROP_ACTIONS:
- g_value_set_boolean (value, shell->priv->show_actions);
- break;
case PROP_IS_CELL_RENDERER:
g_value_set_boolean (value, shell->priv->is_cell_renderer);
break;
@@ -287,177 +480,34 @@ gdaui_entry_shell_get_property (GObject *object,
}
}
-
/**
* gdaui_entry_shell_pack_entry:
* @shell: a #GdauiEntryShell object
- * @main_widget: a #GtkWidget to pack into @shell
+ * @entry: a #GtkWidget to pack into @shell
*
- * Packs a #GTkWidget widget into the GdauiEntryShell.
+ * Packs a #GtkWidget widget into the @shell.
*/
void
-gdaui_entry_shell_pack_entry (GdauiEntryShell *shell, GtkWidget *main_widget)
+gdaui_entry_shell_pack_entry (GdauiEntryShell *shell, GtkWidget *entry)
{
g_return_if_fail (GDAUI_IS_ENTRY_SHELL (shell));
- g_return_if_fail (main_widget && GTK_IS_WIDGET (main_widget));
- gtk_container_add (GTK_CONTAINER (shell->priv->embedder), main_widget);
+ g_return_if_fail (GTK_IS_WIDGET (entry));
- /* signals */
- g_signal_connect (G_OBJECT (shell), "contents-modified",
- G_CALLBACK (contents_modified_cb), NULL);
-
- g_signal_connect (G_OBJECT (shell), "status-changed",
- G_CALLBACK (contents_modified_cb), NULL);
-}
-
-static void
-contents_modified_cb (GdauiEntryShell *shell, G_GNUC_UNUSED gpointer unused)
-{
- gdaui_entry_shell_refresh (shell);
-}
-
-static void mitem_activated_cb (GtkWidget *mitem, GdauiEntryShell *shell);
-static GdaValueAttribute gdaui_entry_shell_refresh_attributes (GdauiEntryShell *shell);
-static gint
-event_cb (G_GNUC_UNUSED GtkWidget *widget, GdkEvent *event, GdauiEntryShell *shell)
-{
- gboolean done = FALSE;
-
- if (!shell->priv->show_actions)
- return done;
-
- if (event->type == GDK_BUTTON_PRESS) {
- GdkEventButton *bevent = (GdkEventButton *) event;
- if ((bevent->button == 1) || (bevent->button == 3)) {
- GtkWidget *menu;
- guint attributes;
-
- attributes = gdaui_entry_shell_refresh_attributes (shell);
- menu = _gdaui_utility_entry_build_actions_menu (G_OBJECT (shell), attributes,
- G_CALLBACK (mitem_activated_cb));
- gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
- bevent->button, bevent->time);
- done = TRUE;
- }
+ /* real packing */
+ if (gtk_stack_get_child_by_name (GTK_STACK (shell->priv->stack), PAGE_ENTRY)) {
+ g_warning ("Implementation error: %s() has already been called for this GdauiEntryShell.",
+ __FUNCTION__);
+ return;
}
+ gtk_stack_add_named (GTK_STACK (shell->priv->stack), entry, PAGE_ENTRY);
- if (event->type == GDK_KEY_PRESS) {
- GtkWidget *menu;
- GdkEventKey *kevent = (GdkEventKey *) event;
-
- if (kevent->keyval == GDK_KEY_space) {
- guint attributes;
-
- attributes = gdaui_entry_shell_refresh_attributes (shell);
- menu = _gdaui_utility_entry_build_actions_menu (G_OBJECT (shell), attributes,
- G_CALLBACK (mitem_activated_cb));
-
- gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
- 0, kevent->time);
- done = TRUE;
- }
- else {
- if (kevent->keyval == GDK_KEY_Tab)
- done = FALSE;
- else
- done = TRUE;
- }
- }
-
- return done;
-}
-
-static void
-mitem_activated_cb (GtkWidget *mitem, GdauiEntryShell *shell)
-{
- guint action;
-
- action = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (mitem), "action"));
- gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (shell), action, action);
-}
-
-static void
-gdaui_entry_shell_refresh_status_display (GdauiEntryShell *shell)
-{
- static GdkRGBA **colors = NULL;
- GdkRGBA *normal = NULL, *prelight = NULL;
-
- g_return_if_fail (GDAUI_IS_ENTRY_SHELL (shell));
-
- if (!colors)
- colors = _gdaui_utility_entry_build_info_colors_array_a ();
-
- gtk_widget_set_tooltip_text (shell->priv->button, NULL);
-
- if (shell->priv->value_is_null) {
- normal = colors[0];
- prelight = colors[1];
- gtk_widget_set_tooltip_text (shell->priv->button, _("Value is NULL"));
- }
-
- if (shell->priv->value_is_default) {
- normal = colors[2];
- prelight = colors[3];
- gtk_widget_set_tooltip_text (shell->priv->button, _("Value will be determined by default"));
- }
-
- if (shell->priv->value_is_non_valid) {
- normal = colors[4];
- prelight = colors[5];
- gtk_widget_set_tooltip_text (shell->priv->button, _("Value is invalid"));
- }
-
- gtk_widget_override_background_color (shell->priv->button, GTK_STATE_FLAG_NORMAL, normal);
- gtk_widget_override_background_color (shell->priv->button, GTK_STATE_FLAG_ACTIVE, normal);
- gtk_widget_override_background_color (shell->priv->button, GTK_STATE_FLAG_PRELIGHT, prelight);
-}
-
-static GdaValueAttribute
-gdaui_entry_shell_refresh_attributes (GdauiEntryShell *shell)
-{
- GdaValueAttribute attrs;
-
- attrs = gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (shell));
- shell->priv->value_is_null = attrs & GDA_VALUE_ATTR_IS_NULL;
- shell->priv->value_is_modified = ! (attrs & GDA_VALUE_ATTR_IS_UNCHANGED);
- shell->priv->value_is_default = attrs & GDA_VALUE_ATTR_IS_DEFAULT;
- shell->priv->value_is_non_valid = attrs & GDA_VALUE_ATTR_DATA_NON_VALID;
-
- return attrs;
-}
-
-/**
- * gdaui_entry_shell_refresh:
- * @shell: the GdauiEntryShell widget to refresh
- *
- * Forces the shell to refresh its display (mainly the color of the
- * button).
- */
-void
-gdaui_entry_shell_refresh (GdauiEntryShell *shell)
-{
- g_return_if_fail (GDAUI_IS_ENTRY_SHELL (shell));
- gdaui_entry_shell_refresh_attributes (shell);
- gdaui_entry_shell_refresh_status_display (shell);
-}
-
-/**
- * gdaui_entry_shell_set_unknown:
- * @shell: the #GdauiEntryShell widget to refresh
- * @unknown: set to %TRUE if @shell's contents is unavailable and should not be modified
- *
- * Defines if @shell's contents is in an undefined state (shows or hides @shell's contents)
- */
-void
-gdaui_entry_shell_set_unknown (GdauiEntryShell *shell, gboolean unknown)
-{
- g_return_if_fail (GDAUI_IS_ENTRY_SHELL (shell));
-
- widget_embedder_set_valid ((WidgetEmbedder*) shell->priv->embedder, !unknown);
+ /* signals */
+ g_signal_connect_after (G_OBJECT (entry), "event-after",
+ G_CALLBACK (event_after_cb), shell);
}
/**
- * gdaui_entry_shell_set_ucolor:
+ * gdaui_entry_shell_set_invalid_color:
* @shell: a #GdauiEntryShell
* @red: the red component of a color
* @green: the green component of a color
@@ -470,9 +520,96 @@ gdaui_entry_shell_set_unknown (GdauiEntryShell *shell, gboolean unknown)
* Since: 5.0.3
*/
void
-gdaui_entry_shell_set_ucolor (GdauiEntryShell *shell, gdouble red, gdouble green,
- gdouble blue, gdouble alpha)
+gdaui_entry_shell_set_invalid_color (GdauiEntryShell *shell, gdouble red, gdouble green,
+ gdouble blue, gdouble alpha)
{
g_return_if_fail (GDAUI_IS_ENTRY_SHELL (shell));
- widget_embedder_set_ucolor ((WidgetEmbedder*) shell->priv->embedder, red, green, blue, alpha);
+ g_return_if_fail ((red >= 0.) && (red <= 1.));
+ g_return_if_fail ((green >= 0.) && (green <= 1.));
+ g_return_if_fail ((blue >= 0.) && (blue <= 1.));
+ g_return_if_fail ((alpha >= 0.) && (alpha <= 1.));
+
+ static GtkCssProvider *prov = NULL;
+ if (!prov) {
+ prov = gtk_css_provider_new ();
+ gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
+ GTK_STYLE_PROVIDER (prov),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ }
+
+#define BASE_CSS_FORMAT "@define-color gdaui_inv_color lighter (rgba (%u,%u,%u,0.%d));" \
+ ".invalid-entry #invalid-label {" \
+ "color: darker (@selected_fg_color);" \
+ "background-color: @gdaui_inv_color;" \
+ "border-width:1px;" \
+ "border-style:solid;" \
+ "border-radius:3px;" \
+ "border-color: @gdaui_inv_color;" \
+ "}" \
+ ".invalid-entry GtkEntry, .invalid-entry GtkButton, .invalid-entry GtkScrolledWindow,
.invalid-entry GtkSwitch {" \
+ "border-radius:3px;" \
+ "border-color: @gdaui_inv_color;" \
+ "border-width:1px;" \
+ "border-style:solid;" \
+ "}" \
+ ".invalid-entry GtkLabel {" \
+ "color: @gdaui_inv_color;" \
+ "}"
+
+ gchar *css;
+ css = g_strdup_printf (BASE_CSS_FORMAT, (guint) (red * 255), (guint) (green * 255),
+ (guint) (blue * 255), (gint) (alpha * 100));
+ gtk_css_provider_load_from_data (prov, css, -1, NULL);
+ g_free (css);
+}
+
+void
+_gdaui_entry_shell_mark_editable (GdauiEntryShell *shell, gboolean editable)
+{
+
+ if (editable != shell->priv->editable) {
+ shell->priv->editable = editable;
+ _gdaui_entry_shell_attrs_changed (shell,
+ gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (shell)));
+ }
+}
+
+/*
+ * Call this function to inform @shell that it may need to refresh its UI settings.
+ */
+void
+_gdaui_entry_shell_attrs_changed (GdauiEntryShell *shell, GdaValueAttribute attr)
+{
+
+ MessageType msg = MESSAGE_NONE;
+ if (value_is_valid (attr)) {
+ if (value_is_null (attr)) {
+ if (value_is_default (attr))
+ msg = MESSAGE_DEFAULT_AND_NULL;
+ else
+ msg = MESSAGE_NULL;
+ }
+ else if (value_is_default (attr))
+ msg = MESSAGE_DEFAULT;
+ }
+ else
+ msg = MESSAGE_INVALID;
+
+ if (! shell->priv->being_edited) {
+ gtk_label_set_markup (GTK_LABEL (shell->priv->label), messages[msg]);
+ if ((msg == MESSAGE_NONE) ||
+ ((msg == MESSAGE_INVALID) && ! (attr & GDA_VALUE_ATTR_READ_ONLY)))
+ gtk_stack_set_visible_child_name (GTK_STACK (shell->priv->stack), PAGE_ENTRY);
+ else
+ gtk_stack_set_visible_child_name (GTK_STACK (shell->priv->stack), PAGE_LABEL);
+ }
+
+ if (msg == MESSAGE_INVALID)
+ gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (shell)),
+ "invalid-entry");
+ else
+ gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (shell)),
+ "invalid-entry");
+
+ show_or_hide_actions_button (shell, attr);
}
diff --git a/libgda-ui/data-entries/gdaui-entry-shell.h b/libgda-ui/data-entries/gdaui-entry-shell.h
index 92cea9e..38488a3 100644
--- a/libgda-ui/data-entries/gdaui-entry-shell.h
+++ b/libgda-ui/data-entries/gdaui-entry-shell.h
@@ -42,7 +42,7 @@ typedef struct _GdauiEntryShellPriv GdauiEntryShellPriv;
/* struct for the object's data */
struct _GdauiEntryShell
{
- GtkViewport object;
+ GtkBox object;
GdauiEntryShellPriv *priv;
};
@@ -50,17 +50,18 @@ struct _GdauiEntryShell
/* struct for the object's class */
struct _GdauiEntryShellClass
{
- GtkViewportClass parent_class;
+ GtkBoxClass parent_class;
};
-GType gdaui_entry_shell_get_type (void) G_GNUC_CONST;
-void gdaui_entry_shell_pack_entry (GdauiEntryShell *shell, GtkWidget *main_widget);
-void gdaui_entry_shell_refresh (GdauiEntryShell *shell);
-void gdaui_entry_shell_set_unknown (GdauiEntryShell *shell, gboolean unknown);
-void gdaui_entry_shell_set_ucolor (GdauiEntryShell *shell, gdouble red, gdouble green,
- gdouble blue, gdouble alpha);
+GType gdaui_entry_shell_get_type (void) G_GNUC_CONST;
+void gdaui_entry_shell_pack_entry (GdauiEntryShell *shell, GtkWidget *entry);
+void gdaui_entry_shell_set_invalid_color (GdauiEntryShell *shell, gdouble red, gdouble green,
+ gdouble blue, gdouble alpha);
+/* private */
+void _gdaui_entry_shell_mark_editable (GdauiEntryShell *shell, gboolean editable);
+void _gdaui_entry_shell_attrs_changed (GdauiEntryShell *shell, GdaValueAttribute attr);
G_END_DECLS
diff --git a/libgda-ui/data-entries/gdaui-entry-string.c b/libgda-ui/data-entries/gdaui-entry-string.c
index 8935963..2eecf00 100644
--- a/libgda-ui/data-entries/gdaui-entry-string.c
+++ b/libgda-ui/data-entries/gdaui-entry-string.c
@@ -87,8 +87,6 @@ struct _GdauiEntryStringPrivate
GtkWidget *view;
gint maxsize;
-
- gulong entry_change_sig;
};
static void
@@ -182,8 +180,6 @@ gdaui_entry_string_init (GdauiEntryString *mgstr)
mgstr->priv->maxsize = 65535; /* eg. unlimited for GtkEntry */
- mgstr->priv->entry_change_sig = 0;
-
g_signal_connect (mgstr, "key-press-event",
G_CALLBACK (key_press_event_cb), NULL);
}
@@ -192,8 +188,9 @@ gdaui_entry_string_init (GdauiEntryString *mgstr)
* gdaui_entry_string_new:
* @dh: the data handler to be used by the new widget
* @type: the requested data type (compatible with @dh)
+ * @options: (allow-none): some options formatting the new entry, or %NULL
*
- * Creates a new data entry widget
+ * Creates a new data entry widget. Known options are: MAX_SIZE, MULTILINE, and HIDDEN
*
* Returns: (transfer full): the new widget
*/
@@ -320,6 +317,13 @@ gdaui_entry_string_get_property (GObject *object,
}
static void widget_shown_cb (GtkWidget *wid, GdauiEntryString *mgstr);
+static void
+ev_cb (GtkWidget *wid, GdkEvent *event, GObject *obj)
+{
+ /* see /usr/include/gtk-3.0/gdk/gdkevents.h */
+ if ((event->type == GDK_FOCUS_CHANGE) && !((GdkEventFocus*)event)->in)
+ g_signal_emit_by_name (obj, "event-after", event);
+}
static GtkWidget *
create_entry (GdauiEntryWrapper *mgwrap)
@@ -332,7 +336,9 @@ create_entry (GdauiEntryWrapper *mgwrap)
g_return_val_if_fail (mgstr->priv, NULL);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_widget_set_hexpand (GTK_WIDGET (mgwrap), TRUE);
mgstr->priv->vbox = vbox;
+ gtk_widget_add_events (vbox, GDK_FOCUS_CHANGE_MASK);
/* one line entry */
mgstr->priv->entry = gdaui_entry_new (NULL, NULL);
@@ -343,6 +349,7 @@ create_entry (GdauiEntryWrapper *mgwrap)
/* multiline entry */
mgstr->priv->view = gtk_text_view_new ();
+ gtk_widget_set_vexpand (mgstr->priv->view, TRUE);
mgstr->priv->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (mgstr->priv->view));
mgstr->priv->sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (mgstr->priv->sw), GTK_SHADOW_IN);
@@ -355,11 +362,14 @@ create_entry (GdauiEntryWrapper *mgwrap)
g_signal_connect_after (G_OBJECT (mgstr->priv->sw), "show",
G_CALLBACK (widget_shown_cb), mgstr);
-
- /* show widgets if they need to be shown */
+ /* mark both widgets to be shown */
gtk_widget_show (mgstr->priv->entry);
gtk_widget_show (mgstr->priv->sw);
+ g_signal_connect (mgstr->priv->entry, "event-after",
+ G_CALLBACK (ev_cb), vbox);
+ g_signal_connect (mgstr->priv->view, "event-after",
+ G_CALLBACK (ev_cb), vbox);
return vbox;
}
@@ -465,13 +475,13 @@ connect_signals(GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activa
mgstr = GDAUI_ENTRY_STRING (mgwrap);
g_return_if_fail (mgstr->priv);
- mgstr->priv->entry_change_sig = g_signal_connect (G_OBJECT (mgstr->priv->entry), "changed",
- modify_cb, mgwrap);
- g_signal_connect (G_OBJECT (mgstr->priv->entry), "activate",
- activate_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgstr->priv->entry), "changed",
+ modify_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgstr->priv->entry), "activate",
+ activate_cb, mgwrap);
- g_signal_connect (G_OBJECT (mgstr->priv->buffer), "changed",
- modify_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgstr->priv->buffer), "changed",
+ modify_cb, mgwrap);
/* FIXME: how does the user "activates" the GtkTextView widget ? */
}
@@ -541,7 +551,6 @@ gdaui_entry_string_start_editing (GtkCellEditable *iface, GdkEvent *event)
G_CALLBACK (gtk_cell_editable_entry_editing_done_cb), mgstr);
g_signal_connect (mgstr->priv->entry, "remove-widget",
G_CALLBACK (gtk_cell_editable_entry_remove_widget_cb), mgstr);
- gdaui_entry_shell_refresh (GDAUI_ENTRY_SHELL (mgstr));
gtk_widget_grab_focus (mgstr->priv->entry);
gtk_widget_queue_draw (GTK_WIDGET (mgstr));
diff --git a/libgda-ui/data-entries/gdaui-entry-string.xml.in
b/libgda-ui/data-entries/gdaui-entry-string.xml.in
index 640bc0e..19d7a4a 100644
--- a/libgda-ui/data-entries/gdaui-entry-string.xml.in
+++ b/libgda-ui/data-entries/gdaui-entry-string.xml.in
@@ -1,8 +1,10 @@
<?xml version="1.0"?>
<data-set-spec>
<parameters>
- <parameter id="MAX_SIZE" _name="Maximum length" _descr="Maximum acceptable length of the text"
gdatype="gint"/>
- <parameter id="MULTILINE" _name="Multiline" _descr="Display only one line, or a complete text editor"
gdatype="gboolean"/>
- <parameter id="HIDDEN" _name="Hidden" _descr="If set to TRUE, characters are all displayed using a
single 'invisible' character, suitable to enter passwords" gdatype="gboolean"/>
+ <parameter id="MAX_SIZE" _name="Maximum length" _descr="Maximum acceptable length of the text"
gdatype="gint" nullok="TRUE"/>
+ <parameter id="MULTILINE" _name="Multiline" _descr="Display only one line, or a complete text editor"
gdatype="gboolean" nullok="TRUE"/>
+ <parameter id="HIDDEN" _name="Hidden" _descr="If set to TRUE, characters are all displayed using a
single 'invisible' character, suitable to enter passwords" gdatype="gboolean" nullok="TRUE">
+ <gda_value>FALSE</gda_value>
+ </parameter>
</parameters>
</data-set-spec>
diff --git a/libgda-ui/data-entries/gdaui-entry-wrapper.c b/libgda-ui/data-entries/gdaui-entry-wrapper.c
index 8090f13..a744fbb 100644
--- a/libgda-ui/data-entries/gdaui-entry-wrapper.c
+++ b/libgda-ui/data-entries/gdaui-entry-wrapper.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 - 2012 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2009 - 2015 Vivien Malerba <malerba gnome-db org>
* Copyright (C) 2010 David King <davidk openismus com>
* Copyright (C) 2011 Murray Cumming <murrayc murrayc com>
*
@@ -23,6 +23,8 @@
#include <libgda/gda-data-handler.h>
#include <libgda/gda-enums.h>
+/*#define DEBUG*/
+
static void gdaui_entry_wrapper_class_init (GdauiEntryWrapperClass *klass);
static void gdaui_entry_wrapper_init (GdauiEntryWrapper *wid);
static void gdaui_entry_wrapper_dispose (GObject *object);
@@ -36,8 +38,8 @@ static void gdaui_entry_wrapper_get_property (GObject *object,
GValue *value,
GParamSpec *pspec);
-static void contents_changed_cb (GtkWidget *entry, GdauiEntryWrapper *wrapper);
-static void contents_activated_cb (GtkWidget *entry, GdauiEntryWrapper *wrapper);
+static void contents_changed_cb (GdauiEntryWrapper *wrapper);
+static void contents_activated_cb (GdauiEntryWrapper *wrapper);
static void check_correct_init (GdauiEntryWrapper *wid);
static void block_signals (GdauiEntryWrapper *wid);
static void unblock_signals (GdauiEntryWrapper *wid);
@@ -79,9 +81,9 @@ struct _GdauiEntryWrapperPriv {
gboolean null_forced;
gboolean default_forced;
+ gboolean invalid;
gboolean null_possible;
gboolean default_possible;
- gboolean show_actions;
gboolean editable;
gboolean contents_has_changed; /* since this variable was reset */
@@ -175,22 +177,28 @@ check_correct_init (GdauiEntryWrapper *wrapper)
klass = GDAUI_ENTRY_WRAPPER_CLASS (G_OBJECT_GET_CLASS (wrapper));
if (! klass->create_entry) {
- g_warning ("create_entry () virtual function not implemented for object class %s\n",
+ g_warning ("create_entry () virtual function not implemented for object class %s",
G_OBJECT_TYPE_NAME (wrapper));
class_impl_error = TRUE;
}
if (! klass->real_set_value) {
- g_warning ("real_set_value () virtual function not implemented for object class %s\n",
+ g_warning ("real_set_value () virtual function not implemented for object class %s",
G_OBJECT_TYPE_NAME (wrapper));
class_impl_error = TRUE;
}
if (! klass->real_get_value) {
- g_warning ("real_get_value () virtual function not implemented for object class %s\n",
+ g_warning ("real_get_value () virtual function not implemented for object class %s",
G_OBJECT_TYPE_NAME (wrapper));
class_impl_error = TRUE;
}
if (! klass->connect_signals) {
- g_warning ("connect_signals () virtual function not implemented for object class
%s\n",
+ g_warning ("connect_signals () virtual function not implemented for object class %s",
+ G_OBJECT_TYPE_NAME (wrapper));
+ class_impl_error = TRUE;
+ }
+ if ((klass->value_is_null && !klass->value_is_equal_to) ||
+ (!klass->value_is_null && klass->value_is_equal_to)) {
+ g_warning ("value_is_null() and value_is_equal_to() virtuals functions must eithe
both be implemented for object class %s, or none must be implemented",
G_OBJECT_TYPE_NAME (wrapper));
class_impl_error = TRUE;
}
@@ -205,7 +213,7 @@ check_correct_init (GdauiEntryWrapper *wrapper)
wrapper->priv->entry = entry;
(*wrapper->priv->real_class->connect_signals) (wrapper, G_CALLBACK
(contents_changed_cb),
- G_CALLBACK (contents_activated_cb));
+ G_CALLBACK (contents_activated_cb));
}
else {
/* we need to exit because the program WILL BE unstable and WILL crash */
@@ -244,9 +252,9 @@ gdaui_entry_wrapper_init (GdauiEntryWrapper *wrapper)
wrapper->priv->null_forced = FALSE;
wrapper->priv->default_forced = FALSE;
+ wrapper->priv->invalid = FALSE;
wrapper->priv->null_possible = TRUE;
wrapper->priv->default_possible = FALSE;
- wrapper->priv->show_actions = TRUE;
wrapper->priv->editable = TRUE;
wrapper->priv->contents_has_changed = FALSE;
@@ -347,7 +355,7 @@ gdaui_entry_wrapper_contents_changed (GdauiEntryWrapper *wrapper)
{
g_return_if_fail (GDAUI_IS_ENTRY_WRAPPER (wrapper));
- contents_changed_cb (NULL, wrapper);
+ contents_changed_cb (wrapper);
}
/**
@@ -362,15 +370,17 @@ gdaui_entry_wrapper_contents_activated (GdauiEntryWrapper *wrapper)
{
g_return_if_fail (GDAUI_IS_ENTRY_WRAPPER (wrapper));
- contents_activated_cb (NULL, wrapper);
+ contents_activated_cb (wrapper);
}
static void gdaui_entry_wrapper_emit_signal (GdauiEntryWrapper *wrapper);
static void
-contents_changed_cb (G_GNUC_UNUSED GtkWidget *entry, GdauiEntryWrapper *wrapper)
+contents_changed_cb (GdauiEntryWrapper *wrapper)
{
- /* @entry is not used */
+#ifdef DEBUG
+ g_print ("%s(%p)\n", __FUNCTION__, wrapper);
+#endif
if (! wrapper->priv->signals_blocked) {
wrapper->priv->null_forced = FALSE;
wrapper->priv->default_forced = FALSE;
@@ -380,34 +390,25 @@ contents_changed_cb (G_GNUC_UNUSED GtkWidget *entry, GdauiEntryWrapper *wrapper)
}
static void
-contents_activated_cb (G_GNUC_UNUSED GtkWidget *entry, GdauiEntryWrapper *wrapper)
+contents_activated_cb (GdauiEntryWrapper *wrapper)
{
- /* @entry is not used */
+#ifdef DEBUG
+ g_print ("%s(%p)\n", __FUNCTION__, wrapper);
+#endif
if (! wrapper->priv->signals_blocked) {
wrapper->priv->null_forced = FALSE;
wrapper->priv->default_forced = FALSE;
-#ifdef debug_signal
- g_print (">> 'CONTENTS_ACTIVATED' from %s\n", __FUNCTION__);
-#endif
g_signal_emit_by_name (G_OBJECT (wrapper), "contents-activated");
-#ifdef debug_signal
- g_print ("<< 'CONTENTS_ACTIVATED' from %s\n", __FUNCTION__);
-#endif
}
}
static void
gdaui_entry_wrapper_emit_signal (GdauiEntryWrapper *wrapper)
{
- if (! wrapper->priv->signals_blocked) {
-#ifdef debug_signal
- g_print (">> 'CONTENTS_MODIFIED' from %s\n", __FUNCTION__);
-#endif
+ if (! wrapper->priv->signals_blocked)
g_signal_emit_by_name (G_OBJECT (wrapper), "contents-modified");
-#ifdef debug_signal
- g_print ("<< 'CONTENTS_MODIFIED' from %s\n", __FUNCTION__);
-#endif
- }
+ _gdaui_entry_shell_attrs_changed (GDAUI_ENTRY_SHELL (wrapper),
+ gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (wrapper)));
}
@@ -528,13 +529,13 @@ gdaui_entry_wrapper_set_ref_value (GdauiDataEntry *iface, const GValue *value)
changed = ! wrapper->priv->real_class->value_is_equal_to (wrapper, value);
else {
evalue = gdaui_entry_wrapper_get_value (iface);
+ g_assert (evalue);
if ((!value || (G_VALUE_TYPE (value) == GDA_TYPE_NULL)) &&
- (!evalue || (G_VALUE_TYPE (evalue) == GDA_TYPE_NULL)))
+ (G_VALUE_TYPE (evalue) == GDA_TYPE_NULL))
changed = FALSE;
else if (!gda_value_differ ((GValue *) value, evalue))
changed = FALSE;
- if (evalue)
- gda_value_free (evalue);
+ gda_value_free (evalue);
}
/* get rid on any existing orig value */
@@ -595,13 +596,12 @@ gdaui_entry_wrapper_set_value_default (GdauiDataEntry *iface, const GValue *valu
gdaui_entry_wrapper_set_value (iface, wrapper->priv->value_default);
unblock_signals (wrapper);
wrapper->priv->default_forced = TRUE;
- gdaui_entry_wrapper_emit_signal (wrapper);
}
else {
check_correct_init (wrapper);
(*wrapper->priv->real_class->real_set_value) (wrapper, NULL);
- gdaui_entry_wrapper_emit_signal (wrapper);
}
+ gdaui_entry_wrapper_emit_signal (wrapper);
}
}
@@ -609,17 +609,42 @@ static void
gdaui_entry_wrapper_set_attributes (GdauiDataEntry *iface, GdaValueAttribute attrs, guint mask)
{
GdauiEntryWrapper *wrapper;
- gboolean signal_contents_changed = FALSE;
+ gboolean do_signal = FALSE;
g_return_if_fail (GDAUI_IS_ENTRY_WRAPPER (iface));
wrapper = (GdauiEntryWrapper*) iface;
check_correct_init (wrapper);
+#ifdef DEBUG
+ g_print ("%s (%p): %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", __FUNCTION__, iface,
+ (mask & GDA_VALUE_ATTR_IS_NULL) ? "IS_NULL:" : "",
+ (mask & GDA_VALUE_ATTR_IS_NULL) ? ((attrs & GDA_VALUE_ATTR_IS_NULL) ? "X" : ".") : "",
+ (mask & GDA_VALUE_ATTR_CAN_BE_NULL) ? "CAN_BE_NULL:" : "",
+ (mask & GDA_VALUE_ATTR_CAN_BE_NULL) ? ((attrs & GDA_VALUE_ATTR_CAN_BE_NULL) ? "X" : ".") :
"",
+ (mask & GDA_VALUE_ATTR_IS_DEFAULT) ? "IS_DEFAULT:" : "",
+ (mask & GDA_VALUE_ATTR_IS_DEFAULT) ? ((attrs & GDA_VALUE_ATTR_IS_DEFAULT) ? "X" : ".") : "",
+ (mask & GDA_VALUE_ATTR_CAN_BE_DEFAULT) ? "CAN_BE_DEFAULT:" : "",
+ (mask & GDA_VALUE_ATTR_CAN_BE_DEFAULT) ? ((attrs & GDA_VALUE_ATTR_CAN_BE_DEFAULT) ? "X" :
".") : "",
+ (mask & GDA_VALUE_ATTR_IS_UNCHANGED) ? "IS_UNCHANGED:" : "",
+ (mask & GDA_VALUE_ATTR_IS_UNCHANGED) ? ((attrs & GDA_VALUE_ATTR_IS_UNCHANGED) ? "X" : ".") :
"",
+ (mask & GDA_VALUE_ATTR_DATA_NON_VALID) ? "NON_VALID:" : "",
+ (mask & GDA_VALUE_ATTR_DATA_NON_VALID) ? ((attrs & GDA_VALUE_ATTR_DATA_NON_VALID) ? "X" :
".") : "",
+ (mask & GDA_VALUE_ATTR_READ_ONLY) ? "READ_ONLY:" : "",
+ (mask & GDA_VALUE_ATTR_READ_ONLY) ? ((attrs & GDA_VALUE_ATTR_READ_ONLY) ? "X" : ".") : "",
+ (mask & GDA_VALUE_ATTR_HAS_VALUE_ORIG) ? "HAS_VALUE_ORIG:" : "",
+ (mask & GDA_VALUE_ATTR_HAS_VALUE_ORIG) ? ((attrs & GDA_VALUE_ATTR_HAS_VALUE_ORIG) ? "X" :
".") : "");
+#endif
+
+ /* Can be NULL ? */
+ if (mask & GDA_VALUE_ATTR_CAN_BE_NULL)
+ wrapper->priv->null_possible = (attrs & GDA_VALUE_ATTR_CAN_BE_NULL) ? TRUE : FALSE;
+
+ /* Can be DEFAULT ? */
+ if (mask & GDA_VALUE_ATTR_CAN_BE_DEFAULT)
+ wrapper->priv->default_possible = (attrs & GDA_VALUE_ATTR_CAN_BE_DEFAULT) ? TRUE : FALSE;
+
/* Setting to NULL */
if (mask & GDA_VALUE_ATTR_IS_NULL) {
- if ((mask & GDA_VALUE_ATTR_CAN_BE_NULL) &&
- !(attrs & GDA_VALUE_ATTR_CAN_BE_NULL))
- g_return_if_reached ();
if (attrs & GDA_VALUE_ATTR_IS_NULL) {
block_signals (wrapper);
gdaui_entry_wrapper_set_value (iface, NULL);
@@ -627,91 +652,74 @@ gdaui_entry_wrapper_set_attributes (GdauiDataEntry *iface, GdaValueAttribute att
wrapper->priv->null_forced = TRUE;
/* if default is set, see if we can keep it that way */
- if (wrapper->priv->default_forced) {
- if (G_VALUE_TYPE (wrapper->priv->value_default) !=
- GDA_TYPE_NULL) {
+ if (wrapper->priv->default_forced &&
+ (G_VALUE_TYPE (wrapper->priv->value_default) != GDA_TYPE_NULL))
wrapper->priv->default_forced = FALSE;
- }
- }
}
else
wrapper->priv->null_forced = FALSE;
- signal_contents_changed = TRUE;
+ do_signal = TRUE;
}
- /* Can be NULL ? */
- if (mask & GDA_VALUE_ATTR_CAN_BE_NULL)
- wrapper->priv->null_possible = (attrs & GDA_VALUE_ATTR_CAN_BE_NULL) ? TRUE : FALSE;
-
/* Setting to DEFAULT */
- guint current = gdaui_data_entry_get_attributes (iface);
if (mask & GDA_VALUE_ATTR_IS_DEFAULT) {
- if (! (current & GDA_VALUE_ATTR_CAN_BE_DEFAULT))
- g_warning ("Data entry does not have a default value");
if (attrs & GDA_VALUE_ATTR_IS_DEFAULT) {
- block_signals (wrapper);
- if (wrapper->priv->value_default) {
- if (G_VALUE_TYPE (wrapper->priv->value_default) == wrapper->priv->type)
- gdaui_entry_wrapper_set_value (iface, wrapper->priv->value_default);
- else
- (*wrapper->priv->real_class->real_set_value) (wrapper, NULL);
+ if (! wrapper->priv->default_possible) {
+ g_warning ("Data entry does not have a default value");
+ wrapper->priv->default_forced = FALSE;
}
- else
- gdaui_entry_wrapper_set_value (iface, NULL);
- unblock_signals (wrapper);
+ else {
+ block_signals (wrapper);
+ if (wrapper->priv->value_default) {
+ if (G_VALUE_TYPE (wrapper->priv->value_default) ==
wrapper->priv->type)
+ gdaui_entry_wrapper_set_value (iface,
wrapper->priv->value_default);
+ else
+ (*wrapper->priv->real_class->real_set_value) (wrapper, NULL);
+ }
+ else
+ gdaui_entry_wrapper_set_value (iface, NULL);
+ unblock_signals (wrapper);
- /* if NULL is set, see if we can keep it that way */
- if (wrapper->priv->null_forced) {
- if (G_VALUE_TYPE (wrapper->priv->value_default) !=
- GDA_TYPE_NULL)
+ /* if NULL is set, see if we can keep it that way */
+ if (wrapper->priv->null_forced &&
+ (G_VALUE_TYPE (wrapper->priv->value_default) != GDA_TYPE_NULL))
wrapper->priv->null_forced = FALSE;
+ wrapper->priv->default_forced = TRUE;
}
-
- wrapper->priv->default_forced = TRUE;
}
else
wrapper->priv->default_forced = FALSE;
- signal_contents_changed = TRUE;
+ do_signal = TRUE;
}
- /* Can be DEFAULT ? */
- if (mask & GDA_VALUE_ATTR_CAN_BE_DEFAULT)
- wrapper->priv->default_possible = (attrs & GDA_VALUE_ATTR_CAN_BE_DEFAULT) ? TRUE : FALSE;
-
- /* Modified ? */
+ /* Reset value to original */
if (mask & GDA_VALUE_ATTR_IS_UNCHANGED) {
if (attrs & GDA_VALUE_ATTR_IS_UNCHANGED) {
wrapper->priv->default_forced = FALSE;
block_signals (wrapper);
gdaui_entry_wrapper_set_value (iface, wrapper->priv->value_ref);
unblock_signals (wrapper);
- signal_contents_changed = TRUE;
+ do_signal = TRUE;
}
}
- /* Actions buttons ? */
- if (mask & GDA_VALUE_ATTR_ACTIONS_SHOWN) {
- GValue *gval;
- wrapper->priv->show_actions = (attrs & GDA_VALUE_ATTR_ACTIONS_SHOWN) ? TRUE : FALSE;
+ /* invalid data */
+ if (mask & GDA_VALUE_ATTR_DATA_NON_VALID)
+ wrapper->priv->invalid = attrs & GDA_VALUE_ATTR_DATA_NON_VALID;
- gval = g_new0 (GValue, 1);
- g_value_init (gval, G_TYPE_BOOLEAN);
- g_value_set_boolean (gval, wrapper->priv->show_actions);
- g_object_set_property (G_OBJECT (wrapper), "actions", gval);
- g_free (gval);
- }
+ /* editable */
+ if (mask & GDA_VALUE_ATTR_READ_ONLY)
+ gdaui_entry_wrapper_set_editable (GDAUI_DATA_ENTRY (wrapper), attrs &
GDA_VALUE_ATTR_READ_ONLY);
/* NON WRITABLE attributes */
- if (mask & GDA_VALUE_ATTR_DATA_NON_VALID)
- g_warning ("Can't force a GdauiDataEntry to be invalid!");
-
if (mask & GDA_VALUE_ATTR_HAS_VALUE_ORIG)
- g_warning ("Having an original value is not a write attribute on GdauiDataEntry!");
+ g_warning ("Use gdaui_entry_wrapper_set_value_default() instead of
GDA_VALUE_ATTR_HAS_VALUE_ORIG");
- current = gdaui_data_entry_get_attributes (iface);
+ _gdaui_entry_shell_attrs_changed (GDAUI_ENTRY_SHELL (wrapper),
+ gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (wrapper)));
- if (signal_contents_changed) {
+ if (do_signal) {
wrapper->priv->contents_has_changed = FALSE;
gdaui_entry_wrapper_emit_signal (wrapper);
}
@@ -724,24 +732,36 @@ gdaui_entry_wrapper_get_attributes (GdauiDataEntry *iface)
GdaValueAttribute retval = 0;
GdauiEntryWrapper *wrapper;
GValue *value = NULL;
- gboolean has_current_value;
- gboolean value_is_null = FALSE;
g_return_val_if_fail (GDAUI_IS_ENTRY_WRAPPER (iface), 0);
wrapper = (GdauiEntryWrapper*) iface;
check_correct_init (wrapper);
+
+ gboolean specific_impl = TRUE;
if (!wrapper->priv->real_class->value_is_equal_to ||
!wrapper->priv->real_class->value_is_null) {
- value = gdaui_entry_wrapper_get_value (iface);
- has_current_value = TRUE;
+ value = gdaui_entry_wrapper_get_value (iface); /* @value may NOT be @NULL ! */
+ g_assert (value);
+ specific_impl = FALSE;
}
- else
- has_current_value = FALSE;
+
+ /* can be NULL? */
+ if (wrapper->priv->null_possible)
+ retval |= GDA_VALUE_ATTR_CAN_BE_NULL;
+
+ /* can be default? */
+ if (wrapper->priv->default_possible)
+ retval |= GDA_VALUE_ATTR_CAN_BE_DEFAULT;
/* NULL? */
- if (has_current_value) {
- if ((value && (G_VALUE_TYPE (value) == GDA_TYPE_NULL)) || !value) {
+ gboolean value_is_null = FALSE;
+ if (specific_impl) {
+ if ((wrapper->priv->real_class->value_is_null) (wrapper))
+ value_is_null = TRUE;
+ }
+ else {
+ if (G_VALUE_TYPE (value) == GDA_TYPE_NULL) {
if (wrapper->priv->default_forced) {
if (wrapper->priv->null_forced)
value_is_null = TRUE;
@@ -750,61 +770,52 @@ gdaui_entry_wrapper_get_attributes (GdauiDataEntry *iface)
value_is_null = TRUE;
}
}
- else {
- if ((wrapper->priv->real_class->value_is_null) (wrapper))
- value_is_null = TRUE;
- }
if (value_is_null)
- retval = retval | GDA_VALUE_ATTR_IS_NULL;
-
- /* can be NULL? */
- if (wrapper->priv->null_possible)
- retval = retval | GDA_VALUE_ATTR_CAN_BE_NULL;
+ retval |= GDA_VALUE_ATTR_IS_NULL;
/* is default */
if (wrapper->priv->default_forced)
- retval = retval | GDA_VALUE_ATTR_IS_DEFAULT;
-
- /* can be default? */
- if (wrapper->priv->default_possible)
- retval = retval | GDA_VALUE_ATTR_CAN_BE_DEFAULT;
-
- /* is unchanged */
- if (has_current_value) {
- if (wrapper->priv->value_ref &&
- (G_VALUE_TYPE (value) == G_VALUE_TYPE (wrapper->priv->value_ref))) {
- if (gda_value_is_null (value))
- retval = retval | GDA_VALUE_ATTR_IS_UNCHANGED;
- else {
+ retval |= GDA_VALUE_ATTR_IS_DEFAULT;
+ else {
+ /* is unchanged */
+ if (wrapper->priv->value_ref) {
+ if (specific_impl) {
+ if ((wrapper->priv->real_class->value_is_equal_to) (wrapper,
wrapper->priv->value_ref))
+ retval |= GDA_VALUE_ATTR_IS_UNCHANGED;
+ }
+ else if (G_VALUE_TYPE (value) == G_VALUE_TYPE (wrapper->priv->value_ref)) {
if (! gda_value_differ (value, wrapper->priv->value_ref))
- retval = retval | GDA_VALUE_ATTR_IS_UNCHANGED;
+ retval |= GDA_VALUE_ATTR_IS_UNCHANGED;
}
}
}
- else if ((wrapper->priv->real_class->value_is_equal_to) (wrapper, wrapper->priv->value_ref))
- retval = retval | GDA_VALUE_ATTR_IS_UNCHANGED;
-
- /* actions shown */
- if (wrapper->priv->show_actions)
- retval = retval | GDA_VALUE_ATTR_ACTIONS_SHOWN;
/* data valid? */
- if (! (wrapper->priv->default_forced && wrapper->priv->default_possible)) {
- if (/*(value_is_null && !wrapper->priv->null_forced) ||*/
- (value_is_null && !wrapper->priv->null_possible))
- retval = retval | GDA_VALUE_ATTR_DATA_NON_VALID;
- }
+ if (wrapper->priv->invalid ||
+ (value_is_null && !wrapper->priv->null_possible))
+ retval |= GDA_VALUE_ATTR_DATA_NON_VALID;
/* has original value? */
if (wrapper->priv->value_ref)
- retval = retval | GDA_VALUE_ATTR_HAS_VALUE_ORIG;
+ retval |= GDA_VALUE_ATTR_HAS_VALUE_ORIG;
- if (has_current_value)
- gda_value_free (value);
+ gda_value_free (value);
+ /* editable ? */
if (!wrapper->priv->editable)
- retval = retval | GDA_VALUE_ATTR_NO_MODIF;
-
+ retval |= GDA_VALUE_ATTR_READ_ONLY;
+
+#ifdef DEBUG
+ g_print ("%s (%p): %s%s%s%s%s%s%s%s\n", __FUNCTION__, iface,
+ (retval & GDA_VALUE_ATTR_IS_NULL) ? "IS_NULL " : " ",
+ (retval & GDA_VALUE_ATTR_CAN_BE_NULL) ? "CAN_BE_NULL " : " ",
+ (retval & GDA_VALUE_ATTR_IS_DEFAULT) ? "IS_DEFAULT " : " ",
+ (retval & GDA_VALUE_ATTR_CAN_BE_DEFAULT) ? "CAN_BE_DEFAULT " : " ",
+ (retval & GDA_VALUE_ATTR_IS_UNCHANGED) ? "IS_UNCHANGED " : " ",
+ (retval & GDA_VALUE_ATTR_DATA_NON_VALID) ? "NON_VALID " : " ",
+ (retval & GDA_VALUE_ATTR_READ_ONLY) ? "READ_ONLY " : " ",
+ (retval & GDA_VALUE_ATTR_HAS_VALUE_ORIG) ? "HAS_VALUE_ORIG " : " ");
+#endif
return retval;
}
@@ -837,6 +848,7 @@ gdaui_entry_wrapper_set_editable (GdauiDataEntry *iface, gboolean editable)
(wrapper->priv->real_class->set_editable) (wrapper, editable);
else
gtk_widget_set_sensitive (GTK_WIDGET (iface), editable);
+ _gdaui_entry_shell_mark_editable (GDAUI_ENTRY_SHELL (wrapper), editable);
}
static gboolean
@@ -873,5 +885,5 @@ static void
gdaui_entry_wrapper_set_unknown_color (GdauiDataEntry *de, gdouble red, gdouble green,
gdouble blue, gdouble alpha)
{
- gdaui_entry_shell_set_ucolor (GDAUI_ENTRY_SHELL (de), red, green, blue, alpha);
+ gdaui_entry_shell_set_invalid_color (GDAUI_ENTRY_SHELL (de), red, green, blue, alpha);
}
diff --git a/libgda-ui/data-entries/gdaui-entry.c b/libgda-ui/data-entries/gdaui-entry.c
index ccd9abb..9db3196 100644
--- a/libgda-ui/data-entries/gdaui-entry.c
+++ b/libgda-ui/data-entries/gdaui-entry.c
@@ -35,6 +35,7 @@ struct _GdauiEntryPrivate {
gint maxlen; /* UTF8 len */
gboolean isnull;
guchar internal_changes;
+ gint max_width;
};
#define ENTER_INTERNAL_CHANGES(entry) (entry)->priv->internal_changes ++
@@ -83,6 +84,8 @@ static void signal_handlers_unblock (GdauiEntry *entry);
static void changed_cb (GtkEditable *editable, gpointer data);
static void delete_text_cb (GtkEditable *editable, gint start_pos, gint end_pos, gpointer data);
static void insert_text_cb (GtkEditable *editable, const gchar *text, gint length, gint *position, gpointer
data);
+static void internal_insert_text (GtkEditable *editable, const gchar *text, gint text_length, gint *position,
+ gboolean handle_default_insert);
static GObjectClass *parent_class = NULL;
@@ -146,6 +149,7 @@ gdaui_entry_init (GdauiEntry *entry)
entry->priv->maxlen = 65535; /* eg. unlimited for GtkEntry */
entry->priv->isnull = TRUE;
entry->priv->internal_changes = 0;
+ entry->priv->max_width = -1;
g_signal_connect (G_OBJECT (entry), "delete-text",
G_CALLBACK (delete_text_cb), NULL);
@@ -208,6 +212,7 @@ gdaui_entry_set_property (GObject *object,
}
adjust_display (entry, otext);
g_free (otext);
+ gdaui_entry_set_width_chars (entry, entry->priv->max_width);
break;
case PROP_SUFFIX:
otext = gdaui_entry_get_text (entry);
@@ -227,18 +232,20 @@ gdaui_entry_set_property (GObject *object,
}
adjust_display (entry, otext);
g_free (otext);
+ gdaui_entry_set_width_chars (entry, entry->priv->max_width);
break;
case PROP_MAXLEN:
entry->priv->maxlen = g_value_get_int (value);
otext = gdaui_entry_get_text (entry);
adjust_display (entry, otext);
g_free (otext);
+ gdaui_entry_set_width_chars (entry, entry->priv->max_width);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
- }
+ }
}
static void
@@ -435,18 +442,28 @@ gdaui_entry_set_text (GdauiEntry *entry, const gchar *text)
gtk_entry_set_text (GTK_ENTRY (entry), "");
signal_handlers_unblock (entry);
ENTER_INTERNAL_CHANGES(entry);
- gtk_entry_set_text (GTK_ENTRY (entry), text); /* emits the "insert-text" signal which is
treated */
+
+ if (entry->priv->internal_changes == 1) {
+ /* function has been called by "external" programmer,
+ * emits the "insert-text" signal which is treated */
+ gtk_entry_set_text (GTK_ENTRY (entry), text);
+ }
+ else {
+ /* function has been called by a subsequent call of one of
+ * the descendant's implementation */
+ gint pos = 0;
+ internal_insert_text (GTK_EDITABLE (entry), text, g_utf8_strlen (text, -1), &pos,
TRUE);
+ }
entry->priv->isnull = FALSE; /* in case it has not been set */
LEAVE_INTERNAL_CHANGES(entry);
- g_signal_emit_by_name (entry, "changed");
}
else {
entry->priv->isnull = TRUE;
signal_handlers_block (entry);
gtk_entry_set_text (GTK_ENTRY (entry), "");
signal_handlers_unblock (entry);
- g_signal_emit_by_name (entry, "changed");
}
+ g_signal_emit_by_name (entry, "changed");
}
/**
@@ -487,7 +504,7 @@ gdaui_entry_set_suffix (GdauiEntry *entry, const gchar *suffix)
* @entry: a #GdauiEntry widget
* @max_width: maximum width, or -1
*
- * Sets @entry's maximum width in characters, without taking into account
+ * Sets @entry's width in characters, without taking into account
* any prefix or suffix (which will automatically be handled). If you want to take
* a prefix or suffix into account direclty, then use gtk_entry_set_width_chars()
*/
@@ -495,12 +512,17 @@ void
gdaui_entry_set_width_chars (GdauiEntry *entry, gint max_width)
{
g_return_if_fail (GDAUI_IS_ENTRY (entry));
- if (max_width < 0)
+ entry->priv->max_width = max_width;
+ if (max_width < 0) {
gtk_entry_set_width_chars (GTK_ENTRY (entry), -1);
+ gtk_widget_set_hexpand (GTK_WIDGET (entry), TRUE);
+ }
else {
- max_width += entry->priv->prefix_clen;
- max_width += entry->priv->suffix_clen;
+ max_width += (entry->priv->prefix_clen > 0 ? entry->priv->prefix_clen + 1 : 0);
+ max_width += (entry->priv->suffix_clen > 0 ? entry->priv->suffix_clen + 1 : 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), max_width);
+ gtk_entry_set_max_width_chars (GTK_ENTRY (entry), max_width);
+ gtk_widget_set_hexpand (GTK_WIDGET (entry), FALSE);
}
}
@@ -578,11 +600,11 @@ delete_text_cb (GtkEditable *editable, gint start_pos, gint end_pos, G_GNUC_UNUS
g_signal_emit_by_name (entry, "changed");
}
-
static void
-insert_text_cb (GtkEditable *editable, const gchar *text, gint text_length, gint *position,
- G_GNUC_UNUSED gpointer data)
+internal_insert_text (GtkEditable *editable, const gchar *text, gint text_length, gint *position,
+ gboolean handle_default_insert)
{
+ /*g_print ("%s ([%s] @ %d)\n", __FUNCTION__, text, *position);*/
const gchar *otext;
gint clen;
GdauiEntry *entry = GDAUI_ENTRY (editable);
@@ -618,7 +640,19 @@ insert_text_cb (GtkEditable *editable, const gchar *text, gint text_length, gint
/* test if the whole insertion is Ok */
text_clen = g_utf8_strlen (text, text_length);
- if (clen - entry->priv->prefix_clen - entry->priv->suffix_clen + text_clen > entry->priv->maxlen) {
+ if (GDAUI_ENTRY_GET_CLASS (editable)->assume_insert) {
+ /* Subclass assumes text insert */
+ gint pos = *position - entry->priv->prefix_clen;
+ GDAUI_ENTRY_GET_CLASS (editable)->assume_insert (entry, text, text_length,
+ &pos, entry->priv->prefix_clen);
+ *position = pos + entry->priv->prefix_clen;
+
+ g_signal_stop_emission_by_name (editable, "insert-text");
+ signal_handlers_unblock (entry);
+ g_signal_emit_by_name (entry, "changed");
+ }
+ else if (clen - entry->priv->prefix_clen - entry->priv->suffix_clen + text_clen >
entry->priv->maxlen) {
+ /* text to insert is too long and needs to be truncated */
gchar *itext;
gint nallowed;
nallowed = entry->priv->maxlen - (clen - entry->priv->prefix_clen - entry->priv->suffix_clen);
@@ -633,17 +667,22 @@ insert_text_cb (GtkEditable *editable, const gchar *text, gint text_length, gint
signal_handlers_unblock (entry);
g_signal_emit_by_name (entry, "changed");
}
- else if (GDAUI_ENTRY_GET_CLASS (editable)->assume_insert) {
- g_signal_stop_emission_by_name (editable, "insert-text");
- //g_print ("Subclass assumes text insert\n");
- gint pos = *position - entry->priv->prefix_clen;
- GDAUI_ENTRY_GET_CLASS (editable)->assume_insert (entry, text, text_length,
- &pos, entry->priv->prefix_clen);
- *position = pos + entry->priv->prefix_clen;
-
- signal_handlers_unblock (entry);
- g_signal_emit_by_name (entry, "changed");
+ else {
+ if (handle_default_insert) {
+ ENTER_INTERNAL_CHANGES(entry);
+ gtk_editable_insert_text (editable, text, text_length, position);
+ LEAVE_INTERNAL_CHANGES(entry);
+ signal_handlers_unblock (entry);
+ g_signal_emit_by_name (entry, "changed");
+ }
+ else
+ signal_handlers_unblock (entry);
}
- else
- signal_handlers_unblock (entry);
+}
+
+static void
+insert_text_cb (GtkEditable *editable, const gchar *text, gint text_length, gint *position,
+ G_GNUC_UNUSED gpointer data)
+{
+ internal_insert_text (editable, text, text_length, position, FALSE);
}
diff --git a/libgda-ui/data-entries/gdaui-formatted-entry.c b/libgda-ui/data-entries/gdaui-formatted-entry.c
index 14e9ce1..d0d7c21 100644
--- a/libgda-ui/data-entries/gdaui-formatted-entry.c
+++ b/libgda-ui/data-entries/gdaui-formatted-entry.c
@@ -394,7 +394,7 @@ gdaui_formatted_entry_assume_delete (GdauiEntry *entry, gint virt_start_pos, gin
#endif
g_assert (virt_end_pos <= fentry->priv->format_clen);
-
+
/* move fptr to the @virt_start_pos in fentry->priv->format */
for (fptr = fentry->priv->format, i = 0;
(i < virt_start_pos) && *fptr;
diff --git a/libgda-ui/data-entries/gdaui-numeric-entry.c b/libgda-ui/data-entries/gdaui-numeric-entry.c
index 77ecaa7..bd9ea08 100644
--- a/libgda-ui/data-entries/gdaui-numeric-entry.c
+++ b/libgda-ui/data-entries/gdaui-numeric-entry.c
@@ -37,6 +37,7 @@ typedef struct {
gdouble fmax;
gboolean is_int;
gboolean is_signed;
+ guint8 max_nchars;
} NumAttr;
struct _GdauiNumericEntryPrivate {
@@ -142,6 +143,7 @@ compute_numeric_attributes (GType type, NumAttr *attr)
attr->is_int = FALSE;
attr->is_signed = TRUE;
attr->is_numerical = TRUE;
+ attr->max_nchars = 0;
if (type == G_TYPE_INT64) {
attr->imax = G_MAXINT64;
@@ -189,6 +191,7 @@ compute_numeric_attributes (GType type, NumAttr *attr)
attr->fmax = G_MAXDOUBLE;
}
else if (type == GDA_TYPE_NUMERIC) {
+ attr->max_nchars = 30;
}
else if (type == GDA_TYPE_SHORT) {
attr->imax = G_MAXSHORT;
@@ -203,6 +206,21 @@ compute_numeric_attributes (GType type, NumAttr *attr)
else {
attr->is_numerical = FALSE;
}
+
+ if (attr->is_numerical && attr->is_int) {
+ guint64 number;
+ if (attr->is_signed) {
+ number = (guint64) attr->imax;
+ attr->max_nchars = 1; /* for the sign */
+ }
+ else
+ number = attr->uimax;
+
+ do {
+ number /= 10;
+ attr->max_nchars ++;
+ } while (number != 0);
+ }
}
static gchar
@@ -227,7 +245,6 @@ gdaui_numeric_entry_init (GdauiNumericEntry *entry)
entry->priv->decimal_sep = get_default_decimal_sep ();
entry->priv->thousands_sep = 0;
entry->priv->nb_decimals = G_MAXUINT16;
- gtk_entry_set_width_chars (GTK_ENTRY (entry), 3);
}
static void
@@ -302,6 +319,21 @@ gdaui_numeric_entry_set_property (GObject *object,
}
gdaui_entry_set_text (GDAUI_ENTRY (entry), otext);
g_free (otext);
+
+ gint msize;
+ if (entry->priv->num_attr.max_nchars == 0)
+ msize = -1;
+ else {
+ msize = (gint) entry->priv->num_attr.max_nchars;
+ if (entry->priv->thousands_sep)
+ msize += entry->priv->num_attr.max_nchars / 3;
+ if (! entry->priv->num_attr.is_int)
+ msize += 1;
+ if (entry->priv->nb_decimals != G_MAXUINT16)
+ msize += entry->priv->nb_decimals;
+ }
+ /*g_print ("GdauiNumericEntry: type %s => msize = %d\n", g_type_name (entry->priv->type), msize);*/
+ gdaui_entry_set_width_chars (GDAUI_ENTRY (entry), msize);
}
static void
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-cidr.c
b/libgda-ui/data-entries/plugins/gdaui-entry-cidr.c
index 5796a35..e7593b0 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-cidr.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-cidr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 - 2012 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2009 - 2015 Vivien Malerba <malerba gnome-db org>
* Copyright (C) 2010 David King <davidk openismus com>
*
* This library is free software; you can redistribute it and/or
@@ -585,8 +585,8 @@ connect_signals(GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activa
mgcidr = GDAUI_ENTRY_CIDR (mgwrap);
g_return_if_fail (mgcidr->priv);
- g_signal_connect (G_OBJECT (mgcidr->priv->entry), "changed", modify_cb, mgwrap);
- g_signal_connect (G_OBJECT (mgcidr->priv->entry), "activate", activate_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgcidr->priv->entry), "changed", modify_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgcidr->priv->entry), "activate", activate_cb, mgwrap);
}
static SplitValues *
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-filesel.c
b/libgda-ui/data-entries/plugins/gdaui-entry-filesel.c
index f6591a5..c8ce8b9 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-filesel.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-filesel.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 - 2014 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2009 - 2015 Vivien Malerba <malerba gnome-db org>
* Copyright (C) 2010 David King <davidk openismus com>
* Copyright (C) 2011 Murray Cumming <murrayc murrayc com>
*
@@ -310,10 +310,10 @@ connect_signals(GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activa
filesel = GDAUI_ENTRY_FILESEL (mgwrap);
g_return_if_fail (filesel->priv);
- g_signal_connect (G_OBJECT (filesel->priv->entry), "changed",
- modify_cb, mgwrap);
- g_signal_connect (G_OBJECT (filesel->priv->entry), "activate",
- activate_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (filesel->priv->entry), "changed",
+ modify_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (filesel->priv->entry), "activate",
+ activate_cb, mgwrap);
}
static void
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-format.c
b/libgda-ui/data-entries/plugins/gdaui-entry-format.c
index b9a840a..62fb5af 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-format.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-format.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2012 - 2015 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
@@ -250,6 +250,6 @@ connect_signals (GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activ
mgformat = GDAUI_ENTRY_FORMAT (mgwrap);
g_return_if_fail (mgformat->priv);
- g_signal_connect (G_OBJECT (mgformat->priv->entry), "changed", modify_cb, mgwrap);
- g_signal_connect (G_OBJECT (mgformat->priv->entry), "activate", activate_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgformat->priv->entry), "changed", modify_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgformat->priv->entry), "activate", activate_cb, mgwrap);
}
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-password.c
b/libgda-ui/data-entries/plugins/gdaui-entry-password.c
index 352eed5..08a926e 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-password.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-password.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 - 2012 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2009 - 2015 Vivien Malerba <malerba gnome-db org>
* Copyright (C) 2010 David King <davidk openismus com>
*
* This library is free software; you can redistribute it and/or
@@ -289,10 +289,10 @@ connect_signals(GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activa
g_signal_connect (G_OBJECT (mgstr->priv->entry), "insert-text",
G_CALLBACK (entry_insert_text_cb), mgwrap);
- g_signal_connect (G_OBJECT (mgstr->priv->entry), "changed",
- modify_cb, mgwrap);
- g_signal_connect (G_OBJECT (mgstr->priv->entry), "activate",
- activate_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgstr->priv->entry), "changed",
+ modify_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgstr->priv->entry), "activate",
+ activate_cb, mgwrap);
}
static void
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-rt.c b/libgda-ui/data-entries/plugins/gdaui-entry-rt.c
index 28f63f1..7739bb3 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-rt.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-rt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 - 2012 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2010 - 2015 Vivien Malerba <malerba gnome-db org>
* Copyright (C) 2011 Murray Cumming <murrayc murrayc com>
*
* This library is free software; you can redistribute it and/or
@@ -274,10 +274,10 @@ connect_signals(GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activa
g_return_if_fail (mgtxt->priv);
g_object_set_data (G_OBJECT (mgtxt->priv->view), "_activate_cb", activate_cb);
- g_signal_connect (G_OBJECT (GDAUI_RT_EDITOR (mgtxt->priv->view)), "changed",
- modify_cb, mgwrap);
- g_signal_connect (G_OBJECT (mgtxt->priv->view), "focus-out-event",
- G_CALLBACK (focus_out_cb), mgtxt);
+ g_signal_connect_swapped (G_OBJECT (GDAUI_RT_EDITOR (mgtxt->priv->view)), "changed",
+ modify_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgtxt->priv->view), "focus-out-event",
+ G_CALLBACK (focus_out_cb), mgtxt);
/* FIXME: how does the user "activates" the GtkRtView widget ? */
}
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-text.c
b/libgda-ui/data-entries/plugins/gdaui-entry-text.c
index 1f634bd..e447b19 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-text.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-text.c
@@ -114,6 +114,7 @@ gdaui_entry_text_init (GdauiEntryText *gdaui_entry_text)
gdaui_entry_text->priv->view = NULL;
gdaui_entry_text->priv->wrapmode = GTK_WRAP_NONE;
gtk_widget_set_vexpand (GTK_WIDGET (gdaui_entry_text), TRUE);
+ gtk_widget_set_hexpand (GTK_WIDGET (gdaui_entry_text), TRUE);
}
/**
@@ -402,10 +403,10 @@ connect_signals(GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activa
g_return_if_fail (mgtxt->priv);
g_object_set_data (G_OBJECT (mgtxt->priv->view), "_activate_cb", activate_cb);
- g_signal_connect (G_OBJECT (mgtxt->priv->buffer), "changed",
- modify_cb, mgwrap);
- g_signal_connect (G_OBJECT (mgtxt->priv->view), "focus-out-event",
- G_CALLBACK (focus_out_cb), mgtxt);
+ g_signal_connect_swapped (G_OBJECT (mgtxt->priv->buffer), "changed",
+ modify_cb, mgwrap);
+ g_signal_connect_swapped (G_OBJECT (mgtxt->priv->view), "focus-out-event",
+ G_CALLBACK (focus_out_cb), mgtxt);
/* FIXME: how does the user "activates" the GtkTextView widget ? */
}
diff --git a/libgda-ui/data/Makefile.am b/libgda-ui/data/Makefile.am
index 0e4f3af..0a6e92e 100644
--- a/libgda-ui/data/Makefile.am
+++ b/libgda-ui/data/Makefile.am
@@ -1,8 +1,7 @@
# icons
iconsdir=$(datadir)/libgda-$(GDA_ABI_MAJOR_VERSION).$(GDA_ABI_MINOR_VERSION)/pixmaps
icons_DATA= \
- gdaui-generic.png \
- bin-attachment-16x16.png
+ gdaui-generic.png
# other
xmldir = $(datadir)/libgda-$(GDA_ABI_MAJOR_VERSION).$(GDA_ABI_MINOR_VERSION)
diff --git a/libgda-ui/data/mime-types-extensions b/libgda-ui/data/mime-types-extensions
new file mode 100644
index 0000000..6f9870a
--- /dev/null
+++ b/libgda-ui/data/mime-types-extensions
@@ -0,0 +1,413 @@
+# Manually generated using:
+# cat /etc/mime.types | grep -v '^#' | awk '{if ($2 != "") print $1 "." $2}'
+application/andrew-inset.ez
+application/annodex.anx
+application/atom+xml.atom
+application/atomcat+xml.atomcat
+application/atomserv+xml.atomsrv
+application/bbolin.lin
+application/cu-seeme.cu
+application/davmount+xml.davmount
+application/dicom.dcm
+application/dsptype.tsp
+application/ecmascript.es
+application/font-sfnt.otf
+application/font-tdpfr.pfr
+application/font-woff.woff
+application/futuresplash.spl
+application/gzip.gz
+application/hta.hta
+application/java-archive.jar
+application/java-serialized-object.ser
+application/java-vm.class
+application/javascript.js
+application/json.json
+application/m3g.m3g
+application/mac-binhex40.hqx
+application/mac-compactpro.cpt
+application/mathematica.nb
+application/mbox.mbox
+application/msaccess.mdb
+application/msword.doc
+application/mxf.mxf
+application/octet-stream.bin
+application/oda.oda
+application/oebps-package+xml.opf
+application/ogg.ogx
+application/onenote.one
+application/pdf.pdf
+application/pgp-encrypted.pgp
+application/pgp-keys.key
+application/pgp-signature.sig
+application/pics-rules.prf
+application/postscript.ps
+application/rar.rar
+application/rdf+xml.rdf
+application/rtf.rtf
+application/sla.stl
+application/smil+xml.smi
+application/xhtml+xml.xhtml
+application/xml.xml
+application/xslt+xml.xsl
+application/xspf+xml.xspf
+application/zip.zip
+application/vnd.android.package-archive.apk
+application/vnd.cinderella.cdy
+application/vnd.debian.binary-package.deb
+application/vnd.font-fontforge-sfd.sfd
+application/vnd.google-earth.kml+xml.kml
+application/vnd.google-earth.kmz.kmz
+application/vnd.mozilla.xul+xml.xul
+application/vnd.ms-excel.xls
+application/vnd.ms-excel.addin.macroEnabled.12.xlam
+application/vnd.ms-excel.sheet.binary.macroEnabled.12.xlsb
+application/vnd.ms-excel.sheet.macroEnabled.12.xlsm
+application/vnd.ms-excel.template.macroEnabled.12.xltm
+application/vnd.ms-fontobject.eot
+application/vnd.ms-officetheme.thmx
+application/vnd.ms-pki.seccat.cat
+application/vnd.ms-powerpoint.ppt
+application/vnd.ms-powerpoint.addin.macroEnabled.12.ppam
+application/vnd.ms-powerpoint.presentation.macroEnabled.12.pptm
+application/vnd.ms-powerpoint.slide.macroEnabled.12.sldm
+application/vnd.ms-powerpoint.slideshow.macroEnabled.12.ppsm
+application/vnd.ms-powerpoint.template.macroEnabled.12.potm
+application/vnd.ms-word.document.macroEnabled.12.docm
+application/vnd.ms-word.template.macroEnabled.12.dotm
+application/vnd.oasis.opendocument.chart.odc
+application/vnd.oasis.opendocument.database.odb
+application/vnd.oasis.opendocument.formula.odf
+application/vnd.oasis.opendocument.graphics.odg
+application/vnd.oasis.opendocument.graphics-template.otg
+application/vnd.oasis.opendocument.image.odi
+application/vnd.oasis.opendocument.presentation.odp
+application/vnd.oasis.opendocument.presentation-template.otp
+application/vnd.oasis.opendocument.spreadsheet.ods
+application/vnd.oasis.opendocument.spreadsheet-template.ots
+application/vnd.oasis.opendocument.text.odt
+application/vnd.oasis.opendocument.text-master.odm
+application/vnd.oasis.opendocument.text-template.ott
+application/vnd.oasis.opendocument.text-web.oth
+application/vnd.openxmlformats-officedocument.presentationml.presentation.pptx
+application/vnd.openxmlformats-officedocument.presentationml.slide.sldx
+application/vnd.openxmlformats-officedocument.presentationml.slideshow.ppsx
+application/vnd.openxmlformats-officedocument.presentationml.template.potx
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.xlsx
+application/vnd.openxmlformats-officedocument.spreadsheetml.template.xltx
+application/vnd.openxmlformats-officedocument.wordprocessingml.document.docx
+application/vnd.openxmlformats-officedocument.wordprocessingml.template.dotx
+application/vnd.rim.cod.cod
+application/vnd.smaf.mmf
+application/vnd.stardivision.calc.sdc
+application/vnd.stardivision.chart.sds
+application/vnd.stardivision.draw.sda
+application/vnd.stardivision.impress.sdd
+application/vnd.stardivision.math.sdf
+application/vnd.stardivision.writer.sdw
+application/vnd.stardivision.writer-global.sgl
+application/vnd.sun.xml.calc.sxc
+application/vnd.sun.xml.calc.template.stc
+application/vnd.sun.xml.draw.sxd
+application/vnd.sun.xml.draw.template.std
+application/vnd.sun.xml.impress.sxi
+application/vnd.sun.xml.impress.template.sti
+application/vnd.sun.xml.math.sxm
+application/vnd.sun.xml.writer.sxw
+application/vnd.sun.xml.writer.global.sxg
+application/vnd.sun.xml.writer.template.stw
+application/vnd.symbian.install.sis
+application/vnd.tcpdump.pcap.cap
+application/vnd.visio.vsd
+application/vnd.wap.wbxml.wbxml
+application/vnd.wap.wmlc.wmlc
+application/vnd.wap.wmlscriptc.wmlsc
+application/vnd.wordperfect.wpd
+application/vnd.wordperfect5.1.wp5
+application/x-123.wk
+application/x-7z-compressed.7z
+application/x-abiword.abw
+application/x-apple-diskimage.dmg
+application/x-bcpio.bcpio
+application/x-bittorrent.torrent
+application/x-cab.cab
+application/x-cbr.cbr
+application/x-cbz.cbz
+application/x-cdf.cdf
+application/x-cdlink.vcd
+application/x-chess-pgn.pgn
+application/x-comsol.mph
+application/x-cpio.cpio
+application/x-csh.csh
+application/x-debian-package.deb
+application/x-director.dcr
+application/x-dms.dms
+application/x-doom.wad
+application/x-dvi.dvi
+application/x-font.pfa
+application/x-font-pcf.pcf
+application/x-freemind.mm
+application/x-futuresplash.spl
+application/x-ganttproject.gan
+application/x-gnumeric.gnumeric
+application/x-go-sgf.sgf
+application/x-graphing-calculator.gcf
+application/x-gtar.gtar
+application/x-gtar-compressed.tgz
+application/x-hdf.hdf
+application/x-hwp.hwp
+application/x-ica.ica
+application/x-info.info
+application/x-internet-signup.ins
+application/x-iphone.iii
+application/x-iso9660-image.iso
+application/x-jam.jam
+application/x-java-jnlp-file.jnlp
+application/x-jmol.jmz
+application/x-kchart.chrt
+application/x-killustrator.kil
+application/x-koan.skp
+application/x-kpresenter.kpr
+application/x-kspread.ksp
+application/x-kword.kwd
+application/x-latex.latex
+application/x-lha.lha
+application/x-lyx.lyx
+application/x-lzh.lzh
+application/x-lzx.lzx
+application/x-maker.frm
+application/x-mif.mif
+application/x-mpegURL.m3u8
+application/x-ms-wmd.wmd
+application/x-ms-wmz.wmz
+application/x-msdos-program.com
+application/x-msi.msi
+application/x-netcdf.nc
+application/x-ns-proxy-autoconfig.pac
+application/x-nwc.nwc
+application/x-object.o
+application/x-oz-application.oza
+application/x-pkcs7-certreqresp.p7r
+application/x-pkcs7-crl.crl
+application/x-python-code.pyc
+application/x-qgis.qgs
+application/x-quicktimeplayer.qtl
+application/x-rdp.rdp
+application/x-redhat-package-manager.rpm
+application/x-rss+xml.rss
+application/x-ruby.rb
+application/x-scilab.sci
+application/x-scilab-xcos.xcos
+application/x-sh.sh
+application/x-shar.shar
+application/x-shockwave-flash.swf
+application/x-silverlight.scr
+application/x-sql.sql
+application/x-stuffit.sit
+application/x-sv4cpio.sv4cpio
+application/x-sv4crc.sv4crc
+application/x-tar.tar
+application/x-tcl.tcl
+application/x-tex-gf.gf
+application/x-tex-pk.pk
+application/x-texinfo.texinfo
+application/x-trash.~
+application/x-troff.t
+application/x-troff-man.man
+application/x-troff-me.me
+application/x-troff-ms.ms
+application/x-ustar.ustar
+application/x-wais-source.src
+application/x-wingz.wz
+application/x-x509-ca-cert.crt
+application/x-xcf.xcf
+application/x-xfig.fig
+application/x-xpinstall.xpi
+application/x-xz.xz
+audio/amr.amr
+audio/amr-wb.awb
+audio/annodex.axa
+audio/basic.au
+audio/csound.csd
+audio/flac.flac
+audio/midi.mid
+audio/mpeg.mpga
+audio/mpegurl.m3u
+audio/ogg.oga
+audio/prs.sid.sid
+audio/x-aiff.aif
+audio/x-gsm.gsm
+audio/x-mpegurl.m3u
+audio/x-ms-wma.wma
+audio/x-ms-wax.wax
+audio/x-pn-realaudio.ra
+audio/x-realaudio.ra
+audio/x-scpls.pls
+audio/x-sd2.sd2
+audio/x-wav.wav
+chemical/x-alchemy.alc
+chemical/x-cache.cac
+chemical/x-cache-csf.csf
+chemical/x-cactvs-binary.cbin
+chemical/x-cdx.cdx
+chemical/x-cerius.cer
+chemical/x-chem3d.c3d
+chemical/x-chemdraw.chm
+chemical/x-cif.cif
+chemical/x-cmdf.cmdf
+chemical/x-cml.cml
+chemical/x-compass.cpa
+chemical/x-crossfire.bsd
+chemical/x-csml.csml
+chemical/x-ctx.ctx
+chemical/x-cxf.cxf
+chemical/x-embl-dl-nucleotide.emb
+chemical/x-galactic-spc.spc
+chemical/x-gamess-input.inp
+chemical/x-gaussian-checkpoint.fch
+chemical/x-gaussian-cube.cub
+chemical/x-gaussian-input.gau
+chemical/x-gaussian-log.gal
+chemical/x-gcg8-sequence.gcg
+chemical/x-genbank.gen
+chemical/x-hin.hin
+chemical/x-isostar.istr
+chemical/x-jcamp-dx.jdx
+chemical/x-kinemage.kin
+chemical/x-macmolecule.mcm
+chemical/x-macromodel-input.mmd
+chemical/x-mdl-molfile.mol
+chemical/x-mdl-rdfile.rd
+chemical/x-mdl-rxnfile.rxn
+chemical/x-mdl-sdfile.sd
+chemical/x-mdl-tgf.tgf
+chemical/x-mmcif.mcif
+chemical/x-mol2.mol2
+chemical/x-molconn-Z.b
+chemical/x-mopac-graph.gpt
+chemical/x-mopac-input.mop
+chemical/x-mopac-out.moo
+chemical/x-mopac-vib.mvb
+chemical/x-ncbi-asn1.asn
+chemical/x-ncbi-asn1-ascii.prt
+chemical/x-ncbi-asn1-binary.val
+chemical/x-ncbi-asn1-spec.asn
+chemical/x-pdb.pdb
+chemical/x-rosdal.ros
+chemical/x-swissprot.sw
+chemical/x-vamas-iso14976.vms
+chemical/x-vmd.vmd
+chemical/x-xtel.xtel
+chemical/x-xyz.xyz
+image/gif.gif
+image/ief.ief
+image/jp2.jp2
+image/jpeg.jpeg
+image/jpm.jpm
+image/jpx.jpx
+image/pcx.pcx
+image/png.png
+image/svg+xml.svg
+image/tiff.tiff
+image/vnd.djvu.djvu
+image/vnd.microsoft.icon.ico
+image/vnd.wap.wbmp.wbmp
+image/x-canon-cr2.cr2
+image/x-canon-crw.crw
+image/x-cmu-raster.ras
+image/x-coreldraw.cdr
+image/x-coreldrawpattern.pat
+image/x-coreldrawtemplate.cdt
+image/x-corelphotopaint.cpt
+image/x-epson-erf.erf
+image/x-jg.art
+image/x-jng.jng
+image/x-ms-bmp.bmp
+image/x-nikon-nef.nef
+image/x-olympus-orf.orf
+image/x-photoshop.psd
+image/x-portable-anymap.pnm
+image/x-portable-bitmap.pbm
+image/x-portable-graymap.pgm
+image/x-portable-pixmap.ppm
+image/x-rgb.rgb
+image/x-xbitmap.xbm
+image/x-xpixmap.xpm
+image/x-xwindowdump.xwd
+message/rfc822.eml
+model/iges.igs
+model/mesh.msh
+model/vrml.wrl
+model/x3d+vrml.x3dv
+model/x3d+xml.x3d
+model/x3d+binary.x3db
+text/cache-manifest.appcache
+text/calendar.ics
+text/css.css
+text/csv.csv
+text/h323.323
+text/html.html
+text/iuls.uls
+text/mathml.mml
+text/plain.asc
+text/richtext.rtx
+text/scriptlet.sct
+text/texmacs.tm
+text/tab-separated-values.tsv
+text/turtle.ttl
+text/vcard.vcf
+text/vnd.sun.j2me.app-descriptor.jad
+text/vnd.wap.wml.wml
+text/vnd.wap.wmlscript.wmls
+text/x-bibtex.bib
+text/x-boo.boo
+text/x-c++hdr.h++
+text/x-c++src.c++
+text/x-chdr.h
+text/x-component.htc
+text/x-csh.csh
+text/x-csrc.c
+text/x-dsrc.d
+text/x-diff.diff
+text/x-haskell.hs
+text/x-java.java
+text/x-lilypond.ly
+text/x-literate-haskell.lhs
+text/x-moc.moc
+text/x-pascal.p
+text/x-pcs-gcd.gcd
+text/x-perl.pl
+text/x-python.py
+text/x-scala.scala
+text/x-setext.etx
+text/x-sfv.sfv
+text/x-sh.sh
+text/x-tcl.tcl
+text/x-tex.tex
+text/x-vcalendar.vcs
+video/3gpp.3gp
+video/annodex.axv
+video/dl.dl
+video/dv.dif
+video/fli.fli
+video/gl.gl
+video/mpeg.mpeg
+video/MP2T.ts
+video/mp4.mp4
+video/quicktime.qt
+video/ogg.ogv
+video/webm.webm
+video/vnd.mpegurl.mxu
+video/x-flv.flv
+video/x-la-asf.lsf
+video/x-mng.mng
+video/x-ms-asf.asf
+video/x-ms-wm.wm
+video/x-ms-wmv.wmv
+video/x-ms-wmx.wmx
+video/x-ms-wvx.wvx
+video/x-msvideo.avi
+video/x-sgi-movie.movie
+video/x-matroska.mpv
+x-conference/x-cooltalk.ice
+x-epoc/x-sisx-app.sisx
+x-world/x-vrml.vrm
diff --git a/libgda-ui/gdaui-basic-form.c b/libgda-ui/gdaui-basic-form.c
index b1f9221..67774a7 100644
--- a/libgda-ui/gdaui-basic-form.c
+++ b/libgda-ui/gdaui-basic-form.c
@@ -35,7 +35,6 @@
#include <libgda-ui/gdaui-easy.h>
#include <libgda/gda-debug-macros.h>
-#define SPACING 3
static void gdaui_basic_form_class_init (GdauiBasicFormClass * class);
static void gdaui_basic_form_init (GdauiBasicForm *wid);
static void gdaui_basic_form_dispose (GObject *object);
@@ -106,7 +105,6 @@ static void unpack_entries (GdauiBasicForm *form);
static void destroy_entries (GdauiBasicForm *form);
static gchar *create_text_label_for_sentry (SingleEntry *sentry, gchar **out_title);
-static void gdaui_basic_form_show_entry_actions (GdauiBasicForm *form, gboolean show_actions);
static void gdaui_basic_form_set_entries_auto_default (GdauiBasicForm *form, gboolean auto_default);
static void get_rid_of_set (GdaSet *paramlist, GdauiBasicForm *form);
@@ -118,6 +116,7 @@ static void paramlist_holder_type_set_cb (GdaSet *paramlist, GdaHolder *param,
static void entry_contents_modified (GdauiDataEntry *entry, SingleEntry *sentry);
static void entry_contents_activated (GdauiDataEntry *entry, GdauiBasicForm *form);
+static void sync_entry_attributes (GdaHolder *param, SingleEntry *sentry);
static void parameter_changed_cb (GdaHolder *param, SingleEntry *sentry);
static void mark_not_null_entry_labels (GdauiBasicForm *form, gboolean show_mark);
@@ -135,7 +134,6 @@ enum {
PROP_XML_LAYOUT,
PROP_PARAMLIST,
PROP_HEADERS_SENSITIVE,
- PROP_SHOW_ACTIONS,
PROP_ENTRIES_AUTO_DEFAULT,
PROP_CAN_VEXPAND
};
@@ -160,7 +158,6 @@ struct _GdauiBasicFormPriv
GtkWidget *top_container;
- gboolean show_actions;
gboolean entries_auto_default;
GSList *size_groups; /* list of SizeGroup pointers */
@@ -304,11 +301,6 @@ gdaui_basic_form_class_init (GdauiBasicFormClass *klass)
"",
NULL, FALSE,
G_PARAM_READABLE | G_PARAM_WRITABLE));
- g_object_class_install_property (object_class, PROP_SHOW_ACTIONS,
- g_param_spec_boolean ("show-actions",
- _("Show Entry actions"),
- NULL, FALSE,
- G_PARAM_READABLE | G_PARAM_WRITABLE));
g_object_class_install_property (object_class, PROP_ENTRIES_AUTO_DEFAULT,
g_param_spec_boolean ("entries-auto-default",
_("Entries Auto-default"),
@@ -406,7 +398,6 @@ gdaui_basic_form_init (GdauiBasicForm *wid)
wid->priv->place_holders = NULL;
wid->priv->top_container = NULL;
- wid->priv->show_actions = FALSE;
wid->priv->entries_auto_default = FALSE;
gtk_orientable_set_orientation (GTK_ORIENTABLE (wid), GTK_ORIENTATION_VERTICAL);
@@ -425,10 +416,10 @@ gdaui_basic_form_init (GdauiBasicForm *wid)
g_signal_connect (evbox, "button-press-event",
G_CALLBACK (button_press_event_cb), wid);
- wid->priv->red = .98;
- wid->priv->green = .93;
- wid->priv->blue = .25;
- wid->priv->alpha = .50;
+ wid->priv->red = 0.;
+ wid->priv->green = 0.;
+ wid->priv->blue = 0.;
+ wid->priv->alpha = 0.;
}
/**
@@ -472,7 +463,6 @@ get_rid_of_set (GdaSet *paramlist, GdauiBasicForm *form)
/* unref the paramlist */
g_signal_handlers_disconnect_by_func (form->priv->set_info,
G_CALLBACK (paramlist_public_data_changed_cb), form);
-
g_signal_handlers_disconnect_by_func (paramlist,
G_CALLBACK (paramlist_param_attr_changed_cb), form);
g_signal_handlers_disconnect_by_func (paramlist,
@@ -500,9 +490,6 @@ paramlist_holder_type_set_cb (G_GNUC_UNUSED GdaSet *paramlist, GdaHolder *param,
sentry = get_single_entry_for_holder (form, param);
if (sentry) {
create_entry_widget (sentry);
- gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (sentry->entry),
- form->priv->show_actions ? GDA_VALUE_ATTR_ACTIONS_SHOWN : 0,
- GDA_VALUE_ATTR_ACTIONS_SHOWN);
pack_entry_widget (sentry);
gdaui_basic_form_entry_set_visible (form, param, !sentry->hidden);
}
@@ -563,9 +550,6 @@ paramlist_param_attr_changed_cb (G_GNUC_UNUSED GdaSet *paramlist, GdaHolder *par
if (sentry) {
/* recreate an entry widget */
create_entry_widget (sentry);
- gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (sentry->entry),
- form->priv->show_actions ?
GDA_VALUE_ATTR_ACTIONS_SHOWN : 0,
- GDA_VALUE_ATTR_ACTIONS_SHOWN);
pack_entry_widget (sentry);
gdaui_basic_form_entry_set_visible (form, param, !sentry->hidden);
}
@@ -685,9 +669,6 @@ gdaui_basic_form_set_property (GObject *object,
break;
case PROP_HEADERS_SENSITIVE:
break;
- case PROP_SHOW_ACTIONS:
- gdaui_basic_form_show_entry_actions (form, g_value_get_boolean (value));
- break;
case PROP_ENTRIES_AUTO_DEFAULT:
gdaui_basic_form_set_entries_auto_default (form, g_value_get_boolean (value));
break;
@@ -714,9 +695,6 @@ gdaui_basic_form_get_property (GObject *object,
break;
case PROP_HEADERS_SENSITIVE:
break;
- case PROP_SHOW_ACTIONS:
- g_value_set_boolean (value, form->priv->show_actions);
- break;
case PROP_ENTRIES_AUTO_DEFAULT:
g_value_set_boolean (value, form->priv->entries_auto_default);
break;
@@ -959,6 +937,7 @@ create_entry_widget (SingleEntry *sentry)
GDAUI_ATTRIBUTE_PLUGIN);
}
entry = GTK_WIDGET (gdaui_new_data_entry (type, plugin));
+ sentry->entry = GDAUI_DATA_ENTRY (entry);
/* set current value */
if (gda_holder_is_valid (param))
@@ -975,20 +954,8 @@ create_entry_widget (SingleEntry *sentry)
(G_VALUE_TYPE ((GValue *) value) != GDA_TYPE_NULL)))
gdaui_data_entry_set_reference_value (GDAUI_DATA_ENTRY (entry), value);
- if (default_val) {
+ if (default_val)
gdaui_data_entry_set_default_value (GDAUI_DATA_ENTRY (entry), default_val);
- gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (entry),
- GDA_VALUE_ATTR_CAN_BE_DEFAULT,
- GDA_VALUE_ATTR_CAN_BE_DEFAULT);
- if (gda_holder_value_is_default (param))
- gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (entry),
- GDA_VALUE_ATTR_IS_DEFAULT,
- GDA_VALUE_ATTR_IS_DEFAULT);
- }
-
- gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (entry),
- nnul ? 0 : GDA_VALUE_ATTR_CAN_BE_NULL,
- GDA_VALUE_ATTR_CAN_BE_NULL);
/* connect to the parameter's changes */
sentry->single_signal.holder = g_object_ref (param);
@@ -1010,6 +977,9 @@ create_entry_widget (SingleEntry *sentry)
if (title && *title)
gtk_widget_set_tooltip_text (sentry->label, title);
g_free (title);
+
+ /* set up the data entry's attributes */
+ sync_entry_attributes (param, sentry);
}
else {
/* several parameters depending on the values of a GdaDataModel object */
@@ -1017,6 +987,7 @@ create_entry_widget (SingleEntry *sentry)
gboolean nullok = TRUE;
entry = gdaui_entry_combo_new (sentry->form->priv->set_info, gdaui_set_group_get_source
(group));
+ sentry->entry = GDAUI_DATA_ENTRY (entry);
/* connect to the parameter's changes */
sentry->group_signals = g_array_new (FALSE, FALSE, sizeof (SignalData));
@@ -1024,7 +995,7 @@ create_entry_widget (SingleEntry *sentry)
GdaHolder *param;
param = gda_set_node_get_holder (GDA_SET_NODE (plist->data));
- if (gda_holder_get_not_null (param))
+ if (nullok && gda_holder_get_not_null (param))
nullok = FALSE;
SignalData sd;
@@ -1034,9 +1005,6 @@ create_entry_widget (SingleEntry *sentry)
sentry);
g_array_append_val (sentry->group_signals, sd);
}
- gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (entry),
- nullok ? GDA_VALUE_ATTR_CAN_BE_NULL : 0,
- GDA_VALUE_ATTR_CAN_BE_NULL);
sentry->not_null = !nullok;
/* label */
@@ -1055,16 +1023,20 @@ create_entry_widget (SingleEntry *sentry)
if (title && *title)
gtk_widget_set_tooltip_text (sentry->label, title);
+ /* set up the data entry's attributes using the 1st parameter */
+ plist = gda_set_group_get_nodes (gdaui_set_group_get_group (group));
+ sync_entry_attributes (gda_set_node_get_holder (GDA_SET_NODE (plist->data)), sentry);
}
- gtk_widget_set_halign (sentry->label, GTK_ALIGN_START);
- gtk_widget_set_hexpand (sentry->label, FALSE);
- g_object_set (G_OBJECT (sentry->label), "xalign", 0., NULL);
- sentry->entry = GDAUI_DATA_ENTRY (entry);
g_object_ref_sink (sentry->entry);
+
+ gtk_widget_set_halign (sentry->label, GTK_ALIGN_END);
+ gtk_widget_set_hexpand (sentry->label, FALSE);
+ g_object_set (G_OBJECT (sentry->label), "xalign", 1., NULL);
gdaui_data_entry_set_editable (sentry->entry, editable);
- gdaui_data_entry_set_unknown_color (sentry->entry, sentry->form->priv->red,
- sentry->form->priv->green, sentry->form->priv->blue,
- sentry->form->priv->alpha);
+ if (sentry->form->priv->alpha > 0.)
+ gdaui_data_entry_set_unknown_color (sentry->entry, sentry->form->priv->red,
+ sentry->form->priv->green, sentry->form->priv->blue,
+ sentry->form->priv->alpha);
GSList *list;
for (list = sentry->form->priv->size_groups; list; list = list->next) {
@@ -1119,8 +1091,6 @@ create_entries (GdauiBasicForm *form)
create_entry_widget (sentry);
}
- /* Set the Show actions in the entries */
- gdaui_basic_form_show_entry_actions (form, form->priv->show_actions);
/* Set the Auto entries default in the entries */
gdaui_basic_form_set_entries_auto_default (form, form->priv->entries_auto_default);
@@ -1182,10 +1152,16 @@ pack_entries_in_table (GdauiBasicForm *form)
/* creating a table for all the entries */
grid = gtk_grid_new ();
- gtk_grid_set_row_spacing (GTK_GRID (grid), SPACING);
- gtk_grid_set_column_spacing (GTK_GRID (grid), SPACING);
+ gtk_grid_set_row_spacing (GTK_GRID (grid), GDAUI_HIG_FORM_VSPACE);
+ gtk_grid_set_column_spacing (GTK_GRID (grid), GDAUI_HIG_FORM_HSPACE);
form->priv->top_container = grid;
gtk_box_pack_start (GTK_BOX (form->priv->mainbox), grid, TRUE, TRUE, 0);
+ g_object_set (G_OBJECT (grid),
+ "margin-top", GDAUI_HIG_FORM_VBORDER,
+ "margin-bottom", GDAUI_HIG_FORM_VBORDER,
+ "margin-start", GDAUI_HIG_FORM_HBORDER,
+ "margin-end", GDAUI_HIG_FORM_HBORDER, NULL);
+
for (list = form->priv->s_entries, i = 0;
list;
list = list->next, i++) {
@@ -1285,7 +1261,7 @@ load_xml_layout_children (GdauiBasicForm *form, xmlNodePtr parent_node)
if (wid) {
switch (ctype) {
case TOP_BOX:
- gtk_box_pack_start (GTK_BOX (top), wid, TRUE, TRUE, SPACING);
+ gtk_box_pack_start (GTK_BOX (top), wid, TRUE, TRUE, GDAUI_HIG_FORM_VSPACE);
break;
case TOP_PANED:
if (pos == 0)
@@ -1351,9 +1327,9 @@ load_xml_layout_column (GdauiBasicForm *form, xmlNodePtr box_node)
}
sentry->label = gtk_label_new ((gchar*) label);
g_object_ref_sink (sentry->label);
- gtk_widget_set_halign (sentry->label, GTK_ALIGN_START);
+ gtk_widget_set_halign (sentry->label, GTK_ALIGN_END);
gtk_widget_set_hexpand (sentry->label, FALSE);
- g_object_set (G_OBJECT (sentry->label), "xalign", 0., NULL);
+ g_object_set (G_OBJECT (sentry->label), "xalign", 1., NULL);
xmlFree (label);
}
@@ -1395,8 +1371,8 @@ load_xml_layout_column (GdauiBasicForm *form, xmlNodePtr box_node)
g_warning ("Unknown node type '%s', ignoring", (gchar*) child->name);
}
- gtk_grid_set_row_spacing (GTK_GRID (grid), SPACING);
- gtk_grid_set_column_spacing (GTK_GRID (grid), SPACING);
+ gtk_grid_set_row_spacing (GTK_GRID (grid), GDAUI_HIG_FORM_VSPACE);
+ gtk_grid_set_column_spacing (GTK_GRID (grid), GDAUI_HIG_FORM_HSPACE);
return grid;
}
@@ -1416,9 +1392,9 @@ load_xml_layout_section (GdauiBasicForm *form, xmlNodePtr section_node)
label = gtk_label_new ("");
gtk_label_set_markup (GTK_LABEL (label), str);
g_free (str);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_widget_set_halign (label, GTK_ALIGN_END);
gtk_widget_set_hexpand (label, FALSE);
- g_object_set (G_OBJECT (label), "xalign", 0., NULL);
+ g_object_set (G_OBJECT (label), "xalign", 1., NULL);
GtkWidget *vbox;
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
@@ -1566,6 +1542,64 @@ entry_contents_modified (GdauiDataEntry *entry, SingleEntry *sentry)
}
}
+static void
+sync_entry_attributes (GdaHolder *param, SingleEntry *sentry)
+{
+ const GValue *value = gda_holder_get_value (param);
+ GdauiDataEntry *entry;
+ gboolean param_valid;
+ param_valid = gda_holder_is_valid (param);
+
+ entry = sentry->entry;
+ if (sentry->single_param) {
+ gdaui_data_entry_set_value (entry, param_valid ? value : NULL);
+ sentry->not_null = gda_holder_get_not_null (param);
+ }
+ else {
+ GSList *values = NULL;
+ GSList *list;
+ gboolean allnull = TRUE;
+ gboolean nullok = TRUE;
+
+ for (list = gda_set_group_get_nodes (gdaui_set_group_get_group (sentry->group));
+ list; list = list->next) {
+ const GValue *pvalue;
+ pvalue = gda_holder_get_value (gda_set_node_get_holder (GDA_SET_NODE (list->data)));
+ param_valid = param_valid && gda_holder_is_valid (param);
+ values = g_slist_append (values, (GValue *) pvalue);
+ if (allnull && pvalue &&
+ (G_VALUE_TYPE ((GValue *) pvalue) != GDA_TYPE_NULL))
+ allnull = FALSE;
+ if (nullok && gda_holder_get_not_null (param))
+ nullok = FALSE;
+ }
+
+ if (!allnull)
+ gdaui_entry_combo_set_values (GDAUI_ENTRY_COMBO (entry), values);
+ else
+ gdaui_entry_combo_set_values (GDAUI_ENTRY_COMBO (entry), NULL);
+
+ g_slist_free (values);
+ sentry->not_null = !nullok;
+ }
+
+ g_signal_emit (G_OBJECT (sentry->form), gdaui_basic_form_signals[HOLDER_CHANGED], 0,
+ param, FALSE);
+
+ /* correctly update the NULLOK status */
+ GdaValueAttribute attr;
+ gboolean nullok;
+ attr = gdaui_data_entry_get_attributes (entry);
+ nullok = !sentry->not_null;
+ if (((attr & GDA_VALUE_ATTR_CAN_BE_NULL) && !nullok) ||
+ (! (attr & GDA_VALUE_ATTR_CAN_BE_NULL) && nullok))
+ gdaui_data_entry_set_attributes (entry, nullok ? GDA_VALUE_ATTR_CAN_BE_NULL : 0,
+ GDA_VALUE_ATTR_CAN_BE_NULL);
+
+ /* update the VALID atttibute */
+ gdaui_data_entry_set_attributes (entry, (!param_valid) ? GDA_VALUE_ATTR_DATA_NON_VALID : 0,
+ GDA_VALUE_ATTR_DATA_NON_VALID);
+}
/*
* Called when a parameter changes
@@ -1575,22 +1609,20 @@ entry_contents_modified (GdauiDataEntry *entry, SingleEntry *sentry)
static void
parameter_changed_cb (GdaHolder *param, SingleEntry *sentry)
{
- const GValue *value = gda_holder_get_value (param);
GdauiDataEntry *entry;
-
entry = sentry->entry;
if (sentry->forward_param_updates) {
- gboolean param_valid;
gboolean default_if_invalid = FALSE;
+ gboolean param_valid;
+ param_valid = gda_holder_is_valid (param);
/* There can be a feedback from the entry if the param is invalid and "set-default-if-invalid"
exists and is TRUE */
- param_valid = gda_holder_is_valid (param);
if (!param_valid)
if (g_object_class_find_property (G_OBJECT_GET_CLASS (entry),
"set-default-if-invalid"))
g_object_get (G_OBJECT (entry),
- "set-default-if-invalid", &default_if_invalid, NULL);
+ "set-default-if-invalid", &default_if_invalid, NULL);
/* updating the corresponding entry */
if (! default_if_invalid) {
@@ -1599,58 +1631,14 @@ parameter_changed_cb (GdaHolder *param, SingleEntry *sentry)
g_signal_handler_block (G_OBJECT (entry),
sentry->entry_contents_activated_id);
}
-
- if (sentry->single_param)
- gdaui_data_entry_set_value (entry, param_valid ? value : NULL);
- else {
- GSList *values = NULL;
- GSList *list;
- gboolean allnull = TRUE;
-
- for (list = gda_set_group_get_nodes (gdaui_set_group_get_group (sentry->group));
- list; list = list->next) {
- const GValue *pvalue;
- pvalue = gda_holder_get_value (gda_set_node_get_holder (GDA_SET_NODE
(list->data)));
- values = g_slist_append (values, (GValue *) pvalue);
- if (allnull && pvalue &&
- (G_VALUE_TYPE ((GValue *) pvalue) != GDA_TYPE_NULL))
- allnull = FALSE;
- }
-
- if (!allnull)
- gdaui_entry_combo_set_values (GDAUI_ENTRY_COMBO (entry), values);
- else
- gdaui_entry_combo_set_values (GDAUI_ENTRY_COMBO (entry), NULL);
-
- g_slist_free (values);
- }
-
+ sync_entry_attributes (param, sentry);
if (! default_if_invalid) {
g_signal_handler_unblock (G_OBJECT (entry),
sentry->entry_contents_modified_id);
g_signal_handler_unblock (G_OBJECT (entry),
sentry->entry_contents_activated_id);
- }
-
- gdaui_entry_shell_set_unknown (GDAUI_ENTRY_SHELL (entry),
- !gda_holder_is_valid (param));
-
- g_signal_emit (G_OBJECT (sentry->form), gdaui_basic_form_signals[HOLDER_CHANGED], 0,
- param, FALSE);
+ }
}
- else
- gdaui_entry_shell_set_unknown (GDAUI_ENTRY_SHELL (entry),
- !gda_holder_is_valid (param));
-
- /* correctly update the NULLOK status */
- GdaValueAttribute attr;
- gboolean nullok;
- attr = gdaui_data_entry_get_attributes (entry);
- nullok = !gda_holder_get_not_null (param);
- if (((attr & GDA_VALUE_ATTR_CAN_BE_NULL) && !nullok) ||
- (! (attr & GDA_VALUE_ATTR_CAN_BE_NULL) && nullok))
- gdaui_data_entry_set_attributes (entry, nullok ? GDA_VALUE_ATTR_CAN_BE_NULL : 0,
- GDA_VALUE_ATTR_CAN_BE_NULL);
}
/**
@@ -1775,33 +1763,6 @@ gdaui_basic_form_has_changed (GdauiBasicForm *form)
return FALSE;
}
-/*
- * gdaui_basic_form_show_entry_actions
- * @form: a #GdauiBasicForm widget
- * @show_actions: a boolean
- *
- * Show or hide the actions button available at the end of each data entry
- * in the form
- */
-static void
-gdaui_basic_form_show_entry_actions (GdauiBasicForm *form, gboolean show_actions)
-{
- GSList *list;
- guint show;
-
- g_return_if_fail (GDAUI_IS_BASIC_FORM (form));
-
- show = show_actions ? GDA_VALUE_ATTR_ACTIONS_SHOWN : 0;
- form->priv->show_actions = show_actions;
-
- for (list = form->priv->s_entries; list; list = list->next) {
- SingleEntry *sentry = (SingleEntry*) list->data;
- gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (sentry->entry), show,
- GDA_VALUE_ATTR_ACTIONS_SHOWN);
- /* mark_not_null_entry_labels (form, show_actions); */
- }
-}
-
/**
* gdaui_basic_form_reset:
* @form: a #GdauiBasicForm widget
@@ -2169,14 +2130,14 @@ gdaui_basic_form_new_in_dialog (GdaSet *data_set, GtkWindow *parent,
gchar *str;
label = gtk_label_new (NULL);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_widget_set_halign (label, GTK_ALIGN_END);
gtk_widget_set_hexpand (label, FALSE);
- g_object_set (G_OBJECT (label), "xalign", 0., NULL);
+ g_object_set (G_OBJECT (label), "xalign", 1., NULL);
str = g_markup_printf_escaped ("<b>%s:</b>", header);
gtk_label_set_markup (GTK_LABEL (label), str);
g_free (str);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
- label, FALSE, FALSE, SPACING);
+ label, FALSE, FALSE, GDAUI_HIG_FORM_VSEP);
gtk_widget_show (label);
}
@@ -2184,7 +2145,7 @@ gdaui_basic_form_new_in_dialog (GdaSet *data_set, GtkWindow *parent,
can_expand = gtk_widget_compute_expand (GTK_WIDGET (form), GTK_ORIENTATION_VERTICAL);
gtk_container_set_border_width (GTK_CONTAINER (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG
(dlg)))), 4);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), form,
- can_expand, can_expand, 10);
+ can_expand, can_expand, 0);
g_signal_connect (G_OBJECT (form), "holder-changed",
G_CALLBACK (form_holder_changed), dlg);
@@ -2416,6 +2377,11 @@ gdaui_basic_form_set_unknown_color (GdauiBasicForm *form, gdouble red, gdouble g
gdouble blue, gdouble alpha)
{
g_return_if_fail (GDAUI_IS_BASIC_FORM (form));
+ g_return_if_fail ((red >= 0.) && (red <= 1.));
+ g_return_if_fail ((green >= 0.) && (green <= 1.));
+ g_return_if_fail ((blue >= 0.) && (blue <= 1.));
+ g_return_if_fail ((alpha >= 0.) && (alpha <= 1.));
+
form->priv->red = red;
form->priv->green = green;
form->priv->blue = blue;
diff --git a/libgda-ui/gdaui-cloud.c b/libgda-ui/gdaui-cloud.c
index 3384d14..3daa0e1 100644
--- a/libgda-ui/gdaui-cloud.c
+++ b/libgda-ui/gdaui-cloud.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 - 2013 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2009 - 2015 Vivien Malerba <malerba gnome-db org>
* Copyright (C) 2010 David King <davidk openismus com>
* Copyright (C) 2011 Murray Cumming <murrayc murrayc com>
*
@@ -24,7 +24,6 @@
#include <libgda/libgda.h>
#include "gdaui-cloud.h"
#include <gdk/gdkkeysyms.h>
-#include "internal/popup-container.h"
#include "gdaui-data-selector.h"
#include <libgda/gda-debug-macros.h>
diff --git a/libgda-ui/gdaui-data-entry.h b/libgda-ui/gdaui-data-entry.h
index 6454045..cfd3b40 100644
--- a/libgda-ui/gdaui-data-entry.h
+++ b/libgda-ui/gdaui-data-entry.h
@@ -68,7 +68,7 @@ struct _GdauiDataEntryIface
void (*set_attributes) (GdauiDataEntry *de, GdaValueAttribute attrs,
GdaValueAttribute mask);
GdaValueAttribute (*get_attributes) (GdauiDataEntry *de);
GdaDataHandler *(*get_handler) (GdauiDataEntry *de);
- gboolean (*can_expand) (GdauiDataEntry *de, gboolean horiz); /* not used anymore */
+ gboolean (*can_expand) (GdauiDataEntry *de, gboolean horiz); /* FIXME: not used
anymore */
void (*set_editable) (GdauiDataEntry *de, gboolean editable);
gboolean (*get_editable) (GdauiDataEntry *de);
void (*grab_focus) (GdauiDataEntry *de);
@@ -126,7 +126,7 @@ GType gdaui_data_entry_get_value_type (GdauiDataEntry *de);
void gdaui_data_entry_set_value (GdauiDataEntry *de, const GValue *value);
GValue *gdaui_data_entry_get_value (GdauiDataEntry *de);
gboolean gdaui_data_entry_content_is_valid (GdauiDataEntry *de, GError **error);
-gboolean gdaui_data_entry_validate (GdauiDataEntry *de, GError
**error);
+gboolean gdaui_data_entry_validate (GdauiDataEntry *de, GError **error);
void gdaui_data_entry_set_reference_value (GdauiDataEntry *de, const GValue *value);
const GValue *gdaui_data_entry_get_reference_value (GdauiDataEntry *de);
void gdaui_data_entry_set_reference_current (GdauiDataEntry *de);
diff --git a/libgda-ui/gdaui-enums.h b/libgda-ui/gdaui-enums.h
index e3e1e90..e3a5197 100644
--- a/libgda-ui/gdaui-enums.h
+++ b/libgda-ui/gdaui-enums.h
@@ -58,6 +58,14 @@ typedef enum {
/* possible predefined attribute names for gda_holder_get_attribute() or gda_column_get_attribute() */
#define GDAUI_ATTRIBUTE_PLUGIN "__gdaui_attr_plugin" /* G_TYPE_STRING expected */
+/* issued from HIG 3 */
+#define GDAUI_HIG_FORM_HBORDER 18
+#define GDAUI_HIG_FORM_HSPACE 12
+
+#define GDAUI_HIG_FORM_VBORDER 18
+#define GDAUI_HIG_FORM_VSPACE 6
+#define GDAUI_HIG_FORM_VSEP 18
+
#endif
diff --git a/libgda-ui/gdaui-form.c b/libgda-ui/gdaui-form.c
index 5aee348..2a613b8 100644
--- a/libgda-ui/gdaui-form.c
+++ b/libgda-ui/gdaui-form.c
@@ -202,12 +202,11 @@ gdaui_form_init (GdauiForm *form)
GtkWidget *frame;
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
- gtk_box_pack_start (GTK_BOX (form), frame, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (form), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
form->priv->raw_form = gdaui_raw_form_new (NULL);
gtk_container_add (GTK_CONTAINER (frame), form->priv->raw_form);
- gtk_container_set_border_width (GTK_CONTAINER (form->priv->raw_form), 6);
gtk_widget_show (form->priv->raw_form);
g_signal_connect (form->priv->raw_form, "layout-changed",
diff --git a/libgda-ui/gdaui-raw-form.c b/libgda-ui/gdaui-raw-form.c
index 0469844..ad9d171 100644
--- a/libgda-ui/gdaui-raw-form.c
+++ b/libgda-ui/gdaui-raw-form.c
@@ -453,9 +453,6 @@ gdaui_raw_form_init (GdauiRawForm *wid)
G_CALLBACK (form_activated_cb), NULL);
g_signal_connect (G_OBJECT (wid), "holder-changed",
G_CALLBACK (form_holder_changed_cb), NULL);
-
- /* raw forms' default unknown color */
- gdaui_basic_form_set_unknown_color ((GdauiBasicForm*) wid, -1., -1., -1., -1.);
}
/**
@@ -561,17 +558,6 @@ gdaui_raw_form_set_property (GObject *object,
/* we don't want chuncking */
gda_data_proxy_set_sample_size (form->priv->proxy, 0);
- /* handle invalid iterators' GdaHolder */
- GSList *list;
- for (list = GDA_SET (form->priv->iter)->holders; list; list = list->next) {
- GtkWidget *entry;
- entry = gdaui_basic_form_get_entry_widget (GDAUI_BASIC_FORM (form),
- (GdaHolder*) list->data);
- if (entry)
- gdaui_entry_shell_set_unknown ((GdauiEntryShell*) entry,
- !gda_holder_is_valid
((GdaHolder*) list->data));
- }
-
iter_row_changed_cb (form->priv->iter,
gda_data_model_iter_get_row (form->priv->iter), form);
diff --git a/libgda-ui/gdaui.css b/libgda-ui/gdaui.css
index 2397273..5cef693 100644
--- a/libgda-ui/gdaui.css
+++ b/libgda-ui/gdaui.css
@@ -2,18 +2,6 @@
background-color : transparent;
}
-GdauiEntryShell {
- -GtkArrow-arrow-scaling: 0.4;
- margin: 0;
- padding: 0;
- border-style: none;
- border-width: 0;
- -GtkButton-default-border: 0;
- -GtkButton-default-outside-border: 0;
- -GtkButton-inner-border: 0;
- background-color : transparent;
-}
-
GdauiCombo.gdaui-combo-as-list {
-GtkComboBox-appears-as-list : true;
}
diff --git a/libgda-ui/gdaui.gresource.xml b/libgda-ui/gdaui.gresource.xml
index bb9b463..ce94b37 100644
--- a/libgda-ui/gdaui.gresource.xml
+++ b/libgda-ui/gdaui.gresource.xml
@@ -9,8 +9,8 @@
<gresource prefix="/gdaui/images">
<file compressed="no">data/gdaui-generic.png</file>
</gresource>
- <gresource prefix="/gdaui/images">
- <file compressed="no">data/bin-attachment-16x16.png</file>
+ <gresource prefix="/gdaui">
+ <file compressed="true">data/mime-types-extensions</file>
</gresource>
<gresource prefix="/gdaui">
<file compressed="true">data-entries/gdaui-entry-string.xml</file>
diff --git a/libgda-ui/internal/utility.c b/libgda-ui/internal/utility.c
index aa5173b..e61d79f 100644
--- a/libgda-ui/internal/utility.c
+++ b/libgda-ui/internal/utility.c
@@ -180,9 +180,9 @@ gchar *
_gdaui_utility_markup_title (const gchar *title, gboolean optional)
{
if (!optional)
- return g_strdup_printf ("%s <span foreground='red' weight='bold'>*</span>:", title);
+ return g_markup_printf_escaped ("%s <span foreground='red' weight='bold'>*</span>:", title);
else
- return g_strdup_printf ("%s:", title);
+ return g_markup_printf_escaped ("%s:", title);
}
/*
diff --git a/libgda-ui/libgda-ui.symbols b/libgda-ui/libgda-ui.symbols
index 1d26742..a05e60e 100644
--- a/libgda-ui/libgda-ui.symbols
+++ b/libgda-ui/libgda-ui.symbols
@@ -123,8 +123,7 @@
gdaui_entry_set_width_chars
gdaui_entry_shell_get_type
gdaui_entry_shell_pack_entry
- gdaui_entry_shell_refresh
- gdaui_entry_shell_set_ucolor
+ gdaui_entry_shell_set_invalid_color
gdaui_entry_string_get_type
gdaui_entry_string_new
gdaui_entry_time_get_type
diff --git a/libgda/gda-enums.h b/libgda/gda-enums.h
index 973a551..f8072ec 100644
--- a/libgda/gda-enums.h
+++ b/libgda/gda-enums.h
@@ -41,7 +41,20 @@ typedef enum {
#define GDA_TRANSACTION_ISOLATION_UNKNOWN GDA_TRANSACTION_ISOLATION_SERVER_DEFAULT
-/* status of a value */
+/**
+ * GdaValueAttribute:
+ * @GDA_VALUE_ATTR_NONE: no specific attribute
+ * @GDA_VALUE_ATTR_IS_NULL: value is NULL (in the SQL sense)
+ * @GDA_VALUE_ATTR_CAN_BE_NULL: value can be set to NULL (in the SQL sense)
+ * @GDA_VALUE_ATTR_IS_DEFAULT: value is defined as the default value (the value itself is not specified)
+ * @GDA_VALUE_ATTR_CAN_BE_DEFAULT: a default value (not specified) exists for the value
+ * @GDA_VALUE_ATTR_IS_UNCHANGED: the value has not been changed (in the context of the attribute usage)
+ * @GDA_VALUE_ATTR_DATA_NON_VALID: the value is not valid (with regards to the context)
+ * @GDA_VALUE_ATTR_HAS_VALUE_ORIG: the value can be resetted to its "original" value (i.e. before it was
modified)
+ * @GDA_VALUE_ATTR_READ_ONLY: the value can't be modified
+ *
+ * Attributes of a value, used internally by Libgda in different contexts. Values can be OR'ed.
+ */
typedef enum {
GDA_VALUE_ATTR_NONE = 0,
GDA_VALUE_ATTR_IS_NULL = 1 << 0,
@@ -49,10 +62,10 @@ typedef enum {
GDA_VALUE_ATTR_IS_DEFAULT = 1 << 2,
GDA_VALUE_ATTR_CAN_BE_DEFAULT = 1 << 3,
GDA_VALUE_ATTR_IS_UNCHANGED = 1 << 4,
- GDA_VALUE_ATTR_ACTIONS_SHOWN = 1 << 5,
GDA_VALUE_ATTR_DATA_NON_VALID = 1 << 6,
GDA_VALUE_ATTR_HAS_VALUE_ORIG = 1 << 7,
GDA_VALUE_ATTR_NO_MODIF = 1 << 8,
+ GDA_VALUE_ATTR_READ_ONLY = 1 << 8, /* same as GDA_VALUE_ATTR_NO_MODIF */
} GdaValueAttribute;
/* how SQL identifiers are represented */
diff --git a/libgda/gda-value.c b/libgda/gda-value.c
index 43c7825..4c2367f 100644
--- a/libgda/gda-value.c
+++ b/libgda/gda-value.c
@@ -1628,29 +1628,35 @@ gda_value_new_blob_from_file (const gchar *filename)
}
/*
- * Warning: modifies @gmttm and loctm
+ * Warning: DOES NOT modify @gmttm and loctm
*
* Returns: the offset, or G_MAXLONG in case of error
*/
static glong
compute_tz_offset (struct tm *gmttm, struct tm *loctm)
{
- time_t lt, gt;
if (! gmttm || !loctm)
return G_MAXLONG;
- gmttm->tm_isdst = 0;
- loctm->tm_isdst = 0;
+ struct tm cgmttm, cloctm;
+ cgmttm = *gmttm;
+ cloctm = *loctm;
+
+ time_t lt, gt;
+ cgmttm.tm_isdst = 0;
+ cloctm.tm_isdst = 0;
- lt = mktime (loctm);
+ lt = mktime (&cloctm);
if (lt == -1)
return G_MAXLONG;
- gt = mktime (gmttm);
+ gt = mktime (&cgmttm);
if (gt == -1)
return G_MAXLONG;
-
glong off;
off = lt - gt;
+ g_print ("%s(): %02d:%02d:%02d %d\n", __FUNCTION__,
+ loctm->tm_hour, loctm->tm_min, loctm->tm_sec, (gint) (off / 3600));
+
if ((off >= 24 * 3600) || (off <= - 24 * 3600))
return G_MAXLONG;
else
@@ -1658,7 +1664,7 @@ compute_tz_offset (struct tm *gmttm, struct tm *loctm)
}
/**
- * gda_value_new_timestamp_from_timet: (skip)
+ * gda_value_new_timestamp_from_timet:
* @val: value to set for the new #GValue.
*
* Makes a new #GValue of type #GDA_TYPE_TIMESTAMP with value @val
@@ -1732,6 +1738,79 @@ gda_value_new_timestamp_from_timet (time_t val)
}
/**
+ * gda_value_new_time_from_timet:
+ * @val: value to set for the new #GValue.
+ *
+ * Makes a new #GValue of type #GDA_TYPE_TIME with value @val
+ * (of type time_t). The returned times's value is relative to the current
+ * timezone (i.e. is localtime).
+ *
+ * For example, to get a time representing the current time, use:
+ *
+ * <code>
+ * ts = gda_value_new_time_from_timet (time (NULL));
+ * </code>
+ *
+ * Returns: (transfer full): the newly created #GValue, or %NULL in case of error
+ *
+ * Free-function: gda_value_free
+ *
+ * Since: 6.0
+ */
+GValue *
+gda_value_new_time_from_timet (time_t val)
+{
+ GValue *value = NULL;
+ struct tm *ltm = NULL;
+ glong tz = 0;
+
+#ifdef HAVE_LOCALTIME_R
+ struct tm gmttm, loctm;
+ tzset ();
+ ltm = localtime_r ((const time_t *) &val, &loctm);
+ tz = compute_tz_offset (gmtime_r ((const time_t *) &val, &gmttm), &loctm);
+ if (tz == G_MAXLONG)
+ ltm = NULL;
+#elif HAVE_LOCALTIME_S
+ struct tm gmttm, loctm;
+ if ((localtime_s (&loctm, (const time_t *) &val) == 0) &&
+ (gmtime_s (&gmttm, (const time_t *) &val) == 0)) {
+ tz = compute_tz_offset (&gmttm, &loctm);
+ if (tz != G_MAXLONG)
+ ltm = &loctm;
+ }
+#else
+ struct tm gmttm, loctm;
+ ltm = gmtime ((const time_t *) &val);
+ if (ltm) {
+ gmttm = *ltm;
+ ltm = localtime ((const time_t *) &val);
+ if (ltm) {
+ loctm = *ltm;
+ tz = compute_tz_offset (&gmttm, &loctm);
+ if (tz == G_MAXLONG)
+ ltm = NULL;
+ }
+ }
+
+#endif
+
+ if (ltm) {
+ GdaTime tim;
+ tim.hour = ltm->tm_hour;
+ tim.minute = ltm->tm_min;
+ tim.second = ltm->tm_sec;
+ tim.fraction = 0;
+ tim.timezone = tz;
+
+ value = g_new0 (GValue, 1);
+ gda_value_set_time (value, (const GdaTime *) &tim);
+ }
+
+ return value;
+}
+
+/**
* gda_value_new_from_string: (skip)
* @as_string: stringified representation of the value.
* @type: the new value type.
diff --git a/libgda/gda-value.h b/libgda/gda-value.h
index 7ac4629..1037aaf 100644
--- a/libgda/gda-value.h
+++ b/libgda/gda-value.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2001 - 2003 Rodrigo Moya <rodrigo gnome-db org>
* Copyright (C) 2002 - 2003 Gonzalo Paniagua Javier <gonzalo gnome-db org>
- * Copyright (C) 2002 - 2013 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2002 - 2015 Vivien Malerba <malerba gnome-db org>
* Copyright (C) 2003 Akira TAGOH <tagoh gnome-db org>
* Copyright (C) 2003 Danilo Schoeneberg <dschoene src gnome org>
* Copyright (C) 2003 Laurent Sansonetti <laurent datarescue be>
@@ -203,6 +203,7 @@ GValue *gda_value_new_default (const gchar *default_va
GValue *gda_value_new_binary (const guchar *val, glong size);
GValue *gda_value_new_blob (const guchar *val, glong size);
GValue *gda_value_new_blob_from_file (const gchar *filename);
+GValue *gda_value_new_time_from_timet (time_t val);
GValue *gda_value_new_timestamp_from_timet (time_t val);
GValue *gda_value_new_from_string (const gchar *as_string, GType type);
diff --git a/libgda/handlers/gda-handler-time.c b/libgda/handlers/gda-handler-time.c
index b4b7632..5c4385a 100644
--- a/libgda/handlers/gda-handler-time.c
+++ b/libgda/handlers/gda-handler-time.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 - 2013 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2006 - 2015 Vivien Malerba <malerba gnome-db org>
* Copyright (C) 2007 Murray Cumming <murrayc murrayc com>
* Copyright (C) 2009 Bas Driessen <bas driessen xobas com>
* Copyright (C) 2010 David King <davidk openismus com>
@@ -597,6 +597,66 @@ gda_handler_time_get_format (GdaHandlerTime *dh, GType type)
return str;
}
+/**
+ * gda_handler_time_get_hint:
+ * @dh: a #GdaHandlerTime object
+ * @type: the type of data being handled
+ *
+ * Get a string giving the user a hint about the locale-dependent requested format.
+ *
+ * Returns: a new string
+ *
+ * Since: 6.0
+ */
+gchar *
+gda_handler_time_get_hint (GdaHandlerTime *dh, GType type)
+{
+ gchar *str;
+ GString *string;
+ gint i;
+
+ g_return_val_if_fail (GDA_IS_HANDLER_TIME (dh), NULL);
+
+ string = g_string_new ("");
+ if ((type == G_TYPE_DATE) || (type == GDA_TYPE_TIMESTAMP) || (type == G_TYPE_DATE_TIME)) {
+ for (i=0; i<3; i++) {
+ if (i > 0)
+ g_string_append_c (string, dh->priv->str_locale->separator);
+ switch (dh->priv->str_locale->dmy_order[i]) {
+ case G_DATE_DAY:
+ /* To translators: DD represents a place holder in a date string. For example
in the "YYYY-MM-DD" format, one knows that she has to replace DD by a day number */
+ g_string_append (string, _("DD"));
+ break;
+ case G_DATE_MONTH:
+ /* To translators: MM represents a place holder in a date string. For example
in the "YYYY-MM-DD" format, one knows that she has to replace MM by a month number */
+ g_string_append (string, _("MM"));
+ break;
+ case G_DATE_YEAR:
+ if (dh->priv->str_locale->twodigit_years)
+ /* To translators: YY represents a place holder in a date string. For
example in the "YY-MM-DD" format, one knows that she has to replace YY by a year number, on 2 digits */
+ g_string_append (string, _("YY"));
+ else
+ /* To translators: YYYY represents a place holder in a date string.
For example in the "YYYY-MM-DD" format, one knows that she has to replace YYYY by a year number, on 4 digits
*/
+ g_string_append (string, _("YYYY"));
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
+ }
+ if (type == GDA_TYPE_TIMESTAMP)
+ g_string_append_c (string, ' ');
+
+ if ((type == GDA_TYPE_TIME) || (type == GDA_TYPE_TIMESTAMP) || (type == G_TYPE_DATE_TIME))
+ /* To translators: HH:MM:SS represents a time format. For example in the "HH:MM:SS" format,
one knows that she has to replace HH by a number of hours, and so on */
+ g_string_append (string, "HH:MM:SS");
+
+ str = string->str;
+ g_string_free (string, FALSE);
+ return str;
+}
+
/* Interface implementation */
/* REM: SQL date format is always returned using the MM-DD-YYY format, it's up to the
diff --git a/libgda/handlers/gda-handler-time.h b/libgda/handlers/gda-handler-time.h
index 834410d..c1e2124 100644
--- a/libgda/handlers/gda-handler-time.h
+++ b/libgda/handlers/gda-handler-time.h
@@ -74,6 +74,8 @@ void gda_handler_time_set_str_spec (GdaHandlerTime *dh, GDateDMY fir
gchar *gda_handler_time_get_no_locale_str_from_value (GdaHandlerTime *dh, const GValue *value);
gchar *gda_handler_time_get_format (GdaHandlerTime *dh, GType type);
+gchar *gda_handler_time_get_hint (GdaHandlerTime *dh, GType type);
+
G_END_DECLS
#endif
diff --git a/libgda/libgda.symbols b/libgda/libgda.symbols
index 851ea6a..93f0b24 100644
--- a/libgda/libgda.symbols
+++ b/libgda/libgda.symbols
@@ -372,6 +372,7 @@
gda_handler_string_new_with_provider
gda_handler_time_get_format
gda_handler_time_get_no_locale_str_from_value
+ gda_handler_time_get_hint
gda_handler_time_get_type
gda_handler_time_new
gda_handler_time_new_no_locale
@@ -949,6 +950,7 @@
gda_value_new_from_string
gda_value_new_from_xml
gda_value_new_null
+ gda_value_new_time_from_timet
gda_value_new_timestamp_from_timet
gda_value_reset_with_type
gda_value_set_binary
diff --git a/testing/gdaui-test-data-entries.c b/testing/gdaui-test-data-entries.c
index cc4bcb4..b8bd831 100644
--- a/testing/gdaui-test-data-entries.c
+++ b/testing/gdaui-test-data-entries.c
@@ -144,10 +144,11 @@ main (int argc, char **argv)
gdaui_init ();
/* init main conf */
- GType tested_gtypes [] = {G_TYPE_INT64, G_TYPE_UINT64, GDA_TYPE_BINARY, G_TYPE_BOOLEAN, GDA_TYPE_BLOB,
+ GType tested_gtypes [] = {G_TYPE_STRING,
+ G_TYPE_INT64, G_TYPE_UINT64, GDA_TYPE_BINARY, G_TYPE_BOOLEAN, GDA_TYPE_BLOB,
G_TYPE_DATE, G_TYPE_DOUBLE,
GDA_TYPE_GEOMETRIC_POINT, G_TYPE_OBJECT, G_TYPE_INT,
- GDA_TYPE_NUMERIC, G_TYPE_FLOAT, GDA_TYPE_SHORT, GDA_TYPE_USHORT,
G_TYPE_STRING,
+ GDA_TYPE_NUMERIC, G_TYPE_FLOAT, GDA_TYPE_SHORT, GDA_TYPE_USHORT,
GDA_TYPE_TIME, GDA_TYPE_TIMESTAMP, G_TYPE_CHAR, G_TYPE_UCHAR, G_TYPE_UINT};
mainconf.test_type = TESTED_BASIC;
if (test_type) {
@@ -197,6 +198,8 @@ main (int argc, char **argv)
"them in pages of a notebook. Each page presents the default "
"data entry for the corresponding data type.");
gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_widget_set_margin_start (label, 10);
+ gtk_widget_set_margin_end (label, 10);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 5);
gtk_widget_show (label);
@@ -221,6 +224,8 @@ main (int argc, char **argv)
"them in pages of a notebook. Each page tests a plugin for a given "
"data type");
gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_widget_set_margin_start (label, 10);
+ gtk_widget_set_margin_end (label, 10);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 5);
gtk_widget_show (label);
@@ -404,6 +409,8 @@ build_test_for_plugin_struct (GdauiPlugin *plugin)
g_assert (plugin);
grid = gtk_grid_new ();
+ gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
+ gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
/* explain top label */
if (plugin->plugin_file)
@@ -459,12 +466,17 @@ build_test_for_plugin_struct (GdauiPlugin *plugin)
g_error_free (error);
}
else {
- GtkWidget *form;
-
+ GtkWidget *form, *frame;
+ frame = gtk_frame_new ("");
form = gdaui_basic_form_new (plist);
g_object_unref (plist);
- gtk_grid_attach (GTK_GRID (grid), form, 1, 2, 1, 1);
- gtk_widget_show (form);
+ gtk_widget_set_margin_top (form, 10);
+ gtk_widget_set_margin_bottom (form, 10);
+ gtk_widget_set_margin_start (form, 10);
+ gtk_widget_set_margin_end (form, 10);
+ gtk_grid_attach (GTK_GRID (grid), frame, 1, 2, 1, 1);
+ gtk_container_add (GTK_CONTAINER (frame), form);
+ gtk_widget_show_all (frame);
g_object_set_data (G_OBJECT (grid), "options", form);
g_signal_connect (G_OBJECT (form), "holder-changed",
G_CALLBACK (options_form_holder_changed_cb), grid);
@@ -494,9 +506,14 @@ create_plugin_nb (GtkWidget *grid, GdauiPlugin *plugin)
GType type;
GdaDataHandler *dh;
+ label = gtk_label_new ("");
+ gtk_label_set_markup (GTK_LABEL (label), "<b>Handled GTypes:</b>");
+ gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
+ gtk_widget_show (label);
+
nb = gtk_notebook_new ();
gtk_notebook_set_tab_pos (GTK_NOTEBOOK (nb), GTK_POS_LEFT);
- gtk_grid_attach (GTK_GRID (grid), nb, 0, 1, 2, 1);
+ gtk_grid_attach (GTK_GRID (grid), nb, 1, 3, 1, 1);
gtk_widget_show (nb);
g_signal_connect (G_OBJECT (nb), "switch-page",
G_CALLBACK (plugin_nb_page_changed_cb), grid);
@@ -667,7 +684,7 @@ options_form_holder_changed_cb (G_GNUC_UNUSED GdauiBasicForm *form, G_GNUC_UNUSE
/*
* Basic test (individual GdauiDataEntry widget being tested)
*/
-void entry_contents_modified (GtkWidget *entry, gpointer data);
+void entry_contents_or_attrs_changed (GtkWidget *entry, gpointer data);
void null_toggled_cb (GtkToggleButton *button, GtkWidget *entry);
void default_toggled_cb (GtkToggleButton *button, GtkWidget *entry);
void actions_toggled_cb (GtkToggleButton *button, GtkWidget *entry);
@@ -703,11 +720,22 @@ build_basic_test_for_gtype (GdaDataHandler *dh, GType type, const gchar *plugin_
gtk_widget_show (label);
/* widget being tested */
+ label = gtk_label_new ("Data entry widget: ");
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
+ gtk_widget_show (label);
+
+ GtkWidget *frame;
+ frame = gtk_frame_new ("");
+ gtk_grid_attach (GTK_GRID (grid), frame, 1, 1, 2, 1);
wid = GTK_WIDGET (gdaui_new_data_entry (type, plugin_name));
+ gtk_widget_set_margin_top (wid, 10);
+ gtk_widget_set_margin_bottom (wid, 10);
+ gtk_widget_set_margin_start (wid, 10);
+ gtk_widget_set_margin_end (wid, 10);
g_object_set (G_OBJECT (wid), "handler", dh, NULL);
-
- gtk_grid_attach (GTK_GRID (grid), wid, 0, 1, 3, 1);
- gtk_widget_show (wid);
+ gtk_container_add (GTK_CONTAINER (frame), wid);
+ gtk_widget_show_all (frame);
/* Other widgets */
label = gtk_label_new ("Current flags: ");
@@ -731,13 +759,15 @@ build_basic_test_for_gtype (GdaDataHandler *dh, GType type, const gchar *plugin_
gtk_grid_attach (GTK_GRID (grid), label, 1, 3, 1, 1);
g_object_set_data (G_OBJECT (wid), "value", label);
g_signal_connect (G_OBJECT (wid), "contents-modified",
- G_CALLBACK (entry_contents_modified), NULL);
+ G_CALLBACK (entry_contents_or_attrs_changed), NULL);
+ g_signal_connect (G_OBJECT (wid), "status-changed",
+ G_CALLBACK (entry_contents_or_attrs_changed), NULL);
+ entry_contents_or_attrs_changed (wid, GTK_LABEL (label));
gtk_widget_show (label);
- entry_contents_modified (wid, GTK_LABEL (label));
-
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
- gtk_grid_attach (GTK_GRID (grid), bbox, 0, 4, 3, 1);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START);
+ gtk_grid_attach (GTK_GRID (grid), bbox, 0, 4, 2, 1);
button = gtk_toggle_button_new_with_label ("NULL ok");
g_signal_connect (G_OBJECT (button), "toggled",
@@ -755,31 +785,28 @@ build_basic_test_for_gtype (GdaDataHandler *dh, GType type, const gchar *plugin_
gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (wid)) &
GDA_VALUE_ATTR_CAN_BE_DEFAULT);
- button = gtk_toggle_button_new_with_label ("Actions?");
- g_signal_connect (G_OBJECT (button), "toggled",
- G_CALLBACK (actions_toggled_cb), wid);
- gtk_container_add (GTK_CONTAINER (bbox), button);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
- gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (wid)) &
- GDA_VALUE_ATTR_ACTIONS_SHOWN);
-
button = gtk_toggle_button_new_with_label ("Editable?");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
g_signal_connect (G_OBJECT (button), "toggled",
G_CALLBACK (editable_toggled_cb), wid);
gtk_container_add (GTK_CONTAINER (bbox), button);
-
+
+ entry = gtk_entry_new ();
+ gtk_entry_set_placeholder_text (GTK_ENTRY (entry), "Grab focus here!");
+ gtk_widget_set_can_focus (entry, TRUE);
+ gtk_container_add (GTK_CONTAINER (bbox), entry);
+
gtk_widget_show_all (bbox);
/* to set the original value */
entry = GTK_WIDGET (gdaui_new_data_entry (type, plugin_name));
g_object_set (G_OBJECT (entry), "handler", dh, NULL);
- gtk_grid_attach (GTK_GRID (grid), entry, 0, 5, 2, 1);
+ gtk_grid_attach (GTK_GRID (grid), entry, 1, 5, 1, 1);
gtk_widget_show (entry);
button = gtk_button_new_with_label ("Set as original");
g_object_set_data (G_OBJECT (button), "entry", entry);
- gtk_grid_attach (GTK_GRID (grid), button, 2, 5, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), button, 0, 5, 1, 1);
gtk_widget_show (button);
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (orig_clicked_cb), wid);
@@ -788,11 +815,11 @@ build_basic_test_for_gtype (GdaDataHandler *dh, GType type, const gchar *plugin_
entry = GTK_WIDGET (gdaui_new_data_entry (type, plugin_name));
g_object_set (G_OBJECT (entry), "handler", dh, NULL);
- gtk_grid_attach (GTK_GRID (grid), entry, 0, 6, 2, 1);
+ gtk_grid_attach (GTK_GRID (grid), entry, 1, 6, 1, 1);
gtk_widget_show (entry);
button = gtk_button_new_with_label ("Set as default");
g_object_set_data (G_OBJECT (button), "entry", entry);
- gtk_grid_attach (GTK_GRID (grid), button, 2, 6, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), button, 0, 6, 1, 1);
gtk_widget_show (button);
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (default_clicked_cb), wid);
@@ -832,20 +859,6 @@ default_toggled_cb (GtkToggleButton *button, GtkWidget *entry)
}
void
-actions_toggled_cb (GtkToggleButton *button, GtkWidget *entry)
-{
- guint action = 0;
- if (gtk_toggle_button_get_active (button))
- action = GDA_VALUE_ATTR_ACTIONS_SHOWN;
-
- gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (entry),
- action, GDA_VALUE_ATTR_ACTIONS_SHOWN);
- gtk_toggle_button_set_active (button,
- gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (entry)) &
- GDA_VALUE_ATTR_ACTIONS_SHOWN);
-}
-
-void
editable_toggled_cb (GtkToggleButton *button, GtkWidget *entry)
{
gboolean editable;
@@ -855,27 +868,51 @@ editable_toggled_cb (GtkToggleButton *button, GtkWidget *entry)
}
void
-entry_contents_modified (GtkWidget *entry, G_GNUC_UNUSED gpointer data)
+entry_contents_or_attrs_changed (GtkWidget *entry, G_GNUC_UNUSED gpointer data)
{
guint attrs;
GtkLabel *label;
- GString *str = g_string_new ("");
+ GString *str = NULL;
GValue *value;
GdaDataHandler *dh;
/* flags */
label = g_object_get_data (G_OBJECT (entry), "flags");
attrs = gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (entry));
- if (attrs & GDA_VALUE_ATTR_IS_NULL)
- g_string_append (str, "N ");
- if (attrs & GDA_VALUE_ATTR_IS_DEFAULT)
- g_string_append (str, "D ");
- if (!(attrs & GDA_VALUE_ATTR_IS_UNCHANGED))
- g_string_append (str, "M ");
- if (attrs & GDA_VALUE_ATTR_DATA_NON_VALID)
- g_string_append (str, "U ");
-
- gtk_label_set_text (label, str->str);
+ if (attrs & GDA_VALUE_ATTR_IS_NULL) {
+ if (!str) str = g_string_new (""); else g_string_append (str, ", ");
+ g_string_append (str, "IS_NULL");
+ }
+ if (attrs & GDA_VALUE_ATTR_CAN_BE_NULL) {
+ if (!str) str = g_string_new (""); else g_string_append (str, ", ");
+ g_string_append (str, "CAN_BE_NULL");
+ }
+ if (attrs & GDA_VALUE_ATTR_IS_DEFAULT) {
+ if (!str) str = g_string_new (""); else g_string_append (str, ", ");
+ g_string_append (str, "IS_DEFAULT");
+ }
+ if (attrs & GDA_VALUE_ATTR_CAN_BE_DEFAULT) {
+ if (!str) str = g_string_new (""); else g_string_append (str, ", ");
+ g_string_append (str, "CAN_BE_DEFAULT");
+ }
+ if (attrs & GDA_VALUE_ATTR_IS_UNCHANGED) {
+ if (!str) str = g_string_new (""); else g_string_append (str, ", ");
+ g_string_append (str, "IS_UNCHANGED");
+ }
+ if (attrs & GDA_VALUE_ATTR_DATA_NON_VALID) {
+ if (!str) str = g_string_new (""); else g_string_append (str, ", ");
+ g_string_append (str, "NON_VALID");
+ }
+ if (attrs & GDA_VALUE_ATTR_READ_ONLY) {
+ if (!str) str = g_string_new (""); else g_string_append (str, ", ");
+ g_string_append (str, "READ_ONLY");
+ }
+ if (attrs & GDA_VALUE_ATTR_HAS_VALUE_ORIG) {
+ if (!str) str = g_string_new (""); else g_string_append (str, ", ");
+ g_string_append (str, "HAS_VALUE_ORIG");
+ }
+
+ gtk_label_set_text (label, str ? str->str : "");
g_string_free (str, TRUE);
/* value */
@@ -894,7 +931,6 @@ entry_contents_modified (GtkWidget *entry, G_GNUC_UNUSED gpointer data)
blob = gda_value_get_blob (value);
strval = g_strdup_printf ("Blob data, size=%ld", ((GdaBinary*) blob)->binary_length);
}
-
else
strval = gda_data_handler_get_sql_from_value (dh, value);
gda_value_free (value);
@@ -924,7 +960,6 @@ orig_clicked_cb (GtkButton *button, GtkWidget *entry)
gdaui_data_entry_set_reference_value (GDAUI_DATA_ENTRY (entry), value);
gda_value_free (value);
- entry_contents_modified (entry, NULL);
}
void
diff --git a/testing/gdaui-test-errors.c b/testing/gdaui-test-errors.c
index a1320f3..0f561e8 100644
--- a/testing/gdaui-test-errors.c
+++ b/testing/gdaui-test-errors.c
@@ -27,14 +27,21 @@ static void destroy (G_GNUC_UNUSED GtkWidget *widget, G_GNUC_UNUSED gpointer dat
static gboolean change_unknow_color (GdauiBasicForm *form)
{
+ static gdouble sign = 1.;
static gdouble red = .3;
static gdouble green = .1;
static gdouble blue = .1;
static gdouble alpha = .5;
- red += .075;
- if (red >= 1.)
+ red += .075 * sign;
+ if (red >= 1.) {
+ sign = -1.;
+ red = 1.;
+ }
+ else if (red <= .3) {
+ sign = 1.;
red = .3;
+ }
gdaui_basic_form_set_unknown_color (form, red, green, blue, alpha);
return TRUE; /* keep timer */
}
diff --git a/testing/gdaui-test-widget-entry.c b/testing/gdaui-test-widget-entry.c
index 85e70ad..1e52039 100644
--- a/testing/gdaui-test-widget-entry.c
+++ b/testing/gdaui-test-widget-entry.c
@@ -144,9 +144,8 @@ main (int argc, char* argv[])
#define HAVE_NORMAL
#ifdef HAVE_NORMAL
/* #0 */
- tmp = g_strdup_printf ("#%d", index);
- label = gtk_label_new (tmp);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
+#define L0 "NULL, NULL"
+ label = make_label (0, L0);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
entry = gdaui_entry_new (NULL, NULL);
@@ -154,11 +153,11 @@ main (int argc, char* argv[])
index++;
gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
g_signal_connect (entry, "changed",
- G_CALLBACK (entry_changed_cb), tmp);
+ G_CALLBACK (entry_changed_cb), L0);
+
/* #1 */
- tmp = g_strdup_printf ("#%d", index);
- label = gtk_label_new (tmp);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
+#define L1 "\"€ \", NULL"
+ label = make_label (1, L1);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
entry = gdaui_entry_new ("€ ", NULL);
@@ -166,12 +165,11 @@ main (int argc, char* argv[])
index++;
gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
g_signal_connect (entry, "changed",
- G_CALLBACK (entry_changed_cb), tmp);
+ G_CALLBACK (entry_changed_cb), L1);
/* #2 */
- tmp = g_strdup_printf ("#%d", index);
- label = gtk_label_new (tmp);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
+#define L2 "NULL, \" Ê\""
+ label = make_label (2, L2);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
entry = gdaui_entry_new (NULL, " Ê");
@@ -179,12 +177,11 @@ main (int argc, char* argv[])
index++;
gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
g_signal_connect (entry, "changed",
- G_CALLBACK (entry_changed_cb), tmp);
+ G_CALLBACK (entry_changed_cb), L2);
/* #3 */
- tmp = g_strdup_printf ("#%d", index);
- label = gtk_label_new (tmp);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
+#define L3 "\"€€ \", \" êê\""
+ label = make_label (3, L3);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
entry = gdaui_entry_new ("€€ ", " êê");
@@ -192,7 +189,7 @@ main (int argc, char* argv[])
index++;
gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
g_signal_connect (entry, "changed",
- G_CALLBACK (entry_changed_cb), tmp);
+ G_CALLBACK (entry_changed_cb), L3);
#endif
#define HAVE_FORMATTED
@@ -208,9 +205,8 @@ main (int argc, char* argv[])
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
/* #4 */
- tmp = g_strdup_printf ("#%d", index);
- label = gtk_label_new (tmp);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
+#define L4 "\"TIME=00:00:00\", NULL"
+ label = make_label (4, L4);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
entry = gdaui_formatted_entry_new ("TIME=00:00:00", NULL);
@@ -218,21 +214,20 @@ main (int argc, char* argv[])
index++;
gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
g_signal_connect (entry, "changed",
- G_CALLBACK (entry_changed_cb), tmp);
+ G_CALLBACK (entry_changed_cb), L4);
/* #5 */
- tmp = g_strdup_printf ("#%d", index);
- label = gtk_label_new (tmp);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
+#define L5 "\"TIME=00€00:00\", \"------- -- \""
+ label = make_label (5, L5);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
entry = gdaui_formatted_entry_new ("TIME=00€00:00",
- "------- -- ");
+ "------- -- ");
entries[index] = entry;
index++;
gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
g_signal_connect (entry, "changed",
- G_CALLBACK (entry_changed_cb), tmp);
+ G_CALLBACK (entry_changed_cb), L5);
#endif
#define HAVE_NUMERIC
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]