1 /*
2  * Copyright (C) 2009 - 2012 Vivien Malerba <malerba@gnome-db.org>
3  * Copyright (C) 2010 David King <davidk@openismus.com>
4  * Copyright (C) 2011 Murray Cumming <murrayc@murrayc.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA  02110-1301, USA.
20  */
21 
22 #include "gdaui-decl.h"
23 #include <libgda/gda-config.h>
24 #include <libgda-ui/internal/gdaui-dsn-selector.h>
25 #include <libgda-ui/gdaui-provider-selector.h>
26 #include <glib/gi18n-lib.h>
27 #include <libgda-ui/gdaui-login.h>
28 #include <libgda-ui/internal/gdaui-provider-spec-editor.h>
29 #include <libgda-ui/internal/gdaui-provider-auth-editor.h>
30 #include "gdaui-enum-types.h"
31 #include <gtk/gtk.h>
32 #include <string.h>
33 #include <libgda/binreloc/gda-binreloc.h>
34 
35 struct _GdauiLoginPrivate {
36 	GdauiLoginMode mode;
37 
38 	GdaDsnInfo dsn_info;
39 	GtkWidget *rb_dsn;
40 	GtkWidget *rb_prov;
41 
42 	GtkWidget *dsn_selector;
43 	GtkWidget *cc_button;
44 
45 	GtkWidget *prov_selector;
46 	GtkWidget *cnc_params_editor;
47 
48 	GtkWidget *auth_widget;
49 };
50 
51 static void gdaui_login_class_init   (GdauiLoginClass *klass);
52 static void gdaui_login_init         (GdauiLogin *login, GdauiLoginClass *klass);
53 static void gdaui_login_set_property (GObject *object,
54 				      guint paramid,
55 				      const GValue *value,
56 				      GParamSpec *pspec);
57 static void gdaui_login_get_property (GObject *object,
58 				      guint param_id,
59 				      GValue *value,
60 				      GParamSpec *pspec);
61 static void gdaui_login_finalize     (GObject *object);
62 
63 enum {
64 	PROP_0,
65 	PROP_DSN,
66 	PROP_MODE,
67 	PROP_VALID
68 };
69 
70 static GObjectClass *parent_class = NULL;
71 
72 /* signals */
73 enum
74 {
75         CHANGED,
76         LAST_SIGNAL
77 };
78 
79 static gint gdaui_login_signals[LAST_SIGNAL] = { 0 };
80 
81 
82 static gboolean settings_are_valid (GdauiLogin *login);
83 static void run_cc_cb (GtkButton *button, GdauiLogin *login);
84 static void dsn_entry_changed_cb (GdauiDsnSelector *sel, GdauiLogin *login);
85 static void radio_button_use_dsn_toggled_cb (GtkToggleButton *button, GdauiLogin *login);
86 static void prov_entry_changed_cb (GdauiProviderSelector *sel, GdauiLogin *login);
87 static void cnc_params_editor_changed_cb (GdauiProviderSpecEditor *editor, GdauiLogin *login);
88 
89 /*
90  * GdauiLogin class implementation
91  */
92 
93 static void
gdaui_login_class_init(GdauiLoginClass * klass)94 gdaui_login_class_init (GdauiLoginClass *klass)
95 {
96 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
97 	GtkWidgetClass *widget_class = (GtkWidgetClass*) klass;
98 
99 	parent_class = g_type_class_peek_parent (klass);
100 
101 	gdaui_login_signals[CHANGED] =
102                 g_signal_new ("changed",
103                               G_TYPE_FROM_CLASS (object_class),
104                               G_SIGNAL_RUN_FIRST,
105                               G_STRUCT_OFFSET (GdauiLoginClass, changed),
106                               NULL, NULL,
107                               g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE,
108                               1, G_TYPE_BOOLEAN);
109 
110 	klass->changed = NULL;
111 
112 	object_class->set_property = gdaui_login_set_property;
113 	object_class->get_property = gdaui_login_get_property;
114 	object_class->finalize = gdaui_login_finalize;
115 
116 	widget_class->show_all = gtk_widget_show;
117 
118 	/* add class properties */
119 	g_object_class_install_property (object_class, PROP_DSN,
120 					 g_param_spec_string ("dsn", NULL, NULL, NULL, G_PARAM_READWRITE));
121 	g_object_class_install_property (object_class, PROP_MODE,
122 					 g_param_spec_flags ("mode", NULL, NULL,
123 							     GDAUI_TYPE_LOGIN_MODE, 0, G_PARAM_READWRITE));
124 	g_object_class_install_property (object_class, PROP_VALID,
125 					 g_param_spec_boolean ("valid", NULL, NULL,
126 							       FALSE, G_PARAM_READABLE));
127 }
128 
129 static void
config_dsn_changed_cb(G_GNUC_UNUSED GdaConfig * config,GdaDsnInfo * dsn,GdauiLogin * login)130 config_dsn_changed_cb (G_GNUC_UNUSED GdaConfig *config, GdaDsnInfo *dsn, GdauiLogin *login)
131 {
132 	if (!login->priv->prov_selector)
133 		return;
134 	gchar *sdsn;
135 	sdsn = _gdaui_dsn_selector_get_dsn (GDAUI_DSN_SELECTOR (login->priv->dsn_selector));
136 	if (dsn && dsn->name && sdsn && !strcmp (dsn->name, sdsn)) {
137 		dsn_entry_changed_cb (GDAUI_DSN_SELECTOR (login->priv->dsn_selector), login);
138 		g_print ("Update...\n");
139 	}
140 }
141 
142 static void
auth_data_changed_cb(GdauiProviderAuthEditor * auth,GdauiLogin * login)143 auth_data_changed_cb (GdauiProviderAuthEditor *auth, GdauiLogin *login)
144 {
145 	g_signal_emit (login, gdaui_login_signals [CHANGED], 0, settings_are_valid (login));
146 }
147 
148 static void
gdaui_login_init(GdauiLogin * login,G_GNUC_UNUSED GdauiLoginClass * klass)149 gdaui_login_init (GdauiLogin *login, G_GNUC_UNUSED GdauiLoginClass *klass)
150 {
151 	GtkWidget *grid;
152 	GtkWidget *wid;
153 
154 	/* allocate the internal structure */
155 	login->priv = g_new0 (GdauiLoginPrivate, 1);
156 
157 	/* Init the properties*/
158 	login->priv->mode = GDA_UI_LOGIN_ENABLE_CONTROL_CENTRE_MODE;
159 	memset (&(login->priv->dsn_info), 0, sizeof (GdaDsnInfo));
160 
161 	gtk_orientable_set_orientation (GTK_ORIENTABLE (login), GTK_ORIENTATION_VERTICAL);
162 
163 	/* catch DSN definition changes */
164 	GdaConfig *conf = gda_config_get ();
165 	g_signal_connect (conf, "dsn-changed",
166 			  G_CALLBACK (config_dsn_changed_cb), login);
167 	g_object_unref (conf);
168 
169 	/* table layout */
170 	grid = gtk_grid_new ();
171 	gtk_widget_show (grid);
172 	gtk_grid_set_column_spacing (GTK_GRID (grid), 5);
173 	gtk_grid_set_row_spacing (GTK_GRID (grid), 5);
174 	gtk_box_pack_start (GTK_BOX (login), grid, TRUE, TRUE, 0);
175 
176 	/* radio buttons */
177 	wid = gtk_radio_button_new_with_label (NULL, _("Use data source:"));
178 	g_signal_connect (wid, "toggled",
179 			  G_CALLBACK (radio_button_use_dsn_toggled_cb), login);
180 	gtk_grid_attach (GTK_GRID (grid), wid, 0, 0, 1, 1);
181 	gtk_widget_show (wid);
182 	login->priv->rb_dsn = wid;
183 
184 	wid = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (wid),
185 							   _("Specify connection:"));
186 	gtk_grid_attach (GTK_GRID (grid), wid, 0, 1, 1, 1);
187 	gtk_widget_show (wid);
188 	login->priv->rb_prov = wid;
189 
190 	/* widget to specify a DSN to use */
191 	login->priv->dsn_selector = _gdaui_dsn_selector_new ();
192 	gtk_widget_show (login->priv->dsn_selector); /* Show the DSN selector */
193 	gtk_grid_attach (GTK_GRID (grid), login->priv->dsn_selector, 1, 0, 1, 1);
194 	g_signal_connect (G_OBJECT (login->priv->dsn_selector), "changed",
195 			  G_CALLBACK (dsn_entry_changed_cb), login);
196 
197 	/* Create the DSN add button */
198 	login->priv->cc_button = gtk_button_new_with_label (_("Data sources..."));
199 	gtk_button_set_image (GTK_BUTTON (login->priv->cc_button),
200 			      gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_BUTTON));
201 	g_signal_connect (G_OBJECT (login->priv->cc_button), "clicked",
202 			  G_CALLBACK (run_cc_cb), login);
203 	gtk_widget_show (login->priv->cc_button);
204 	gtk_grid_attach (GTK_GRID (grid), login->priv->cc_button, 2, 0, 1, 1);
205 
206 	/* widget to specify a direct connection */
207 	login->priv->prov_selector = gdaui_provider_selector_new ();
208 	gtk_grid_attach (GTK_GRID (grid),login->priv->prov_selector, 1, 1, 2, 1);
209 	gtk_widget_show (login->priv->prov_selector);
210 	gtk_widget_set_sensitive (login->priv->prov_selector, FALSE);
211 	g_signal_connect (login->priv->prov_selector, "changed",
212 			  G_CALLBACK (prov_entry_changed_cb), login);
213 
214 	login->priv->cnc_params_editor = _gdaui_provider_spec_editor_new (NULL);
215 	gtk_grid_attach (GTK_GRID (grid), login->priv->cnc_params_editor, 1, 2, 2, 1);
216 	gtk_widget_show (login->priv->cnc_params_editor);
217 	gtk_widget_set_sensitive (login->priv->cnc_params_editor, FALSE);
218 	g_signal_connect (login->priv->cnc_params_editor, "changed",
219 			  G_CALLBACK (cnc_params_editor_changed_cb), login);
220 
221 	/* Create the authentication part */
222 	login->priv->auth_widget = _gdaui_provider_auth_editor_new (NULL);
223 	gtk_grid_attach (GTK_GRID (grid), login->priv->auth_widget, 1, 3, 2, 1);
224 	gtk_widget_show (login->priv->auth_widget);
225 	g_signal_connect (login->priv->auth_widget, "changed",
226 			  G_CALLBACK (auth_data_changed_cb), login);
227 
228 	prov_entry_changed_cb (GDAUI_PROVIDER_SELECTOR (login->priv->prov_selector), login);
229 }
230 
231 static void
gdaui_login_set_property(GObject * object,guint param_id,const GValue * value,GParamSpec * pspec)232 gdaui_login_set_property (GObject *object,
233 			     guint param_id,
234 			     const GValue *value,
235 			     GParamSpec *pspec)
236 {
237 	GdauiLogin *login = (GdauiLogin *) object;
238 
239 	g_return_if_fail (GDAUI_IS_LOGIN (login));
240 
241 	switch (param_id) {
242 	case PROP_DSN: {
243 		const gchar *dsn;
244 		dsn = g_value_get_string (value);
245 		gdaui_login_set_dsn (login, dsn);
246 		break;
247 	}
248 	case PROP_MODE:
249 		gdaui_login_set_mode (login, g_value_get_flags (value));
250 		break;
251 	default :
252 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
253 		break;
254 	}
255 }
256 
257 static void
gdaui_login_get_property(GObject * object,guint param_id,GValue * value,GParamSpec * pspec)258 gdaui_login_get_property (GObject *object,
259 			       guint param_id,
260 			       GValue *value,
261 			       GParamSpec *pspec)
262 {
263 	GdauiLogin *login = (GdauiLogin *) object;
264 
265 	g_return_if_fail (GDAUI_IS_LOGIN (login));
266 
267 	switch (param_id) {
268 	case PROP_DSN :
269 		g_value_set_string (value, login->priv->dsn_info.name);
270 		break;
271 	case PROP_MODE:
272 		g_value_set_flags (value, login->priv->mode);
273 		break;
274 	case PROP_VALID:
275 		g_value_set_boolean (value, settings_are_valid (login));
276 		break;
277 	default:
278 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
279 		break;
280 	}
281 }
282 
283 static void
clear_dsn_info(GdauiLogin * login)284 clear_dsn_info (GdauiLogin *login)
285 {
286 	g_free (login->priv->dsn_info.name);
287 	login->priv->dsn_info.name = NULL;
288 
289 	g_free (login->priv->dsn_info.provider);
290 	login->priv->dsn_info.provider = NULL;
291 
292 	g_free (login->priv->dsn_info.description);
293 	login->priv->dsn_info.description = NULL;
294 
295 	g_free (login->priv->dsn_info.cnc_string);
296 	login->priv->dsn_info.cnc_string = NULL;
297 
298 	g_free (login->priv->dsn_info.auth_string);
299 	login->priv->dsn_info.auth_string = NULL;
300 }
301 
302 static void
gdaui_login_finalize(GObject * object)303 gdaui_login_finalize (GObject *object)
304 {
305 	GdauiLogin *login = (GdauiLogin *) object;
306 
307 	g_return_if_fail (GDAUI_IS_LOGIN (login));
308 
309 	GdaConfig *conf = gda_config_get ();
310 	g_signal_handlers_disconnect_by_func (conf,
311 					      G_CALLBACK (config_dsn_changed_cb), login);
312 	g_object_unref (conf);
313 
314 	/* free memory */
315 	clear_dsn_info (login);
316 	g_free (login->priv);
317 	login->priv = NULL;
318 
319 	parent_class->finalize (object);
320 }
321 
322 GType
gdaui_login_get_type(void)323 gdaui_login_get_type (void)
324 {
325 	static GType type = 0;
326 
327 	if (G_UNLIKELY (type == 0)) {
328 		static const GTypeInfo info = {
329 			sizeof (GdauiLoginClass),
330 			(GBaseInitFunc) NULL,
331 			(GBaseFinalizeFunc) NULL,
332 			(GClassInitFunc) gdaui_login_class_init,
333 			NULL,
334 			NULL,
335 			sizeof (GdauiLogin),
336 			0,
337 			(GInstanceInitFunc) gdaui_login_init,
338 			0
339 		};
340 		type = g_type_register_static (GTK_TYPE_BOX, "GdauiLogin", &info, 0);
341 	}
342 	return type;
343 }
344 
345 static gboolean
settings_are_valid(GdauiLogin * login)346 settings_are_valid (GdauiLogin *login)
347 {
348 	/* validate cnc information */
349 	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (login->priv->rb_dsn))) {
350 		/* using a DSN */
351 		gchar *dsn;
352 		dsn = _gdaui_dsn_selector_get_dsn (GDAUI_DSN_SELECTOR (login->priv->dsn_selector));
353 		if (dsn)
354 			g_free (dsn);
355 		else
356 			return FALSE;
357 	}
358 	else {
359 		/* using a direct CNC string */
360 		const gchar *prov;
361 		prov = gdaui_provider_selector_get_provider (GDAUI_PROVIDER_SELECTOR (login->priv->prov_selector));
362 		if (!prov)
363 			return FALSE;
364 
365 		if (! _gdaui_provider_spec_editor_is_valid (GDAUI_PROVIDER_SPEC_EDITOR (login->priv->cnc_params_editor)))
366 			return FALSE;
367 	}
368 
369 	/* validate authentication */
370 	if (! _gdaui_provider_auth_editor_is_valid (GDAUI_PROVIDER_AUTH_EDITOR (login->priv->auth_widget)))
371 		return FALSE;
372 
373 	return TRUE;
374 }
375 
376 static void
radio_button_use_dsn_toggled_cb(GtkToggleButton * button,GdauiLogin * login)377 radio_button_use_dsn_toggled_cb (GtkToggleButton *button, GdauiLogin *login)
378 {
379 	gboolean use_dsn = gtk_toggle_button_get_active (button);
380 
381 	gtk_widget_set_sensitive (login->priv->dsn_selector, use_dsn);
382 	gtk_widget_set_sensitive (login->priv->prov_selector, !use_dsn);
383 	gtk_widget_set_sensitive (login->priv->cnc_params_editor, !use_dsn);
384 	if (use_dsn)
385 		dsn_entry_changed_cb (GDAUI_DSN_SELECTOR (login->priv->dsn_selector), login);
386 	else
387 		prov_entry_changed_cb (GDAUI_PROVIDER_SELECTOR (login->priv->prov_selector), login);
388 }
389 
390 static void
run_cc_cb(G_GNUC_UNUSED GtkButton * button,GdauiLogin * login)391 run_cc_cb (G_GNUC_UNUSED GtkButton *button, GdauiLogin *login)
392 {
393 	gboolean sresult = FALSE;
394 	GError *lerror = NULL;
395 	gchar *cmd;
396 
397 	/* run gda-control-center tool */
398 #ifdef G_OS_WIN32
399 #define EXENAME "gda-control-center-" GDA_ABI_VERSION ".exe"
400 	gchar *argv[] = {EXENAME, NULL};
401 	cmd = gda_gbr_get_file_path (GDA_BIN_DIR, NULL);
402 	sresult = g_spawn_async (cmd, argv, NULL, 0, NULL, NULL, NULL, &lerror);
403 	g_free (cmd);
404 #else
405 #define EXENAME "gda-control-center-" GDA_ABI_VERSION
406 	GAppInfo *appinfo;
407 	GdkAppLaunchContext *context;
408 	GdkScreen *screen;
409 	cmd = gda_gbr_get_file_path (GDA_BIN_DIR, (char *) EXENAME, NULL);
410 	appinfo = g_app_info_create_from_commandline (cmd,
411 						      NULL,
412 						      G_APP_INFO_CREATE_NONE,
413 						      &lerror);
414 	g_free (cmd);
415 	if (!appinfo)
416 		goto checkerror;
417 
418 	screen = gtk_widget_get_screen (GTK_WIDGET (login));
419 	context = gdk_display_get_app_launch_context (gdk_screen_get_display (screen));
420 	gdk_app_launch_context_set_screen (context, screen);
421 	sresult = g_app_info_launch (appinfo, NULL, G_APP_LAUNCH_CONTEXT (context), NULL);
422 	if (! sresult) {
423 		g_object_unref (appinfo);
424 		appinfo = g_app_info_create_from_commandline (EXENAME,
425 							      NULL,
426 							      G_APP_INFO_CREATE_NONE,
427 							      NULL);
428 		if (!appinfo) {
429 			g_object_unref (context);
430 			goto checkerror;
431 		}
432 		sresult = g_app_info_launch (appinfo, NULL, G_APP_LAUNCH_CONTEXT (context), &lerror);
433 	}
434 	g_object_unref (context);
435 	g_object_unref (appinfo);
436 #endif /* G_OS_WIN32 */
437 
438  checkerror:
439 	if (!sresult) {
440 		GtkWidget *msgdialog;
441 		GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (login));
442 		if (!gtk_widget_is_toplevel (toplevel))
443 			toplevel = NULL;
444 		msgdialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (toplevel), GTK_DIALOG_MODAL,
445 								GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
446 								"<b>%s:</b>\n%s",
447 								_("Could not execute the Database access control center"),
448 								lerror && lerror->message ? lerror->message : _("No detail"));
449 
450 		if (lerror)
451 			g_error_free (lerror);
452 		gtk_dialog_run (GTK_DIALOG (msgdialog));
453 		gtk_widget_destroy (msgdialog);
454 	}
455 }
456 
457 static void
dsn_entry_changed_cb(GdauiDsnSelector * sel,GdauiLogin * login)458 dsn_entry_changed_cb (GdauiDsnSelector *sel, GdauiLogin *login)
459 {
460 	gchar *dsn;
461         GdaDsnInfo *info = NULL;
462         dsn = _gdaui_dsn_selector_get_dsn (sel);
463 
464 	if (dsn) {
465 		info = gda_config_get_dsn_info (dsn);
466 		g_free (dsn);
467 	}
468 
469 	/* update prov_selector */
470 	g_signal_handlers_block_by_func (login->priv->prov_selector, G_CALLBACK (prov_entry_changed_cb), login);
471 	gdaui_provider_selector_set_provider (GDAUI_PROVIDER_SELECTOR (login->priv->prov_selector),
472 					      info ? info->provider : NULL);
473 	g_signal_handlers_unblock_by_func (login->priv->prov_selector, G_CALLBACK (prov_entry_changed_cb), login);
474 
475 	/* update auth editor */
476 	_gdaui_provider_auth_editor_set_provider (GDAUI_PROVIDER_AUTH_EDITOR (login->priv->auth_widget),
477 						 info ? info->provider : NULL);
478 	_gdaui_provider_auth_editor_set_auth (GDAUI_PROVIDER_AUTH_EDITOR (login->priv->auth_widget),
479 					     info && info->auth_string ? info->auth_string : NULL);
480 
481 	/* update spec editor */
482 	_gdaui_provider_spec_editor_set_provider (GDAUI_PROVIDER_SPEC_EDITOR (login->priv->cnc_params_editor),
483 						  info ? info->provider : NULL);
484 	_gdaui_provider_spec_editor_set_specs (GDAUI_PROVIDER_SPEC_EDITOR (login->priv->cnc_params_editor),
485 					       info ? info->cnc_string : NULL);
486 
487 	if (login->priv->auth_widget)
488 		gtk_widget_grab_focus (login->priv->auth_widget);
489 
490 	g_signal_emit (login, gdaui_login_signals [CHANGED], 0, settings_are_valid (login));
491 }
492 
493 static void
prov_entry_changed_cb(GdauiProviderSelector * sel,GdauiLogin * login)494 prov_entry_changed_cb (GdauiProviderSelector *sel, GdauiLogin *login)
495 {
496 
497 	const gchar *prov;
498 
499 	g_signal_handlers_block_by_func (login->priv->dsn_selector, G_CALLBACK (dsn_entry_changed_cb), login);
500 	_gdaui_dsn_selector_set_dsn (GDAUI_DSN_SELECTOR (login->priv->dsn_selector), NULL);
501 	g_signal_handlers_unblock_by_func (login->priv->dsn_selector, G_CALLBACK (dsn_entry_changed_cb), login);
502 
503         prov = gdaui_provider_selector_get_provider (sel);
504 	_gdaui_provider_spec_editor_set_provider (GDAUI_PROVIDER_SPEC_EDITOR (login->priv->cnc_params_editor),
505 						 prov);
506 	_gdaui_provider_auth_editor_set_provider (GDAUI_PROVIDER_AUTH_EDITOR (login->priv->auth_widget),
507 						 prov);
508 
509 	if (login->priv->auth_widget)
510 		gtk_widget_grab_focus (login->priv->auth_widget);
511 
512 	g_signal_emit (login, gdaui_login_signals [CHANGED], 0, settings_are_valid (login));
513 }
514 
515 static void
cnc_params_editor_changed_cb(G_GNUC_UNUSED GdauiProviderSpecEditor * editor,GdauiLogin * login)516 cnc_params_editor_changed_cb (G_GNUC_UNUSED GdauiProviderSpecEditor *editor, GdauiLogin *login)
517 {
518 	g_signal_emit (login, gdaui_login_signals [CHANGED], 0, settings_are_valid (login));
519 }
520 
521 /**
522  * gdaui_login_new:
523  * @dsn: (allow-none): a data source name, or %NULL
524  *
525  * Creates a new login widget which enables the user to specify connection parameters.
526  *
527  * Returns: (transfer full): a new widget
528   *
529  * Since: 4.2
530 */
531 GtkWidget *
gdaui_login_new(G_GNUC_UNUSED const gchar * dsn)532 gdaui_login_new (G_GNUC_UNUSED const gchar *dsn)
533 {
534 	GtkWidget *login;
535 
536 	login = GTK_WIDGET(g_object_new (GDAUI_TYPE_LOGIN, NULL));
537 	return login;
538 }
539 
540 
541 /**
542  * gdaui_login_set_mode:
543  * @login: a #GdauiLogin object
544  * @mode: a flag
545  *
546  * Set how @login operates
547  *
548  * Since: 4.2
549  */
550 void
gdaui_login_set_mode(GdauiLogin * login,GdauiLoginMode mode)551 gdaui_login_set_mode (GdauiLogin *login, GdauiLoginMode mode)
552 {
553 	g_return_if_fail (GDAUI_IS_LOGIN (login));
554 	login->priv->mode = mode;
555 
556 	if (mode & (GDA_UI_LOGIN_HIDE_DSN_SELECTION_MODE | GDA_UI_LOGIN_HIDE_DIRECT_CONNECTION_MODE)) {
557 		gtk_widget_hide (login->priv->rb_dsn);
558 		gtk_widget_hide (login->priv->rb_prov);
559 	}
560 	else {
561 		gtk_widget_show (login->priv->rb_dsn);
562 		gtk_widget_show (login->priv->rb_prov);
563 	}
564 
565 	if (mode & GDA_UI_LOGIN_HIDE_DSN_SELECTION_MODE) {
566 		gtk_widget_hide (login->priv->cc_button);
567 		gtk_widget_hide (login->priv->dsn_selector);
568 	}
569 	else {
570 		if (mode & GDA_UI_LOGIN_ENABLE_CONTROL_CENTRE_MODE)
571 			gtk_widget_show (login->priv->cc_button);
572 		else
573 			gtk_widget_hide (login->priv->cc_button);
574 		gtk_widget_show (login->priv->dsn_selector);
575 	}
576 
577 	if (mode & GDA_UI_LOGIN_HIDE_DIRECT_CONNECTION_MODE) {
578 		gtk_widget_hide (login->priv->prov_selector);
579 		gtk_widget_hide (login->priv->cnc_params_editor);
580 	}
581 	else {
582 		gtk_widget_show (login->priv->prov_selector);
583 		gtk_widget_show (login->priv->cnc_params_editor);
584 	}
585 
586 	if ((mode & GDA_UI_LOGIN_HIDE_DSN_SELECTION_MODE) &&
587 	    !(mode & GDA_UI_LOGIN_HIDE_DIRECT_CONNECTION_MODE))
588 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (login->priv->rb_prov), TRUE);
589 	else if ((mode & GDA_UI_LOGIN_HIDE_DIRECT_CONNECTION_MODE) &&
590 		 !(mode & GDA_UI_LOGIN_HIDE_DSN_SELECTION_MODE))
591 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (login->priv->rb_dsn), TRUE);
592 }
593 
594 /**
595  * gdaui_login_get_connection_information:
596  * @login: a #GdauiLogin object
597  *
598  * Get the information specified in @login as a pointer to a (read-only) #GdaDsnInfo.
599  * If the connection is not specified by a DSN, then the 'name' attribute of the returned
600  * #GdaDsnInfo will be %NULL, and otherwise it will contain the name of the selected DSN.
601  *
602  * Returns: (transfer none): a pointer to a (read-only) #GdaDsnInfo.
603  *
604  * Since: 4.2
605  */
606 const GdaDsnInfo *
gdaui_login_get_connection_information(GdauiLogin * login)607 gdaui_login_get_connection_information (GdauiLogin *login)
608 {
609 	g_return_val_if_fail (GDAUI_IS_LOGIN (login), NULL);
610 
611 	clear_dsn_info (login);
612 	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (login->priv->rb_dsn))) {
613 		GdaDsnInfo *info = NULL;
614 		gchar *dsn;
615 		dsn = _gdaui_dsn_selector_get_dsn (GDAUI_DSN_SELECTOR (login->priv->dsn_selector));
616 		if (dsn && *dsn)
617 			info = gda_config_get_dsn_info (dsn);
618 		g_free (dsn);
619 		if (info) {
620 			login->priv->dsn_info.name = g_strdup (info->name);
621 			if (info->provider)
622 				login->priv->dsn_info.provider = g_strdup (info->provider);
623 			if (info->description)
624 				login->priv->dsn_info.description = g_strdup (info->description);
625 			if (info->cnc_string)
626 				login->priv->dsn_info.cnc_string = g_strdup (info->cnc_string);
627 			login->priv->dsn_info.is_system = info->is_system;
628 		}
629 		login->priv->dsn_info.auth_string = _gdaui_provider_auth_editor_get_auth (GDAUI_PROVIDER_AUTH_EDITOR (login->priv->auth_widget));
630 	}
631 	else {
632 		const gchar *str;
633 		str = gdaui_provider_selector_get_provider (GDAUI_PROVIDER_SELECTOR (login->priv->prov_selector));
634 		if (str)
635 			login->priv->dsn_info.provider = g_strdup (str);
636 		login->priv->dsn_info.cnc_string = _gdaui_provider_spec_editor_get_specs (GDAUI_PROVIDER_SPEC_EDITOR (login->priv->cnc_params_editor));
637 		login->priv->dsn_info.auth_string = _gdaui_provider_auth_editor_get_auth (GDAUI_PROVIDER_AUTH_EDITOR (login->priv->auth_widget));
638 	}
639 
640 	return &(login->priv->dsn_info);
641 }
642 
643 /**
644  * gdaui_login_set_dsn:
645  * @login: a #GdauiLogin object
646  * @dsn: (allow-none): a data source name, or %NULL
647  *
648  * Changes the information displayed in @login, to represent @dsn.
649  * If @login's mode has %GDA_UI_LOGIN_HIDE_DSN_SELECTION_MODE, then
650  * the DSN information is extracted and displayed in the direct login area.
651  *
652  * If @dsn is not a declared data source name, then a warning is shown and the result
653  * is the same as having passed %NULL for the @dsn argument.
654  *
655  * In any case @login's mode (set by gdaui_login_set_mode()) is not changed.
656  */
657 void
gdaui_login_set_dsn(GdauiLogin * login,const gchar * dsn)658 gdaui_login_set_dsn (GdauiLogin *login, const gchar *dsn)
659 {
660 	GdaDsnInfo *cinfo;
661 	g_return_if_fail (GDAUI_IS_LOGIN (login));
662 
663 	cinfo = gda_config_get_dsn_info (dsn);
664 	if (!cinfo)
665 		g_warning (_("Unknown DSN '%s'"), dsn);
666 	gdaui_login_set_connection_information (login, cinfo);
667 }
668 
669 /**
670  * gdaui_login_set_connection_information:
671  * @login: a #GdauiLogin object
672  * @cinfo: a pointer to a structure representing the information to display.
673  *
674  * Changes the information displayed in @login, to represent @cinfo.
675  * If @login's mode has %GDA_UI_LOGIN_HIDE_DIRECT_CONNECTION_MODE, then
676  * if @cinfo->name is not %NULL it is displayed in the DSN selector, otherwise
677  * a warning is shown and the result
678  * is the same as having passed %NULL for the @cinfo argument.
679  *
680  * In any case @login's mode (set by gdaui_login_set_mode()) is not changed.
681  */
682 void
gdaui_login_set_connection_information(GdauiLogin * login,const GdaDsnInfo * cinfo)683 gdaui_login_set_connection_information (GdauiLogin *login, const GdaDsnInfo *cinfo)
684 {
685 	g_return_if_fail (GDAUI_IS_LOGIN (login));
686 	if (!cinfo) {
687 		_gdaui_dsn_selector_set_dsn (GDAUI_DSN_SELECTOR (login->priv->dsn_selector), NULL);
688 	}
689 	else {
690 		GdaDsnInfo *info = NULL;
691 		if (cinfo->name)
692 			info = gda_config_get_dsn_info (cinfo->name);
693 		if (info)
694 			_gdaui_dsn_selector_set_dsn (GDAUI_DSN_SELECTOR (login->priv->dsn_selector), cinfo->name);
695 		else {
696 			/* force switch to */
697 			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (login->priv->rb_dsn), FALSE);
698 		}
699 		g_signal_handlers_block_by_func (login->priv->prov_selector,
700 						 G_CALLBACK (prov_entry_changed_cb), login);
701 		gdaui_provider_selector_set_provider (GDAUI_PROVIDER_SELECTOR (login->priv->prov_selector),
702 		                                      cinfo->provider);
703 		g_signal_handlers_unblock_by_func (login->priv->prov_selector,
704 						   G_CALLBACK (prov_entry_changed_cb), login);
705 
706 		_gdaui_provider_spec_editor_set_provider (GDAUI_PROVIDER_SPEC_EDITOR (login->priv->cnc_params_editor),
707 							  cinfo->provider);
708 		_gdaui_provider_spec_editor_set_specs (GDAUI_PROVIDER_SPEC_EDITOR (login->priv->cnc_params_editor),
709 						       cinfo->cnc_string);
710 		_gdaui_provider_auth_editor_set_provider (GDAUI_PROVIDER_AUTH_EDITOR (login->priv->auth_widget),
711 							  cinfo->provider);
712 		_gdaui_provider_auth_editor_set_auth (GDAUI_PROVIDER_AUTH_EDITOR (login->priv->auth_widget),
713 						      cinfo->auth_string);
714 	}
715 }
716