1 /*
2 * Copyright (C) 2009 - 2012 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 <glib/gi18n-lib.h>
21 #include <string.h>
22 #include <libgda/libgda.h>
23 #include <sql-parser/gda-sql-parser.h>
24 #include "mgr-favorites.h"
25 #include "support.h"
26 #include <libgda/gda-debug-macros.h>
27
28 /* asynchronous (in idle loop) icon resolution */
29 typedef struct {
30 GdaTreeNode *node;
31 gchar *dn;
32 } IconResolutionData;
33 static void
icon_resolution_data_free(IconResolutionData * data)34 icon_resolution_data_free (IconResolutionData *data)
35 {
36 g_object_unref (G_OBJECT (data->node));
37 g_free (data->dn);
38 g_free (data);
39 }
40
41 struct _MgrFavoritesPriv {
42 BrowserConnection *bcnc;
43 ToolsFavoritesType fav_type;
44 gint order_key;
45
46 GSList *icons_resol_list; /* list of IconResolutionData pointers */
47 guint icons_resol_timer;
48 };
49
50 static void mgr_favorites_class_init (MgrFavoritesClass *klass);
51 static void mgr_favorites_init (MgrFavorites *tmgr1, MgrFavoritesClass *klass);
52 static void mgr_favorites_dispose (GObject *object);
53 static void mgr_favorites_set_property (GObject *object,
54 guint param_id,
55 const GValue *value,
56 GParamSpec *pspec);
57 static void mgr_favorites_get_property (GObject *object,
58 guint param_id,
59 GValue *value,
60 GParamSpec *pspec);
61
62 /* virtual methods */
63 static GSList *mgr_favorites_update_children (GdaTreeManager *manager, GdaTreeNode *node,
64 const GSList *children_nodes, gboolean *out_error, GError **error);
65
66 static GObjectClass *parent_class = NULL;
67
68 /* properties */
69 enum {
70 PROP_0,
71 PROP_BROWSER_CNC
72 };
73
74 /*
75 * MgrFavorites class implementation
76 * @klass:
77 */
78 static void
mgr_favorites_class_init(MgrFavoritesClass * klass)79 mgr_favorites_class_init (MgrFavoritesClass *klass)
80 {
81 GObjectClass *object_class = G_OBJECT_CLASS (klass);
82
83 parent_class = g_type_class_peek_parent (klass);
84
85 /* virtual methods */
86 ((GdaTreeManagerClass*) klass)->update_children = mgr_favorites_update_children;
87
88 /* Properties */
89 object_class->set_property = mgr_favorites_set_property;
90 object_class->get_property = mgr_favorites_get_property;
91
92 g_object_class_install_property (object_class, PROP_BROWSER_CNC,
93 g_param_spec_object ("browser-connection", NULL, "Connection to use",
94 BROWSER_TYPE_CONNECTION,
95 G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
96 object_class->dispose = mgr_favorites_dispose;
97 }
98
99 static void
mgr_favorites_init(MgrFavorites * mgr,G_GNUC_UNUSED MgrFavoritesClass * klass)100 mgr_favorites_init (MgrFavorites *mgr, G_GNUC_UNUSED MgrFavoritesClass *klass)
101 {
102 mgr->priv = g_new0 (MgrFavoritesPriv, 1);
103 }
104
105 static void
mgr_favorites_dispose(GObject * object)106 mgr_favorites_dispose (GObject *object)
107 {
108 MgrFavorites *mgr = (MgrFavorites *) object;
109
110 if (mgr->priv) {
111 if (mgr->priv->bcnc)
112 g_object_unref (mgr->priv->bcnc);
113
114 if (mgr->priv->icons_resol_timer) {
115 g_source_remove (mgr->priv->icons_resol_timer);
116 mgr->priv->icons_resol_timer = 0;
117 }
118
119 if (mgr->priv->icons_resol_list) {
120 g_slist_foreach (mgr->priv->icons_resol_list, (GFunc) icon_resolution_data_free, NULL);
121 g_slist_free (mgr->priv->icons_resol_list);
122 mgr->priv->icons_resol_list = NULL;
123 }
124
125 g_free (mgr->priv);
126 mgr->priv = NULL;
127 }
128
129 /* chain to parent class */
130 parent_class->dispose (object);
131 }
132
133 /**
134 * mgr_favorites_get_type
135 *
136 * Returns: the GType
137 */
138 GType
mgr_favorites_get_type(void)139 mgr_favorites_get_type (void)
140 {
141 static GType type = 0;
142
143 if (G_UNLIKELY (type == 0)) {
144 static GMutex registering;
145 static const GTypeInfo info = {
146 sizeof (MgrFavoritesClass),
147 (GBaseInitFunc) NULL,
148 (GBaseFinalizeFunc) NULL,
149 (GClassInitFunc) mgr_favorites_class_init,
150 NULL,
151 NULL,
152 sizeof (MgrFavorites),
153 0,
154 (GInstanceInitFunc) mgr_favorites_init,
155 0
156 };
157
158 g_mutex_lock (®istering);
159 if (type == 0)
160 type = g_type_register_static (GDA_TYPE_TREE_MANAGER, "MgrFavorites", &info, 0);
161 g_mutex_unlock (®istering);
162 }
163 return type;
164 }
165
166 static void
mgr_favorites_set_property(GObject * object,guint param_id,const GValue * value,GParamSpec * pspec)167 mgr_favorites_set_property (GObject *object,
168 guint param_id,
169 const GValue *value,
170 GParamSpec *pspec)
171 {
172 MgrFavorites *mgr;
173
174 mgr = MGR_FAVORITES (object);
175 if (mgr->priv) {
176 switch (param_id) {
177 case PROP_BROWSER_CNC:
178 mgr->priv->bcnc = (BrowserConnection*) g_value_get_object (value);
179 if (mgr->priv->bcnc)
180 g_object_ref (mgr->priv->bcnc);
181
182 break;
183 default:
184 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
185 break;
186 }
187 }
188 }
189
190 static void
mgr_favorites_get_property(GObject * object,guint param_id,GValue * value,GParamSpec * pspec)191 mgr_favorites_get_property (GObject *object,
192 guint param_id,
193 GValue *value,
194 GParamSpec *pspec)
195 {
196 MgrFavorites *mgr;
197
198 mgr = MGR_FAVORITES (object);
199 if (mgr->priv) {
200 switch (param_id) {
201 case PROP_BROWSER_CNC:
202 g_value_set_object (value, mgr->priv->bcnc);
203 break;
204 default:
205 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
206 break;
207 }
208 }
209 }
210
211 /**
212 * mgr_favorites_new
213 * @bcnc: a #BrowserConnection object
214 * @type: the type of favorites to handle
215 * @order_key: ordering key, see gda_tools_favorites_add()
216 *
217 * Creates a new #GdaTreeManager object which will add one tree node for each favorite of the @type type
218 *
219 * Returns: a new #GdaTreeManager object
220 */
221 GdaTreeManager*
mgr_favorites_new(BrowserConnection * bcnc,ToolsFavoritesType type,gint order_key)222 mgr_favorites_new (BrowserConnection *bcnc, ToolsFavoritesType type, gint order_key)
223 {
224 MgrFavorites *mgr;
225 g_return_val_if_fail (BROWSER_IS_CONNECTION (bcnc), NULL);
226
227 mgr = (MgrFavorites*) g_object_new (MGR_FAVORITES_TYPE,
228 "browser-connection", bcnc, NULL);
229 mgr->priv->fav_type = type;
230 mgr->priv->order_key = order_key;
231 return (GdaTreeManager*) mgr;
232 }
233
234 static gchar *
create_summary_for_statement(BrowserConnection * bcnc,const gchar * sql)235 create_summary_for_statement (BrowserConnection *bcnc, const gchar *sql)
236 {
237 GdaSqlParser *parser;
238 GString *string;
239 GdaBatch *batch;
240
241 parser = browser_connection_create_parser (bcnc);
242 string = g_string_new ("");
243
244 batch = gda_sql_parser_parse_string_as_batch (parser, sql, NULL, NULL);
245 if (batch) {
246 const GSList *stmt_list;
247 stmt_list = gda_batch_get_statements (batch);
248 if (!stmt_list || !(stmt_list->data))
249 g_string_append (string, _("Empty statement"));
250 else if (stmt_list->next)
251 g_string_append (string, _("Multiple statements"));
252 else {
253 switch (gda_statement_get_statement_type (GDA_STATEMENT (stmt_list->data))) {
254 case GDA_SQL_STATEMENT_SELECT:
255 g_string_append (string, _("SELECT statement"));
256 break;
257 case GDA_SQL_STATEMENT_INSERT:
258 g_string_append (string, _("INSERT statement"));
259 break;
260 case GDA_SQL_STATEMENT_UPDATE:
261 g_string_append (string, _("UPDATE statement"));
262 break;
263 case GDA_SQL_STATEMENT_DELETE:
264 g_string_append (string, _("DELETE statement"));
265 break;
266 case GDA_SQL_STATEMENT_COMPOUND:
267 g_string_append (string, _("COMPOUND SELECT statement"));
268 break;
269 case GDA_SQL_STATEMENT_BEGIN:
270 g_string_append (string, _("BEGIN statement"));
271 break;
272 case GDA_SQL_STATEMENT_ROLLBACK:
273 g_string_append (string, _("ROLLBACK statement"));
274 break;
275 case GDA_SQL_STATEMENT_COMMIT:
276 g_string_append (string, _("COMMIT statement"));
277 break;
278 case GDA_SQL_STATEMENT_SAVEPOINT:
279 g_string_append (string, _("ADD SAVEPOINT statement"));
280 break;
281 case GDA_SQL_STATEMENT_ROLLBACK_SAVEPOINT:
282 g_string_append (string, _("ROLLBACK SAVEPOINT statement"));
283 break;
284 case GDA_SQL_STATEMENT_DELETE_SAVEPOINT:
285 g_string_append (string, _("DELETE SAVEPOINT statement"));
286 break;
287 case GDA_SQL_STATEMENT_UNKNOWN:
288 g_string_append (string, _("Unknown statement"));
289 break;
290 case GDA_SQL_STATEMENT_NONE:
291 g_string_append (string, _("Empty statement"));
292 break;
293 }
294 }
295
296 /* parameters */
297 GdaSet *params;
298 if (gda_batch_get_parameters (batch, ¶ms, NULL) && params) {
299 GSList *list;
300 GdaHolder *holder;
301 for (list = params->holders; list; list = list->next) {
302 holder = GDA_HOLDER (list->data);
303 g_string_append_c (string, '\n');
304 g_string_append (string, gda_holder_get_id (holder));
305 g_string_append (string, "::");
306 g_string_append (string, gda_g_type_to_string (gda_holder_get_g_type (holder)));
307 if (! gda_holder_get_not_null (holder))
308 g_string_append (string, "::null");
309 }
310 g_object_unref (params);
311 }
312
313 g_object_unref (batch);
314 }
315 else {
316 gint len;
317 gchar *tmp;
318 tmp = g_strdup (sql);
319 len = strlen (sql);
320 if (len > 40)
321 tmp [40] = 0;
322 g_string_append (string, tmp);
323 g_free (tmp);
324 }
325
326 g_object_unref (parser);
327 return g_string_free (string, FALSE);
328 }
329
330 /*
331 * Build a hash where key = contents as a string, and value = GdaTreeNode
332 */
333 static GHashTable *
hash_for_existing_nodes(const GSList * nodes)334 hash_for_existing_nodes (const GSList *nodes)
335 {
336 GHashTable *hash;
337 const GSList *list;
338
339 hash = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, NULL);
340 for (list = nodes; list; list = list->next) {
341 const GValue *cvalue;
342 cvalue = gda_tree_node_get_node_attribute ((GdaTreeNode*) list->data, MGR_FAVORITES_ID_ATT_NAME);
343 if (cvalue && (G_VALUE_TYPE (cvalue) == G_TYPE_INT)) {
344 gint id;
345 id = g_value_get_int (cvalue);
346 if (id >= 0) {
347 gint *key = g_new0 (gint, 1);
348 *key = id;
349 g_hash_table_insert (hash, (gpointer) key, list->data);
350 }
351 }
352 }
353 return hash;
354 }
355
356 static gboolean icons_resol_cb (MgrFavorites *mgr);
357
358 static GSList *
mgr_favorites_update_children(GdaTreeManager * manager,GdaTreeNode * node,const GSList * children_nodes,gboolean * out_error,GError ** error)359 mgr_favorites_update_children (GdaTreeManager *manager, GdaTreeNode *node, const GSList *children_nodes,
360 gboolean *out_error, GError **error)
361 {
362 MgrFavorites *mgr = MGR_FAVORITES (manager);
363 GSList *nodes_list = NULL;
364 GHashTable *ehash = NULL;
365 GSList *fav_list;
366 GError *lerror = NULL;
367 BrowserConnection *bcnc;
368
369 if (out_error)
370 *out_error = FALSE;
371
372 if (children_nodes)
373 ehash = hash_for_existing_nodes (children_nodes);
374
375 bcnc = mgr->priv->bcnc;
376 fav_list = gda_tools_favorites_list (browser_connection_get_favorites (bcnc),
377 0, mgr->priv->fav_type,
378 mgr->priv->order_key, &lerror);
379 if (fav_list) {
380 GSList *list;
381 gint pos;
382 for (list = fav_list, pos = 0; list; list = list->next, pos ++) {
383 ToolsFavoritesAttributes *fav = (ToolsFavoritesAttributes *) list->data;
384 GdaTreeNode* snode = NULL;
385 GValue *av;
386
387 if (ehash)
388 snode = g_hash_table_lookup (ehash, &(fav->id));
389
390
391 if (snode) {
392 /* use the same node */
393 g_object_ref (G_OBJECT (snode));
394 }
395
396 if (fav->type == GDA_TOOLS_FAVORITES_TABLES) {
397 if (!snode) {
398 GdaQuarkList *ql;
399 const gchar *fname = NULL;
400
401 ql = gda_quark_list_new_from_string (fav->contents);
402 if (!ql || !(fname = gda_quark_list_find (ql, "OBJ_SHORT_NAME"))) {
403 g_warning ("Invalid TABLE favorite format: %s", fav->contents);
404 }
405 else {
406 snode = gda_tree_manager_create_node (manager, node, NULL);
407 g_value_set_string ((av = gda_value_new (G_TYPE_STRING)), fname);
408 gda_tree_node_set_node_attribute (snode, "markup", av, NULL);
409 gda_value_free (av);
410
411 g_value_set_string ((av = gda_value_new (G_TYPE_STRING)),
412 fav->contents);
413 gda_tree_node_set_node_attribute (snode,
414 MGR_FAVORITES_CONTENTS_ATT_NAME,
415 av, NULL);
416 gda_value_free (av);
417
418
419 g_value_set_int ((av = gda_value_new (G_TYPE_INT)), fav->id);
420 gda_tree_node_set_node_attribute (snode,
421 MGR_FAVORITES_ID_ATT_NAME,
422 av, NULL);
423 gda_value_free (av);
424
425 g_value_set_uint ((av = gda_value_new (G_TYPE_UINT)), fav->type);
426 gda_tree_node_set_node_attribute (snode,
427 MGR_FAVORITES_TYPE_ATT_NAME,
428 av, NULL);
429 gda_value_free (av);
430
431 /* icon */
432 GdkPixbuf *pixbuf;
433 pixbuf = browser_get_pixbuf_icon (BROWSER_ICON_TABLE);
434 av = gda_value_new (G_TYPE_OBJECT);
435 g_value_set_object (av, pixbuf);
436 gda_tree_node_set_node_attribute (snode, "icon", av, NULL);
437 gda_value_free (av);
438 }
439 if (ql)
440 gda_quark_list_free (ql);
441 }
442 }
443 else if (fav->type == GDA_TOOLS_FAVORITES_DIAGRAMS) {
444 if (!snode) {
445 snode = gda_tree_manager_create_node (manager, node, NULL);
446
447 g_value_set_int ((av = gda_value_new (G_TYPE_INT)), fav->id);
448 gda_tree_node_set_node_attribute (snode,
449 MGR_FAVORITES_ID_ATT_NAME,
450 av, NULL);
451 gda_value_free (av);
452
453 g_value_set_uint ((av = gda_value_new (G_TYPE_UINT)), fav->type);
454 gda_tree_node_set_node_attribute (snode,
455 MGR_FAVORITES_TYPE_ATT_NAME,
456 av, NULL);
457 gda_value_free (av);
458
459 /* icon */
460 GdkPixbuf *pixbuf;
461 pixbuf = browser_get_pixbuf_icon (BROWSER_ICON_DIAGRAM);
462 av = gda_value_new (G_TYPE_OBJECT);
463 g_value_set_object (av, pixbuf);
464 gda_tree_node_set_node_attribute (snode, "icon", av, NULL);
465 gda_value_free (av);
466 }
467
468 g_value_set_string ((av = gda_value_new (G_TYPE_STRING)),
469 fav->contents);
470 gda_tree_node_set_node_attribute (snode,
471 MGR_FAVORITES_CONTENTS_ATT_NAME,
472 av, NULL);
473 gda_value_free (av);
474
475 g_value_set_string ((av = gda_value_new (G_TYPE_STRING)), fav->name);
476 gda_tree_node_set_node_attribute (snode, "markup", av, NULL);
477 gda_value_free (av);
478 }
479 else if (fav->type == GDA_TOOLS_FAVORITES_QUERIES) {
480 if (!snode) {
481 snode = gda_tree_manager_create_node (manager, node, NULL);
482
483 g_value_set_int ((av = gda_value_new (G_TYPE_INT)), fav->id);
484 gda_tree_node_set_node_attribute (snode,
485 MGR_FAVORITES_ID_ATT_NAME,
486 av, NULL);
487 gda_value_free (av);
488
489 g_value_set_int ((av = gda_value_new (G_TYPE_INT)), pos);
490 gda_tree_node_set_node_attribute (snode,
491 MGR_FAVORITES_POSITION_ATT_NAME,
492 av, NULL);
493 gda_value_free (av);
494 }
495
496 /* is action */
497 gboolean is_action = FALSE;
498 GSList *favlist;
499 GdkPixbuf *pixbuf;
500 favlist = gda_tools_favorites_list (browser_connection_get_favorites (bcnc),
501 0, GDA_TOOLS_FAVORITES_ACTIONS,
502 -1, NULL);
503 if (favlist) {
504 gchar *tmp;
505 tmp = g_strdup_printf ("QUERY%d", fav->id);
506 GSList *list;
507 for (list = favlist; list; list = list->next) {
508 ToolsFavoritesAttributes *afav;
509 afav = (ToolsFavoritesAttributes*) list->data;
510 if (!strcmp (afav->contents, tmp)) {
511 is_action = TRUE;
512 break;
513 }
514 }
515 g_free (tmp);
516 gda_tools_favorites_free_list (favlist);
517 }
518 if (is_action)
519 pixbuf = browser_get_pixbuf_icon (BROWSER_ICON_ACTION);
520 else
521 pixbuf = browser_get_pixbuf_icon (BROWSER_ICON_QUERY);
522 av = gda_value_new (G_TYPE_OBJECT);
523 g_value_set_object (av, pixbuf);
524 gda_tree_node_set_node_attribute (snode, "icon", av, NULL);
525 gda_value_free (av);
526
527 /* summary */
528 g_value_take_string ((av = gda_value_new (G_TYPE_STRING)),
529 create_summary_for_statement (bcnc, fav->contents));
530 gda_tree_node_set_node_attribute (snode, "summary", av, NULL);
531 gda_value_free (av);
532
533 g_value_set_string ((av = gda_value_new (G_TYPE_STRING)),
534 fav->contents);
535 gda_tree_node_set_node_attribute (snode,
536 MGR_FAVORITES_CONTENTS_ATT_NAME,
537 av, NULL);
538 gda_value_free (av);
539
540 g_value_set_string ((av = gda_value_new (G_TYPE_STRING)), fav->name);
541 gda_tree_node_set_node_attribute (snode, MGR_FAVORITES_NAME_ATT_NAME,
542 av, NULL);
543 gda_value_free (av);
544 }
545 else if (fav->type == GDA_TOOLS_FAVORITES_DATA_MANAGERS) {
546 if (!snode) {
547 snode = gda_tree_manager_create_node (manager, node, NULL);
548
549 g_value_set_int ((av = gda_value_new (G_TYPE_INT)), fav->id);
550 gda_tree_node_set_node_attribute (snode,
551 MGR_FAVORITES_ID_ATT_NAME,
552 av, NULL);
553 gda_value_free (av);
554
555 g_value_set_int ((av = gda_value_new (G_TYPE_INT)), pos);
556 gda_tree_node_set_node_attribute (snode,
557 MGR_FAVORITES_POSITION_ATT_NAME,
558 av, NULL);
559 gda_value_free (av);
560
561 g_value_set_uint ((av = gda_value_new (G_TYPE_UINT)), fav->type);
562 gda_tree_node_set_node_attribute (snode,
563 MGR_FAVORITES_TYPE_ATT_NAME,
564 av, NULL);
565 gda_value_free (av);
566
567 /* icon */
568 GdkPixbuf *pixbuf;
569 pixbuf = browser_get_pixbuf_icon (BROWSER_ICON_TABLE);
570 av = gda_value_new (G_TYPE_OBJECT);
571 g_value_set_object (av, pixbuf);
572 gda_tree_node_set_node_attribute (snode, "icon", av, NULL);
573 gda_value_free (av);
574 }
575
576 g_value_set_string ((av = gda_value_new (G_TYPE_STRING)),
577 fav->contents);
578 gda_tree_node_set_node_attribute (snode,
579 MGR_FAVORITES_CONTENTS_ATT_NAME,
580 av, NULL);
581 gda_value_free (av);
582
583 g_value_set_string ((av = gda_value_new (G_TYPE_STRING)), fav->name);
584 gda_tree_node_set_node_attribute (snode, MGR_FAVORITES_NAME_ATT_NAME,
585 av, NULL);
586 gda_value_free (av);
587 }
588 #ifdef HAVE_LDAP
589 else if (fav->type == GDA_TOOLS_FAVORITES_LDAP_DN) {
590 if (!snode) {
591 /* favorite ID */
592 snode = gda_tree_manager_create_node (manager, node, NULL);
593
594 g_value_set_int ((av = gda_value_new (G_TYPE_INT)), fav->id);
595 gda_tree_node_set_node_attribute (snode,
596 MGR_FAVORITES_ID_ATT_NAME,
597 av, NULL);
598 gda_value_free (av);
599
600 /* icon */
601 GdkPixbuf *pixbuf;
602 pixbuf = browser_get_pixbuf_icon (BROWSER_ICON_LDAP_ENTRY);
603
604 av = gda_value_new (G_TYPE_OBJECT);
605 g_value_set_object (av, pixbuf);
606 gda_tree_node_set_node_attribute (snode, "icon", av, NULL);
607 gda_value_free (av);
608
609 g_value_set_uint ((av = gda_value_new (G_TYPE_UINT)), fav->type);
610 gda_tree_node_set_node_attribute (snode,
611 MGR_FAVORITES_TYPE_ATT_NAME,
612 av, NULL);
613 gda_value_free (av);
614
615 IconResolutionData *data;
616 data = g_new0 (IconResolutionData, 1);
617 data->node = g_object_ref (snode);
618 data->dn = g_strdup (fav->name);
619 mgr->priv->icons_resol_list = g_slist_prepend (mgr->priv->icons_resol_list, data);
620 if (mgr->priv->icons_resol_timer == 0)
621 mgr->priv->icons_resol_timer = g_idle_add ((GSourceFunc) icons_resol_cb, mgr);
622 }
623
624 gchar **dna;
625 GString *tmpstring;
626 dna = gda_ldap_dn_split (fav->name, FALSE);
627 tmpstring = g_string_new ("");
628 if (dna) {
629 if (dna[0]) {
630 if (dna[1])
631 g_string_append_printf (tmpstring,
632 "<b>%s</b>,%s",
633 dna[0], dna[1]);
634 else
635 g_string_append_printf (tmpstring,
636 "<b>%s</b>",
637 dna[0]);
638 }
639 else {
640 gchar *tmp;
641 tmp = g_markup_escape_text (fav->name, -1);
642 g_string_append (tmpstring, tmp);
643 g_free (tmp);
644 }
645 g_strfreev (dna);
646 }
647 else {
648 gchar *tmp;
649 tmp = g_markup_escape_text (fav->name, -1);
650 g_string_append (tmpstring, tmp);
651 g_free (tmp);
652 }
653
654 if (fav->descr && *fav->descr) {
655 gchar *tmp;
656 tmp = g_markup_escape_text (fav->descr, -1);
657 g_string_append_printf (tmpstring,
658 "\n<small>%s</small>", tmp);
659 g_free (tmp);
660
661 g_value_set_string ((av = gda_value_new (G_TYPE_STRING)),
662 fav->descr);
663 gda_tree_node_set_node_attribute (snode, "descr", av, NULL);
664 gda_value_free (av);
665 }
666
667 g_value_take_string ((av = gda_value_new (G_TYPE_STRING)),
668 g_string_free (tmpstring, FALSE));
669 gda_tree_node_set_node_attribute (snode, "markup", av, NULL);
670 gda_value_free (av);
671
672 g_value_set_string ((av = gda_value_new (G_TYPE_STRING)),
673 fav->name);
674 gda_tree_node_set_node_attribute (snode,
675 MGR_FAVORITES_CONTENTS_ATT_NAME,
676 av, NULL);
677 gda_value_free (av);
678 }
679 else if (fav->type == GDA_TOOLS_FAVORITES_LDAP_CLASS) {
680 if (!snode) {
681 /* favorite ID */
682 snode = gda_tree_manager_create_node (manager, node, NULL);
683
684 g_value_set_int ((av = gda_value_new (G_TYPE_INT)), fav->id);
685 gda_tree_node_set_node_attribute (snode,
686 MGR_FAVORITES_ID_ATT_NAME,
687 av, NULL);
688 gda_value_free (av);
689
690 /* icon */
691 GdkPixbuf *pixbuf;
692 GdaLdapClass *lcl;
693 lcl = browser_connection_get_class_info (bcnc, fav->name);
694 pixbuf = browser_get_pixbuf_for_ldap_class (lcl ? lcl->kind : GDA_LDAP_CLASS_KIND_UNKNOWN);
695 av = gda_value_new (G_TYPE_OBJECT);
696 g_value_set_object (av, pixbuf);
697 gda_tree_node_set_node_attribute (snode, "icon", av, NULL);
698 gda_value_free (av);
699
700 g_value_set_uint ((av = gda_value_new (G_TYPE_UINT)), fav->type);
701 gda_tree_node_set_node_attribute (snode,
702 MGR_FAVORITES_TYPE_ATT_NAME,
703 av, NULL);
704 gda_value_free (av);
705 }
706
707 GString *tmpstring;
708 gchar *tmp;
709
710 tmpstring = g_string_new ("");
711 tmp = g_markup_escape_text (fav->name, -1);
712 g_string_append (tmpstring, tmp);
713 g_free (tmp);
714
715 if (fav->descr && *fav->descr) {
716 gchar *tmp;
717 tmp = g_markup_escape_text (fav->descr, -1);
718 g_string_append_printf (tmpstring,
719 "\n<small>%s</small>", tmp);
720 g_free (tmp);
721
722 g_value_set_string ((av = gda_value_new (G_TYPE_STRING)),
723 fav->descr);
724 gda_tree_node_set_node_attribute (snode, "descr", av, NULL);
725 gda_value_free (av);
726 }
727
728 g_value_take_string ((av = gda_value_new (G_TYPE_STRING)),
729 g_string_free (tmpstring, FALSE));
730 gda_tree_node_set_node_attribute (snode, "markup", av, NULL);
731 gda_value_free (av);
732
733 g_value_set_string ((av = gda_value_new (G_TYPE_STRING)),
734 fav->name);
735 gda_tree_node_set_node_attribute (snode,
736 MGR_FAVORITES_CONTENTS_ATT_NAME,
737 av, NULL);
738 gda_value_free (av);
739 }
740 #endif
741 else {
742 TO_IMPLEMENT;
743 }
744 if (snode)
745 nodes_list = g_slist_prepend (nodes_list, snode);
746 }
747 gda_tools_favorites_free_list (fav_list);
748 }
749 else if (lerror) {
750 if (out_error)
751 *out_error = TRUE;
752 g_propagate_error (error, lerror);
753
754 GdaTreeNode* snode = NULL;
755 gchar *str;
756 GValue *value;
757
758 str = g_strdup_printf ("<i>%s</i>", _("Getting\nfavorites..."));
759 snode = gda_tree_manager_create_node (manager, node, str);
760 g_value_take_string ((value = gda_value_new (G_TYPE_STRING)), str);
761 gda_tree_node_set_node_attribute (snode, "markup", value, NULL);
762 nodes_list = g_slist_prepend (nodes_list, snode);
763 }
764 else {
765 GdaTreeNode* snode = NULL;
766 gchar *str;
767 GValue *value;
768
769 if (mgr->priv->fav_type & GDA_TOOLS_FAVORITES_TABLES) {
770 str = g_strdup_printf ("<i>%s</i>", _("No favorite:\ndrag item to\ndefine one"));
771 snode = gda_tree_manager_create_node (manager, node, str);
772 g_value_take_string ((value = gda_value_new (G_TYPE_STRING)), str);
773 gda_tree_node_set_node_attribute (snode, "markup", value, NULL);
774 nodes_list = g_slist_prepend (nodes_list, snode);
775 }
776 }
777
778 if (ehash)
779 g_hash_table_destroy (ehash);
780
781 return g_slist_reverse (nodes_list);
782 }
783
784 static void
icon_fetched_cb(G_GNUC_UNUSED BrowserConnection * bcnc,GdkPixbuf * pixbuf,GdaTreeNode * node,G_GNUC_UNUSED GError * error)785 icon_fetched_cb (G_GNUC_UNUSED BrowserConnection *bcnc,
786 GdkPixbuf *pixbuf, GdaTreeNode *node, G_GNUC_UNUSED GError *error)
787 {
788 if (pixbuf) {
789 GValue *av;
790 av = gda_value_new (G_TYPE_OBJECT);
791 g_value_set_object (av, pixbuf);
792 gda_tree_node_set_node_attribute (node, "icon", av, NULL);
793 gda_value_free (av);
794 }
795 g_object_unref (node);
796 }
797
798 #ifdef HAVE_LDAP
799 static gboolean
icons_resol_cb(MgrFavorites * mgr)800 icons_resol_cb (MgrFavorites *mgr)
801 {
802 if (mgr->priv->icons_resol_timer == 0)
803 return FALSE;
804 if (mgr->priv->icons_resol_list) {
805 IconResolutionData *data;
806 data = (IconResolutionData*) mgr->priv->icons_resol_list->data;
807 mgr->priv->icons_resol_list = g_slist_delete_link (mgr->priv->icons_resol_list,
808 mgr->priv->icons_resol_list);
809
810 if (browser_connection_ldap_icon_for_dn (mgr->priv->bcnc, data->dn,
811 (BrowserConnectionJobCallback) icon_fetched_cb,
812 g_object_ref (data->node), NULL) == 0)
813 g_object_unref (data->node);
814 icon_resolution_data_free (data);
815 }
816
817 if (! mgr->priv->icons_resol_list) {
818 mgr->priv->icons_resol_timer = 0;
819 return FALSE;
820 }
821 else
822 return TRUE;
823 }
824 #endif
825