2
* Copyright (C) 2003 - 2004 Vivien Malerba <malerba@gnome-db.org>
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Library General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Library General Public License for more details.
14
* You should have received a copy of the GNU Library General Public
15
* License along with this library; if not, write to the
16
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
* Boston, MA 02111-1307, USA.
22
#include <libgda/libgda.h>
23
#include "mg-data-entry.h"
24
#include "mg-result-set.h"
25
#include "mg-parameter.h"
26
#include "mg-server-data-type.h"
27
#include "mg-server.h"
29
#include "mg-renderer.h"
30
#include "mg-entity.h"
32
#include "mg-qfield.h"
33
#include "mg-qf-field.h"
37
* utility_entry_build_actions_menu
42
* Creates a GtkMenu widget which contains the possible actions on a data entry which
43
* attributes are @attrs. After the menu has been displayed, and when an action is selected,
44
* the @function callback is called with the 'user_data' being @obj_data.
46
* The menu item which emits the signal has a "action" attribute which describes what action the
49
* Returns: the new menu
52
utility_entry_build_actions_menu (GObject *obj_data, guint attrs, GCallback function)
54
GtkWidget *menu, *mitem;
56
gboolean nullact = FALSE;
57
gboolean defact = FALSE;
58
gboolean reset = FALSE;
60
gboolean value_is_null;
61
gboolean value_is_modified;
62
gboolean value_is_default;
64
menu = gtk_menu_new ();
66
/* which menu items to make sensitive ? */
67
value_is_null = attrs & MG_DATA_ENTRY_IS_NULL;
68
value_is_modified = ! (attrs & MG_DATA_ENTRY_IS_UNCHANGED);
69
value_is_default = attrs & MG_DATA_ENTRY_IS_DEFAULT;
71
if ((attrs & MG_DATA_ENTRY_CAN_BE_NULL) &&
72
!(attrs & MG_DATA_ENTRY_IS_NULL))
74
if ((attrs & MG_DATA_ENTRY_CAN_BE_DEFAULT) &&
75
!(attrs & MG_DATA_ENTRY_IS_DEFAULT))
77
if (!(attrs & MG_DATA_ENTRY_IS_UNCHANGED)) {
78
if (attrs & MG_DATA_ENTRY_HAS_VALUE_ORIG)
82
/* set to NULL item */
83
str = g_strdup (_("Unset"));
84
mitem = gtk_check_menu_item_new_with_label (str);
85
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mitem),
87
gtk_widget_show (mitem);
88
g_object_set_data (G_OBJECT (mitem), "action", GUINT_TO_POINTER (MG_DATA_ENTRY_IS_NULL));
89
g_signal_connect (G_OBJECT (mitem), "activate",
90
G_CALLBACK (function), obj_data);
91
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mitem);
93
gtk_widget_set_sensitive (mitem, nullact);
95
/* default value item */
96
str = g_strdup (_("Set to default value"));
97
mitem = gtk_check_menu_item_new_with_label (str);
98
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mitem),
100
gtk_widget_show (mitem);
101
g_object_set_data (G_OBJECT (mitem), "action", GUINT_TO_POINTER (MG_DATA_ENTRY_IS_DEFAULT));
102
g_signal_connect (G_OBJECT (mitem), "activate",
103
G_CALLBACK (function), obj_data);
104
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mitem);
106
gtk_widget_set_sensitive (mitem, defact);
108
/* reset to original value item */
109
str = g_strdup (_("Reset to original value"));
110
mitem = gtk_check_menu_item_new_with_label (str);
111
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mitem),
113
gtk_widget_show (mitem);
114
g_object_set_data (G_OBJECT (mitem), "action", GUINT_TO_POINTER (MG_DATA_ENTRY_IS_UNCHANGED));
115
g_signal_connect (G_OBJECT (mitem), "activate",
116
G_CALLBACK (function), obj_data);
117
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mitem);
119
gtk_widget_set_sensitive (mitem, reset);
126
* utility_entry_build_info_colors_array
128
* Creates an array of colors for the different states of an entry:
129
* Valid <-> No special color
133
* Each status (except Valid) is represented by two colors for GTK_STATE_NORMAL and
134
* GTK_STATE_PRELIGHT.
136
* Returns: a new array of 6 colors
138
GdkColor **utility_entry_build_info_colors_array ()
143
colors = g_new0 (GdkColor *, 6);
146
color = g_new0 (GdkColor, 1);
147
gdk_color_parse (MG_COLOR_NORMAL_NULL, color);
148
if (!gdk_colormap_alloc_color (gtk_widget_get_default_colormap (), color, FALSE, TRUE)) {
154
color = g_new0 (GdkColor, 1);
155
gdk_color_parse (MG_COLOR_PRELIGHT_NULL, color);
156
if (!gdk_colormap_alloc_color (gtk_widget_get_default_colormap (), color, FALSE, TRUE)) {
164
color = g_new0 (GdkColor, 1);
165
gdk_color_parse (MG_COLOR_NORMAL_DEFAULT, color);
166
if (!gdk_colormap_alloc_color (gtk_widget_get_default_colormap (), color, FALSE, TRUE)) {
172
color = g_new0 (GdkColor, 1);
173
gdk_color_parse (MG_COLOR_PRELIGHT_DEFAULT, color);
174
if (!gdk_colormap_alloc_color (gtk_widget_get_default_colormap (), color, FALSE, TRUE)) {
182
color = g_new0 (GdkColor, 1);
183
gdk_color_parse (MG_COLOR_NORMAL_INVALID, color);
184
if (!gdk_colormap_alloc_color (gtk_widget_get_default_colormap (), color, FALSE, TRUE)) {
190
color = g_new0 (GdkColor, 1);
191
gdk_color_parse (MG_COLOR_PRELIGHT_INVALID, color);
192
if (!gdk_colormap_alloc_color (gtk_widget_get_default_colormap (), color, FALSE, TRUE)) {
202
static const GdaValue *get_value_from_recordset (GtkTreeModel *tree_model, GtkTreeIter *iter,
203
MgWorkCore *core, MgParameter *context_param);
204
static ModelUserModifiedValue *get_user_modifs (GtkTreeModel *tree_model, GtkTreeIter *iter, MgContextNode *context_node);
207
* utility_grid_model_get_value
215
* Fetch the GdaValue which is in @core's resultset corresponding to the @node column
216
* and the row described through @iter in the @tree_model model.
218
* If @attributes is not %NULL, then after the call, it will contain the #MgDataEntry attributes
219
* corresponding to the value.
221
* The returned value can be of type GDA_VALUE_TYPE_LIST if several values are to be stored.
223
* Returns: the GdaValue (a newly allocated one), never returns NULL.
226
utility_grid_model_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter,
227
MgWorkCore *core, MgContextNode *context_node,
228
gboolean pk_values_only, guint *attributes)
231
GdaValue *retval = NULL;
233
/* signle direct parameter */
234
if (context_node->param) {
235
const GdaValue *value = NULL;
236
ModelUserModifiedValue *user_modif;
237
gboolean is_default = FALSE;
238
gboolean is_unchanged = TRUE;
240
const GdaValue *default_val;
242
/* if (row >= 0) then the data row originally exists into the resultset, and
243
* otherwise it is a new row, to be inserted */
244
gtk_tree_model_get (tree_model, iter, COLUMN_ROW_NUM, &row, -1);
246
default_val = mg_parameter_get_default_value (context_node->param);
247
user_modif = get_user_modifs (tree_model, iter, context_node);
249
value = user_modif->value;
250
attrs = user_modif->attributes;
251
is_default = attrs & MG_DATA_ENTRY_IS_DEFAULT;
253
const GdaValue *orig_value;
255
orig_value = get_value_from_recordset (tree_model, iter, core, context_node->param);
256
is_unchanged = FALSE;
257
if (((!value || gda_value_is_null (value)) &&
258
(!orig_value || gda_value_is_null (orig_value))) ||
259
(value && orig_value &&
260
(gda_value_get_type (value) == gda_value_get_type (orig_value)) &&
261
!gda_value_compare (value, orig_value)))
265
is_unchanged = FALSE;
268
if (!g_slist_find (core->params_in_data_rs, context_node->param))
269
value = mg_parameter_get_value (context_node->param);
272
value = get_value_from_recordset (tree_model, iter, core, context_node->param);
279
/* Same attributes setting as for mg-form.c mg_form_initialize() around line 296 */
280
attrs = attrs | ((!value || gda_value_is_null (value)) ? MG_DATA_ENTRY_IS_NULL : 0);
281
attrs = attrs | (mg_parameter_get_not_null (context_node->param) ? 0 : MG_DATA_ENTRY_CAN_BE_NULL);
282
attrs = attrs | (default_val ? MG_DATA_ENTRY_CAN_BE_DEFAULT : 0);
283
attrs = attrs | (is_unchanged ? MG_DATA_ENTRY_IS_UNCHANGED : 0);
285
/* Validity calculation: the same as for mg-entry-wrapper mg_entry_wrapper_get_attributes() */
286
if (! (is_default && (attrs & MG_DATA_ENTRY_CAN_BE_DEFAULT))) {
287
if (/*(gda_value_is_null (value) && !null_forced) ||*/
288
((!value || gda_value_is_null (value)) && !(attrs & MG_DATA_ENTRY_CAN_BE_NULL)))
289
attrs = attrs | MG_DATA_ENTRY_DATA_NON_VALID;
292
/* if we are not inserting a new row, then we consider that we have an original value */
294
attrs = attrs | MG_DATA_ENTRY_HAS_VALUE_ORIG;
297
retval = gda_value_new_null ();
299
retval = gda_value_copy (value);
309
/* Parameter(s) constrained by a query, we only want the PK fields for the query */
310
if (pk_values_only) {
311
GList *values = NULL;
312
ModelUserModifiedValue *user_modif;
313
gboolean is_default = TRUE;
314
gboolean is_unchanged = TRUE;
315
gboolean is_null = TRUE;
316
gboolean can_be_default = TRUE;
317
gboolean can_be_null = TRUE;
322
/* if (row >= 0) then the data row originally exists into the resultset, and
323
* otherwise it is a new row, to be inserted */
324
gtk_tree_model_get (tree_model, iter, COLUMN_ROW_NUM, &row, -1);
326
user_modif = get_user_modifs (tree_model, iter, context_node);
328
/* building the 'values' list */
330
if (user_modif->value && !gda_value_is_null (user_modif->value)) {
331
GList *tmplist = (GList *) gda_value_get_list (user_modif->value);
332
g_assert (gda_value_isa (user_modif->value, GDA_VALUE_TYPE_LIST));
334
params = context_node->params;
338
pos = GPOINTER_TO_INT (g_hash_table_lookup (context_node->params_pos_in_query,
340
values = g_list_append (values, g_list_nth_data (tmplist, pos));
341
params = g_slist_next (params);
345
attrs = user_modif->attributes;
349
params = context_node->params;
351
values = g_list_append (values,
352
get_value_from_recordset (tree_model, iter, core,
353
MG_PARAMETER (params->data)));
354
params = g_slist_next (params);
360
/* computing the attributes if necessary */
363
is_unchanged = FALSE;
365
params = context_node->params;
367
const GdaValue *value = NULL;
371
value = (GdaValue *) (list->data);
372
list = g_list_next (list);
376
can_be_default = mg_parameter_get_default_value (MG_PARAMETER (params->data)) ? TRUE : FALSE;
379
can_be_null = mg_parameter_get_not_null (MG_PARAMETER (params->data)) ? FALSE : TRUE;
382
const GdaValue *orig_value;
384
orig_value = get_value_from_recordset (tree_model, iter, core,
385
MG_PARAMETER (params->data));
386
is_unchanged = FALSE;
387
if (((!value || gda_value_is_null (value)) && (!orig_value || gda_value_is_null (orig_value))) ||
388
(value && orig_value &&
389
(gda_value_get_type (value) == gda_value_get_type (orig_value)) &&
390
!gda_value_compare (value, orig_value)))
395
is_null = (!value || gda_value_is_null (value)) ? TRUE : 0;
397
params = g_slist_next (params);
400
/* Same attributes setting as for mg-form.c mg_form_initialize() around line 296 */
401
attrs = attrs | (is_null ? MG_DATA_ENTRY_IS_NULL : 0);
402
attrs = attrs | (can_be_null ? MG_DATA_ENTRY_CAN_BE_NULL : 0);
403
attrs = attrs | (can_be_default ? MG_DATA_ENTRY_CAN_BE_DEFAULT : 0);
404
attrs = attrs | (is_unchanged ? MG_DATA_ENTRY_IS_UNCHANGED : 0);
406
/* Validity calculation: the same as for mg-entry-wrapper mg_entry_wrapper_get_attributes() */
407
if (! (is_default && (attrs & MG_DATA_ENTRY_CAN_BE_DEFAULT))) {
408
if (is_null && !can_be_null)
409
attrs = attrs | MG_DATA_ENTRY_DATA_NON_VALID;
412
/* if we are not inserting a new row, then we consider that we have an original value */
414
attrs = attrs | MG_DATA_ENTRY_HAS_VALUE_ORIG;
418
retval = gda_value_new_list ((GdaValueList *) values);
419
g_list_free (values);
422
retval = gda_value_new_null ();
431
/* Parameter(s) constrained by a query, we want all the fields for the query */
432
if (!pk_values_only) {
433
const GdaValue *value = NULL;
434
GList *values = NULL;
435
ModelUserModifiedValue *user_modif;
436
gboolean is_default = TRUE;
437
gboolean is_unchanged = TRUE;
438
gboolean is_null = TRUE;
439
gboolean can_be_default = TRUE;
440
gboolean can_be_null = TRUE;
445
/* if (row >= 0) then the data row originally exists into the resultset, and
446
* otherwise it is a new row, to be inserted */
447
gtk_tree_model_get (tree_model, iter, COLUMN_ROW_NUM, &row, -1);
449
user_modif = get_user_modifs (tree_model, iter, context_node);
451
/* building the 'values' list, and set 'value' if user_modif does exist */
453
if (user_modif->value && !gda_value_is_null (user_modif->value)) {
454
g_assert (gda_value_isa (user_modif->value, GDA_VALUE_TYPE_LIST));
456
value = user_modif->value;
457
values = (GList *) gda_value_get_list (user_modif->value);
460
attrs = user_modif->attributes;
464
GSList *fields = mg_entity_get_visible_fields (MG_ENTITY (context_node->query));
470
if (IS_MG_QF_FIELD (list->data)) {
471
pos = GPOINTER_TO_INT (g_hash_table_lookup (core->work_context_qf_position,
474
values = g_list_append (values, mg_resultset_get_gdavalue (core->data_rs, row, pos));
476
list = g_slist_next (list);
478
g_slist_free (fields);
483
/* computing the attributes if necessary */
486
is_unchanged = FALSE;
488
params = context_node->params;
490
const GdaValue *value = NULL;
494
value = (GdaValue *) (list->data);
495
list = g_list_next (list);
499
can_be_default = mg_parameter_get_default_value (MG_PARAMETER (params->data)) ? TRUE : FALSE;
502
can_be_null = mg_parameter_get_not_null (MG_PARAMETER (params->data)) ? FALSE : TRUE;
505
const GdaValue *orig_value;
507
orig_value = get_value_from_recordset (tree_model, iter, core, MG_PARAMETER (params->data));
508
is_unchanged = FALSE;
509
if (((!value || gda_value_is_null (value)) && (!orig_value || gda_value_is_null (orig_value))) ||
510
(value && orig_value &&
511
(gda_value_get_type (value) == gda_value_get_type (orig_value)) &&
512
!gda_value_compare (value, orig_value)))
517
is_null = (!value || gda_value_is_null (value)) ? TRUE : 0;
519
params = g_slist_next (params);
522
/* Same attributes setting as for mg-form.c mg_form_initialize() around line 296 */
523
attrs = attrs | (is_null ? MG_DATA_ENTRY_IS_NULL : 0);
524
attrs = attrs | (can_be_null ? MG_DATA_ENTRY_CAN_BE_NULL : 0);
525
attrs = attrs | (can_be_default ? MG_DATA_ENTRY_CAN_BE_DEFAULT : 0);
526
attrs = attrs | (is_unchanged ? MG_DATA_ENTRY_IS_UNCHANGED : 0);
528
/* Validity calculation: the same as for mg-entry-wrapper mg_entry_wrapper_get_attributes() */
529
if (! (is_default && (attrs & MG_DATA_ENTRY_CAN_BE_DEFAULT))) {
530
if (is_null && !can_be_null)
531
attrs = attrs | MG_DATA_ENTRY_DATA_NON_VALID;
534
/* if we are not inserting a new row, then we consider that we have an original value */
536
attrs = attrs | MG_DATA_ENTRY_HAS_VALUE_ORIG;
540
retval = gda_value_copy (value);
543
retval = gda_value_new_list ((GdaValueList *) values);
544
g_list_free (values);
547
retval = gda_value_new_null ();
559
static const GdaValue *
560
get_value_from_recordset (GtkTreeModel *tree_model, GtkTreeIter *iter, MgWorkCore *core, MgParameter *context_param)
563
MgWorkCoreNode *cnode;
566
g_return_val_if_fail (context_param, NULL);
568
gtk_tree_model_get (tree_model, iter, COLUMN_ROW_NUM, &row, -1);
569
cnode = mg_work_core_find_core_node (core, context_param);
572
col = cnode->position;
575
return mg_resultset_get_gdavalue (core->data_rs, row, col);
578
static ModelUserModifiedValue *
579
get_user_modifs (GtkTreeModel *tree_model, GtkTreeIter *iter, MgContextNode *context_node)
581
ModelUserModifiedRow *user_modifs;
582
ModelUserModifiedValue *user_value = NULL;
584
gtk_tree_model_get (tree_model, iter, COLUMN_USER_MODIFS_ROW, &user_modifs, -1);
587
list = user_modifs->user_values;
588
while (list && !user_value) {
589
if (MODEL_USER_MODIFIED_VALUE (list->data)->context_node == context_node)
590
user_value = MODEL_USER_MODIFIED_VALUE (list->data);
591
list = g_slist_next (list);
602
static void combo_core_nullified_query_cb (MgQuery *query, ComboCore *ccore);
603
static void combo_core_nullified_param_cb (MgParameter *param, ComboCore *ccore);
604
static gint *utility_combo_compute_choice_columns_mask (ComboCore *core, gint *mask_size);
606
* utility_combo_initialize_core
610
* @dependency_param_callback:
613
* Returns: a new ComboCore
616
utility_combo_initialize_core (MgConf *conf, MgContext *context, MgContextNode *node,
617
GCallback dependency_param_callback, gpointer data)
622
g_return_val_if_fail (node && node->query, NULL);
624
ccore = g_new0 (ComboCore, 1);
628
g_object_add_weak_pointer (G_OBJECT (ccore->conf), (gpointer) &(ccore->conf));
630
ccore->context = context;
631
g_object_add_weak_pointer (G_OBJECT (ccore->context), (gpointer) &(ccore->context));
633
ccore->query = node->query;
634
g_object_ref (G_OBJECT (ccore->query));
635
g_signal_connect (G_OBJECT (ccore->query), "nullified",
636
G_CALLBACK (combo_core_nullified_query_cb), ccore);
637
list = mg_entity_get_visible_fields (MG_ENTITY (ccore->query));
638
ccore->nb_visible_cols = g_slist_length (list);
640
ccore->dependency_param_callback = dependency_param_callback;
641
ccore->dependency_data = data;
646
MgField *source_field;
647
ComboNode *cnode = g_new0 (ComboNode, 1);
649
source_field = MG_FIELD (mg_parameter_get_source_field (MG_PARAMETER (list->data)));
650
cnode->param = MG_PARAMETER (list->data);
651
cnode->position = mg_entity_get_field_index (MG_ENTITY (ccore->query), source_field);
652
cnode->value_orig = NULL;
653
cnode->value_default = NULL;
654
ccore->nodes = g_slist_append (ccore->nodes, cnode);
655
g_object_ref (G_OBJECT (list->data));
656
g_signal_connect (G_OBJECT (list->data), "nullified",
657
G_CALLBACK (combo_core_nullified_param_cb), ccore);
659
list = g_slist_next (list);
662
/* connect the parameters dependencies */
665
/* FIXME: make sure we don't connect several times to the changes of one single param */
666
GSList *depend = mg_parameter_get_dependencies (COMBO_NODE (list->data)->param);
668
g_signal_connect (G_OBJECT (depend->data), "changed",
669
G_CALLBACK (dependency_param_callback), data);
670
depend = g_slist_next (depend);
672
list = g_slist_next (list);
675
/* compute the mask and its size */
676
ccore->mask = utility_combo_compute_choice_columns_mask (ccore, &(ccore->masksize));
682
combo_core_nullified_query_cb (MgQuery *query, ComboCore *ccore)
684
g_assert (ccore->query == query);
685
g_signal_handlers_disconnect_by_func (G_OBJECT (query),
686
G_CALLBACK (combo_core_nullified_query_cb), ccore);
687
g_object_unref (G_OBJECT (query));
692
combo_core_nullified_param_cb (MgParameter *param, ComboCore *ccore)
694
/* remove the associated ComboNode */
696
ComboNode *node = NULL;
700
if (COMBO_NODE (list->data)->param == param)
701
node = COMBO_NODE (list->data);
702
list = g_slist_next (list);
706
ccore->nodes = g_slist_remove (ccore->nodes, node);
707
g_signal_handlers_disconnect_by_func (G_OBJECT (param),
708
G_CALLBACK (combo_core_nullified_param_cb), ccore);
709
list = mg_parameter_get_dependencies (node->param);
711
g_signal_handlers_disconnect_by_func (G_OBJECT (list->data),
712
G_CALLBACK (ccore->dependency_param_callback), ccore->dependency_data);
713
list = g_slist_next (list);
716
g_object_unref (G_OBJECT (param));
718
node->value = NULL; /* don't free that value since we have not copied it */
719
if (node->value_orig)
720
gda_value_free (node->value_orig);
721
if (node->value_default)
722
gda_value_free (node->value_default);
728
* utility_combo_free_core
730
* Free @core and cleans the associated memory allocations made when utility_combo_initialize_core()
734
utility_combo_free_core (ComboCore *ccore)
736
while (ccore->nodes) {
737
ComboNode *node = COMBO_NODE (ccore->nodes->data);
738
g_assert (node->param);
739
combo_core_nullified_param_cb (node->param, ccore);
743
g_free (ccore->mask);
746
combo_core_nullified_query_cb (ccore->query, ccore);
749
g_object_remove_weak_pointer (G_OBJECT (ccore->conf),
750
(gpointer) &(ccore->conf));
753
g_object_remove_weak_pointer (G_OBJECT (ccore->context),
754
(gpointer) &(ccore->context));
756
utility_combo_destroy_model (ccore);
761
static GdaDataModel *make_single_line_model (const gchar *line);
764
* utility_combo_compute_model
767
* Computes a new GdaDataModel model (eventualy re-runs 'core->query') if necessary.
768
* Some special 1 line models are created in case of errors.
771
utility_combo_compute_model (ComboCore *core)
775
GdaDataModel *data_model = NULL;
777
srv = mg_conf_get_server (core->conf);
778
utility_combo_destroy_model (core);
780
if (mg_server_conn_is_opened (srv)) {
781
MgResultSet *rs = NULL;
783
GError *error = NULL;
785
sql = mg_renderer_render_as_sql (MG_RENDERER (core->query), core->context, 0, &error);
788
data_model = make_single_line_model (_("No value available"));
790
g_warning ("COMBO Model update SQL execution error: %s", error->message);
791
g_error_free (error);
795
rs = mg_server_do_query (srv, sql, MG_SERVER_QUERY_SQL, &error);
798
data_model = make_single_line_model (error->message);
799
g_error_free (error);
802
if (mg_resultset_get_nbtuples (rs) == 0) {
804
data_model = make_single_line_model (_("No value available"));
808
core->resultset = rs;
809
data_model = mg_resultset_get_data_model (rs);
811
/* keep our own reference on the data model */
812
g_object_ref (G_OBJECT (data_model));
819
data_model = make_single_line_model (_("Connection not opened"));
822
/* setting the new model */
823
core->data_model = data_model;
824
core->data_model_valid = valid_data;
828
* Creates a MgDataModel object with a single line and column
829
* containing the provided message
831
static GdaDataModel *
832
make_single_line_model (const gchar *line)
835
GdaDataModel *data_model;
838
data_model = gda_data_model_array_new (1);
839
value = gda_value_new_string (line);
840
rowvalues = g_list_append (NULL, value);
841
gda_data_model_append_row (GDA_DATA_MODEL (data_model), rowvalues);
842
g_list_free (rowvalues);
843
gda_value_free (value);
849
* utility_combo_destroy_model
852
* Free the memory associated with @core's model
855
utility_combo_destroy_model (ComboCore *core)
857
if (core->data_model) {
858
g_object_unref (core->data_model);
859
core->data_model = NULL;
860
core->data_model_valid = FALSE;
863
if (core->resultset) {
864
g_object_unref (G_OBJECT (core->resultset));
865
core->resultset = NULL;
871
* utility_combo_compute_choice_strings
874
* Creates a list of (allocated strings), one for each row of the data model stored within @core
875
* ('core->data_model')
877
* Returns: a new list of strings
880
utility_combo_compute_choice_strings (ComboCore *core)
882
GList *strings = NULL;
883
const GdaValue *value;
887
GdaDataModel *model = core->data_model;
889
/* actual string rendering */
890
nrows = gda_data_model_get_n_rows (model);
891
for (i=0; i<nrows; i++) {
892
str = g_string_new ("");
894
for (j=0; j<core->masksize; j++) {
895
value = gda_data_model_get_value_at (model, core->mask[j], i);
896
if (value && !gda_value_is_null (value))
897
tmpstr = gda_value_stringify (value);
899
tmpstr = g_strdup ("---");
902
g_string_append (str, " / " );
903
g_string_append (str, tmpstr);
908
strings = g_list_append (strings, str->str);
909
g_string_free (str, FALSE);
916
* utility_combo_compute_display_string
919
* Creates a new string for @core (no query is run and no value is searched for
922
* Returns: a new string to display
925
utility_combo_compute_display_string (ComboCore *core, GList *values)
927
gchar *retval = NULL;
928
const GdaValue *value;
933
g_return_val_if_fail (values && (g_list_length (values) == core->nb_visible_cols), NULL);
935
/* actual string rendering */
936
str = g_string_new ("");
938
for (j=0; j<core->masksize; j++) {
939
value = (GdaValue*) g_list_nth_data (values, core->mask[j]);
940
if (value && !gda_value_is_null (value))
941
tmpstr = gda_value_stringify (value);
943
tmpstr = g_strdup ("---");
945
g_string_append (str, " / " );
947
g_string_append (str, tmpstr);
954
g_string_free (str, FALSE);
961
* utility_combo_compute_choice_columns_mask
965
* Create a mask of which column of the resultset needs to be displayed in a combo box.
966
* The mask is an array of the column numbers to be displayed, and must be de-allocated after usage.
968
* Returns: a new array of columns to display
971
utility_combo_compute_choice_columns_mask (ComboCore *core, gint *mask_size)
974
gint *mask = NULL, masksize = 0;
976
/* mask making: we only want columns which are not parameter values and if not internal MgQField */
977
ncols = core->nb_visible_cols;
978
if (ncols - g_slist_length (core->nodes) > 0) {
981
masksize = ncols - g_slist_length (core->nodes);
982
mask = g_new0 (gint, masksize);
983
for (i=0; i<ncols ; i++) {
984
GSList *list = core->nodes;
985
gboolean found = FALSE;
986
while (list && !found) {
987
if (COMBO_NODE (list->data)->position == i)
990
list = g_slist_next (list);
993
MgField *field = mg_entity_get_field_by_index (MG_ENTITY (core->query), i);
995
if (!mg_qfield_is_internal (MG_QFIELD (field))) {
1007
mask = g_new0 (gint, masksize);
1008
for (i=0; i<ncols; i++) {
1014
*mask_size = masksize;