1 /*
2  * Copyright (C) 2009 - 2011 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/libgda.h>
23 #include <libgda/binreloc/gda-binreloc.h>
24 #include "gdaui-data-proxy.h"
25 #include  <glib/gi18n-lib.h>
26 #include <libgda-ui/gdaui-raw-form.h>
27 #include <libgda-ui/gdaui-raw-grid.h>
28 
29 /* signals */
30 enum {
31         PROXY_CHANGED,
32         LAST_SIGNAL
33 };
34 
35 static gint gdaui_data_proxy_signals[LAST_SIGNAL] = { 0 };
36 
37 static void gdaui_data_proxy_iface_init (gpointer g_class);
38 
39 GType
gdaui_data_proxy_get_type(void)40 gdaui_data_proxy_get_type (void)
41 {
42 	static GType type = 0;
43 
44 	if (G_UNLIKELY (type == 0)) {
45 		static const GTypeInfo info = {
46 			sizeof (GdauiDataProxyIface),
47 			(GBaseInitFunc) gdaui_data_proxy_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, "GdauiDataProxy", &info, 0);
59 		g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
60 	}
61 	return type;
62 }
63 
64 
65 static void
gdaui_data_proxy_iface_init(G_GNUC_UNUSED gpointer g_class)66 gdaui_data_proxy_iface_init (G_GNUC_UNUSED gpointer g_class)
67 {
68 	static gboolean initialized = FALSE;
69 
70 	if (! initialized) {
71 		/**
72 		 * GdauiDataProxy::proxy-changed:
73 		 * @gdauidataproxy: the #GdauiDataProxy
74 		 * @arg1: the GdaDataProxy which would be returned by gdaui_data_proxy_get_proxy()
75 		 *
76 		 * The ::proxy-changed signal is emitted each time the #GdaDataProxy which would be
77 		 * returned by gdaui_data_proxy_get_proxy() changes. This is generally the result
78 		 * of changes in the structure of the proxied data model (different number and/or type
79 		 * of columns for example).
80 		 */
81 		gdaui_data_proxy_signals[PROXY_CHANGED] =
82 			g_signal_new ("proxy-changed",
83                                       GDAUI_TYPE_DATA_PROXY,
84                                       G_SIGNAL_RUN_FIRST,
85                                       G_STRUCT_OFFSET (GdauiDataProxyIface, proxy_changed),
86                                       NULL, NULL,
87                                       g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE,
88                                       1, GDA_TYPE_DATA_PROXY);
89 		initialized = TRUE;
90 	}
91 }
92 
93 /**
94  * gdaui_data_proxy_get_proxy:
95  * @iface: an object which implements the #GdauiDataProxy interface
96  *
97  * Get a pointer to the #GdaDataProxy being used by @iface
98  *
99  * Returns: (transfer none): a #GdaDataProxy pointer
100  *
101  * Since: 4.2
102  */
103 GdaDataProxy *
gdaui_data_proxy_get_proxy(GdauiDataProxy * iface)104 gdaui_data_proxy_get_proxy (GdauiDataProxy *iface)
105 {
106 	g_return_val_if_fail (GDAUI_IS_DATA_PROXY (iface), NULL);
107 
108 	if (GDAUI_DATA_PROXY_GET_IFACE (iface)->get_proxy)
109 		return (GDAUI_DATA_PROXY_GET_IFACE (iface)->get_proxy) (iface);
110 	else
111 		return NULL;
112 }
113 
114 /**
115  * gdaui_data_proxy_column_set_editable:
116  * @iface: an object which implements the #GdauiDataProxy interface
117  * @column: column number of the data
118  * @editable: set to %TRUE to make the column editable
119  *
120  * Sets if the data entry in the @iface widget at @column (in the data model @iface operates on)
121  * can be edited or not.
122  *
123  * Since: 4.2
124  */
125 void
gdaui_data_proxy_column_set_editable(GdauiDataProxy * iface,gint column,gboolean editable)126 gdaui_data_proxy_column_set_editable (GdauiDataProxy *iface, gint column, gboolean editable)
127 {
128 	g_return_if_fail (GDAUI_IS_DATA_PROXY (iface));
129 
130 	if (GDAUI_DATA_PROXY_GET_IFACE (iface)->set_column_editable)
131 		(GDAUI_DATA_PROXY_GET_IFACE (iface)->set_column_editable) (iface, column, editable);
132 }
133 
134 /**
135  * gdaui_data_proxy_column_show_actions:
136  * @iface: an object which implements the #GdauiDataProxy interface
137  * @column: column number of the data, or -1 to apply the setting to all the columns
138  * @show_actions: set to %TRUE if the actions menu must be shown
139  *
140  * Sets if the data entry in the @iface widget at @column (in the data model @iface operates on) must show its
141  * actions menu or not.
142  *
143  * Since: 4.2
144  */
145 void
gdaui_data_proxy_column_show_actions(GdauiDataProxy * iface,gint column,gboolean show_actions)146 gdaui_data_proxy_column_show_actions (GdauiDataProxy *iface, gint column, gboolean show_actions)
147 {
148 	g_return_if_fail (GDAUI_IS_DATA_PROXY (iface));
149 
150 	if (GDAUI_DATA_PROXY_GET_IFACE (iface)->show_column_actions)
151 		(GDAUI_DATA_PROXY_GET_IFACE (iface)->show_column_actions) (iface, column, show_actions);
152 }
153 
154 /**
155  * gdaui_data_proxy_get_actions_group:
156  * @iface: an object which implements the #GdauiDataProxy interface
157  *
158  * Each widget imlplementing the #GdauiDataProxy interface provides actions. Actions can be triggered
159  * using the gdaui_data_proxy_perform_action() method, but using this method allows for the creation of
160  * toolbars, menus, etc calling these actions.
161  *
162  * The actions are among:
163  * <itemizedlist><listitem><para>Data edition actions: "ActionNew", "ActionCommit",
164  *    "ActionDelete", "ActionReset". Note that the "ActionDelete" action is actually a #GtkToggleAction
165  *    action which can be used to delete a row or undelete it.</para></listitem>
166  * <listitem><para>Record by record moving: "ActionFirstRecord", "ActionPrevRecord",
167  *    "ActionNextRecord", "ActionLastRecord".</para></listitem>
168  * <listitem><para>Chuncks of records moving: "ActionFirstChunck", "ActionPrevChunck",
169  *     "ActionNextChunck", "ActionLastChunck".</para></listitem>
170  * <listitem><para>Filtering: "ActionFilter".</para></listitem></itemizedlist>
171  *
172  * Returns: (transfer none): the #GtkActionGroup with all the possible actions on the widget.
173  *
174  * Since: 4.2
175  */
176 GtkActionGroup *
gdaui_data_proxy_get_actions_group(GdauiDataProxy * iface)177 gdaui_data_proxy_get_actions_group (GdauiDataProxy *iface)
178 {
179 	g_return_val_if_fail (GDAUI_IS_DATA_PROXY (iface), NULL);
180 
181 	if (GDAUI_DATA_PROXY_GET_IFACE (iface)->get_actions_group)
182 		return (GDAUI_DATA_PROXY_GET_IFACE (iface)->get_actions_group) (iface);
183 	return NULL;
184 }
185 
186 /**
187  * gdaui_data_proxy_perform_action:
188  * @iface: an object which implements the #GdauiDataProxy interface
189  * @action: a #GdauiAction action
190  *
191  * Forces the widget to perform the selected @action, as if the user
192  * had pressed on the corresponding action button in the @iface widget,
193  * if the corresponding action is possible and if the @iface widget
194  * supports the action.
195  *
196  * Since: 4.2
197  */
198 void
gdaui_data_proxy_perform_action(GdauiDataProxy * iface,GdauiAction action)199 gdaui_data_proxy_perform_action (GdauiDataProxy *iface, GdauiAction action)
200 {
201 	gchar *action_name = NULL;
202 	GtkActionGroup *group;
203 	GtkAction *gtkaction;
204 
205 	g_return_if_fail (GDAUI_IS_DATA_PROXY (iface));
206 	group = gdaui_data_proxy_get_actions_group (iface);
207 	if (!group) {
208 		g_warning ("Object class %s does not support the gdaui_data_proxy_get_actions_group() method",
209 			   G_OBJECT_TYPE_NAME (iface));
210 		return;
211 	}
212 
213 	switch (action) {
214 	case GDAUI_ACTION_NEW_DATA:
215 		action_name = "ActionNew";
216 		break;
217 	case GDAUI_ACTION_WRITE_MODIFIED_DATA:
218 		action_name = "ActionCommit";
219 		break;
220         case GDAUI_ACTION_DELETE_SELECTED_DATA:
221         case GDAUI_ACTION_UNDELETE_SELECTED_DATA:
222 		action_name = "ActionDelete";
223 		break;
224         case GDAUI_ACTION_RESET_DATA:
225 		action_name = "ActionReset";
226 		break;
227         case GDAUI_ACTION_MOVE_FIRST_RECORD:
228 		action_name = "ActionFirstRecord";
229 		break;
230         case GDAUI_ACTION_MOVE_PREV_RECORD:
231 		action_name = "ActionPrevRecord";
232 		break;
233         case GDAUI_ACTION_MOVE_NEXT_RECORD:
234 		action_name = "ActionNextRecord";
235 		break;
236         case GDAUI_ACTION_MOVE_LAST_RECORD:
237 		action_name = "ActionLastRecord";
238 		break;
239         case GDAUI_ACTION_MOVE_FIRST_CHUNCK:
240 		action_name = "ActionFirstChunck";
241 		break;
242         case GDAUI_ACTION_MOVE_PREV_CHUNCK:
243 		action_name = "ActionPrevChunck";
244 		break;
245         case GDAUI_ACTION_MOVE_NEXT_CHUNCK:
246 		action_name = "ActionNextChunck";
247 		break;
248         case GDAUI_ACTION_MOVE_LAST_CHUNCK:
249 		action_name = "ActionLastChunck";
250 		break;
251 	default:
252 		g_assert_not_reached ();
253 	}
254 
255 	gtkaction = gtk_action_group_get_action (group, action_name);
256 	if (gtkaction)
257 		gtk_action_activate (gtkaction);
258 }
259 
260 /**
261  * gdaui_data_proxy_set_write_mode:
262  * @iface: an object which implements the #GdauiDataProxy interface
263  * @mode: the requested #GdauiDataProxyWriteMode mode
264  *
265  * Specifies the way the modifications stored in the #GdaDataProxy used internally by @iface are written back to
266  * the #GdaDataModel which holds the data displayed in @iface.
267  *
268  * Returns: TRUE if the proposed mode has been taken into account
269  *
270  * Since: 4.2
271  */
272 gboolean
gdaui_data_proxy_set_write_mode(GdauiDataProxy * iface,GdauiDataProxyWriteMode mode)273 gdaui_data_proxy_set_write_mode (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode)
274 {
275 	g_return_val_if_fail (GDAUI_IS_DATA_PROXY (iface), FALSE);
276 
277 	if (GDAUI_DATA_PROXY_GET_IFACE (iface)->set_write_mode)
278 		return (GDAUI_DATA_PROXY_GET_IFACE (iface)->set_write_mode) (iface, mode);
279 	else
280 		return FALSE;
281 }
282 
283 /**
284  * gdaui_data_proxy_get_write_mode:
285  * @iface: an object which implements the #GdauiDataProxy interface
286  *
287  * Get the way the modifications stored in the #GdaDataProxy used internally by @iface are written back to
288  * the #GdaDataModel which holds the data displayed in @iface.
289  *
290  * Returns: the write mode used by @iface
291  *
292  * Since: 4.2
293  */
294 GdauiDataProxyWriteMode
gdaui_data_proxy_get_write_mode(GdauiDataProxy * iface)295 gdaui_data_proxy_get_write_mode (GdauiDataProxy *iface)
296 {
297 	g_return_val_if_fail (GDAUI_IS_DATA_PROXY (iface), GDAUI_DATA_PROXY_WRITE_ON_DEMAND);
298 
299 	if (GDAUI_DATA_PROXY_GET_IFACE (iface)->get_write_mode)
300 		return (GDAUI_DATA_PROXY_GET_IFACE (iface)->get_write_mode) (iface);
301 	else
302 		return GDAUI_DATA_PROXY_WRITE_ON_DEMAND;
303 }
304