1 /*
2  * Copyright (C) 2009 - 2012 Vivien Malerba <malerba@gnome-db.org>
3  * Copyright (C) 2010 David King <davidk@openismus.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA  02110-1301, USA.
19  */
20 
21 #include <string.h>
22 #include <libgda/binreloc/gda-binreloc.h>
23 #include "gdaui-data-selector.h"
24 #include  <glib/gi18n-lib.h>
25 #include <libgda-ui/gdaui-raw-form.h>
26 #include <libgda-ui/gdaui-raw-grid.h>
27 
28 /* signals */
29 enum
30 {
31         SELECTION_CHANGED,
32         LAST_SIGNAL
33 };
34 
35 static gint gdaui_data_selector_signals[LAST_SIGNAL] = { 0 };
36 
37 static void gdaui_data_selector_iface_init (gpointer g_class);
38 
39 GType
gdaui_data_selector_get_type(void)40 gdaui_data_selector_get_type (void)
41 {
42 	static GType type = 0;
43 
44 	if (G_UNLIKELY (type == 0)) {
45 		static const GTypeInfo info = {
46 			sizeof (GdauiDataSelectorIface),
47 			(GBaseInitFunc) gdaui_data_selector_iface_init,
48 			(GBaseFinalizeFunc) NULL,
49 			(GClassInitFunc) NULL,
50 			NULL,
51 			NULL,
52 			0,
53 			0,
54 			(GInstanceInitFunc) NULL,
55 			0
56 		};
57 
58 		type = g_type_register_static (G_TYPE_INTERFACE, "GdauiDataSelector", &info, 0);
59 		g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
60 	}
61 	return type;
62 }
63 
64 
65 static void
gdaui_data_selector_iface_init(G_GNUC_UNUSED gpointer g_class)66 gdaui_data_selector_iface_init (G_GNUC_UNUSED gpointer g_class)
67 {
68 	static gboolean initialized = FALSE;
69 
70 	if (! initialized) {
71 		gdaui_data_selector_signals[SELECTION_CHANGED] =
72 			g_signal_new ("selection-changed",
73                                       GDAUI_TYPE_DATA_SELECTOR,
74                                       G_SIGNAL_RUN_FIRST,
75                                       G_STRUCT_OFFSET (GdauiDataSelectorIface, selection_changed),
76                                       NULL, NULL,
77                                       g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
78                                       0);
79 
80 		initialized = TRUE;
81 	}
82 }
83 
84 /**
85  * gdaui_data_selector_get_model:
86  * @iface: an object which implements the #GdauiDataSelector interface
87  *
88  * Queries the #GdaDataModel from which the data displayed by the widget implementing @iface
89  * are. Beware that the returned data model may be different than the one used when the
90  * widget was created in case it internally uses a #GdaDataProxy.
91  *
92  * Returns: (transfer none): the #GdaDataModel
93  *
94  * Since: 4.2
95  */
96 GdaDataModel *
gdaui_data_selector_get_model(GdauiDataSelector * iface)97 gdaui_data_selector_get_model (GdauiDataSelector *iface)
98 {
99 	g_return_val_if_fail (GDAUI_IS_DATA_SELECTOR (iface), NULL);
100 
101 	if (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->get_model)
102 		return (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->get_model) (iface);
103 	return NULL;
104 }
105 
106 /**
107  * gdaui_data_selector_set_model:
108  * @iface: an object which implements the #GdauiDataSelector interface
109  * @model: a #GdaDataModel to use
110  *
111  * Sets the data model from which the data being displayed are. Also see gdaui_data_selector_get_model()
112  *
113  * Since: 4.2
114  */
115 void
gdaui_data_selector_set_model(GdauiDataSelector * iface,GdaDataModel * model)116 gdaui_data_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model)
117 {
118 	g_return_if_fail (GDAUI_IS_DATA_SELECTOR (iface));
119 	g_return_if_fail (!model || GDA_IS_DATA_MODEL (model));
120 
121 	if (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->set_model)
122 		(GDAUI_DATA_SELECTOR_GET_IFACE (iface)->set_model) (iface, model);
123 }
124 
125 /**
126  * gdaui_data_selector_get_selected_rows:
127  * @iface: an object which implements the #GdauiDataSelector interface
128  *
129  * Gat an array of selected rows. If no row is selected, the the returned value is %NULL.
130  *
131  * Please note that rows refers to the "visible" rows
132  * at the time it's being called, which may change if the widget implementing this interface
133  * uses a #GdaDataProxy (as is the case for example for the #GdauiRawForm, #GdauiForm, #GdauiRawGrid
134  * and #GdauiGrid).
135  *
136  * Returns: (transfer full) (element-type gint): an array of #gint values, one for each selected row. Use g_array_free() when finished (passing %TRUE as the last argument)
137  *
138  * Since: 4.2
139  */
140 GArray *
gdaui_data_selector_get_selected_rows(GdauiDataSelector * iface)141 gdaui_data_selector_get_selected_rows (GdauiDataSelector *iface)
142 {
143 	g_return_val_if_fail (GDAUI_IS_DATA_SELECTOR (iface), NULL);
144 
145 	if (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->get_selected_rows)
146 		return (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->get_selected_rows) (iface);
147 	else
148 		return NULL;
149 }
150 
151 /**
152  * gdaui_data_selector_select_row:
153  * @iface: an object which implements the #GdauiDataSelector interface
154  * @row: the row to select
155  *
156  * Force the selection of a specific row.
157  *
158  * Please note that @row refers to the "visible" row
159  * at the time it's being called, which may change if the widget implementing this interface
160  * uses a #GdaDataProxy (as is the case for example for the #GdauiRawForm, #GdauiForm, #GdauiRawGrid
161  * and #GdauiGrid).
162  *
163  * Returns: %TRUE if the row has been selected
164  *
165  * Since: 4.2
166  */
167 gboolean
gdaui_data_selector_select_row(GdauiDataSelector * iface,gint row)168 gdaui_data_selector_select_row (GdauiDataSelector *iface, gint row)
169 {
170 	g_return_val_if_fail (GDAUI_IS_DATA_SELECTOR (iface), FALSE);
171 
172 	if (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->select_row)
173 		return (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->select_row) (iface, row);
174 	else
175 		return FALSE;
176 }
177 
178 /**
179  * gdaui_data_selector_unselect_row:
180  * @iface: an object which implements the #GdauiDataSelector interface
181  * @row: the row to unselect
182  *
183  * Please note that @row refers to the "visible" row
184  * at the time it's being called, which may change if the widget implementing this interface
185  * uses a #GdaDataProxy (as is the case for example for the #GdauiRawForm, #GdauiForm, #GdauiRawGrid
186  * and #GdauiGrid).
187  *
188  * Since: 4.2
189  */
190 void
gdaui_data_selector_unselect_row(GdauiDataSelector * iface,gint row)191 gdaui_data_selector_unselect_row (GdauiDataSelector *iface, gint row)
192 {
193 	g_return_if_fail (GDAUI_IS_DATA_SELECTOR (iface));
194 
195 	if (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->unselect_row)
196 		(GDAUI_DATA_SELECTOR_GET_IFACE (iface)->unselect_row) (iface, row);
197 }
198 
199 /**
200  * gdaui_data_selector_set_column_visible:
201  * @iface: an object which implements the #GdauiDataSelector interface
202  * @column: a column number, starting at %0, or -1 tp apply to all the columns
203  * @visible: required visibility of the data in the @column column
204  *
205  * Shows or hides the data at column @column
206  *
207  * Since: 4.2
208  */
209 void
gdaui_data_selector_set_column_visible(GdauiDataSelector * iface,gint column,gboolean visible)210 gdaui_data_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible)
211 {
212 	g_return_if_fail (GDAUI_IS_DATA_SELECTOR (iface));
213 
214 	if (!GDAUI_DATA_SELECTOR_GET_IFACE (iface)->set_column_visible)
215 		return;
216 
217 	if (column >= 0)
218 		(GDAUI_DATA_SELECTOR_GET_IFACE (iface)->set_column_visible) (iface, column, visible);
219 	else if (column == -1) {
220 		gint i, ncols;
221 		GdaDataModelIter *iter;
222 		iter = gdaui_data_selector_get_data_set (iface);
223 		if (!iter)
224 			return;
225 		ncols = g_slist_length (GDA_SET (iter)->holders);
226 		for (i = 0; i < ncols; i++)
227 			(GDAUI_DATA_SELECTOR_GET_IFACE (iface)->set_column_visible) (iface, i, visible);
228 	}
229 	else
230 		g_warning (_("Invalid column number %d"), column);
231 }
232 
233 /**
234  * gdaui_data_selector_get_data_set:
235  * @iface: an object which implements the #GdauiDataSelector interface
236  *
237  * Get the #GdaDataModelIter object represented the current selected row in @iface. This
238  * function may return either %NULL or an invalid iterator (see gda_data_model_iter_is_valid()) if
239  * the selection cannot be represented by a single selected row.
240  *
241  * Note that the returned #GdaDataModelIter is actually an iterator iterating on the #GdaDataModel
242  * returned by the gdaui_data_selector_get_model() method.
243  *
244  * Returns: (transfer none): a pointer to a #GdaDataModelIter object, or %NULL
245  *
246  * Since: 4.2
247  */
248 GdaDataModelIter *
gdaui_data_selector_get_data_set(GdauiDataSelector * iface)249 gdaui_data_selector_get_data_set (GdauiDataSelector *iface)
250 {
251 	g_return_val_if_fail (GDAUI_IS_DATA_SELECTOR (iface), NULL);
252 
253 	if (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->get_data_set)
254 		return (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->get_data_set) (iface);
255 	return NULL;
256 }
257