1 /*
2  * Copyright (C) 2009 - 2011 Vivien Malerba <malerba@gnome-db.org>
3  * Copyright (C) 2010 David King <davidk@openismus.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program 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
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19 
20 #include <unistd.h>
21 #include <glib/gi18n-lib.h>
22 #include <glib/gprintf.h>
23 #include <string.h>
24 #include <libgda-ui/libgda-ui.h>
25 #include "support.h"
26 #include "browser-core.h"
27 #include "browser-connection.h"
28 #include "browser-window.h"
29 #include "login-dialog.h"
30 #include "auth-dialog.h"
31 #include "browser-stock-icons.h"
32 #include "../config-info.h"
33 
34 #ifdef HAVE_LOCALE_H
35 #include <locale.h>
36 #endif
37 
38 /* Perspectives' factories */
39 #include "schema-browser/perspective-main.h"
40 #include "query-exec/perspective-main.h"
41 #include "data-manager/perspective-main.h"
42 #ifdef HAVE_LDAP
43 #include "ldap-browser/perspective-main.h"
44 #endif
45 /* #include "dummy-perspective/perspective-main.h" */
46 
47 extern BrowserCoreInitFactories browser_core_init_factories;
48 
49 GSList *
50 main_browser_core_init_factories (void)
51 {
52 	GSList *factories = NULL;
53 	factories = g_slist_append (factories, schema_browser_perspective_get_factory ());
54 	factories = g_slist_append (factories, query_exec_perspective_get_factory ());
55 	factories = g_slist_append (factories, data_manager_perspective_get_factory ());
56 #ifdef HAVE_LDAP
57 	factories = g_slist_append (factories, ldap_browser_perspective_get_factory ());
58 #endif
59 	/* factories = g_slist_append (factories, dummy_perspective_get_factory ()); */
60 	return factories;
61 }
62 
63 static void
64 output_data_model (GdaDataModel *model)
65 {
66 	if (! getenv ("GDA_DATA_MODEL_DUMP_TITLE"))
67 		g_setenv ("GDA_DATA_MODEL_DUMP_TITLE", "Yes", TRUE);
68 	if (! getenv ("GDA_DATA_MODEL_NULL_AS_EMPTY"))
69 		g_setenv ("GDA_DATA_MODEL_NULL_AS_EMPTY", "Yes", TRUE);
70 	if (isatty (fileno (stdout))) {
71 		if (! getenv ("GDA_DATA_MODEL_DUMP_TRUNCATE"))
72 			g_setenv ("GDA_DATA_MODEL_DUMP_TRUNCATE", "-1", TRUE);
73 	}
74 	gda_data_model_dump (model, NULL);
75 }
76 
77 
78 /* options */
79 gchar *perspective = NULL;
80 gboolean list_configs = FALSE;
81 gboolean list_providers = FALSE;
82 gboolean list_data_files = FALSE;
83 gchar *purge_data_files = NULL;
84 
85 static GOptionEntry entries[] = {
86         { "perspective", 'p', 0, G_OPTION_ARG_STRING, &perspective, "Perspective", "default perspective "
87 	  "to use when opening windows"},
88         { "list-dsn", 'l', 0, G_OPTION_ARG_NONE, &list_configs, "List configured data sources and exit", NULL },
89         { "list-providers", 'L', 0, G_OPTION_ARG_NONE, &list_providers, "List installed database providers and exit", NULL },
90         { "data-files-list", 0, 0, G_OPTION_ARG_NONE, &list_data_files, "List files used to hold information related to each connection", NULL },
91         { "data-files-purge", 0, 0, G_OPTION_ARG_STRING, &purge_data_files, "Remove some files used to hold information related to each connection", "criteria"},
92 	{ NULL, 0, 0, 0, NULL, NULL, NULL }
93 };
94 
95 int
96 main (int argc, char *argv[])
97 {
98 	GOptionContext *context;
99         GError *error = NULL;
100 	gboolean have_loop = FALSE;
101 
102 	/* set factories function */
103 	browser_core_init_factories = main_browser_core_init_factories;
104 
105 	context = g_option_context_new (_("[DSN|connection string]..."));
106         g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
107 	g_option_context_add_group (context, gtk_get_option_group (TRUE));
108         g_option_context_set_ignore_unknown_options (context, TRUE);
109         if (!g_option_context_parse (context, &argc, &argv, &error)) {
110                 g_fprintf  (stderr, "Can't parse arguments: %s\n", error->message);
111                 return EXIT_FAILURE;
112         }
113         g_option_context_free (context);
114 
115 	/* treat here lists of providers and defined DSN */
116 	if (list_providers) {
117 		gda_init ();
118 		setlocale (LC_ALL, "");
119 		GdaDataModel *model;
120 		if (argc == 2)
121 			model = config_info_detail_provider (argv[1], &error);
122 		else
123 			model = config_info_list_all_providers ();
124 
125 		if (model) {
126 			output_data_model (model);
127 			g_object_unref (model);
128 		}
129 		else {
130 			g_print (_("Error: %s\n"),
131 				 error && error->message ? error->message : _("No detail"));
132 			g_clear_error (&error);
133 		}
134 		return 0;
135 	}
136 	if (list_configs) {
137 		gda_init ();
138 		setlocale (LC_ALL, "");
139 		GdaDataModel *model;
140 		if (argc == 2)
141 			model = config_info_detail_dsn (argv[1], &error);
142 		else
143 			model = config_info_list_all_dsn ();
144 		if (model) {
145 			output_data_model (model);
146 			g_object_unref (model);
147 		}
148 		else {
149 			g_print (_("Error: %s\n"),
150 				 error && error->message ? error->message : _("No detail"));
151 			g_clear_error (&error);
152 		}
153 		return 0;
154 	}
155 	if (list_data_files) {
156 		gchar *confdir;
157 		GdaDataModel *model;
158 
159 		gda_init ();
160 		setlocale (LC_ALL, "");
161 		confdir = config_info_compute_dict_directory ();
162 		g_print (_("All files are in the directory: %s\n"), confdir);
163 		g_free (confdir);
164 		model = config_info_list_data_files (&error);
165 		if (model) {
166 			output_data_model (model);
167 			g_object_unref (model);
168 		}
169 		else
170 			g_print (_("Can't get the list of files used to store information about each connection: %s\n"),
171 				 error->message);
172 		return 0;
173 	}
174 	if (purge_data_files) {
175 		gchar *tmp;
176 
177 		gda_init ();
178 		setlocale (LC_ALL, "");
179 		tmp = config_info_purge_data_files (purge_data_files, &error);
180 		if (tmp) {
181 			g_print ("%s\n", tmp);
182 			g_free (tmp);
183 		}
184 		if (error)
185 			g_print (_("Error while purging files used to store information about each connection: %s\n"),
186 				 error->message);
187 		return 0;
188 	}
189 
190 	gtk_init (&argc, &argv);
191 	gdaui_init ();
192 
193 #ifdef HAVE_MAC_INTEGRATION
194 	theApp = g_object_new (GTK_TYPE_OSX_APPLICATION, NULL);
195 #endif
196 	browser_stock_icons_init ();
197 
198 	browser_core_set_default_factory (perspective);
199 
200 	if (argc == 1) {
201 		GError *error = NULL;
202 		if (browser_connection_open (&error))
203 			have_loop = TRUE;
204 		else
205 			g_print ("Connection NOT opened: %s\n",
206 				 error && error->message ? error->message : _("No detail"));
207 	}
208 	else {
209 		AuthDialog *dialog;
210 		GError *error = NULL;
211 		gint i;
212 
213 		dialog = auth_dialog_new (NULL);
214 
215 		for (i = 1; i < argc; i++) {
216 			if (! auth_dialog_add_cnc_string (dialog, argv[i], &error)) {
217 				gtk_widget_destroy (GTK_WIDGET (dialog));
218 				dialog = NULL;
219 				g_print ("Connection NOT opened: %s\n",
220 					 error && error->message ? error->message : _("No detail"));
221 				break;
222 			}
223 			config_info_modify_argv (argv[i]);
224 		}
225 
226 		if (dialog) {
227 			have_loop = auth_dialog_run (dialog);
228 			if (have_loop) {
229 				/* create a window for each opened connection */
230 				const GSList *cnclist, *list;
231 
232 				cnclist = auth_dialog_get_connections (dialog);
233 				for (list = cnclist; list; list = list->next) {
234 					AuthDialogConnection *ad = (AuthDialogConnection*) list->data;
235 					if (ad->cnc) {
236 						BrowserConnection *bcnc;
237 						BrowserWindow *bwin;
238 						bcnc = browser_connection_new (ad->cnc);
239 						bwin = browser_window_new (bcnc, NULL);
240 
241 						browser_core_take_window (bwin);
242 						browser_core_take_connection (bcnc);
243 					}
244 					else {
245 						g_print ("Connection NOT opened: %s\n",
246 							 ad->cnc_open_error && ad->cnc_open_error->message ?
247 							 ad->cnc_open_error->message : _("No detail"));
248 						have_loop = FALSE;
249 						break;
250 					}
251 				}
252 			}
253 			gtk_widget_destroy ((GtkWidget*) dialog);
254 		}
255 	}
256 
257 	/*g_print ("Main (GTK+) THREAD is %p\n", g_thread_self ());*/
258 	if (have_loop)
259 		/* application loop */
260 		gtk_main ();
261 	else if (browser_core_exists ())
262 		g_object_unref (browser_core_get ());
263 
264 	return 0;
265 }
266 
267