1 /*
2  * Copyright (C) 2009 - 2011 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 program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 
21 #include <string.h>
22 #include <libgda/gda-config.h>
23 #include <libgda/gda-set.h>
24 #include <libgda/gda-holder.h>
25 #include <gdk-pixbuf/gdk-pixbuf.h>
26 #include "gdaui-dsn-assistant.h"
27 #include <libgda-ui/internal/gdaui-provider-spec-editor.h>
28 #include <libgda-ui/internal/gdaui-provider-auth-editor.h>
29 #include <libgda-ui/gdaui-provider-selector.h>
30 #include <libgda-ui/gdaui-server-operation.h>
31 #include <glib/gi18n-lib.h>
32 #include <libgda-ui/internal/utility.h>
33 #include <libgda/binreloc/gda-binreloc.h>
34 
35 enum {
36 	PAGE_START           = 0,
37 	PAGE_GENERAL_INFO    = 1,
38 	PAGE_OPT_CREATE_DB   = 2,
39 	PAGE_CREATE_DB_INFO  = 3,
40 	PAGE_CONNECT_INFO    = 4,
41 	PAGE_AUTH_INFO       = 5,
42 	PAGE_LAST            = 6
43 };
44 
45 struct _GdauiDsnAssistantPrivate {
46 	GdaDsnInfo  *dsn_info;
47 	GdaServerOperation *create_db_op;
48 
49 	/* widgets */
50 	GtkWidget *general_page;
51 	GtkWidget *general_name;
52 	GtkWidget *general_provider;
53 	GtkWidget *general_description;
54 	GtkWidget *general_is_system;
55 
56 	GtkWidget *choose_toggle;
57 
58 	GtkWidget *newdb_box;
59 	GtkWidget *newdb_params;
60 
61 	GtkWidget *cnc_params_page;
62 	GtkWidget *provider_container;
63 	GtkWidget *provider_detail;
64 
65 	GtkWidget *cnc_auth_page;
66 	GtkWidget *auth_container;
67 	GtkWidget *auth_detail;
68 
69 	GtkSizeGroup *size_group;
70 };
71 
72 static void gdaui_dsn_assistant_class_init (GdauiDsnAssistantClass *klass);
73 static void gdaui_dsn_assistant_init       (GdauiDsnAssistant *assistant,
74 						  GdauiDsnAssistantClass *klass);
75 static void gdaui_dsn_assistant_finalize   (GObject *object);
76 
77 enum {
78 	FINISHED,
79 	LAST_SIGNAL
80 };
81 
82 static guint config_assistant_signals[LAST_SIGNAL] = { 0, };
83 static GObjectClass *parent_class = NULL;
84 
85 static void
data_source_info_free(GdaDsnInfo * info)86 data_source_info_free (GdaDsnInfo *info)
87 {
88 	g_free (info->provider);
89 	g_free (info->cnc_string);
90 	g_free (info->description);
91 	g_free (info->auth_string);
92 	g_free (info);
93 }
94 
95 /*
96  * Callbacks
97  */
98 
99 static void
assistant_cancelled_cb(GtkAssistant * assistant,G_GNUC_UNUSED gpointer data)100 assistant_cancelled_cb (GtkAssistant *assistant, G_GNUC_UNUSED gpointer data)
101 {
102 	g_return_if_fail (GDAUI_IS_DSN_ASSISTANT (assistant));
103 	g_signal_emit_by_name (G_OBJECT (assistant), "finished", TRUE);
104 	g_signal_emit_by_name (G_OBJECT (assistant), "close");
105 }
106 
107 static void
assistant_applied_cb(GtkAssistant * assist,G_GNUC_UNUSED gpointer data)108 assistant_applied_cb (GtkAssistant *assist, G_GNUC_UNUSED gpointer data)
109 {
110 	gboolean allok = TRUE;
111 	GString *cnc_string = NULL;
112 	GdauiDsnAssistant *assistant = (GdauiDsnAssistant *) assist;
113 
114 	g_return_if_fail (GDAUI_IS_DSN_ASSISTANT (assistant));
115 
116 	/* clear the internal dsn_info */
117 	if (assistant->priv->dsn_info) {
118 		data_source_info_free (assistant->priv->dsn_info);
119 		assistant->priv->dsn_info = NULL;
120 	}
121 
122 	/* New database creation first */
123 	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (assistant->priv->choose_toggle))) {
124 		if (!gda_server_operation_is_valid (assistant->priv->create_db_op, NULL, NULL)) {
125 			_gdaui_utility_show_error (NULL, _("Missing mandatory information, to create database"));
126 			gtk_assistant_set_current_page (assist, PAGE_CREATE_DB_INFO);
127 			return;
128 		}
129 		else {
130 			GdaProviderInfo *prov_info;
131 			GSList *dsn_params;
132 			GError *error = NULL;
133 
134 			allok = gda_server_operation_perform_create_database (assistant->priv->create_db_op, NULL, &error);
135 			if (!allok) {
136 				gchar *str;
137 				str = g_strdup_printf (_("Error creating database: %s"),
138 						       error && error->message ? error->message : _("Unknown error"));
139 				_gdaui_utility_show_error (NULL, str);
140 				g_free (str);
141 
142 				gtk_assistant_set_current_page (assist, PAGE_CREATE_DB_INFO);
143 				return;
144 			}
145 
146 			/* make the connection string for the data source */
147 			prov_info = gda_config_get_provider_info (gdaui_provider_selector_get_provider
148 								  (GDAUI_PROVIDER_SELECTOR (assistant->priv->general_provider)));
149 			g_return_if_fail (prov_info);
150 			for (dsn_params = prov_info->dsn_params->holders; dsn_params; dsn_params = dsn_params->next) {
151 				GdaHolder *param = GDA_HOLDER (dsn_params->data);
152 				const GValue *value;
153 
154 				value = gda_server_operation_get_value_at (assistant->priv->create_db_op,
155 									   "/DB_DEF_P/%s",
156 									   gda_holder_get_id (param));
157 				if (!value)
158 					value = gda_server_operation_get_value_at (assistant->priv->create_db_op,
159 										   "/SERVER_CNX_P/%s",
160 										   gda_holder_get_id (param));
161 
162 				if (value && !gda_value_is_null ((GValue *) value)) {
163 					gchar *str;
164 
165 					if (dsn_params == prov_info->dsn_params->holders)
166 						cnc_string = g_string_new ("");
167 					else
168 						g_string_append (cnc_string, ";");
169 					str = gda_value_stringify ((GValue *) value);
170 					g_string_append_printf (cnc_string, "%s=%s", gda_holder_get_id (param), str);
171 					g_free (str);
172 				}
173 			}
174 		}
175 	}
176 
177 	/* Data source declaration */
178 	if (allok) {
179 		assistant->priv->dsn_info = g_new0 (GdaDsnInfo, 1);
180 		assistant->priv->dsn_info->name = g_strdup (gtk_entry_get_text (GTK_ENTRY (assistant->priv->general_name)));
181 		assistant->priv->dsn_info->provider = g_strdup (
182 					 gdaui_provider_selector_get_provider (
183 					 GDAUI_PROVIDER_SELECTOR (assistant->priv->general_provider)));
184 		if (cnc_string) {
185 			assistant->priv->dsn_info->cnc_string = cnc_string->str;
186 			g_string_free (cnc_string, FALSE);
187 		}
188 		else
189 			assistant->priv->dsn_info->cnc_string = _gdaui_provider_spec_editor_get_specs
190 				(GDAUI_PROVIDER_SPEC_EDITOR (assistant->priv->provider_detail));
191 		assistant->priv->dsn_info->description =
192 			g_strdup (gtk_entry_get_text (GTK_ENTRY (assistant->priv->general_description)));
193 		assistant->priv->dsn_info->auth_string = NULL;
194 		if (assistant->priv->auth_detail)
195 			assistant->priv->dsn_info->auth_string =
196 				_gdaui_provider_auth_editor_get_auth (GDAUI_PROVIDER_AUTH_EDITOR (assistant->priv->auth_detail));
197 		if (gda_config_can_modify_system_config ())
198 			assistant->priv->dsn_info->is_system = gtk_toggle_button_get_active
199 				(GTK_TOGGLE_BUTTON (assistant->priv->general_is_system));
200 		else
201 			assistant->priv->dsn_info->is_system = FALSE;
202 	}
203 
204 	/* notify listeners */
205 	g_signal_emit (G_OBJECT (assistant), config_assistant_signals[FINISHED], 0, !allok);
206 }
207 
208 static GdaServerOperation *
get_specs_database_creation(GdauiDsnAssistant * assistant)209 get_specs_database_creation (GdauiDsnAssistant *assistant)
210 {
211 	if (! assistant->priv->create_db_op)
212 		assistant->priv->create_db_op =
213 			gda_server_operation_prepare_create_database (gdaui_provider_selector_get_provider (
214 						     GDAUI_PROVIDER_SELECTOR (assistant->priv->general_provider)),
215 						     NULL, NULL);
216 
217 	return assistant->priv->create_db_op;
218 }
219 
220 static void
dsn_spec_changed_cb(GdauiProviderSpecEditor * spec,GdauiDsnAssistant * assistant)221 dsn_spec_changed_cb (GdauiProviderSpecEditor *spec, GdauiDsnAssistant *assistant)
222 {
223 	gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant),
224 					 assistant->priv->cnc_params_page,
225 					 _gdaui_provider_spec_editor_is_valid (spec));
226 }
227 
228 static void
dsn_auth_changed_cb(GdauiProviderAuthEditor * auth,GdauiDsnAssistant * assistant)229 dsn_auth_changed_cb (GdauiProviderAuthEditor *auth, GdauiDsnAssistant *assistant)
230 {
231 	gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant),
232 					 assistant->priv->cnc_auth_page,
233 					 _gdaui_provider_auth_editor_is_valid (auth));
234 }
235 
236 static void
provider_changed_cb(G_GNUC_UNUSED GtkWidget * combo,GdauiDsnAssistant * assistant)237 provider_changed_cb (G_GNUC_UNUSED GtkWidget *combo, GdauiDsnAssistant *assistant)
238 {
239 	GdaServerOperation *op;
240 	const gchar *provider;
241 
242 	/* clean any previous Provider specific stuff */
243 	if (assistant->priv->newdb_params) {
244 		gtk_widget_destroy (assistant->priv->newdb_params);
245 		assistant->priv->newdb_params = NULL;
246 	}
247 
248 	if (assistant->priv->create_db_op) {
249 		g_object_unref (assistant->priv->create_db_op);
250 		assistant->priv->create_db_op = NULL;
251 	}
252 
253 	if (!assistant->priv->size_group)
254 		assistant->priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
255 
256 	/* is the database creation supported by the chosen provider? */
257 	op = get_specs_database_creation (assistant);
258 	if (op) {
259 		assistant->priv->newdb_params = g_object_new (GDAUI_TYPE_SERVER_OPERATION,
260 							      "hide-single-header", TRUE,
261 							      "server-operation", op, NULL);
262 		gtk_widget_show (assistant->priv->newdb_params);
263 		gtk_container_add (GTK_CONTAINER (assistant->priv->newdb_box),
264 				   assistant->priv->newdb_params);
265 		assistant->priv->create_db_op = op;
266 		gtk_widget_set_sensitive (assistant->priv->choose_toggle, TRUE);
267 	}
268 	else {
269 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (assistant->priv->choose_toggle),
270 					      FALSE);
271 		gtk_widget_set_sensitive (assistant->priv->choose_toggle, FALSE);
272 	}
273 
274 	/* dsn spec for the selected provider */
275 	provider = gdaui_provider_selector_get_provider (GDAUI_PROVIDER_SELECTOR (assistant->priv->general_provider));
276 	g_assert (provider);
277 	if (!assistant->priv->provider_detail) {
278 		assistant->priv->provider_detail = _gdaui_provider_spec_editor_new (provider);
279 		gtk_box_pack_start (GTK_BOX (assistant->priv->provider_container),
280 				    assistant->priv->provider_detail, TRUE, TRUE, 0);
281 		gtk_widget_show (assistant->priv->provider_detail);
282 		g_signal_connect (assistant->priv->provider_detail, "changed",
283 				  G_CALLBACK (dsn_spec_changed_cb), assistant);
284 		_gdaui_provider_spec_editor_add_to_size_group (GDAUI_PROVIDER_SPEC_EDITOR (assistant->priv->provider_detail),
285 							       assistant->priv->size_group,
286 							       GDAUI_BASIC_FORM_LABELS);
287 	}
288 	else
289 		_gdaui_provider_spec_editor_set_provider (GDAUI_PROVIDER_SPEC_EDITOR (assistant->priv->provider_detail), provider);
290 
291 	/* dsn authentication for the selected provider */
292 	if (!assistant->priv->auth_detail) {
293 		assistant->priv->auth_detail = _gdaui_provider_auth_editor_new (provider);
294 		gtk_box_pack_start (GTK_BOX (assistant->priv->auth_container),
295 				    assistant->priv->auth_detail, TRUE, TRUE, 0);
296 		gtk_widget_show (assistant->priv->auth_detail);
297 		g_signal_connect (assistant->priv->auth_detail, "changed",
298 				  G_CALLBACK (dsn_auth_changed_cb), assistant);
299 		_gdaui_provider_auth_editor_add_to_size_group (GDAUI_PROVIDER_AUTH_EDITOR (assistant->priv->auth_detail),
300 							       assistant->priv->size_group,
301 							       GDAUI_BASIC_FORM_LABELS);
302 	}
303 	else
304 		_gdaui_provider_auth_editor_set_provider (GDAUI_PROVIDER_AUTH_EDITOR (assistant->priv->auth_detail), provider);
305 }
306 
307 static void
dsn_name_changed_cb(GtkEntry * entry,GdauiDsnAssistant * assistant)308 dsn_name_changed_cb (GtkEntry *entry, GdauiDsnAssistant *assistant)
309 {
310 	const gchar *name;
311 	gboolean page_complete = TRUE;
312 	GdaDsnInfo *dsn_info;
313 
314 	/* check required fields have values */
315 	name = gtk_entry_get_text (GTK_ENTRY (assistant->priv->general_name));
316 	if (!name || strlen (name) < 1) {
317 		gtk_widget_grab_focus (assistant->priv->general_name);
318 		page_complete = FALSE;
319 	}
320 
321 	dsn_info = gda_config_get_dsn_info (name);
322 	if (dsn_info) {
323 		gint i = 2;
324 		gchar *str = NULL;
325 
326 		do {
327 			g_free (str);
328 			str = g_strdup_printf ("%s_%d", name, i);
329 			dsn_info = gda_config_get_dsn_info (str);
330 		} while (dsn_info);
331 
332 		gtk_entry_set_text (entry, str);
333 		g_free (str);
334 		/*gtk_widget_grab_focus (assistant->priv->general_name);*/
335 	}
336 
337 	gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant),
338 					 assistant->priv->general_page,
339 					 page_complete);
340 }
341 
342 /*
343  * GdauiDsnAssistant class implementation
344  */
345 
346 static void
gdaui_dsn_assistant_class_init(GdauiDsnAssistantClass * klass)347 gdaui_dsn_assistant_class_init (GdauiDsnAssistantClass *klass)
348 {
349 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
350 
351 	parent_class = g_type_class_peek_parent (klass);
352 
353 	config_assistant_signals[FINISHED] =
354 		g_signal_new ("finished",
355 			      G_TYPE_FROM_CLASS (object_class),
356 			      G_SIGNAL_RUN_LAST,
357 			      G_STRUCT_OFFSET (GdauiDsnAssistantClass, finished),
358 			      NULL, NULL,
359 			      g_cclosure_marshal_VOID__BOOLEAN,
360 			      G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
361 
362 	klass->finished = NULL;
363 	object_class->finalize = gdaui_dsn_assistant_finalize;
364 }
365 
366 static gint
forward_page_function(gint current_page,GdauiDsnAssistant * assistant)367 forward_page_function (gint current_page, GdauiDsnAssistant *assistant)
368 {
369 	switch (current_page) {
370 	case PAGE_START:
371 		return PAGE_GENERAL_INFO;
372 	case PAGE_GENERAL_INFO:
373 		if (assistant->priv->newdb_params)
374 			return PAGE_OPT_CREATE_DB;
375 		else
376 			return PAGE_CONNECT_INFO;
377 	case PAGE_OPT_CREATE_DB:
378 		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (assistant->priv->choose_toggle)))
379 			return PAGE_CREATE_DB_INFO;
380 		else
381 			return PAGE_CONNECT_INFO;
382 	case PAGE_CREATE_DB_INFO:
383 		return PAGE_LAST;
384 	case PAGE_CONNECT_INFO: {
385 		GdaProviderInfo *pinfo;
386 		const gchar *provider;
387 		provider = gdaui_provider_selector_get_provider (GDAUI_PROVIDER_SELECTOR (assistant->priv->general_provider));
388 		if (provider != NULL) {
389 		pinfo = gda_config_get_provider_info (provider);
390 			if (pinfo != NULL) {
391 				if (pinfo->auth_params && pinfo->auth_params->holders)
392 					return PAGE_AUTH_INFO;
393 				else
394 					return PAGE_LAST;
395 			}
396 		}
397 	}
398 	case PAGE_AUTH_INFO:
399 		return PAGE_LAST;
400 	case PAGE_LAST:
401 		break;
402 	default:
403 		g_assert_not_reached ();
404 	}
405 	return -1;
406 }
407 
408 static void
gdaui_dsn_assistant_init(GdauiDsnAssistant * assistant,G_GNUC_UNUSED GdauiDsnAssistantClass * klass)409 gdaui_dsn_assistant_init (GdauiDsnAssistant *assistant,
410 			     G_GNUC_UNUSED GdauiDsnAssistantClass *klass)
411 {
412 	GtkWidget *label, *vbox, *grid;
413 	GtkAssistant *assist;
414 	gchar *str;
415 
416 	g_return_if_fail (GDAUI_IS_DSN_ASSISTANT (assistant));
417 
418 	/* global assistant settings */
419 	assist = GTK_ASSISTANT (assistant);
420 	gtk_window_set_title (GTK_WINDOW (assist), _("New data source definition"));
421 	gtk_container_set_border_width (GTK_CONTAINER (assist), 0);
422 	g_signal_connect (assist, "cancel", G_CALLBACK (assistant_cancelled_cb), NULL);
423 	g_signal_connect (assist, "apply", G_CALLBACK (assistant_applied_cb), NULL);
424 	gtk_assistant_set_forward_page_func (assist, (GtkAssistantPageFunc) forward_page_function,
425 					     assistant, NULL);
426 
427 	/* create private structure */
428 	assistant->priv = g_new0 (GdauiDsnAssistantPrivate, 1);
429 	assistant->priv->dsn_info = g_new0 (GdaDsnInfo, 1);
430 	assistant->priv->provider_detail = NULL;
431 	assistant->priv->create_db_op = NULL;
432 
433 	/*
434 	 * start page
435 	 */
436 	label = gtk_label_new ("");
437 	gtk_label_set_markup (GTK_LABEL (label),
438 			      _("This assistant will guide you through the process of "
439 				"creating a new data source, and optionally will allow you to "
440 				"create a new database.\n\nJust follow the steps!"));
441 	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
442 	gtk_widget_show (label);
443 	gtk_assistant_append_page (assist, label);
444 	gtk_assistant_set_page_title (assist, label, _("Add a new data source..."));
445 
446 	/* TODO: This is deprecated. Add it to the main content instead: */
447 	gtk_assistant_set_page_type (assist, label, GTK_ASSISTANT_PAGE_INTRO);
448 	gtk_assistant_set_page_complete (assist, label, TRUE);
449 
450 	/*
451 	 * general info page
452 	 */
453 	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
454 
455 	grid = gtk_grid_new ();
456 	gtk_box_pack_start (GTK_BOX (vbox), grid, FALSE, FALSE, 0);
457 	gtk_container_set_border_width (GTK_CONTAINER (grid), 0);
458 	gtk_grid_set_row_spacing (GTK_GRID (grid), 3);
459 	gtk_grid_set_column_spacing (GTK_GRID (grid), 5);
460 
461 	label = gtk_label_new (NULL);
462 	gtk_label_set_markup (GTK_LABEL (label),
463 			      _("The following fields represent the basic information "
464 				"items for your new data source. Mandatory fields are marked "
465 				"with a star. "
466 				"To create a local database in a file, select the 'SQLite' type "
467 				"of database."));
468 	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
469 	gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 2, 1);
470 
471 	str = _gdaui_utility_markup_title (_("Data source name"), FALSE);
472 	label = gtk_label_new ("");
473 	gtk_label_set_markup (GTK_LABEL (label), str);
474 	g_free (str);
475 	gtk_misc_set_alignment (GTK_MISC (label), 0., 0.);
476 	gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
477 
478 	assistant->priv->general_name = gtk_entry_new ();
479 	gtk_editable_set_editable (GTK_EDITABLE (assistant->priv->general_name), TRUE);
480         gtk_widget_show (assistant->priv->general_name);
481 	gtk_grid_attach (GTK_GRID (grid), assistant->priv->general_name, 1, 1, 1, 1);
482 	g_signal_connect (assistant->priv->general_name, "changed",
483 			  G_CALLBACK (dsn_name_changed_cb), assistant);
484 
485 	if (gda_config_can_modify_system_config ()) {
486 		label = gtk_label_new (_("System wide data source:"));
487 		gtk_misc_set_alignment (GTK_MISC (label), 0., 0.);
488 		gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
489 
490 		assistant->priv->general_is_system = gtk_check_button_new ();
491 		gtk_grid_attach (GTK_GRID (grid), assistant->priv->general_is_system, 1, 2, 1, 1);
492 	}
493 	else
494 		assistant->priv->general_is_system = NULL;
495 
496 	str = _gdaui_utility_markup_title (_("Database type"), FALSE);
497 	label = gtk_label_new ("");
498 	gtk_label_set_markup (GTK_LABEL (label), str);
499 	g_free (str);
500 	gtk_misc_set_alignment (GTK_MISC (label), 0., 0.);
501 	gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
502 
503 	assistant->priv->general_provider = gdaui_provider_selector_new ();
504 	gtk_grid_attach (GTK_GRID (grid), assistant->priv->general_provider, 1, 3, 1, 1);
505 
506 	label = gtk_label_new (_("Description:"));
507 	gtk_misc_set_alignment (GTK_MISC (label), 0., 0.);
508 	gtk_grid_attach (GTK_GRID (grid), label, 0, 4, 1, 1);
509 
510 	assistant->priv->general_description = gtk_entry_new ();
511 	gtk_editable_set_editable (GTK_EDITABLE (assistant->priv->general_description), TRUE);
512         gtk_widget_show (assistant->priv->general_description);
513 	gtk_grid_attach (GTK_GRID (grid), assistant->priv->general_description, 1, 4, 1, 1);
514 
515 	gtk_widget_show_all (vbox);
516 
517 	gtk_assistant_append_page (assist, vbox);
518 	gtk_assistant_set_page_title (assist, vbox, _("General Information"));
519 	gtk_assistant_set_page_type (assist, vbox, GTK_ASSISTANT_PAGE_CONTENT);
520 	assistant->priv->general_page = vbox;
521 
522 	/*
523 	 * Choose between existing database or create a new one
524 	 */
525 	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
526 
527 	grid = gtk_grid_new ();
528 	gtk_box_pack_start (GTK_BOX (vbox), grid, FALSE, FALSE, 0);
529 	gtk_container_set_border_width (GTK_CONTAINER (grid), 0);
530 	gtk_grid_set_row_spacing (GTK_GRID (grid), 3);
531 	gtk_grid_set_column_spacing (GTK_GRID (grid), 5);
532 
533 	label = gtk_label_new (NULL);
534 	gtk_label_set_markup (GTK_LABEL (label),
535 			      _("This page lets you choose between using an existing database "
536 				"or to create a new database to use with this new data source"));
537 	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
538 	gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 2, 1);
539 
540 	label = gtk_label_new (_("Create a new database:"));
541 	gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
542 
543 	assistant->priv->choose_toggle = gtk_check_button_new ();
544 	gtk_grid_attach (GTK_GRID (grid), assistant->priv->choose_toggle, 1, 1, 1, 1);
545 
546 	gtk_widget_show_all (vbox);
547 
548 	gtk_assistant_append_page (assist, vbox);
549 	gtk_assistant_set_page_title (assist, vbox, _("Create a new database?"));
550 	gtk_assistant_set_page_type (assist, vbox, GTK_ASSISTANT_PAGE_CONTENT);
551 	gtk_assistant_set_page_complete (assist, vbox, TRUE);
552 
553 	/*
554 	 * New database information page
555 	 */
556 	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
557 	gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
558 
559 	label = gtk_label_new (NULL);
560 	gtk_label_set_markup (GTK_LABEL (label),
561 			      _("The following fields represent the information needed "
562 				"to create a new database "
563 				"(mandatory fields are marked with a star)."
564 				"This information is database-specific, so check "
565 				"the manual for more information."));
566 	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
567 	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
568 
569 	GtkWidget *sw, *vp;
570 	sw = gtk_scrolled_window_new (NULL, NULL);
571 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC,
572 					GTK_POLICY_AUTOMATIC);
573 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_NONE);
574 	vp = gtk_viewport_new (NULL, NULL);
575 	gtk_widget_set_name (vp, "gdaui-transparent-background");
576 	gtk_viewport_set_shadow_type (GTK_VIEWPORT (vp), GTK_SHADOW_NONE);
577 	gtk_container_add (GTK_CONTAINER (sw), vp);
578 	assistant->priv->newdb_box = vp;
579 	gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
580 	assistant->priv->newdb_params = NULL;
581 
582 	gtk_widget_show_all (vbox);
583 
584 	gtk_assistant_append_page (assist, vbox);
585 	gtk_assistant_set_page_title (assist, vbox, _("New database definition"));
586 	gtk_assistant_set_page_type (assist, vbox, GTK_ASSISTANT_PAGE_CONTENT);
587 	gtk_assistant_set_page_complete (assist, vbox, TRUE);
588 
589 	/*
590 	 * provider parameters to open connection page
591 	 */
592 	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
593 	gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
594 
595 	label = gtk_label_new (NULL);
596 	gtk_label_set_markup (GTK_LABEL (label),
597 			      _("The following fields represent the information needed "
598 				"to open a connection (mandatory fields are marked with a star). "
599 				"This information is database-specific, so check "
600 				"the manual for more information."));
601 	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
602 	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
603 
604 	assistant->priv->provider_container = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
605 	gtk_box_pack_start (GTK_BOX (vbox), assistant->priv->provider_container, TRUE, TRUE, 0);
606 
607 	gtk_widget_show_all (vbox);
608 
609 	gtk_assistant_append_page (assist, vbox);
610 	gtk_assistant_set_page_title (assist, vbox, _("Connection's parameters"));
611 	gtk_assistant_set_page_type (assist, vbox, GTK_ASSISTANT_PAGE_CONTENT);
612 	assistant->priv->cnc_params_page = vbox;
613 
614 	/*
615 	 * authentication page
616 	 */
617 	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
618 	gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
619 
620 	label = gtk_label_new (NULL);
621 	gtk_label_set_markup (GTK_LABEL (label),
622 			      _("The following fields represent the authentication information needed "
623 				"to open a connection."));
624 	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
625 	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
626 
627 	assistant->priv->auth_container = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
628 	gtk_box_pack_start (GTK_BOX (vbox), assistant->priv->auth_container, TRUE, TRUE, 0);
629 
630 	gtk_widget_show_all (vbox);
631 
632 	gtk_assistant_append_page (assist, vbox);
633 	gtk_assistant_set_page_title (assist, vbox, _("Authentication parameters"));
634 	gtk_assistant_set_page_type (assist, vbox, GTK_ASSISTANT_PAGE_CONTENT);
635 	assistant->priv->cnc_auth_page = vbox;
636 
637 	/*
638 	 * end page
639 	 */
640 	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
641 	gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
642 
643 	label = gtk_label_new (NULL);
644 	gtk_label_set_markup (GTK_LABEL (label),
645 			      _("All information needed to create a new data source "
646 				"has been retrieved. Now, press 'Apply' to close "
647 				"this dialog."));
648 	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
649 	gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
650 
651 	gtk_widget_show_all (vbox);
652 
653 	gtk_assistant_append_page (assist, vbox);
654 	gtk_assistant_set_page_title (assist, vbox, _("Ready to add a new data source"));
655 	gtk_assistant_set_page_type (assist, vbox, GTK_ASSISTANT_PAGE_CONFIRM);
656 	gtk_assistant_set_page_complete (assist, vbox, TRUE);
657 
658 	/* force correct init */
659 	provider_changed_cb (assistant->priv->general_provider, assistant);
660 
661 	g_signal_connect (G_OBJECT (assistant->priv->general_provider), "changed",
662 			  G_CALLBACK (provider_changed_cb), assistant);
663 }
664 
665 static void
gdaui_dsn_assistant_finalize(GObject * object)666 gdaui_dsn_assistant_finalize (GObject *object)
667 {
668 	GdauiDsnAssistant *assistant = (GdauiDsnAssistant *) object;
669 
670 	g_return_if_fail (GDAUI_IS_DSN_ASSISTANT (assistant));
671 
672 	/* free memory */
673 	if (assistant->priv->dsn_info)
674 		data_source_info_free (assistant->priv->dsn_info);
675 
676 	if (assistant->priv->create_db_op)
677 		g_object_unref (assistant->priv->create_db_op);
678 
679 	if (assistant->priv->size_group)
680 		g_object_unref (assistant->priv->size_group);
681 
682 	g_free (assistant->priv);
683 	assistant->priv = NULL;
684 
685 	parent_class->finalize (object);
686 }
687 
688 GType
gdaui_dsn_assistant_get_type(void)689 gdaui_dsn_assistant_get_type (void)
690 {
691 	static GType type = 0;
692 
693 	if (G_UNLIKELY (type == 0)) {
694 		static const GTypeInfo info = {
695 			sizeof (GdauiDsnAssistantClass),
696 			(GBaseInitFunc) NULL,
697 			(GBaseFinalizeFunc) NULL,
698 			(GClassInitFunc) gdaui_dsn_assistant_class_init,
699 			NULL,
700 			NULL,
701 			sizeof (GdauiDsnAssistant),
702 			0,
703 			(GInstanceInitFunc) gdaui_dsn_assistant_init,
704 			0
705 		};
706 		type = g_type_register_static (GTK_TYPE_ASSISTANT, "GdauiDsnAssistant",
707 					       &info, 0);
708 	}
709 	return type;
710 }
711 
712 /**
713  * gdaui_dsn_assistant_new
714  *
715  *
716  *
717  * Returns:
718  */
719 GtkWidget *
gdaui_dsn_assistant_new(void)720 gdaui_dsn_assistant_new (void)
721 {
722 	GdauiDsnAssistant *assistant;
723 
724 	assistant = g_object_new (GDAUI_TYPE_DSN_ASSISTANT, NULL);
725 	return GTK_WIDGET (assistant);
726 }
727 
728 /**
729  * gdaui_dsn_assistant_get_dsn
730  * @assistant:
731  *
732  *
733  *
734  * Returns:
735  */
736 const GdaDsnInfo *
gdaui_dsn_assistant_get_dsn(GdauiDsnAssistant * assistant)737 gdaui_dsn_assistant_get_dsn (GdauiDsnAssistant *assistant)
738 {
739 	g_return_val_if_fail (GDAUI_IS_DSN_ASSISTANT (assistant), NULL);
740 	return (const GdaDsnInfo *) assistant->priv->dsn_info;
741 }
742