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 <string.h>
21 #include <glib/gi18n-lib.h>
22 #include "browser-core.h"
23 #include "browser-window.h"
24 #include "browser-connection.h"
25
26 /*
27 * Main static functions
28 */
29 static void browser_core_class_init (BrowserCoreClass *klass);
30 static void browser_core_init (BrowserCore *bcore);
31 static void browser_core_dispose (GObject *object);
32
33 /* get a pointer to the parents to be able to call their destructor */
34 static GObjectClass *parent_class = NULL;
35
main(int argc,char ** argv)36 /* pointer to the singleton */
37 static BrowserCore *_bcore = NULL;
38
39 /* signals */
40 enum
41 {
42 CNC_ADDED,
43 CNC_REMOVED,
44 LAST_SIGNAL
45 };
46
47 static gint browser_core_signals[LAST_SIGNAL] = { 0, 0 };
48
49 struct _BrowserCorePrivate {
50 GSList *factories; /* list of PerspectiveFactory pointers, statically compiled */
51 BrowserPerspectiveFactory *default_factory; /* used by default, no ref held on it */
52 GSList *connections; /* list of BrowserConnection objects, referenced here */
53 GSList *windows; /* list of BrowserWindow pointers: list of opened windows */
54 };
55
56 GType
57 browser_core_get_type (void)
58 {
59 static GType type = 0;
60
61 if (G_UNLIKELY (type == 0)) {
62 static GMutex registering;
63 static const GTypeInfo info = {
64 sizeof (BrowserCoreClass),
65 (GBaseInitFunc) NULL,
66 (GBaseFinalizeFunc) NULL,
67 (GClassInitFunc) browser_core_class_init,
68 NULL,
69 NULL,
70 sizeof (BrowserCore),
71 0,
72 (GInstanceInitFunc) browser_core_init,
73 0
74 };
75
76
77 g_mutex_lock (®istering);
78 if (type == 0)
79 type = g_type_register_static (G_TYPE_OBJECT, "BrowserCore", &info, 0);
80 g_mutex_unlock (®istering);
81 }
82 return type;
83 }
84
85 static void
86 browser_core_class_init (BrowserCoreClass *klass)
87 {
88 GObjectClass *object_class = G_OBJECT_CLASS (klass);
89 parent_class = g_type_class_peek_parent (klass);
90
91 browser_core_signals[CNC_ADDED] =
92 g_signal_new ("connection-added",
93 G_TYPE_FROM_CLASS (object_class),
94 G_SIGNAL_RUN_FIRST,
95 G_STRUCT_OFFSET (BrowserCoreClass, connection_added),
96 NULL, NULL,
97 g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, BROWSER_TYPE_CONNECTION);
98
99 browser_core_signals[CNC_REMOVED] =
100 g_signal_new ("connection-removed",
101 G_TYPE_FROM_CLASS (object_class),
102 G_SIGNAL_RUN_FIRST,
103 G_STRUCT_OFFSET (BrowserCoreClass, connection_removed),
104 NULL, NULL,
105 g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, BROWSER_TYPE_CONNECTION);
106
107 klass->connection_added = NULL;
108 klass->connection_removed = NULL;
109
110 object_class->dispose = browser_core_dispose;
111 }
112
113 BrowserCoreInitFactories browser_core_init_factories = NULL;
114
115 static void
116 browser_core_init (BrowserCore *bcore)
117 {
118 bcore->priv = g_new0 (BrowserCorePrivate, 1);
119 bcore->priv->factories = NULL;
120
121 if (browser_core_init_factories)
122 bcore->priv->factories = browser_core_init_factories ();
123
124 /* set default perspective */
125 if (bcore->priv->factories)
126 bcore->priv->default_factory = (BrowserPerspectiveFactory*) bcore->priv->factories->data;
127
128 bcore->priv->windows = NULL;
129 }
130
131 /**
132 * browser_core_exists
133 *
134 * Tells if a #BrowserCore has already been created
135 *
136 * Returns: %TRUE if the #BrowserCore singleton has already been created
137 */
138 gboolean
139 browser_core_exists (void)
140 {
141 return _bcore ? TRUE : FALSE;
142 }
143
144 /**
145 * browser_core_get
146 *
147 * Returns a #BrowserCore object which holds the browser's configuration. This is
148 * a singleton factory.
149 *
150 * Returns: the #BrowserCore object
151 */
152 BrowserCore*
153 browser_core_get (void)
154 {
155 if (!_bcore)
156 _bcore = BROWSER_CORE (g_object_new (BROWSER_TYPE_CORE, NULL));
157
158 return _bcore;
159 }
160
161 static void
do_test(GdaSqlParser * parser,const xmlChar * id,const xmlChar * sql,const xmlChar * expected,const xmlChar * error_line,const xmlChar * error_col)162 browser_core_dispose (GObject *object)
163 {
164 BrowserCore *bcore;
165
166 g_return_if_fail (object != NULL);
167 g_return_if_fail (BROWSER_IS_CORE (object));
168
169 bcore = BROWSER_CORE (object);
170 if (bcore->priv) {
171 if (bcore->priv->factories) {
172 g_slist_free (bcore->priv->factories);
173 bcore->priv->factories = NULL;
174 }
175 bcore->priv->default_factory = NULL;
176
177 if (bcore->priv->windows) {
178 g_slist_foreach (bcore->priv->windows, (GFunc) g_object_unref, NULL);
179 g_slist_free (bcore->priv->windows);
180 bcore->priv->windows = NULL;
181 }
182
183 g_free (bcore->priv);
184 bcore->priv = NULL;
185 }
186
187 /* parent class */
188 parent_class->dispose (object);
189 }
190
191 /**
192 * browser_core_take_window
193 * @bwin: a #BrowserWindow
194 *
195 * Makes sure @bwin is handled by the #BrowserCore object, reference to @bwin is stolen here.
196 * This method should be called after a #BrowserWindow has been created to have it managed properly.
197 */
198 void
199 browser_core_take_window (BrowserWindow *bwin)
200 {
201 g_return_if_fail (BROWSER_IS_WINDOW (bwin));
202
203 _bcore = browser_core_get ();
204 _bcore->priv->windows = g_slist_append (_bcore->priv->windows, bwin);
205 }
206
207 /**
208 * browser_core_close_window
209 * @bwin: a #BrowserWindow
210 *
211 * Requests that @bwin be closed.
212 */
213 void
214 browser_core_close_window (BrowserWindow *bwin)
215 {
216 g_return_if_fail (BROWSER_IS_WINDOW (bwin));
217 _bcore = browser_core_get ();
218 g_return_if_fail (g_slist_find (_bcore->priv->windows, bwin));
219
220 _bcore->priv->windows = g_slist_remove (_bcore->priv->windows, bwin);
221 gtk_widget_destroy (GTK_WIDGET (bwin));
222
223 if (! _bcore->priv->windows) {
224 /* no more windows left => quit */
225 g_print ("Closed last window, bye!\n");
226 browser_core_quit ();
227 }
228 }
229
230 /**
231 * browser_core_get_windows
232 *
233 * Get a list of #BrowserWindow mananged by the browser (windows must have been
234 * declared using browser_core_take_window()).
235 *
create_parser_for_provider(const gchar * prov_name)236 * Returns: a new list, free it with g_slist_free()
237 */
238 GSList *
239 browser_core_get_windows (void)
240 {
241 _bcore = browser_core_get ();
242 if (_bcore->priv->windows)
243 return g_slist_copy (_bcore->priv->windows);
244 else
245 return NULL;
246 }
247
248 /**
249 * browser_core_take_connection
250 * @bcnc: a #BrowserConnection
251 *
252 * Makes sure @bcnc is handled by @dbata, reference to @bcnc is stolen here
253 */
254 void
255 browser_core_take_connection (BrowserConnection *bcnc)
256 {
257 g_return_if_fail (BROWSER_IS_CONNECTION (bcnc));
258
259 _bcore = browser_core_get ();
260 _bcore->priv->connections = g_slist_append (_bcore->priv->connections, bcnc);
261 g_signal_emit (_bcore, browser_core_signals [CNC_ADDED], 0, bcnc);
262 }
263
264 /**
265 * browser_core_close_connection
266 * @bcnc: a #BrowserConnection
267 *
268 * Requests that @bcnc be closed.
269 */
270 void
271 browser_core_close_connection (BrowserConnection *bcnc)
272 {
273 g_return_if_fail (g_slist_find (_bcore->priv->connections, bcnc));
274
275 _bcore = browser_core_get ();
276 _bcore->priv->connections = g_slist_remove (_bcore->priv->connections, bcnc);
277 g_signal_emit (_bcore, browser_core_signals [CNC_REMOVED], 0, bcnc);
278 g_object_unref (bcnc);
279 }
280
281 /**
282 * browser_core_get_connections
283 *
284 * Get a list of #BrowserWindow
285 *
286 * Returns: a new list, free it with g_slist_free()
287 */
288 GSList *
289 browser_core_get_connections (void)
290 {
291 _bcore = browser_core_get ();
292 if (_bcore->priv->connections)
293 return g_slist_copy (_bcore->priv->connections);
294 else
295 return NULL;
296 }
297
298 /**
299 * browser_core_get_factory
300 * @factory: the name of the requested factory
301 *
302 * Get a pointer to a #BrowserPerspectiveFactory, from its name
303 *
304 * Returns: a pointer to the #BrowserPerspectiveFactory, or %NULL if not found
305 */
306 BrowserPerspectiveFactory *
307 browser_core_get_factory (const gchar *factory)
308 {
309 GSList *list;
310 g_return_val_if_fail (factory, NULL);
311 _bcore = browser_core_get ();
312 for (list = _bcore->priv->factories; list; list = list->next) {
313 BrowserPerspectiveFactory *bpf = BROWSER_PERSPECTIVE_FACTORY (list->data);
314 if (!g_ascii_strcasecmp (bpf->perspective_name, factory))
315 return bpf;
316 }
317 return NULL;
318 }
319
320 /**
321 * browser_core_get_default_factory
322 *
323 * Get the default #BrowserPerspectiveFactory used when making new #BrowserWindow if none
324 * is provided when calling browser_window_new().
325 *
326 * Returns: the default #BrowserPerspectiveFactory
327 */
328 BrowserPerspectiveFactory *
329 browser_core_get_default_factory (void)
330 {
331 _bcore = browser_core_get ();
332 return _bcore->priv->default_factory;
333 }
334
335 /**
336 * browser_core_set_default_factory
337 * @factory: the name of a #BrowserPerspectiveFactory
338 *
339 * Sets the default #BrowserPerspectiveFactory used when making new #BrowserWindow if none
340 * is provided when calling browser_window_new().
341 */
342 void
343 browser_core_set_default_factory (const gchar *factory)
344 {
345 GSList *list;
346 gchar *lc2;
347 _bcore = browser_core_get ();
348
349 if (!factory)
350 return;
351
352 lc2 = g_utf8_strdown (factory, -1);
353 for (list = _bcore->priv->factories; list; list = list->next) {
354 BrowserPerspectiveFactory *fact = (BrowserPerspectiveFactory*) list->data;
355 gchar *lc1;
356 lc1 = g_utf8_strdown (fact->perspective_name, -1);
357
358 if (strstr (lc1, lc2)) {
359 _bcore->priv->default_factory = fact;
360 g_free (lc1);
361 break;
362 }
363
364 g_free (lc1);
365 }
366 g_free (lc2);
367 }
368
369 /**
370 * browser_core_get_factories
371 *
372 * Get a list of all the known Perspective factories
373 *
374 * Returns: a constant list which must not be altered
375 */
376 const GSList *
377 browser_core_get_factories (void)
378 {
379 _bcore = browser_core_get ();
380 return _bcore->priv->factories;
381 }
382
383 /**
384 * browser_core_quit
385 *
386 * Quits the browser after having made some clean-ups
387 */
388 void
389 browser_core_quit (void)
390 {
391 if (_bcore) {
392 g_object_unref (_bcore);
393 _bcore = NULL;
394 }
395 gtk_main_quit();
396 }
397