1 /* morla - Copyright (C) 2005-2007 bakunin - Andrea Marchesini
2  *                                      <bakunin@morlardf.net>
3  *
4  * This source code is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Public License as published
6  * by the Free Software Foundation; either version 2 of the License,
7  * or (at your option) any later version.
8  *
9  * This source code is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  * Please refer to the GNU Public License for more details.
13  *
14  * You should have received a copy of the GNU Public License along with
15  * this source code; if not, write to:
16  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #else
22 # error Use configure; make; make install
23 #endif
24 
25 #include "editor.h"
26 
27 struct invisible_t
28 {
29   struct template_input_t *input;
30   struct rdf_t *rdf;
31 };
32 
33 enum template_widget_t
34 {
35   TEMPLATE_WIDGET_LITERAL,
36   TEMPLATE_WIDGET_RESOURCE,
37   TEMPLATE_WIDGET_ALT_LITERAL,
38   TEMPLATE_WIDGET_ALT_RESOURCE,
39   TEMPLATE_WIDGET_CARDINALITY,
40   TEMPLATE_WIDGET_OTHER,
41   TEMPLATE_WIDGET_DEFAULT
42 };
43 
44 struct template_func_t
45 {
46   gchar *(*name) (GtkWidget *, gchar *);
47     gboolean (*low_check) (GtkWidget *, gchar *, gint min_cardinality);
48     gboolean (*high_check) (GtkWidget *, gchar *, gint min_cardinality);
49   void (*destroy) (GtkWidget *);
50   void (*save) (GtkWidget *, struct editor_data_t *, gchar * subject,
51 		gchar * predicate, struct unredo_t * unredo,
52 		struct rdf_t * rdf_prev);
53     gboolean (*is_your) (GtkWidget *, struct rdf_t *, GList **);
54   void (*get) (GtkWidget *, struct template_value_t * value);
55   void (*set) (GtkWidget *, struct template_value_t * value);
56 
57   enum template_widget_t type;
58 };
59 
60 GList *template_menus = NULL;
61 GList *template_list = NULL;
62 
63 static void template_import_new (gchar * template, GList ** list,
64 				 GList * rdf);
65 static void template_parse_input (gchar * input, GList ** list, GList * rdf);
66 static gchar *template_parse_input_typevalue (gchar * node, GList * rdf,
67 					      GList ** alt);
68 static void template_input_free (struct template_input_t *i);
69 static void template_free (struct template_t *t);
70 static void template_refresh (GtkWidget * treeview);
71 static gint template_remove (GtkWidget * treeview);
72 static void template_open_dialog (GtkWidget * treeview);
73 static void template_activate (GtkWidget * w, GtkTreePath * p,
74 			       GtkTreeViewColumn * c, GtkWidget * dialog);
75 static GtkWidget *template_widget_create (GList * resources, GList * blanks,
76 					  struct template_input_t *,
77 					  gboolean cardinality
78 #ifdef USE_JS
79 					  , struct js_t *js
80 #endif
81   );
82 static gboolean template_widget_check (GtkWidget * widget);
83 static void template_widget_save_on (GtkWidget * widget);
84 static gboolean template_widget_is_your (GtkWidget *, struct rdf_t *,
85 					 GList **);
86 static void template_widget_save_off (GtkWidget * widget);
87 static void template_widget_save_reset (GtkWidget * widget);
88 static void template_widget_save (GtkWidget * widget, struct editor_data_t *,
89 				  gchar *, struct unredo_t *unredo);
90 static void template_widget_set (GtkWidget * widget,
91 				 struct template_value_t *);
92 static void template_widget_destroy (GtkWidget * wiget);
93 static gchar *template_widget_name (GtkWidget * wiget);
94 static gchar *template_widget_blank (struct editor_data_t *data);
95 static void template_invisible_save (gchar * subject,
96 				     struct template_input_t *i,
97 				     struct editor_data_t *data,
98 				     struct unredo_t *unredo, struct rdf_t *);
99 static void template_update_real (GtkWidget * menu);
100 static gboolean template_run (GtkWidget * widget, struct template_t *);
101 static GtkWidget *template_run_create (GtkWidget * widget_inputs,
102 				       struct template_t *t,
103 				       GList * resources, GList * blanks,
104 				       GtkWidget ** type_resource,
105 				       GtkWidget ** type_blanknode,
106 				       GtkWidget ** object,
107 				       GtkWidget ** toggle);
108 static void template_edit_set (GList ** wi, GList ** rdf, gchar * subject);
109 static GList *template_edit_set_sort (GList * widgets);
110 static void template_edit_invisible (GList ** invisible, GList ** rdf,
111 				     gchar * subject, struct template_t *t);
112 static void template_set_size (GtkWidget * dialog, GtkWidget * sw,
113 			       GtkWidget *);
114 
115 #ifdef USE_JS
116 static gboolean template_destroy (GtkWidget * widget, GdkEvent * event,
117 				  gpointer user_data);
118 static gboolean template_js_evaluate (struct js_t *js, GtkWidget * widget,
119 				      gchar * func);
120 #endif
121 
122 /* UPDATE DEI MENU **********************************************************/
123 
124 /* Questa funzione aggiorna i menu con i template importati: */
125 void
template_update(void)126 template_update (void)
127 {
128   g_list_foreach (template_menus, (GFunc) template_update_real, NULL);
129 }
130 
131 /* Check fra le categorie di due template (utile per l'ordinamento) : */
132 static gint
template_strcmp(struct template_t * a,struct template_t * b)133 template_strcmp (struct template_t *a, struct template_t *b)
134 {
135   if (!a->category && !b->category)
136     return 0;
137 
138   if (!a->category && b->category)
139     return 1;
140 
141   if (a->category && !b->category)
142     return -1;
143 
144   return strcmp (a->category, b->category);
145 }
146 
147 /* Estrapolare un nome sensato da una categoria sotto forma di URI: */
148 static gchar *
template_parse_category(gchar * str)149 template_parse_category (gchar * str)
150 {
151   gint len = strlen (str);
152 
153   while (--len)
154     {
155       if (*(str + len) == '#' || *(str + len) == '/')
156 	return str + len + 1;
157     }
158 
159   return str;
160 }
161 
162 /* Questa funzione aggiorna un menu con la lista dei template: */
163 static void
template_update_real(GtkWidget * menu)164 template_update_real (GtkWidget * menu)
165 {
166   GList *list;
167   GtkWidget *menuitem;
168   GtkWidget *label;
169   struct template_t *t;
170   gchar *category;
171   gchar *str;
172   gpointer func;
173 
174   /* Prelevo la funzione da eseguire al click: */
175   func = g_object_get_data (G_OBJECT (menu), "func");
176 
177   /* Cancello tutto cio' che c'e': */
178   gtk_container_foreach (GTK_CONTAINER (menu),
179 			 (GtkCallback) gtk_widget_destroy, NULL);
180 
181   if (!template_list)
182     return;
183 
184   /* Ordino la lista: */
185   template_list = g_list_sort (template_list, (GCompareFunc) template_strcmp);
186 
187   /* Creo il menu: */
188   menuitem = gtk_menu_item_new ();
189   gtk_container_add (GTK_CONTAINER (menu), menuitem);
190 
191   /* Setto il primo nome della categoria: */
192   category = ((struct template_t *) template_list->data)->category;
193 
194   if (category)
195     {
196       gchar *s = markup (template_parse_category (category));
197       str = g_strdup_printf ("<b>%s</b>", s);
198       g_free (s);
199     }
200   else
201     str = g_strdup_printf (_("<b>Generic</b>"));
202 
203   label = gtk_label_new (str);
204   g_free (str);
205 
206   gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
207   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
208   gtk_container_add (GTK_CONTAINER (menuitem), label);
209 
210   /* Per ogni item della lista aggiungo una voce: */
211   list = template_list;
212   while (list)
213     {
214       t = list->data;
215 
216       /* Se cambia categoria: */
217       if (category
218 	  && ((!t->category && category) || strcmp (t->category, category)))
219 	{
220 	  category = t->category;
221 
222 	  menuitem = gtk_menu_item_new ();
223 	  gtk_widget_set_sensitive (menuitem, FALSE);
224 	  gtk_container_add (GTK_CONTAINER (menu), menuitem);
225 
226 	  menuitem = gtk_menu_item_new ();
227 	  gtk_container_add (GTK_CONTAINER (menu), menuitem);
228 
229 	  if (category)
230 	    {
231 	      gchar *s = markup (template_parse_category (category));
232 	      str = g_strdup_printf ("<b>%s</b>", s);
233 	      g_free (s);
234 	    }
235 	  else
236 	    str = g_strdup_printf (_("<b>Generic</b>"));
237 
238 	  label = gtk_label_new (str);
239 	  g_free (str);
240 
241 	  gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
242 	  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
243 	  gtk_container_add (GTK_CONTAINER (menuitem), label);
244 	}
245 
246       /* Inserisco il template e lo rendo cliccabile: */
247       menuitem = gtk_menu_item_new_with_label (t->name);
248       gtk_container_add (GTK_CONTAINER (menu), menuitem);
249       g_signal_connect ((gpointer) menuitem, "activate", G_CALLBACK (func),
250 			t);
251 
252       list = list->next;
253     }
254 
255   gtk_widget_show_all (menu);
256 }
257 
258 /* IMPORT DEI TEMPLATE ******************************************************/
259 
260 /* Questa funzione importa templates da file: */
261 void
template_import_file(GtkWidget * w,gpointer dummy)262 template_import_file (GtkWidget * w, gpointer dummy)
263 {
264   gchar *file;
265   gchar *uri;
266   gchar s[1024];
267 
268   /* Statusbar: */
269   editor_statusbar_lock = LOCK;
270   statusbar_set (_("Import a new template..."));
271 
272   /* Richiedo un file: */
273   if (!
274       (file =
275        file_chooser (_("Open a template file..."), GTK_SELECTION_SINGLE,
276 		     GTK_FILE_CHOOSER_ACTION_OPEN, NULL)))
277     {
278       statusbar_set (_("Open a template file: aborted"));
279       editor_statusbar_lock = WAIT;
280       return;
281     }
282 
283   /* Creo un uri compatibile: */
284   uri = g_filename_to_uri (file, NULL, NULL);
285 
286   /* Provo ad importarlo: */
287   if (uri && template_import (uri, NULL, TRUE, TRUE) == TRUE)
288     {
289       template_update ();
290       template_save ();
291 
292       g_snprintf (s, sizeof (s), _("Template %s imported"), file);
293       statusbar_set (s);
294 
295       g_free (uri);
296     }
297   else
298     {
299       statusbar_set (_("Open a template file: error!"));
300 
301       if (uri)
302 	g_free (uri);
303     }
304 
305   /* Libero la statusbar e la memoria: */
306   editor_statusbar_lock = WAIT;
307   g_free (file);
308 }
309 
310 /* Come sopra ma per gli uri: */
311 void
template_import_uri(GtkWidget * w,gpointer dummy)312 template_import_uri (GtkWidget * w, gpointer dummy)
313 {
314   gchar *uri;
315   gchar s[1024];
316   struct download_t *download;
317 
318   editor_statusbar_lock = LOCK;
319   statusbar_set (_("Import a new template..."));
320 
321   if (!(uri = uri_chooser (_("Import a new template..."), &download)))
322     {
323       statusbar_set (_("Import a new template: about"));
324       editor_statusbar_lock = WAIT;
325       return;
326     }
327 
328   /* Importo: */
329   if (template_import (uri, download, TRUE, TRUE) == TRUE)
330     {
331       template_update ();
332       template_save ();
333 
334       g_snprintf (s, sizeof (s), _("Template %s imported"), uri);
335       statusbar_set (s);
336     }
337 
338   if (download)
339     download_free (download);
340 
341   /* Statusbar e memory */
342   editor_statusbar_lock = WAIT;
343   g_free (uri);
344 }
345 
346 /* Funzione utile per ordinare: */
347 static gint
template_list_sort(struct template_t * t1,struct template_t * t2)348 template_list_sort (struct template_t *t1, struct template_t *t2)
349 {
350   return strcmp (t1->name, t2->name);
351 }
352 
353 /* Questa funzione importa un uri: */
354 gboolean
template_import(gchar * uri,struct download_t * download,gboolean msg,gboolean thread)355 template_import (gchar * uri, struct download_t * download, gboolean msg,
356 		 gboolean thread)
357 {
358   GList *list, *nslist;
359   GList *l;
360   GList *t = NULL, *templates = NULL;
361   struct rdf_t *rdf;
362   gchar s[1024];
363   gboolean ok = TRUE;
364 
365   /* Se devo usare i thread parso l'RDF con rdf_parse_thread: */
366   if (thread == TRUE)
367     {
368       if (rdf_parse_thread (uri, download, &list, &nslist, FALSE, NULL, NULL)
369 	  == FALSE)
370 	ok = FALSE;
371     }
372 
373   /* Altrimenti faccio senza thread: */
374   else
375     {
376       if (rdf_parse (uri, download, FALSE, &list, NULL, NULL) == FALSE)
377 	ok = FALSE;
378 
379       else if (namespace_parse (list, &nslist) == FALSE)
380 	ok = FALSE;
381     }
382 
383   /* Se ci sono problemi comunico solo se devo: */
384   if (ok == FALSE)
385     {
386       if (msg)
387 	{
388 	  g_snprintf (s, sizeof (s), _("Error opening resource '%s'"), uri);
389 	  dialog_msg (s);
390 	}
391 
392       return FALSE;
393     }
394 
395   /* Libero memoria: */
396   g_list_foreach (nslist, (GFunc) namespace_free, NULL);
397   g_list_free (nslist);
398 
399   /* Cerco delle valide triplette di possibili template e li salvo dentro
400    * ad una lista: */
401   l = list;
402   while (l)
403     {
404       rdf = l->data;
405 
406       if (!strcmp (rdf->predicate, RDF_TYPE)
407 	  && rdf->object_type == RDF_OBJECT_RESOURCE
408 	  && !strcmp (rdf->object, MORLA_NS MORLA_TEMPLATE))
409 	t = g_list_append (t, rdf->subject);
410 
411       l = l->next;
412     }
413 
414   /* Se ho una lista per ognuni elemento provo ad importare il template: */
415   if (t)
416     {
417       l = t;
418       while (l)
419 	{
420 	  template_import_new (l->data, &templates, list);
421 	  l = l->next;
422 	}
423 
424       g_list_free (t);
425     }
426 
427   /* Libero altra memoria: */
428   g_list_foreach (list, (GFunc) rdf_free, NULL);
429   g_list_free (list);
430 
431   /* Se non ho template importati, comuinico: */
432   if (!templates)
433     {
434       if (msg)
435 	dialog_msg (_("No template in this RDF Document!"));
436 
437       return FALSE;
438     }
439 
440   /* Per ogni template controllo se ce l'ho gia: */
441   l = templates;
442   while (l)
443     {
444       ok = TRUE;
445 
446       /* Cerco duplicati: */
447       list = template_list;
448       while (list)
449 	{
450 	  /* Se coincidono: */
451 	  if (!strcmp
452 	      (((struct template_t *) l->data)->uri,
453 	       ((struct template_t *) list->data)->uri))
454 	    {
455 
456 	      /* e le versioni sono uguali... */
457 	      if (!strcmp (((struct template_t *) l->data)->version,
458 			   ((struct template_t *) list->data)->version))
459 		ok = FALSE;
460 
461 	      /* altrimenti rimuovo quello vecchio: */
462 	      else
463 		{
464 		  template_free (list->data);
465 		  template_list = g_list_remove (template_list, list->data);
466 		}
467 
468 	      break;
469 	    }
470 
471 	  list = list->next;
472 	}
473 
474       /* Se non ci sono problemi aggiungo: */
475       if (ok == TRUE)
476 	{
477 	  template_list = g_list_append (template_list, l->data);
478 	  template_list =
479 	    g_list_sort (template_list, (GCompareFunc) template_list_sort);
480 	}
481 
482       /* altrimenti comunico e libero la memoria: */
483       else
484 	{
485 	  if (msg)
486 	    {
487 	      g_snprintf (s, sizeof (s), _("Duplicated template '%s'!"),
488 			  ((struct template_t *) l->data)->name);
489 	      dialog_msg (s);
490 	    }
491 
492 	  template_free (l->data);
493 	}
494 
495       l = l->next;
496     }
497 
498   /* Libero memoria finale: */
499   g_list_free (templates);
500 
501   return TRUE;
502 }
503 
504 /* Questa funzione cerca di importare un template preciso dato una lista
505  * di triplette e un nome: */
506 static void
template_import_new(gchar * template,GList ** list,GList * rdf)507 template_import_new (gchar * template, GList ** list, GList * rdf)
508 {
509   GList *l, *input = NULL;
510   struct rdf_t *r;
511   gchar *uri = NULL;
512   gchar *name = NULL;
513   gchar *version = NULL;
514   gchar *category = NULL;
515   struct template_t *ret;
516   GList *input_ret = NULL;
517 
518   l = rdf;
519 
520   while (l)
521     {
522       r = l->data;
523       if (!strcmp (r->subject, template))
524 	{
525 	  /* Cerco le triplette che hanno alcune caratteriche proprieta': */
526 	  if (r->object_type == RDF_OBJECT_LITERAL
527 	      && !strcmp (r->predicate, RDFS_LABEL))
528 	    {
529 	      name = r->object;
530 	      uri = r->subject;
531 	    }
532 
533 	  else if (r->object_type == RDF_OBJECT_LITERAL
534 		   && !strcmp (r->predicate, MORLA_NS MORLA_HASVERSION))
535 	    version = r->object;
536 
537 	  else if (r->object_type == RDF_OBJECT_RESOURCE
538 		   && !strcmp (r->predicate, MORLA_NS MORLA_CATEGORY))
539 	    category = r->object;
540 
541 	  else if (r->object_type != RDF_OBJECT_LITERAL
542 		   && !strcmp (r->predicate, MORLA_NS MORLA_HASINPUT))
543 	    input = g_list_append (input, r->object);
544 	}
545 
546       l = l->next;
547     }
548 
549   /* Ultimi controlli: */
550   if (!input)
551     {
552       g_message (_("No input for template '%s'"), template);
553       return;
554     }
555 
556   if (!uri || !name || !version)
557     {
558       g_message (_("No URI, name or version for template '%s'"), template);
559       g_list_free (input);
560       return;
561     }
562 
563   /* Per ogni input provo ad importarlo: */
564   l = input;
565   while (l)
566     {
567       template_parse_input (l->data, &input_ret, rdf);
568       l = l->next;
569     }
570 
571   /* Libero memoria: */
572   g_list_free (input);
573 
574   /* se non ho importato nessun input: */
575   if (!input_ret)
576     {
577       g_message (_("No input for template '%s'"), template);
578       return;
579     }
580 
581   /* Alloco memoria ed inserisco nella lista: */
582   ret = (struct template_t *) g_malloc0 (sizeof (struct template_t));
583 
584   ret->name = g_strdup (name);
585   ret->uri = g_strdup (uri);
586   ret->version = g_strdup (version);
587   ret->category = category ? g_strdup (category) : NULL;
588   ret->input = input_ret;
589 
590   (*list) = g_list_append (*list, ret);
591 }
592 
593 /* Funzione per l'import di input di template: */
594 static void
template_parse_input(gchar * input,GList ** list,GList * rdf)595 template_parse_input (gchar * input, GList ** list, GList * rdf)
596 {
597   GList *l;
598   struct rdf_t *r;
599   GList *labels = NULL;
600   GList *comments = NULL;
601   gint min_cardinality = 0;
602   gint max_cardinality = 1;
603   gchar *typevalue = NULL;
604   GList *alt_typevalue = NULL;
605   gchar *default_value = NULL;
606   gchar *default_language = NULL;
607   gchar *default_datatype = NULL;
608   gchar *function_init = NULL;
609   gchar *function_check = NULL;
610   gchar *function_destroy = NULL;
611   gchar *function_save = NULL;
612   gboolean visible = 1;
613   gboolean lang = 1;
614   gboolean datatype = 1;
615   gboolean longtext = 0;
616   gchar *rdfs = NULL;
617   struct template_input_t *ret;
618   struct info_box_t *lang_input;
619   gboolean ok = 0;
620 
621   l = rdf;
622 
623   /* Per ogni tripletta cerco alcune property particolari: */
624   while (l)
625     {
626       r = l->data;
627 
628       if (!strcmp (r->subject, input))
629 	{
630 	  if (r->object_type == RDF_OBJECT_LITERAL
631 	      && !strcmp (r->predicate, RDFS_LABEL))
632 	    {
633 	      lang_input = g_malloc (sizeof (struct info_box_t));
634 	      lang_input->value = g_strdup (r->object);
635 	      lang_input->lang = r->lang ? g_strdup (r->lang) : NULL;
636 
637 	      labels = g_list_append (labels, lang_input);
638 	    }
639 
640 	  else if (r->object_type == RDF_OBJECT_LITERAL
641 		   && !strcmp (r->predicate, RDFS_COMMENT))
642 	    {
643 	      lang_input = g_malloc (sizeof (struct info_box_t));
644 	      lang_input->value = g_strdup (r->object);
645 	      lang_input->lang = r->lang ? g_strdup (r->lang) : NULL;
646 
647 	      comments = g_list_append (comments, lang_input);
648 	    }
649 
650 	  else if (r->object_type == RDF_OBJECT_LITERAL
651 		   && !strcmp (r->predicate, MORLA_NS MORLA_MINCARD))
652 	    min_cardinality = atoi (r->object);
653 
654 	  else if (r->object_type == RDF_OBJECT_LITERAL
655 		   && !strcmp (r->predicate, MORLA_NS MORLA_MAXCARD))
656 	    max_cardinality = atoi (r->object);
657 
658 	  else if (r->object_type == RDF_OBJECT_LITERAL
659 		   && !strcmp (r->predicate, MORLA_NS MORLA_VISIBLE))
660 	    visible = !g_ascii_strcasecmp (r->object, "yes");
661 
662 	  else if (r->object_type == RDF_OBJECT_LITERAL
663 		   && !strcmp (r->predicate, MORLA_NS MORLA_LANGUAGE))
664 	    lang = !g_ascii_strcasecmp (r->object, "yes");
665 
666 	  else if (r->object_type == RDF_OBJECT_LITERAL
667 		   && !strcmp (r->predicate, MORLA_NS MORLA_DATATYPE))
668 	    datatype = !g_ascii_strcasecmp (r->object, "yes");
669 
670 	  else if (!strcmp (r->predicate, MORLA_NS MORLA_TYPEVALUE))
671 	    {
672 	      switch (r->object_type)
673 		{
674 		case RDF_OBJECT_RESOURCE:
675 		  typevalue = r->object;
676 		  break;
677 
678 		case RDF_OBJECT_BLANK:
679 		  typevalue =
680 		    template_parse_input_typevalue (r->object, rdf,
681 						    &alt_typevalue);
682 		  break;
683 
684 		default:
685 		  break;
686 		}
687 	    }
688 
689 	  else if (!strcmp (r->predicate, MORLA_NS MORLA_DEFAULTVALUE))
690 	    default_value = r->object;
691 
692 	  else if (r->object_type == RDF_OBJECT_RESOURCE
693 		   && !strcmp (r->predicate, MORLA_NS MORLA_DEFAULTDATATYPE))
694 	    default_datatype = r->object;
695 
696 	  else if (r->object_type == RDF_OBJECT_LITERAL
697 		   && !strcmp (r->predicate, MORLA_NS MORLA_DEFAULTLANGUAGE))
698 	    default_language = r->object;
699 
700 	  else if (r->object_type == RDF_OBJECT_RESOURCE
701 		   && !strcmp (r->predicate, MORLA_NS MORLA_HASRDFS))
702 	    rdfs = r->object;
703 
704 	  else if (r->object_type == RDF_OBJECT_RESOURCE
705 		   && !strcmp (r->predicate, RDF_TYPE)
706 		   && !strcmp (r->object, MORLA_NS MORLA_INPUT))
707 	    ok = 1;
708 
709 	  else if (r->object_type == RDF_OBJECT_LITERAL
710 		   && !strcmp (r->predicate, MORLA_NS MORLA_FUNCTIONINIT))
711 	    function_init = r->object;
712 
713 	  else if (r->object_type == RDF_OBJECT_LITERAL
714 		   && !strcmp (r->predicate, MORLA_NS MORLA_FUNCTIONCHECK))
715 	    function_check = r->object;
716 
717 	  else if (r->object_type == RDF_OBJECT_LITERAL
718 		   && !strcmp (r->predicate, MORLA_NS MORLA_FUNCTIONDESTROY))
719 	    function_destroy = r->object;
720 
721 	  else if (r->object_type == RDF_OBJECT_LITERAL
722 		   && !strcmp (r->predicate, MORLA_NS MORLA_FUNCTIONSAVE))
723 	    function_save = r->object;
724 
725 	  else if (r->object_type == RDF_OBJECT_LITERAL
726 		   && !strcmp (r->predicate, MORLA_NS MORLA_LONGTEXT))
727 	    longtext = !g_ascii_strcasecmp (r->object, "yes");
728 
729 	}
730 
731       l = l->next;
732     }
733 
734   /* Ultimi check: */
735   if (!ok || !rdfs || !labels)
736     {
737       if (labels)
738 	{
739 	  g_list_foreach (labels, (GFunc) info_box_free, NULL);
740 	  g_list_free (labels);
741 	}
742 
743       if (comments)
744 	{
745 	  g_list_foreach (comments, (GFunc) info_box_free, NULL);
746 	  g_list_free (comments);
747 	}
748 
749       g_message (_("Input '%s' has no rdfs, label or istance of input!"),
750 		 input);
751       return;
752     }
753 
754   /* Controllo se ci sono problemi nella visibilita': */
755   if (!visible
756       && (!default_value
757 	  || (strcmp (typevalue, RDFS_LITERAL)
758 	      && strcmp (typevalue, RDFS_RESOURCE))))
759     {
760       g_list_foreach (labels, (GFunc) info_box_free, NULL);
761       g_list_free (labels);
762 
763       if (comments)
764 	{
765 	  g_list_foreach (comments, (GFunc) info_box_free, NULL);
766 	  g_list_free (comments);
767 	}
768 
769       g_message (_
770 		 ("This input '%s' is novisible but has not a defualt value!"),
771 		 input);
772       return;
773     }
774 
775   /* Controllo se ci sono problemi nella cardinalita' degli invisibili visibilita': */
776   if (!visible && (!max_cardinality > 0 || min_cardinality != 1))
777     {
778       g_list_foreach (labels, (GFunc) info_box_free, NULL);
779       g_list_free (labels);
780 
781       if (comments)
782 	{
783 	  g_list_foreach (comments, (GFunc) info_box_free, NULL);
784 	  g_list_free (comments);
785 	}
786 
787       g_message (_
788 		 ("This input '%s' is novisible but has max_cardinality or min_cardinality != 1!"),
789 		 input);
790       return;
791     }
792 
793   /* Alloco e inserisco nella lista: */
794   ret =
795     (struct template_input_t *) g_malloc0 (sizeof (struct template_input_t));
796 
797   ret->labels = labels;
798   ret->comments = comments;
799 
800   /* Controllo il typevalue: */
801   if (typevalue)
802     {
803       if (!strcmp (typevalue, RDFS_LITERAL))
804 	{
805 	  if (alt_typevalue)
806 	    {
807 	      g_message
808 		(_
809 		 ("This input '%s' has a alternative list of value but it is not a alternative typevalue!"),
810 		 input);
811 	      template_input_free (ret);
812 	      return;
813 	    }
814 
815 	  ret->typevalue = TEMPLATE_INPUT_TYPEVALUE_LITERAL;
816 	  ret->datatype = datatype;
817 	  ret->lang = lang;
818 	}
819 
820       else if (!strcmp (typevalue, RDFS_RESOURCE))
821 	{
822 	  if (alt_typevalue)
823 	    {
824 	      g_message
825 		(_
826 		 ("This input '%s' has a alternative list of value but it is not a alternative typevalue!"),
827 		 input);
828 	      template_input_free (ret);
829 	      return;
830 	    }
831 
832 	  ret->typevalue = TEMPLATE_INPUT_TYPEVALUE_RESOURCE;
833 	}
834 
835       else if (!strcmp (typevalue, MORLA_NS MORLA_ALT_LITERAL))
836 	{
837 	  if (!alt_typevalue)
838 	    {
839 	      g_message
840 		(_("This input '%s' has no a alternative list of value!"),
841 		 input);
842 	      template_input_free (ret);
843 	      return;
844 	    }
845 
846 	  ret->typevalue = TEMPLATE_INPUT_TYPEVALUE_ALT_LITERAL;
847 	  ret->alt_typevalue = alt_typevalue;
848 	}
849 
850       else if (!strcmp (typevalue, MORLA_NS MORLA_ALT_RESOURCE))
851 	{
852 	  if (!alt_typevalue)
853 	    {
854 	      g_message
855 		(_("This input '%s' has no a alternative list of value!"),
856 		 input);
857 	      template_input_free (ret);
858 	      return;
859 	    }
860 
861 	  ret->typevalue = TEMPLATE_INPUT_TYPEVALUE_ALT_RESOURCE;
862 	  ret->alt_typevalue = alt_typevalue;
863 	}
864 
865       else
866 	{
867 	  if (alt_typevalue)
868 	    {
869 	      g_message
870 		(_
871 		 ("This input '%s' has a alternative list of value but it is not a alternative typevalue!"),
872 		 input);
873 	      template_input_free (ret);
874 	      return;
875 	    }
876 
877 	  ret->other_typevalue = g_strdup (typevalue);
878 	  ret->typevalue = TEMPLATE_INPUT_TYPEVALUE_OTHER;
879 	}
880     }
881   else
882     ret->typevalue = TEMPLATE_INPUT_TYPEVALUE_NONE;
883 
884   /* Resto dei valori: */
885   ret->rdfs = g_strdup (rdfs);
886 
887   if (default_language)
888     ret->default_language = g_strdup (default_language);
889 
890   if (default_datatype)
891     {
892       if (datatype_exists (default_datatype) == TRUE)
893 	ret->default_datatype = g_strdup (default_datatype);
894 
895       else
896 	{
897 	  g_message (_
898 		     ("The input '%s' tries to use a impossibile datatype '%s'."),
899 		     input, default_datatype);
900 	  template_input_free (ret);
901 	  return;
902 	}
903     }
904 
905   if (default_value)
906     ret->default_value = g_strdup (default_value);
907 
908   if (min_cardinality > 0)
909     ret->min_cardinality = min_cardinality;
910 
911   if (max_cardinality > 0 && max_cardinality < min_cardinality)
912     max_cardinality = min_cardinality;
913 
914   if (function_init)
915     ret->function_init = g_strdup (function_init);
916 
917   if (function_check)
918     ret->function_check = g_strdup (function_check);
919 
920   if (function_destroy)
921     ret->function_destroy = g_strdup (function_destroy);
922 
923   if (function_save)
924     ret->function_save = g_strdup (function_save);
925 
926   ret->longtext = longtext;
927 
928   ret->max_cardinality = max_cardinality;
929 
930   ret->visible = visible;
931 
932   (*list) = g_list_append (*list, ret);
933 }
934 
935 /* Questa funzione crea la lista di alternative */
936 static gchar *
template_parse_input_typevalue(gchar * node,GList * rdf,GList ** alt)937 template_parse_input_typevalue (gchar * node, GList * rdf, GList ** alt)
938 {
939   struct rdf_t *data;
940   gchar *ret = NULL;
941   GList *list = NULL;
942 
943   while (rdf)
944     {
945       data = rdf->data;
946 
947       if (!strcmp (data->subject, node))
948 	{
949 	  if (!strcmp (data->predicate, RDF_TYPE)
950 	      && data->object_type == RDF_OBJECT_RESOURCE)
951 	    ret = data->object;
952 
953 	  else if (!strncmp (data->predicate, RDF_ITEM, strlen (RDF_ITEM)))
954 	    {
955 	      list = g_list_append (list, g_strdup (data->object));
956 	    }
957 
958 	}
959 
960       rdf = rdf->next;
961     }
962 
963   *alt = list;
964   return ret;
965 }
966 
967 /* SALVATAGGIO **************************************************************/
968 
969 static void
template_save_init(FILE * fl)970 template_save_init (FILE * fl)
971 {
972   fprintf (fl, "<?xml version=\"1.0\"?>\n");
973   fprintf (fl, "<rdf:RDF\n");
974   fprintf (fl,
975 	   "   xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n");
976   fprintf (fl, "   xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\"\n");
977   fprintf (fl, "   xmlns:morla=\"" MORLA_NS "\"\n");
978   fprintf (fl, ">\n\n");
979 }
980 
981 static void
template_save_one(FILE * fl,struct template_t * template,gint t_id)982 template_save_one (FILE * fl, struct template_t *template, gint t_id)
983 {
984   struct template_input_t *input;
985   struct info_box_t *lang_input;
986   gchar *str;
987   GList *ll, *list;
988   gint i, id;
989 
990   str = markup (template->uri);
991   fprintf (fl, "  <rdf:Description rdf:about=\"%s\">\n", str);
992   g_free (str);
993 
994   fprintf (fl, "    <rdf:type rdf:resource=\"%s\" />\n",
995 	   MORLA_NS MORLA_TEMPLATE);
996 
997   str = markup (template->name);
998   fprintf (fl, "    <rdfs:label>%s</rdfs:label>\n", str);
999   g_free (str);
1000 
1001   str = markup (template->version);
1002   fprintf (fl,
1003 	   "    <morla:" MORLA_HASVERSION ">%s</morla:" MORLA_HASVERSION
1004 	   ">\n", str);
1005   g_free (str);
1006 
1007   if (template->category)
1008     {
1009       str = markup (template->category);
1010       fprintf (fl, "    <morla:" MORLA_CATEGORY " rdf:resource=\"%s\" />\n",
1011 	       str);
1012       g_free (str);
1013     }
1014 
1015   for (i = 0, id = g_list_length (template->input); i < id; i++)
1016     fprintf (fl,
1017 	     "    <morla:" MORLA_HASINPUT " rdf:nodeID=\"input_%d_%d\" />\n",
1018 	     t_id, i);
1019   fprintf (fl, "  </rdf:Description>\n\n");
1020 
1021   i = 0;
1022 
1023   /* Per ogni input scrivo: */
1024   ll = template->input;
1025   while (ll)
1026     {
1027       input = ll->data;
1028 
1029       if (input->typevalue == TEMPLATE_INPUT_TYPEVALUE_ALT_RESOURCE)
1030 	{
1031 	  GList *list;
1032 	  gint id = 0;
1033 
1034 	  fprintf (fl,
1035 		   "  <rdf:Description rdf:nodeID=\"input_%d_%d_typevalue\">\n",
1036 		   t_id, i);
1037 	  fprintf (fl, "    <rdf:type rdf:resource=\"%s\" />\n",
1038 		   MORLA_NS MORLA_ALT_RESOURCE);
1039 
1040 	  list = input->alt_typevalue;
1041 	  while (list)
1042 	    {
1043 	      fprintf (fl, "    <rdf:_%d rdf:resource=\"%s\" />\n", ++id,
1044 		       (gchar *) list->data);
1045 	      list = list->next;
1046 	    }
1047 
1048 	  fprintf (fl, "  </rdf:Description>\n\n");
1049 	}
1050 
1051       if (input->typevalue == TEMPLATE_INPUT_TYPEVALUE_ALT_LITERAL)
1052 	{
1053 	  GList *list;
1054 	  gint id = 1;
1055 
1056 	  fprintf (fl,
1057 		   "  <rdf:Description rdf:nodeID=\"input_%d_%d_typevalue\">\n",
1058 		   t_id, i);
1059 	  fprintf (fl, "    <rdf:type rdf:resource=\"%s\" />\n",
1060 		   MORLA_NS MORLA_ALT_LITERAL);
1061 
1062 	  list = input->alt_typevalue;
1063 	  while (list)
1064 	    {
1065 	      fprintf (fl, "    <rdf:_%d>%s</rdf:_%d>\n", id,
1066 		       (gchar *) list->data, id);
1067 	      id++;
1068 	      list = list->next;
1069 	    }
1070 
1071 	  fprintf (fl, "  </rdf:Description>\n\n");
1072 	}
1073 
1074       fprintf (fl, "  <rdf:Description rdf:nodeID=\"input_%d_%d\">\n", t_id,
1075 	       i);
1076       fprintf (fl, "    <rdf:type rdf:resource=\"%s\" />\n",
1077 	       MORLA_NS MORLA_INPUT);
1078 
1079       list = input->labels;
1080       while (list)
1081 	{
1082 	  lang_input = list->data;
1083 
1084 	  fprintf (fl, "    <rdfs:label");
1085 
1086 	  if (lang_input->lang)
1087 	    {
1088 	      str = markup (lang_input->lang);
1089 	      fprintf (fl, " xml:lang=\"%s\"", str);
1090 	      g_free (str);
1091 	    }
1092 
1093 	  str = markup (lang_input->value);
1094 	  fprintf (fl, ">%s</rdfs:label>\n", str);
1095 	  g_free (str);
1096 
1097 	  list = list->next;
1098 	}
1099 
1100       str = markup (input->rdfs);
1101       fprintf (fl, "    <morla:" MORLA_HASRDFS " rdf:resource=\"%s\" />\n",
1102 	       str);
1103       g_free (str);
1104 
1105       fprintf (fl,
1106 	       "    <morla:" MORLA_MINCARD ">%d</morla:" MORLA_MINCARD ">\n",
1107 	       input->min_cardinality);
1108       fprintf (fl,
1109 	       "    <morla:" MORLA_MAXCARD ">%d</morla:" MORLA_MAXCARD ">\n",
1110 	       input->max_cardinality);
1111 
1112       fprintf (fl,
1113 	       "    <morla:" MORLA_VISIBLE ">%s</morla:" MORLA_VISIBLE ">\n",
1114 	       input->visible ? "yes" : "no");
1115 
1116       if (input->function_init)
1117 	fprintf (fl,
1118 		 "    <morla:" MORLA_FUNCTIONINIT ">%s</morla:"
1119 		 MORLA_FUNCTIONINIT ">\n", input->function_init);
1120 
1121       if (input->function_check)
1122 	fprintf (fl,
1123 		 "    <morla:" MORLA_FUNCTIONCHECK ">%s</morla:"
1124 		 MORLA_FUNCTIONCHECK ">\n", input->function_check);
1125 
1126       if (input->function_destroy)
1127 	fprintf (fl,
1128 		 "    <morla:" MORLA_FUNCTIONDESTROY ">%s</morla:"
1129 		 MORLA_FUNCTIONDESTROY ">\n", input->function_destroy);
1130 
1131       if (input->function_save)
1132 	fprintf (fl,
1133 		 "    <morla:" MORLA_FUNCTIONSAVE ">%s</morla:"
1134 		 MORLA_FUNCTIONSAVE ">\n", input->function_save);
1135 
1136       fprintf (fl,
1137 	       "    <morla:" MORLA_LONGTEXT ">%s</morla:" MORLA_LONGTEXT
1138 	       ">\n", input->longtext ? "yes" : "no");
1139 
1140       switch (input->typevalue)
1141 	{
1142 	case TEMPLATE_INPUT_TYPEVALUE_NONE:
1143 	  break;
1144 
1145 	case TEMPLATE_INPUT_TYPEVALUE_RESOURCE:
1146 	  fprintf (fl,
1147 		   "    <morla:" MORLA_TYPEVALUE " rdf:resource=\"%s\" />\n",
1148 		   RDFS_RESOURCE);
1149 	  break;
1150 
1151 	case TEMPLATE_INPUT_TYPEVALUE_LITERAL:
1152 	  fprintf (fl,
1153 		   "    <morla:" MORLA_TYPEVALUE " rdf:resource=\"%s\" />\n",
1154 		   RDFS_LITERAL);
1155 	  fprintf (fl,
1156 		   "    <morla:" MORLA_LANGUAGE ">%s</morla:" MORLA_LANGUAGE
1157 		   ">\n", input->lang ? "yes" : "no");
1158 	  fprintf (fl,
1159 		   "    <morla:" MORLA_DATATYPE ">%s</morla:" MORLA_DATATYPE
1160 		   ">\n", input->datatype ? "yes" : "no");
1161 	  break;
1162 
1163 	case TEMPLATE_INPUT_TYPEVALUE_ALT_RESOURCE:
1164 	case TEMPLATE_INPUT_TYPEVALUE_ALT_LITERAL:
1165 	  fprintf (fl,
1166 		   "    <morla:" MORLA_TYPEVALUE
1167 		   " rdf:nodeID=\"input_%d_%d_typevalue\" />\n", t_id, i);
1168 	  break;
1169 
1170 	case TEMPLATE_INPUT_TYPEVALUE_OTHER:
1171 	  fprintf (fl,
1172 		   "    <morla:" MORLA_TYPEVALUE " rdf:resource=\"%s\" />\n",
1173 		   input->other_typevalue);
1174 	  break;
1175 	}
1176 
1177       if (input->default_value)
1178 	{
1179 	  str = markup (input->default_value);
1180 	  fprintf (fl,
1181 		   "    <morla:" MORLA_DEFAULTVALUE ">%s</morla:"
1182 		   MORLA_DEFAULTVALUE ">\n", str);
1183 	  g_free (str);
1184 	}
1185 
1186       if (input->default_language)
1187 	{
1188 	  str = markup (input->default_language);
1189 	  fprintf (fl,
1190 		   "    <morla:" MORLA_DEFAULTLANGUAGE ">%s</morla:"
1191 		   MORLA_DEFAULTLANGUAGE ">\n", str);
1192 	  g_free (str);
1193 	}
1194 
1195       if (input->default_datatype)
1196 	{
1197 	  str = markup (input->default_datatype);
1198 	  fprintf (fl,
1199 		   "    <morla:" MORLA_DEFAULTDATATYPE
1200 		   " rdf:resource=\"%s\" />\n", str);
1201 	  g_free (str);
1202 	}
1203 
1204       list = input->comments;
1205       while (list)
1206 	{
1207 	  lang_input = list->data;
1208 
1209 	  fprintf (fl, "    <rdfs:comment");
1210 
1211 	  if (lang_input->lang)
1212 	    {
1213 	      str = markup (lang_input->lang);
1214 	      fprintf (fl, " xml:lang=\"%s\"", str);
1215 	      g_free (str);
1216 	    }
1217 
1218 	  str = markup (lang_input->value);
1219 	  fprintf (fl, ">%s</rdfs:comment>\n", str);
1220 	  g_free (str);
1221 
1222 	  list = list->next;
1223 	}
1224 
1225       fprintf (fl, "  </rdf:Description>\n\n");
1226 
1227       i++;
1228       ll = ll->next;
1229     }
1230 }
1231 
1232 static void
template_save_close(FILE * fl)1233 template_save_close (FILE * fl)
1234 {
1235   fprintf (fl, "</rdf:RDF>\n\n");
1236 }
1237 
1238 /* Questa funzione salva i template dentro ad un file: */
1239 void
template_save(void)1240 template_save (void)
1241 {
1242   gchar *path;
1243   FILE *fl;
1244   GList *list;
1245   gint t_id;
1246 
1247   path =
1248     g_build_path (G_DIR_SEPARATOR_S, g_get_user_config_dir (), PACKAGE,
1249 		  "template.rdf", NULL);
1250 
1251   if (!template_list)
1252     {
1253       if (g_file_test (path, G_FILE_TEST_EXISTS) == TRUE && g_remove (path))
1254 	dialog_msg (_("Error saving the template file!"));
1255       g_free (path);
1256       return;
1257     }
1258 
1259   if (!(fl = g_fopen (path, "wb")))
1260     {
1261       dialog_msg (_("Error saving the template file!"));
1262       g_free (path);
1263       return;
1264     }
1265 
1266   g_free (path);
1267 
1268   t_id = 0;
1269   template_save_init (fl);
1270 
1271   /* Per ogni template scrivo: */
1272   for (list = template_list; list; list = list->next)
1273     {
1274       template_save_one (fl, list->data, t_id);
1275       t_id++;
1276     }
1277 
1278   template_save_close (fl);
1279   fclose (fl);
1280 }
1281 
1282 /* Questa funzione salva un template dentro ad un file: */
1283 void
template_save_single(GtkWidget * w,struct template_t * template)1284 template_save_single (GtkWidget * w, struct template_t *template)
1285 {
1286   gchar *path;
1287   FILE *fl;
1288 
1289   editor_statusbar_lock = LOCK;
1290   statusbar_set (_("Export a template..."));
1291 
1292   /* Richiedo un file: */
1293   if (!
1294       (path =
1295        file_chooser (_("Export a template..."), GTK_SELECTION_SINGLE,
1296 		     GTK_FILE_CHOOSER_ACTION_SAVE, NULL)))
1297     {
1298       statusbar_set (_("Export a template: aborted"));
1299       editor_statusbar_lock = WAIT;
1300       return;
1301     }
1302 
1303   if (!(fl = g_fopen (path, "wb")))
1304     {
1305       dialog_msg (_("Error saving the template into a file!"));
1306       statusbar_set (_("Export a template: error."));
1307       editor_statusbar_lock = WAIT;
1308       g_free (path);
1309       return;
1310     }
1311 
1312   g_free (path);
1313 
1314   template_save_init (fl);
1315   template_save_one (fl, template, 0);
1316   template_save_close (fl);
1317   fclose (fl);
1318 
1319   statusbar_set (_("Export a template: done."));
1320   editor_statusbar_lock = WAIT;
1321 }
1322 
1323 /* DISTRUZIONE ***************************************************************/
1324 
1325 /* Questa funzione libera la memoria di un input */
1326 static void
template_input_free(struct template_input_t * i)1327 template_input_free (struct template_input_t *i)
1328 {
1329   if (!i)
1330     return;
1331 
1332   if (i->labels)
1333     {
1334       g_list_foreach (i->labels, (GFunc) info_box_free, NULL);
1335       g_list_free (i->labels);
1336     }
1337 
1338   if (i->rdfs)
1339     g_free (i->rdfs);
1340 
1341   if (i->alt_typevalue)
1342     {
1343       g_list_foreach (i->alt_typevalue, (GFunc) g_free, NULL);
1344       g_list_free (i->alt_typevalue);
1345     }
1346 
1347   if (i->other_typevalue)
1348     g_free (i->other_typevalue);
1349 
1350   if (i->comments)
1351     {
1352       g_list_foreach (i->comments, (GFunc) info_box_free, NULL);
1353       g_list_free (i->comments);
1354     }
1355 
1356   if (i->default_value)
1357     g_free (i->default_value);
1358 
1359   if (i->default_language)
1360     g_free (i->default_language);
1361 
1362   if (i->default_datatype)
1363     g_free (i->default_datatype);
1364 
1365   if (i->function_init)
1366     g_free (i->function_init);
1367 
1368   if (i->function_check)
1369     g_free (i->function_check);
1370 
1371   if (i->function_destroy)
1372     g_free (i->function_destroy);
1373 
1374   if (i->function_save)
1375     g_free (i->function_save);
1376 
1377   g_free (i);
1378 }
1379 
1380 /* Questa funzione libera la memoria di un template: */
1381 static void
template_free(struct template_t * t)1382 template_free (struct template_t *t)
1383 {
1384   if (!t)
1385     return;
1386 
1387   if (t->uri)
1388     g_free (t->uri);
1389 
1390   if (t->name)
1391     g_free (t->name);
1392 
1393   if (t->version)
1394     g_free (t->version);
1395 
1396   if (t->category)
1397     g_free (t->category);
1398 
1399   if (t->input)
1400     {
1401       g_list_foreach (t->input, (GFunc) template_input_free, NULL);
1402       g_list_free (t->input);
1403     }
1404 
1405   g_free (t);
1406 }
1407 
1408 /* FINESTRA DEI TEMPLATE *****************************************************/
1409 
1410 /* Questa funzione mostra i template importati in una interfaccia a lista: */
1411 void
template(GtkWidget * w,gpointer dummy)1412 template (GtkWidget * w, gpointer dummy)
1413 {
1414   GtkWidget *window, *hbox, *scrolledwindow, *treeview, *button, *frame;
1415   GtkListStore *model;
1416   GtkTreeViewColumn *column;
1417   GtkCellRenderer *renderer;
1418   GtkTreeSelection *selection;
1419   gchar s[1024];
1420   gint ret;
1421 
1422   g_snprintf (s, sizeof (s), "%s %s - %s", PACKAGE, VERSION,
1423 	      _("Templates import"));
1424 
1425   window = gtk_dialog_new ();
1426   gtk_window_set_title (GTK_WINDOW (window), s);
1427   gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DIALOG);
1428   gtk_window_set_modal (GTK_WINDOW (window), TRUE);
1429   gtk_window_set_transient_for (GTK_WINDOW (window), main_window ());
1430   gtk_widget_set_size_request (window, 400, 200);
1431 
1432   hbox = gtk_hbox_new (FALSE, 0);
1433   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox, TRUE, TRUE,
1434 		      0);
1435 
1436   frame = gtk_frame_new (_("Templates import"));
1437   gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1438 
1439   scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
1440   gtk_container_add (GTK_CONTAINER (frame), scrolledwindow);
1441   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
1442 				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1443   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
1444 				       GTK_SHADOW_IN);
1445 
1446   model =
1447     gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
1448 			G_TYPE_STRING);
1449 
1450   treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
1451   gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), TRUE);
1452   gtk_container_add (GTK_CONTAINER (scrolledwindow), treeview);
1453   g_signal_connect ((gpointer) treeview, "row_activated",
1454 		    G_CALLBACK (template_activate), window);
1455 
1456   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
1457   gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
1458 
1459   gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
1460 
1461   renderer = gtk_cell_renderer_text_new ();
1462   column =
1463     gtk_tree_view_column_new_with_attributes (_("Template"), renderer, "text",
1464 					      0, NULL);
1465   gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
1466   gtk_tree_view_column_set_resizable (column, TRUE);
1467 
1468   renderer = gtk_cell_renderer_text_new ();
1469   column =
1470     gtk_tree_view_column_new_with_attributes (_("Version"), renderer, "text",
1471 					      1, NULL);
1472   gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
1473   gtk_tree_view_column_set_resizable (column, TRUE);
1474 
1475   renderer = gtk_cell_renderer_text_new ();
1476   column =
1477     gtk_tree_view_column_new_with_attributes (_("Category"), renderer, "text",
1478 					      2, NULL);
1479   gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
1480   gtk_tree_view_column_set_resizable (column, TRUE);
1481 
1482   renderer = gtk_cell_renderer_text_new ();
1483   column =
1484     gtk_tree_view_column_new_with_attributes (_("URI"), renderer, "text",
1485 					      3, NULL);
1486   gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
1487   gtk_tree_view_column_set_resizable (column, TRUE);
1488 
1489   button = gtk_button_new_from_stock ("gtk-add");
1490   gtk_dialog_add_action_widget (GTK_DIALOG (window), button, GTK_RESPONSE_OK);
1491   gtk_widget_set_can_default(button, TRUE);
1492 
1493   button = gtk_button_new_from_stock ("gtk-remove");
1494   gtk_dialog_add_action_widget (GTK_DIALOG (window), button,
1495 				GTK_RESPONSE_CANCEL);
1496   gtk_widget_set_can_default(button, TRUE);
1497 
1498   button = gtk_button_new_from_stock ("gtk-close");
1499   gtk_dialog_add_action_widget (GTK_DIALOG (window), button, GTK_RESPONSE_NO);
1500   gtk_widget_set_can_default(button, TRUE);
1501 
1502   /* Refresh della finestra: */
1503   template_refresh (treeview);
1504   gtk_widget_show_all (window);
1505 
1506   g_object_unref (model);
1507 
1508   while (1)
1509     {
1510       ret = gtk_dialog_run (GTK_DIALOG (window));
1511 
1512       if (ret == GTK_RESPONSE_OK)
1513 	{
1514 	  if (!gtk_tree_selection_count_selected_rows (selection))
1515 	    {
1516 	      dialog_msg (_("Select a template!"));
1517 	      continue;
1518 	    }
1519 
1520 	  template_open_dialog (treeview);
1521 	  gtk_widget_hide (window);
1522 	  break;
1523 	}
1524 
1525       else if (ret == GTK_RESPONSE_CANCEL)
1526 	{
1527 	  if (!gtk_tree_selection_count_selected_rows (selection))
1528 	    {
1529 	      dialog_msg (_("Select a template!"));
1530 	      continue;
1531 	    }
1532 
1533 	  if (dialog_ask (_("Sure to remove this template?")) ==
1534 	      GTK_RESPONSE_OK && template_remove (treeview))
1535 	    {
1536 	      template_update ();
1537 	      template_save ();
1538 	      template_refresh (treeview);
1539 	    }
1540 	}
1541 
1542       else
1543 	break;
1544     }
1545 
1546   gtk_widget_destroy (window);
1547 }
1548 
1549 /* Questa funzione refreshia l'intefaccia di sopra: */
1550 static void
template_refresh(GtkWidget * treeview)1551 template_refresh (GtkWidget * treeview)
1552 {
1553   GtkListStore *store;
1554   GtkTreeIter iter;
1555   GList *list;
1556   struct template_t *template;
1557 
1558   /* Rimuovo tutto: */
1559   store = (GtkListStore *) gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
1560   while (gtk_tree_model_iter_nth_child
1561 	 (GTK_TREE_MODEL (store), &iter, NULL, 0))
1562     gtk_list_store_remove (store, &iter);
1563 
1564   /* Appendo: */
1565   list = template_list;
1566   while (list)
1567     {
1568       template = (struct template_t *) list->data;
1569 
1570       gtk_list_store_append (store, &iter);
1571       gtk_list_store_set (store, &iter, 0, template->name, 1,
1572 			  template->version, 2, template->category, 3,
1573 			  template->uri, -1);
1574 
1575       list = list->next;
1576     }
1577 }
1578 
1579 /* Questa funzione rimuove gli input selezionati: */
1580 static gint
template_remove(GtkWidget * treeview)1581 template_remove (GtkWidget * treeview)
1582 {
1583   GtkTreeIter iter;
1584   GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
1585   GtkTreeSelection *selection =
1586     gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
1587 
1588   if (gtk_tree_selection_get_selected (selection, NULL, &iter))
1589     {
1590       gint i;
1591       GtkTreePath *path;
1592       GList *list = template_list;
1593 
1594       path = gtk_tree_model_get_path (model, &iter);
1595       i = gtk_tree_path_get_indices (path)[0];
1596 
1597       while (list)
1598 	{
1599 	  if (!i)
1600 	    {
1601 	      template_free (list->data);
1602 	      template_list = g_list_remove (template_list, list->data);
1603 	      break;
1604 	    }
1605 	  i--;
1606 	  list = list->next;
1607 	}
1608 
1609       gtk_tree_path_free (path);
1610       return 1;
1611     }
1612 
1613   return 0;
1614 }
1615 
1616 /* Questa funzione attiva l'uso di un template selezionato nell'interfaccia: */
1617 static void
template_open_dialog(GtkWidget * treeview)1618 template_open_dialog (GtkWidget * treeview)
1619 {
1620   GtkTreeIter iter;
1621   GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
1622   GtkTreeSelection *selection =
1623     gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
1624 
1625   if (gtk_tree_selection_get_selected (selection, NULL, &iter))
1626     {
1627       gint i;
1628       GtkTreePath *path;
1629       GList *list = template_list;
1630 
1631       path = gtk_tree_model_get_path (model, &iter);
1632       i = gtk_tree_path_get_indices (path)[0];
1633 
1634       /* Uso la funzione template_open: */
1635       if ((list = g_list_nth (template_list, i)))
1636 	template_open (NULL, list->data);
1637 
1638       gtk_tree_path_free (path);
1639     }
1640 }
1641 
1642 /* Questa funzione simula il click del pulsante alla selezione di una riga
1643  * dell'interfaccia: */
1644 static void
template_activate(GtkWidget * w,GtkTreePath * p,GtkTreeViewColumn * c,GtkWidget * dialog)1645 template_activate (GtkWidget * w, GtkTreePath * p, GtkTreeViewColumn * c,
1646 		   GtkWidget * dialog)
1647 {
1648   gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
1649 }
1650 
1651 /* REMOTE TEMPLATE ***********************************************************/
1652 
1653 static GList *template_remote_list = NULL;
1654 
1655 /* Questa funzione distrugge la lista dei template remoti gia' richiesti: */
1656 static void
template_remote_init(void)1657 template_remote_init (void)
1658 {
1659   if (template_remote_list)
1660     {
1661       g_list_free (template_remote_list);
1662       template_remote_list = NULL;
1663     }
1664 }
1665 
1666 /* Questa funzione controlla se ci sono elementi gia' richiamati: */
1667 static void
template_remote_parse(GList ** remote)1668 template_remote_parse (GList ** remote)
1669 {
1670   GList *l = template_remote_list;
1671 
1672   while (l)
1673     {
1674       GList *list = *remote;
1675 
1676       while (list)
1677 	{
1678 	  if (!strcmp (list->data, l->data))
1679 	    {
1680 	      *remote = g_list_remove (*remote, l->data);
1681 	      break;
1682 	    }
1683 
1684 	  list = list->next;
1685 	}
1686 
1687       l = l->next;
1688     }
1689 }
1690 
1691 /* Questa funzione aggiunge tutti quei templete che si e' richiesto di
1692  * aggiungere: */
1693 static void
template_remote_add(GList * add)1694 template_remote_add (GList * add)
1695 {
1696   while (add)
1697     {
1698       template_remote_list = g_list_append (template_remote_list, add->data);
1699       add = add->next;
1700     }
1701 }
1702 
1703 /* Questa funzione mostra la finestra per richeidere l'import di template remotati */
1704 static gint
template_dialog_remote(GList * remote)1705 template_dialog_remote (GList * remote)
1706 {
1707   GString *str;
1708   GList *list;
1709   gchar *buf;
1710   gint ret;
1711 
1712   template_remote_add (remote);
1713 
1714   str =
1715     g_string_new (_
1716 		  ("This template requires other templates. Do you want import them?\n"));
1717 
1718   for (list = remote; list; list = list->next)
1719     g_string_append_printf (str, "%s\n", (gchar *) list->data);
1720 
1721   buf = g_string_free (str, FALSE);
1722   ret = dialog_ask_with_cancel (buf);
1723   g_free (buf);
1724 
1725   return ret;
1726 }
1727 
1728 /* CREATE TEMPLATE ***********************************************************/
1729 
1730 /* Questa funzione crea l'interfaccia per l'uso di un template: */
1731 static GtkWidget *
template_open_real(GList * resources,GList * blanks,struct template_t * t)1732 template_open_real (GList * resources, GList * blanks, struct template_t *t)
1733 {
1734   GList *list;
1735   GList *remote;
1736   GList *real;
1737   GtkWidget *box;
1738   GtkWidget *widget;
1739   gint i;
1740 
1741 #ifdef USE_JS
1742   struct js_t *js;
1743 #endif
1744 
1745   /* Controllo se qualche input richiede template remotati: */
1746   list = t->input;
1747   remote = NULL;
1748   while (list)
1749     {
1750       struct template_input_t *input = list->data;
1751 
1752       if (input->other_typevalue)
1753 	remote = g_list_append (remote, input->other_typevalue);
1754 
1755       list = list->next;
1756     }
1757 
1758   if (remote)
1759     {
1760       GList *l;
1761 
1762       /* Rimuovo eventuali duplicati: */
1763       remote = create_no_dup (remote);
1764 
1765       /* Rimuovo quelli che ho gia': */
1766       list = template_list;
1767       while (list)
1768 	{
1769 	  struct template_t *t = list->data;
1770 
1771 	  l = remote;
1772 	  while (l)
1773 	    {
1774 	      if (!strcmp (t->uri, l->data))
1775 		{
1776 		  remote = g_list_remove (remote, l->data);
1777 		  break;
1778 		}
1779 
1780 	      l = l->next;
1781 	    }
1782 
1783 	  list = list->next;
1784 	}
1785     }
1786 
1787   /* Controllo se li ho gia' chiesti: */
1788   if (remote)
1789     template_remote_parse (&remote);
1790 
1791   if (remote)
1792     {
1793       /* Rimuovo eventuali duplicati: */
1794       remote = create_no_dup (remote);
1795 
1796       switch (template_dialog_remote (remote))
1797 	{
1798 	  /* Importare i template remotati: */
1799 	case GTK_RESPONSE_OK:
1800 	  for (list = remote; list; list = list->next)
1801 	    template_import ((gchar *) list->data, NULL, TRUE, TRUE);
1802 
1803 	  template_update ();
1804 	  template_save ();
1805 	  break;
1806 
1807 	  /* Continuo: */
1808 	case GTK_RESPONSE_NO:
1809 	  break;
1810 
1811 	  /* Esco: */
1812 	default:
1813 	  g_list_free (remote);
1814 	  return NULL;
1815 	}
1816 
1817       g_list_free (remote);
1818     }
1819 
1820 #ifdef USE_JS
1821   /* JS Context: */
1822   js = js_new ();
1823 #endif
1824 
1825   box = gtk_table_new (0, 0, FALSE);
1826 
1827   /* Tolgo tra tutti gli input quelli non visibili: */
1828   list = t->input;
1829   real = NULL;
1830   while (list)
1831     {
1832       if (((struct template_input_t *) list->data)->visible)
1833 	real = g_list_append (real, list->data);
1834 
1835       list = list->next;
1836     }
1837 
1838   /* Per ogni input visibile creo l'oggetto grafico: */
1839   list = real;
1840   i = 0;
1841 
1842   while (list)
1843     {
1844       widget =
1845 	template_widget_create (resources, blanks,
1846 				(struct template_input_t *) list->data, TRUE
1847 #ifdef USE_JS
1848 				, js
1849 #endif
1850 	);
1851       gtk_table_attach (GTK_TABLE (box), widget, 0, 1, i, i + 1,
1852 			GTK_EXPAND | GTK_FILL, GTK_EXPAND, 3, 3);
1853 
1854       /* 2 per riga: */
1855       if (list->next)
1856 	{
1857 	  list = list->next;
1858 
1859 	  widget =
1860 	    template_widget_create (resources, blanks,
1861 				    (struct template_input_t *) list->data,
1862 				    TRUE
1863 #ifdef USE_JS
1864 				    , js
1865 #endif
1866 	    );
1867 	  gtk_table_attach (GTK_TABLE (box), widget, 1, 2, i, i + 1,
1868 			    GTK_EXPAND | GTK_FILL, GTK_EXPAND, 3, 3);
1869 	}
1870 
1871       i++;
1872       list = list->next;
1873     }
1874 
1875 #ifdef USE_JS
1876   g_object_set_data (G_OBJECT (box), "js", js);
1877   g_signal_connect ((gpointer) box, "destroy", G_CALLBACK (template_destroy),
1878 		    NULL);
1879 #endif
1880 
1881   /* Libero memoria: */
1882   g_list_free (real);
1883   return box;
1884 }
1885 
1886 /* Questa funzione crea l'interfaccia per l'uso di un template: */
1887 void
template_open(GtkWidget * w,struct template_t * t)1888 template_open (GtkWidget * w, struct template_t *t)
1889 {
1890   GtkWidget *dialog;
1891   GtkWidget *vbox, *hbox, *gbox;
1892   GtkWidget *image;
1893   GtkWidget *frame;
1894   GtkWidget *button;
1895   GtkWidget *label;
1896   GtkWidget *subject;
1897   GtkWidget *sw;
1898   GtkWidget *button_subject;
1899   GtkWidget *button_subject_this;
1900   GtkWidget *widget_inputs;
1901   GList *list;
1902   GList *resources;
1903   GList *blanks;
1904   GSList *l;
1905   struct editor_data_t *data = editor_get_data ();
1906   gchar s[1024];
1907 
1908   if (!data)
1909     return;
1910 
1911   /* Annullo i template remotati richiesti precedentemente: */
1912   template_remote_init ();
1913 
1914   resources = create_resources (data);
1915   resources = create_resources_by_rdfs (resources);
1916   blanks = create_blank (data);
1917 
1918   if (!(widget_inputs = template_open_real (resources, blanks, t)))
1919     {
1920       g_list_free (resources);
1921       g_list_free (blanks);
1922       return;
1923     }
1924 
1925   dialog = gtk_dialog_new ();
1926 
1927   g_snprintf (s, sizeof (s), "%s %s - %s: %s %s", PACKAGE, VERSION,
1928 	      _("Template"), t->name, t->version);
1929   gtk_window_set_title (GTK_WINDOW (dialog), s);
1930 
1931   gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
1932   gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
1933   gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
1934   gtk_window_set_transient_for (GTK_WINDOW (dialog), main_window ());
1935   gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
1936 
1937   label = gtk_label_new (_("<b>Subject</b>"));
1938   gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
1939 
1940   frame = gtk_frame_new (NULL);
1941   gtk_frame_set_label_widget (GTK_FRAME (frame), label);
1942   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, FALSE,
1943 		      FALSE, 5);
1944 
1945   vbox = gtk_vbox_new (FALSE, 3);
1946   gtk_container_add (GTK_CONTAINER (frame), vbox);
1947 
1948   gbox = gtk_hbox_new (FALSE, 0);
1949   gtk_box_pack_start (GTK_BOX (vbox), gbox, FALSE, FALSE, 0);
1950 
1951   l = NULL;
1952   button = gtk_radio_button_new_with_label (NULL, _("Resource: "));
1953   button_subject = button;
1954   gtk_radio_button_set_group (GTK_RADIO_BUTTON (button), l);
1955   l = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
1956   gtk_box_pack_start (GTK_BOX (gbox), button, FALSE, FALSE, 3);
1957 
1958   hbox = gtk_hbox_new (FALSE, 0);
1959   gtk_box_pack_start (GTK_BOX (gbox), hbox, TRUE, TRUE, 5);
1960 
1961   /* Creazione soggetto con freccia: */
1962   subject = gtk_entry_new ();
1963   gtk_box_pack_start (GTK_BOX (hbox), subject, TRUE, TRUE, 0);
1964 
1965   button = gtk_button_new ();
1966   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1967   g_object_set_data (G_OBJECT (button), "list", resources);
1968   g_signal_connect ((gpointer) button, "clicked",
1969 		    G_CALLBACK (search_resources), subject);
1970 
1971   image = gtk_image_new_from_stock ("gtk-find", GTK_ICON_SIZE_MENU);
1972   gtk_container_add (GTK_CONTAINER (button), image);
1973 
1974   gbox = gtk_hbox_new (FALSE, 0);
1975   gtk_box_pack_start (GTK_BOX (vbox), gbox, FALSE, FALSE, 0);
1976 
1977   button = gtk_radio_button_new_with_label (NULL, _("This document"));
1978   button_subject_this = button;
1979   gtk_radio_button_set_group (GTK_RADIO_BUTTON (button), l);
1980   l = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
1981   gtk_box_pack_start (GTK_BOX (gbox), button, TRUE, TRUE, 3);
1982 
1983   sw = gtk_scrolled_window_new (NULL, NULL);
1984   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
1985 				       GTK_SHADOW_ETCHED_IN);
1986   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
1987 				  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1988 
1989   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), sw, TRUE, TRUE, 5);
1990 
1991   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw),
1992 					 widget_inputs);
1993 
1994   button = gtk_button_new_from_stock ("gtk-no");
1995   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button,
1996 				GTK_RESPONSE_CLOSE);
1997 
1998   gtk_widget_set_can_default(button, TRUE);
1999 
2000   button = gtk_button_new_from_stock ("gtk-ok");
2001   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK);
2002 
2003   gtk_widget_set_can_default(button, TRUE);
2004 
2005   template_set_size (dialog, sw, widget_inputs);
2006   gtk_widget_show_all (dialog);
2007 
2008   while (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
2009     {
2010       GList *old;
2011       gchar *text;
2012       struct unredo_t *unredo;
2013 
2014       /* Check del soggetto: */
2015       if (gtk_toggle_button_get_active
2016 	  (GTK_TOGGLE_BUTTON (button_subject_this)) == TRUE)
2017 	text = THIS_DOCUMENT;
2018       else
2019 	text = (gchar *) gtk_entry_get_text (GTK_ENTRY (subject));
2020 
2021       if (!text || !*text)
2022 	{
2023 	  dialog_msg (_("Invalid subject!"));
2024 	  continue;
2025 	}
2026 
2027       text = g_strdup (text);
2028 
2029       /* Controllo TUTTI i widget di input: */
2030       list = old = gtk_container_get_children (GTK_CONTAINER (widget_inputs));
2031 
2032       while (list)
2033 	{
2034 	  if (template_widget_check (list->data))
2035 	    break;
2036 
2037 	  list = list->next;
2038 	}
2039 
2040       /* Si lamenta la funzione widget_check, quindi io devo solo
2041        * continuare: */
2042       if (list)
2043 	{
2044 	  g_free (text);
2045 	  g_list_free (old);
2046 	  continue;
2047 	}
2048 
2049       /* A questo punto inserisco, quindi undo: */
2050       unredo = unredo_new (data, UNREDO_TYPE_ADD);
2051 
2052       list = old;
2053       while (list)
2054 	{
2055 	  /* Funzione che fa l'inserimento: */
2056 	  template_widget_save (list->data, data, text, unredo);
2057 	  list = list->next;
2058 	}
2059 
2060       g_list_foreach (old, (GFunc) template_widget_destroy, NULL);
2061       g_list_free (old);
2062 
2063       /* Poi tutti gli oggetti invisibili: */
2064       list = t->input;
2065       while (list)
2066 	{
2067 	  if (!((struct template_input_t *) list->data)->visible)
2068 	    template_invisible_save (text, list->data, data, unredo, NULL);
2069 
2070 	  list = list->next;
2071 	}
2072 
2073       g_free (text);
2074       data->changed = TRUE;
2075 
2076       /* Refreshio i namespace e li rigenero */
2077       g_list_foreach (data->namespace, (GFunc) namespace_free, NULL);
2078       g_list_free (data->namespace);
2079 
2080       namespace_parse (data->rdf, &data->namespace);
2081 
2082       editor_refresh (data);
2083       break;
2084     }
2085 
2086   /* Libero memoria: */
2087   g_list_free (resources);
2088   g_list_free (blanks);
2089 
2090   gtk_widget_destroy (dialog);
2091 }
2092 
2093 /* Setto la dimensione della finestra di template */
2094 static void
template_set_size(GtkWidget * dialog,GtkWidget * sw,GtkWidget * w)2095 template_set_size (GtkWidget * dialog, GtkWidget * sw, GtkWidget * w)
2096 {
2097   gint h;
2098 
2099   /* Chiedo alle gtk di realizzare l'oggetto: */
2100   gtk_widget_show_all (dialog);
2101 
2102   if (w->allocation.height > 1
2103       && w->allocation.height <= gdk_screen_height () * 2 / 3)
2104     h = w->allocation.height + 200;
2105   else
2106     h = gdk_screen_height () * 2 / 3;
2107 
2108   gdk_window_move_resize (dialog->window,
2109 			  gdk_screen_width () / 2 -
2110 			  dialog->allocation.width / 2,
2111 			  gdk_screen_height () / 2 - h / 2,
2112 			  dialog->allocation.width, h);
2113 }
2114 
2115 /* Questa funzione rimuove un elemento dalla liste multiple di input: */
2116 static void
template_widget_list_remove(GtkWidget * widget,GtkTreeView * treeview)2117 template_widget_list_remove (GtkWidget * widget, GtkTreeView * treeview)
2118 {
2119   GtkTreeIter iter;
2120   GtkTreeModel *model = gtk_tree_view_get_model (treeview);
2121   GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
2122   GtkWidget *add = g_object_get_data (G_OBJECT (widget), "add");
2123 
2124   /* Se c'e' qualcosa selezionato: */
2125   if (gtk_tree_selection_get_selected (selection, NULL, &iter))
2126     {
2127       gint i;
2128       GtkWidget *w;
2129       struct template_input_t *input;
2130 
2131       gtk_tree_model_get (model, &iter, 1, &w, -1);
2132 
2133       if (w)
2134 	{
2135 	  w = gtk_widget_get_toplevel (w);
2136 	  gtk_widget_destroy (w);
2137 	}
2138 
2139       /* Rimuovo l'elemento: */
2140       gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
2141 
2142       /* Guardo quali pulsanti devo disattivare o attivare: */
2143       i = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL);
2144 
2145       input = g_object_get_data (G_OBJECT (widget), "input");
2146       if (input->max_cardinality > 0 && i < input->max_cardinality)
2147 	gtk_widget_set_sensitive (add, TRUE);
2148 
2149       if (!i)
2150 	gtk_widget_set_sensitive (widget, FALSE);
2151     }
2152 }
2153 
2154 /* Questa funzione mostra un elemento gia' presente nella lista a cardinalita': */
2155 static void
template_widget_list_select(GtkWidget * widget,GtkTreePath * path,GtkTreeViewColumn * c,gpointer dummy)2156 template_widget_list_select (GtkWidget * widget, GtkTreePath * path,
2157 			     GtkTreeViewColumn * c, gpointer dummy)
2158 {
2159   GtkTreeSelection *selection =
2160     gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
2161   GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
2162   GtkTreeIter iter;
2163   GtkWidget *dialog;
2164   GtkWidget *entry;
2165   GtkWidget *w;
2166 
2167   if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
2168     {
2169       dialog_msg (_("Select a input!"));
2170       return;
2171     }
2172 
2173   gtk_tree_model_get (model, &iter, 1, &w, -1);
2174 
2175   entry = g_object_get_data (G_OBJECT (w), "entry");
2176 
2177   /* Se e' un pulsante, simulo il click: */
2178   if (GTK_IS_BUTTON (entry))
2179     {
2180       gchar *name;
2181       struct template_t *template =
2182 	g_object_get_data (G_OBJECT (entry), "template");
2183 
2184       template_run (entry, template);
2185 
2186       name = template_widget_name (w);
2187       gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, name, -1);
2188       g_free (name);
2189       return;
2190     }
2191 
2192   template_widget_save_on (w);
2193 
2194   dialog = gtk_widget_get_toplevel (w);
2195 
2196   gtk_widget_show_all (dialog);
2197 
2198   if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
2199     template_widget_save_off (w);
2200   else
2201     template_widget_save_reset (w);
2202 
2203   gtk_widget_hide (dialog);
2204 }
2205 
2206 /* Funzione per gli oggetti in solitaria: */
2207 static GtkWidget *
template_widget_standalone(GtkWidget * w)2208 template_widget_standalone (GtkWidget * w)
2209 {
2210   GtkWidget *dialog, *button;
2211   gchar s[1024];
2212 
2213   dialog = gtk_dialog_new ();
2214 
2215   g_snprintf (s, sizeof (s), "%s %s - %s", PACKAGE, VERSION,
2216 	      _("Single input..."));
2217   gtk_window_set_title (GTK_WINDOW (dialog), s);
2218 
2219   gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
2220   gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
2221   gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
2222   gtk_window_set_transient_for (GTK_WINDOW (dialog),
2223 				GTK_WINDOW (gtk_widget_get_toplevel (w)));
2224   gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
2225 
2226   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), w, TRUE, TRUE, 5);
2227 
2228   button = gtk_button_new_from_stock ("gtk-no");
2229   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button,
2230 				GTK_RESPONSE_CLOSE);
2231 
2232   gtk_widget_set_can_default(button, TRUE);
2233 
2234   button = gtk_button_new_from_stock ("gtk-ok");
2235   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK);
2236 
2237   gtk_widget_set_can_default(button, TRUE);
2238 
2239   return dialog;
2240 }
2241 
2242 /* Questa funzione aggiunge un elemento alla lista degli input multiple: */
2243 static void
template_widget_list_add(GtkWidget * widget,GtkTreeView * treeview)2244 template_widget_list_add (GtkWidget * widget, GtkTreeView * treeview)
2245 {
2246   struct template_input_t *input;
2247   GtkListStore *model;
2248   GtkTreeIter iter;
2249   GtkWidget *del;
2250   GtkWidget *dialog;
2251   GtkWidget *entry;
2252   GtkWidget *w;
2253   GList *resources;
2254   GList *blanks;
2255   gchar *name;
2256   gint ret;
2257 
2258   input = g_object_get_data (G_OBJECT (widget), "input");
2259   resources = g_object_get_data (G_OBJECT (widget), "resources");
2260   blanks = g_object_get_data (G_OBJECT (widget), "blanks");
2261 
2262   w = template_widget_create (resources, blanks, input, FALSE
2263 #ifdef USE_JS
2264 			      , g_object_get_data (G_OBJECT (widget), "js")
2265 #endif
2266     );
2267 
2268   /* Se e' un pulsante attivo direttamente la funzione come se
2269    * fosse stato cliccato: */
2270   entry = g_object_get_data (G_OBJECT (w), "entry");
2271   if (GTK_IS_BUTTON (entry))
2272     {
2273       struct template_t *template =
2274 	g_object_get_data (G_OBJECT (entry), "template");
2275 
2276       /* Se questa funzione ritorna TRUE, inserisco la linea: */
2277       if (template_run (entry, template) == TRUE)
2278 	{
2279 	  model =
2280 	    (GtkListStore *)
2281 	    gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
2282 	  gtk_list_store_append (model, &iter);
2283 
2284 	  name = template_widget_name (w);
2285 	  gtk_list_store_set (model, &iter, 0, name, 1, w, -1);
2286 	  g_free (name);
2287 
2288 	  /* Disattivo o attivo i pulsanti: */
2289 	  if (input->max_cardinality > 0
2290 	      && gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model),
2291 						 NULL) >=
2292 	      input->max_cardinality)
2293 	    gtk_widget_set_sensitive (widget, FALSE);
2294 
2295 	  del = g_object_get_data (G_OBJECT (widget), "del");
2296 	  gtk_widget_set_sensitive (del, TRUE);
2297 	}
2298       return;
2299     }
2300 
2301   dialog = template_widget_standalone (w);
2302   gtk_widget_show_all (dialog);
2303 
2304   while ((ret = gtk_dialog_run (GTK_DIALOG (dialog))) == GTK_RESPONSE_OK)
2305     {
2306       /* Controllo il widget: */
2307       if (template_widget_check (w))
2308 	continue;
2309 
2310       gtk_widget_hide (dialog);
2311 
2312       model =
2313 	(GtkListStore *) gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
2314       gtk_list_store_append (model, &iter);
2315 
2316       name = template_widget_name (w);
2317       gtk_list_store_set (model, &iter, 0, name, 1, w, -1);
2318       g_free (name);
2319 
2320       /* Disattivo o attivo i pulsanti: */
2321       if (input->max_cardinality > 0
2322 	  && gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model),
2323 					     NULL) >= input->max_cardinality)
2324 	gtk_widget_set_sensitive (widget, FALSE);
2325 
2326       del = g_object_get_data (G_OBJECT (widget), "del");
2327       gtk_widget_set_sensitive (del, TRUE);
2328       break;
2329     }
2330 
2331   if (ret != GTK_RESPONSE_OK)
2332     gtk_widget_destroy (dialog);
2333 }
2334 
2335 /* Questa funzione ritorna il primo blank node libero nella numerazione
2336  * blanknode_name %d: */
2337 static gchar *
template_widget_blank(struct editor_data_t * data)2338 template_widget_blank (struct editor_data_t *data)
2339 {
2340   GList *list;
2341   gint id = -1;
2342   gint max = -1;
2343 
2344   list = data->rdf;
2345   while (list)
2346     {
2347       struct rdf_t *rdf = list->data;
2348 
2349       if (blanknode_get (rdf->subject, &id) == TRUE && id > max)
2350 	max = id;
2351 
2352       if (blanknode_get (rdf->object, &id) == TRUE && id > max)
2353 	max = id;
2354 
2355       list = list->next;
2356     }
2357 
2358   return blanknode_create (max + 1);
2359 }
2360 
2361 /* TEMPLATE DESTROY ********************************************************/
2362 
2363 #ifdef USE_JS
2364 static gboolean
template_destroy(GtkWidget * widget,GdkEvent * event,gpointer user_data)2365 template_destroy (GtkWidget * widget, GdkEvent * event, gpointer user_data)
2366 {
2367   struct js_t *js = g_object_get_data (G_OBJECT (widget), "js");
2368 
2369   if (js)
2370     {
2371       g_object_steal_data (G_OBJECT (widget), "js");
2372       js_destroy (js);
2373     }
2374 
2375   return FALSE;
2376 }
2377 #endif
2378 
2379 /* TEMPLATE NAME WIDGETS ****************************************************/
2380 static gchar *
template_widget_name_literal(GtkWidget * widget,gchar * name)2381 template_widget_name_literal (GtkWidget * widget, gchar * name)
2382 {
2383   GtkWidget *entry = g_object_get_data (G_OBJECT (widget), "entry");
2384 
2385   if (GTK_IS_ENTRY (entry))
2386     return g_strdup_printf ("%s: %s", name,
2387 			    gtk_entry_get_text (GTK_ENTRY (entry)));
2388   else
2389     {
2390       GtkTextIter start, end;
2391       gchar *tmp, *ret;
2392       gint i;
2393 
2394       gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (entry), &start);
2395       gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (entry), &end);
2396 
2397       tmp =
2398 	gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (entry), &start, &end,
2399 				   FALSE);
2400 
2401       for (i = 0; tmp[i] && i < 15; i++)
2402 	if (tmp[i] == '\n')
2403 	  break;
2404 
2405       if (!tmp[i])
2406 	ret = g_strdup_printf ("%s: %s", name, tmp);
2407       else
2408 	{
2409 	  tmp[i] = 0;
2410 	  ret = g_strdup_printf ("%s: %s...", name, tmp);
2411 	}
2412 
2413       g_free (tmp);
2414 
2415       return ret;
2416     }
2417 }
2418 
2419 static gchar *
template_widget_name_resource(GtkWidget * widget,gchar * name)2420 template_widget_name_resource (GtkWidget * widget, gchar * name)
2421 {
2422   return template_widget_name_literal (widget, name);
2423 }
2424 
2425 static gchar *
template_widget_name_alt_literal(GtkWidget * widget,gchar * name)2426 template_widget_name_alt_literal (GtkWidget * widget, gchar * name)
2427 {
2428   GtkWidget *entry = g_object_get_data (G_OBJECT (widget), "entry");
2429   gchar *text = gtk_combo_box_get_active_text (GTK_COMBO_BOX (entry));
2430 
2431   gchar *ret = g_strdup_printf ("%s: %s", name, text);
2432   g_free (text);
2433 
2434   return ret;
2435 }
2436 
2437 static gchar *
template_widget_name_alt_resource(GtkWidget * widget,gchar * name)2438 template_widget_name_alt_resource (GtkWidget * widget, gchar * name)
2439 {
2440   GtkWidget *entry = g_object_get_data (G_OBJECT (widget), "entry");
2441   gchar *text = gtk_combo_box_get_active_text (GTK_COMBO_BOX (entry));
2442 
2443   gchar *ret = g_strdup_printf ("%s: %s", name, text);
2444   g_free (text);
2445 
2446   return ret;
2447 }
2448 
2449 static gchar *
template_widget_name_other(GtkWidget * widget,gchar * name)2450 template_widget_name_other (GtkWidget * widget, gchar * name)
2451 {
2452   GtkWidget *entry = g_object_get_data (G_OBJECT (widget), "entry");
2453 
2454   if (GTK_IS_ENTRY (entry))
2455     return g_strdup_printf ("%s: %s", name,
2456 			    gtk_entry_get_text (GTK_ENTRY (entry)));
2457   else
2458     {
2459       GString *str;
2460 
2461       GtkWidget *type =
2462 	g_object_get_data (G_OBJECT (entry), "type_resource_input");
2463       GtkWidget *object =
2464 	g_object_get_data (G_OBJECT (entry), "subject_input");
2465       GtkWidget *toggle =
2466 	g_object_get_data (G_OBJECT (entry), "toggle_input");
2467 
2468       str = g_string_new (name);
2469 
2470       g_string_append_printf (str, ": %s",
2471 			      gtk_entry_get_text (GTK_ENTRY (object)));
2472 
2473       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type)))
2474 	g_string_append_printf (str, " (%s", _("Resource"));
2475       else
2476 	g_string_append_printf (str, " (%s", _("Blanknode"));
2477 
2478       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)))
2479 	g_string_append_printf (str, _(" with template)"));
2480       else
2481 	g_string_append_printf (str, _(" without template)"));
2482 
2483       return g_string_free (str, FALSE);
2484     }
2485 }
2486 
2487 static gchar *
template_widget_name_default(GtkWidget * widget,gchar * name)2488 template_widget_name_default (GtkWidget * widget, gchar * name)
2489 {
2490   GtkWidget *entry = g_object_get_data (G_OBJECT (widget), "entry");
2491   GtkWidget *type;
2492 
2493   type = g_object_get_data (G_OBJECT (widget), "type_literal");
2494   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type)) == TRUE)
2495     return g_strdup_printf (_("%s: (L) %s"), name,
2496 			    gtk_entry_get_text (GTK_ENTRY (entry)));
2497 
2498   type = g_object_get_data (G_OBJECT (widget), "type_resource");
2499   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type)) == TRUE)
2500     return g_strdup_printf (_("%s: (R) %s"), name,
2501 			    gtk_entry_get_text (GTK_ENTRY (entry)));
2502 
2503   type = g_object_get_data (G_OBJECT (widget), "type_blanknode");
2504   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type)) == TRUE)
2505     return g_strdup_printf (_("%s: (B) %s"), name,
2506 			    gtk_entry_get_text (GTK_ENTRY (entry)));
2507 
2508   return g_strdup_printf ("%s: %s", name,
2509 			  gtk_entry_get_text (GTK_ENTRY (entry)));
2510 }
2511 
2512 static gchar *
template_widget_name(GtkWidget * widget)2513 template_widget_name (GtkWidget * widget)
2514 {
2515   struct template_func_t *func;
2516   gchar *label;
2517 
2518   label = (gchar *) g_object_get_data (G_OBJECT (widget), "label");
2519 
2520   func = g_object_get_data (G_OBJECT (widget), "func");
2521 
2522   if (func && func->name)
2523     return func->name (widget, label);
2524 
2525   return g_strdup ("empty");
2526 }
2527 
2528 /* TEMPLATE LOW CHECK WIDGETS ***********************************************/
2529 static gboolean
template_widget_low_check_literal(GtkWidget * widget,gchar * label,gint min_cardinality)2530 template_widget_low_check_literal (GtkWidget * widget, gchar * label,
2531 				   gint min_cardinality)
2532 {
2533   GtkWidget *entry;
2534   gchar *text;
2535   gboolean allocated = FALSE;
2536 
2537   entry = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "entry");
2538 
2539   if (GTK_IS_ENTRY (entry))
2540     {
2541       text = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
2542 
2543       if (!text || !*text)
2544 	return 0;
2545     }
2546   else
2547     {
2548       GtkTextIter start, end;
2549 
2550       gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (entry), &start);
2551       gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (entry), &end);
2552 
2553       text =
2554 	gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (entry), &start, &end,
2555 				   FALSE);
2556       allocated = TRUE;
2557     }
2558 
2559   if ((entry = g_object_get_data (G_OBJECT (widget), "datatype")))
2560     {
2561       gchar s[1024];
2562       g_snprintf (s, sizeof (s), _("No compatible value for input %s"),
2563 		  label);
2564 
2565       if (datatype_check
2566 	  (gtk_combo_box_get_active (GTK_COMBO_BOX (entry)), text,
2567 	   s) == FALSE)
2568 	{
2569 	  if (allocated == TRUE)
2570 	    g_free (text);
2571 	  return 1;
2572 	}
2573     }
2574 
2575   if (allocated == TRUE)
2576     g_free (text);
2577   return 0;
2578 }
2579 
2580 static gboolean
template_widget_low_check_other(GtkWidget * widget,gchar * label,gint min_cardinality)2581 template_widget_low_check_other (GtkWidget * widget, gchar * label,
2582 				 gint min_cardinality)
2583 {
2584   GtkWidget *entry;
2585   gchar *text;
2586 
2587   entry = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "entry");
2588 
2589   if (GTK_IS_ENTRY (entry))
2590     {
2591       text = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
2592 
2593       if (!text || !*text)
2594 	return 0;
2595     }
2596 
2597   else
2598     {
2599       GtkWidget *widget_inputs;
2600       GtkWidget *button;
2601       GList *list, *old;
2602 
2603       if (!
2604 	  (widget_inputs =
2605 	   g_object_get_data (G_OBJECT (entry), "widget_inputs")))
2606 	return 0;
2607 
2608       button = g_object_get_data (G_OBJECT (entry), "toggle_input");
2609 
2610       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
2611 	{
2612 	  list = old =
2613 	    gtk_container_get_children (GTK_CONTAINER (widget_inputs));
2614 
2615 	  while (list)
2616 	    {
2617 	      if (template_widget_check (list->data))
2618 		{
2619 		  g_list_free (old);
2620 		  return 1;
2621 		}
2622 
2623 	      list = list->next;
2624 	    }
2625 
2626 	  g_list_free (old);
2627 	}
2628     }
2629 
2630   return 0;
2631 }
2632 
2633 static gboolean
template_widget_low_check_default(GtkWidget * widget,gchar * label,gint min_cardinality)2634 template_widget_low_check_default (GtkWidget * widget, gchar * label,
2635 				   gint min_cardinality)
2636 {
2637   GtkWidget *entry;
2638   gchar *text;
2639 
2640   entry = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "entry");
2641   text = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
2642 
2643   if (!text || !*text)
2644     return 0;
2645 
2646   if ((entry = g_object_get_data (G_OBJECT (widget), "datatype")))
2647     {
2648       gchar s[1024];
2649       g_snprintf (s, sizeof (s), _("No compatible value for input %s"),
2650 		  label);
2651 
2652       if (datatype_check
2653 	  (gtk_combo_box_get_active (GTK_COMBO_BOX (entry)), text,
2654 	   s) == FALSE)
2655 	return 1;
2656     }
2657 
2658   return 0;
2659 }
2660 
2661 /* TEMPLATE HIGH CHECK WIDGETS **********************************************/
2662 static gboolean
template_widget_high_check_literal(GtkWidget * widget,gchar * label,gint min_cardinality)2663 template_widget_high_check_literal (GtkWidget * widget, gchar * label,
2664 				    gint min_cardinality)
2665 {
2666   GtkWidget *entry;
2667   gchar *text;
2668   gchar s[1024];
2669   gboolean allocated = FALSE;
2670 
2671   entry = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "entry");
2672 
2673   if (GTK_IS_ENTRY (entry))
2674     text = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
2675 
2676   else
2677     {
2678       GtkTextIter start, end;
2679 
2680       gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (entry), &start);
2681       gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (entry), &end);
2682 
2683       text =
2684 	gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (entry), &start, &end,
2685 				   FALSE);
2686       allocated = TRUE;
2687     }
2688 
2689   if (!text || !*text)
2690     {
2691       g_snprintf (s, sizeof (s), _("No compatible value for input %s"),
2692 		  label);
2693       dialog_msg (s);
2694 
2695       if (allocated == TRUE)
2696 	g_free (text);
2697       return 1;
2698     }
2699 
2700   if ((entry = g_object_get_data (G_OBJECT (widget), "datatype")))
2701     {
2702       gchar s[1024];
2703       g_snprintf (s, sizeof (s), _("No compatible value for input %s"),
2704 		  label);
2705 
2706       if (datatype_check
2707 	  (gtk_combo_box_get_active (GTK_COMBO_BOX (entry)), text,
2708 	   s) == FALSE)
2709 	{
2710 	  if (allocated == TRUE)
2711 	    g_free (text);
2712 	  return 1;
2713 	}
2714     }
2715 
2716   if (allocated == TRUE)
2717     g_free (text);
2718   return 0;
2719 }
2720 
2721 static gboolean
template_widget_high_check_resource(GtkWidget * widget,gchar * label,gint min_cardinality)2722 template_widget_high_check_resource (GtkWidget * widget, gchar * label,
2723 				     gint min_cardinality)
2724 {
2725   return template_widget_high_check_literal (widget, label, min_cardinality);
2726 }
2727 
2728 static gboolean
template_widget_high_check_alt_resource(GtkWidget * widget,gchar * label,gint min_cardinality)2729 template_widget_high_check_alt_resource (GtkWidget * widget, gchar * label,
2730 					 gint min_cardinality)
2731 {
2732   GtkWidget *entry;
2733   gchar *text;
2734   gchar s[1024];
2735 
2736   entry = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "entry");
2737   text = gtk_combo_box_get_active_text (GTK_COMBO_BOX (entry));
2738 
2739   if (!text || !*text)
2740     {
2741       g_snprintf (s, sizeof (s), _("No compatible value for input %s"),
2742 		  label);
2743       dialog_msg (s);
2744 
2745       if (text)
2746 	g_free (text);
2747 
2748       return 1;
2749     }
2750 
2751   return 0;
2752 }
2753 
2754 static gboolean
template_widget_high_check_alt_literal(GtkWidget * widget,gchar * label,gint min_cardinality)2755 template_widget_high_check_alt_literal (GtkWidget * widget, gchar * label,
2756 					gint min_cardinality)
2757 {
2758   return template_widget_high_check_alt_resource (widget, label,
2759 						  min_cardinality);
2760 }
2761 
2762 static gboolean
template_widget_high_check_other(GtkWidget * widget,gchar * label,gint min_cardinality)2763 template_widget_high_check_other (GtkWidget * widget, gchar * label,
2764 				  gint min_cardinality)
2765 {
2766   GtkWidget *entry;
2767   gchar *text;
2768   gchar s[1024];
2769 
2770   entry = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "entry");
2771 
2772   if (GTK_IS_ENTRY (entry))
2773     {
2774       text = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
2775 
2776       if (!text || !*text)
2777 	{
2778 	  g_snprintf (s, sizeof (s), _("No compatible value for input %s"),
2779 		      label);
2780 	  dialog_msg (s);
2781 	  return 1;
2782 	}
2783     }
2784   else
2785     {
2786       GtkWidget *widget_inputs;
2787       GtkWidget *button;
2788       GList *list, *old;
2789 
2790       if (!
2791 	  (widget_inputs =
2792 	   g_object_get_data (G_OBJECT (entry), "widget_inputs")))
2793 	{
2794 	  g_snprintf (s, sizeof (s), _("No compatible value for input %s"),
2795 		      label);
2796 	  dialog_msg (s);
2797 	  return 1;
2798 	}
2799 
2800       button = g_object_get_data (G_OBJECT (entry), "toggle_input");
2801 
2802       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
2803 	{
2804 	  list = old =
2805 	    gtk_container_get_children (GTK_CONTAINER (widget_inputs));
2806 
2807 	  while (list)
2808 	    {
2809 	      if (template_widget_check (list->data))
2810 		{
2811 		  g_list_free (old);
2812 		  return 1;
2813 		}
2814 
2815 	      list = list->next;
2816 	    }
2817 
2818 	  g_list_free (old);
2819 	}
2820     }
2821 
2822   return 0;
2823 }
2824 
2825 static gboolean
template_widget_high_check_default(GtkWidget * widget,gchar * label,gint min_cardinality)2826 template_widget_high_check_default (GtkWidget * widget, gchar * label,
2827 				    gint min_cardinality)
2828 {
2829   GtkWidget *entry;
2830   gchar *text;
2831   gchar s[1024];
2832 
2833   entry = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "entry");
2834   text = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
2835 
2836   if (!text || !*text)
2837     {
2838       g_snprintf (s, sizeof (s), _("No compatible value for input %s"),
2839 		  label);
2840       dialog_msg (s);
2841       return 1;
2842     }
2843 
2844   if ((entry = g_object_get_data (G_OBJECT (widget), "datatype")))
2845     {
2846       gchar s[1024];
2847       g_snprintf (s, sizeof (s), _("No compatible value for input %s"),
2848 		  label);
2849 
2850       if (datatype_check
2851 	  (gtk_combo_box_get_active (GTK_COMBO_BOX (entry)), text,
2852 	   s) == FALSE)
2853 	return 1;
2854     }
2855 
2856   return 0;
2857 }
2858 
2859 static gboolean
template_widget_high_check_cardinality(GtkWidget * widget,gchar * label,gint min_cardinality)2860 template_widget_high_check_cardinality (GtkWidget * widget, gchar * label,
2861 					gint min_cardinality)
2862 {
2863   GtkWidget *entry;
2864   gchar s[1024];
2865   GtkTreeModel *model;
2866 
2867   entry = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "entry");
2868   model = gtk_tree_view_get_model (GTK_TREE_VIEW (entry));
2869 
2870   if (min_cardinality > gtk_tree_model_iter_n_children (model, NULL))
2871     {
2872       g_snprintf (s, sizeof (s), _("Not enough elements for input %s"),
2873 		  label);
2874       dialog_msg (s);
2875       return 1;
2876     }
2877 
2878   return 0;
2879 }
2880 
2881 /* Questa funzione fa il check se l'oggetto e' stato riempito bene: */
2882 static gboolean
template_widget_check(GtkWidget * widget)2883 template_widget_check (GtkWidget * widget)
2884 {
2885   struct template_func_t *func;
2886   gint min_cardinality =
2887     (gboolean) g_object_get_data (G_OBJECT (widget), "min_cardinality");
2888   gchar *label = (gchar *) g_object_get_data (G_OBJECT (widget), "label");
2889   gchar *function_check =
2890     (gchar *) g_object_get_data (G_OBJECT (widget), "function_check");
2891 
2892   if (function_check)
2893     {
2894 #ifdef USE_JS
2895       struct js_t *js = g_object_get_data (G_OBJECT (widget), "js");
2896 
2897       if (template_js_evaluate (js, widget, function_check) == 1)
2898 	return 1;
2899 #else
2900       fprintf (stderr,
2901 	       "WARNING: Javascript not supported on this computer\n");
2902 #endif
2903     }
2904 
2905   /* se non e' richiesto uso la low check: */
2906   if (!min_cardinality)
2907     {
2908       func = g_object_get_data (G_OBJECT (widget), "func");
2909       if (func && func->low_check)
2910 	return func->low_check (widget, label, min_cardinality);
2911 
2912       return 0;
2913     }
2914 
2915   func = g_object_get_data (G_OBJECT (widget), "func");
2916   if (func && func->high_check)
2917     return func->high_check (widget, label, min_cardinality);
2918 
2919   return 0;
2920 }
2921 
2922 /* TEMPLATE DESTROY WIDGETS **************************************************/
2923 
2924 static void
template_widget_destroy_other(GtkWidget * widget)2925 template_widget_destroy_other (GtkWidget * widget)
2926 {
2927   GtkWidget *entry;
2928 
2929   entry = g_object_get_data (G_OBJECT (widget), "entry");
2930 
2931   if (!GTK_IS_ENTRY (entry))
2932     {
2933       GtkWidget *widget_inputs;
2934       GList *list, *old;
2935 
2936       if ((widget_inputs =
2937 	   g_object_get_data (G_OBJECT (entry), "widget_inputs")))
2938 	{
2939 	  list = old =
2940 	    gtk_container_get_children (GTK_CONTAINER (widget_inputs));
2941 
2942 	  while (list)
2943 	    {
2944 	      template_widget_destroy (list->data);
2945 	      list = list->next;
2946 	    }
2947 
2948 	  g_list_free (old);
2949 
2950 	  gtk_widget_destroy (gtk_widget_get_toplevel (widget_inputs));
2951 	  g_object_steal_data (G_OBJECT (entry), "widget_inputs");
2952 	}
2953 
2954       if ((list = g_object_get_data (G_OBJECT (entry), "invisible_inputs")))
2955 	{
2956 	  g_list_foreach (list, (GFunc) g_free, NULL);
2957 	  g_list_free (list);
2958 	}
2959     }
2960 }
2961 
2962 static void
template_widget_destroy_cardinality(GtkWidget * widget)2963 template_widget_destroy_cardinality (GtkWidget * widget)
2964 {
2965   GtkWidget *entry;
2966   GtkTreeModel *model;
2967   GtkTreeIter iter;
2968 
2969   entry = g_object_get_data (G_OBJECT (widget), "entry");
2970   model = gtk_tree_view_get_model (GTK_TREE_VIEW (entry));
2971 
2972   if (gtk_tree_model_get_iter_first (model, &iter))
2973     {
2974       do
2975 	{
2976 	  GtkWidget *w;
2977 	  gtk_tree_model_get (model, &iter, 1, &w, -1);
2978 	  template_widget_destroy (w);
2979 	  gtk_widget_destroy (gtk_widget_get_toplevel (w));
2980 	}
2981       while (gtk_tree_model_iter_next (model, &iter));
2982     }
2983 }
2984 
2985 /* Questa funzione salva il valore di un widget input: */
2986 static void
template_widget_destroy(GtkWidget * widget)2987 template_widget_destroy (GtkWidget * widget)
2988 {
2989   struct template_func_t *func;
2990   gchar *function_destroy =
2991     (gchar *) g_object_get_data (G_OBJECT (widget), "function_destroy");
2992 
2993   if (function_destroy)
2994     {
2995 #ifdef USE_JS
2996       struct js_t *js = g_object_get_data (G_OBJECT (widget), "js");
2997       template_js_evaluate (js, widget, function_destroy);
2998 #else
2999       fprintf (stderr,
3000 	       "WARNING: Javascript not supported on this computer\n");
3001 #endif
3002     }
3003 
3004   func = g_object_get_data (G_OBJECT (widget), "func");
3005   if (func && func->destroy)
3006     func->destroy (widget);
3007 
3008   if (func)
3009     {
3010       g_object_steal_data (G_OBJECT (widget), "func");
3011       g_free (func);
3012     }
3013 }
3014 
3015 /* TEMPLATE SAVE WIDGETS ****************************************************/
3016 static void
template_widget_save_real(GtkWidget * widget,struct editor_data_t * data,gchar * subject,gchar * predicate,gchar * object,gchar * lang,gchar * datatype,enum rdf_object_t object_type,struct unredo_t * unredo,struct rdf_t * rdf_prev)3017 template_widget_save_real (GtkWidget * widget, struct editor_data_t *data,
3018 			   gchar * subject, gchar * predicate, gchar * object,
3019 			   gchar * lang, gchar * datatype,
3020 			   enum rdf_object_t object_type,
3021 			   struct unredo_t *unredo, struct rdf_t *rdf_prev)
3022 {
3023 #ifdef USE_JS
3024   struct js_t *js = g_object_get_data (G_OBJECT (widget), "js");
3025   gchar *function_save =
3026     (gchar *) g_object_get_data (G_OBJECT (widget), "function_save");
3027 
3028   if (function_save)
3029     template_js_evaluate (js, widget, function_save);
3030 #endif
3031 
3032   /* Se devo salvare su una tripletta esistente: */
3033   if (rdf_prev)
3034     {
3035       unredo_add (unredo, rdf_prev, rdf_copy (rdf_prev));
3036 
3037       g_free (rdf_prev->subject);
3038       rdf_prev->subject = g_strdup (subject);
3039 
3040       g_free (rdf_prev->predicate);
3041       rdf_prev->predicate = g_strdup (predicate);
3042 
3043       g_free (rdf_prev->object);
3044       rdf_prev->object = g_strdup (object);
3045 
3046       if (rdf_prev->lang)
3047 	g_free (rdf_prev->lang);
3048 
3049       rdf_prev->lang = lang ? g_strdup (lang) : NULL;
3050 
3051       if (rdf_prev->datatype)
3052 	g_free (rdf_prev->datatype);
3053 
3054       rdf_prev->datatype = datatype ? g_strdup (datatype) : NULL;
3055 
3056       rdf_prev->object_type = object_type;
3057     }
3058 
3059   /* Altrimenti creo una tripletta nuova: */
3060   else
3061     {
3062       struct rdf_t *rdf;
3063 
3064       /* Alloco e inserisco in lista: */
3065       rdf = (struct rdf_t *) g_malloc0 (sizeof (struct rdf_t));
3066 
3067       rdf->subject = g_strdup (subject);
3068       rdf->predicate = g_strdup (predicate);
3069       rdf->object = g_strdup (object);
3070       rdf->lang = lang ? g_strdup (lang) : NULL;
3071       rdf->datatype = datatype ? g_strdup (datatype) : NULL;
3072       rdf->object_type = object_type;
3073 
3074       data->rdf = g_list_append (data->rdf, rdf);
3075       unredo_add (unredo, rdf, NULL);
3076     }
3077 }
3078 
3079 static void
template_widget_save_literal(GtkWidget * widget,struct editor_data_t * data,gchar * subject,gchar * predicate,struct unredo_t * unredo,struct rdf_t * rdf_prev)3080 template_widget_save_literal (GtkWidget * widget, struct editor_data_t *data,
3081 			      gchar * subject, gchar * predicate,
3082 			      struct unredo_t *unredo, struct rdf_t *rdf_prev)
3083 {
3084   GtkWidget *entry;
3085   gchar *object;
3086   gchar *lang = NULL;
3087   gchar *datatype = NULL;
3088   gboolean allocated = FALSE;
3089 
3090   entry = g_object_get_data (G_OBJECT (widget), "entry");
3091 
3092   if (GTK_IS_ENTRY (entry))
3093     {
3094       object = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
3095 
3096       if (!object || !*object)
3097 	return;
3098     }
3099   else
3100     {
3101       GtkTextIter start, end;
3102 
3103       gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (entry), &start);
3104       gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (entry), &end);
3105 
3106       object =
3107 	gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (entry), &start, &end,
3108 				   FALSE);
3109       allocated = TRUE;
3110     }
3111 
3112   if ((entry = g_object_get_data (G_OBJECT (widget), "lang")))
3113     {
3114       lang = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
3115 
3116       if (!lang || !*lang)
3117 	lang = NULL;
3118     }
3119 
3120   if ((entry = g_object_get_data (G_OBJECT (widget), "datatype")))
3121     {
3122       datatype = gtk_combo_box_get_active_text (GTK_COMBO_BOX (entry));
3123 
3124       if (!*datatype)
3125 	{
3126 	  g_free (datatype);
3127 	  datatype = NULL;
3128 	}
3129     }
3130 
3131   template_widget_save_real (widget, data, subject, predicate, object, lang,
3132 			     datatype, RDF_OBJECT_LITERAL, unredo, rdf_prev);
3133 
3134   if (allocated == TRUE)
3135     g_free (object);
3136 
3137   if (datatype)
3138     g_free (datatype);
3139 }
3140 
3141 static void
template_widget_save_resource(GtkWidget * widget,struct editor_data_t * data,gchar * subject,gchar * predicate,struct unredo_t * unredo,struct rdf_t * rdf_prev)3142 template_widget_save_resource (GtkWidget * widget, struct editor_data_t *data,
3143 			       gchar * subject, gchar * predicate,
3144 			       struct unredo_t *unredo,
3145 			       struct rdf_t *rdf_prev)
3146 {
3147   GtkWidget *entry;
3148   gchar *object;
3149 
3150   entry = g_object_get_data (G_OBJECT (widget), "entry");
3151   object = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
3152 
3153   if (!object || !*object)
3154     return;
3155 
3156   template_widget_save_real (widget, data, subject, predicate, object, NULL,
3157 			     NULL, RDF_OBJECT_RESOURCE, unredo, rdf_prev);
3158 }
3159 
3160 static void
template_widget_save_alt_literal(GtkWidget * widget,struct editor_data_t * data,gchar * subject,gchar * predicate,struct unredo_t * unredo,struct rdf_t * rdf_prev)3161 template_widget_save_alt_literal (GtkWidget * widget,
3162 				  struct editor_data_t *data, gchar * subject,
3163 				  gchar * predicate, struct unredo_t *unredo,
3164 				  struct rdf_t *rdf_prev)
3165 {
3166   GtkWidget *entry;
3167   gchar *object;
3168 
3169   entry = g_object_get_data (G_OBJECT (widget), "entry");
3170   object = gtk_combo_box_get_active_text (GTK_COMBO_BOX (entry));
3171 
3172   if (!object)
3173     return;
3174 
3175   if (!*object)
3176     {
3177       g_free (object);
3178       return;
3179     }
3180 
3181   template_widget_save_real (widget, data, subject, predicate, object, NULL,
3182 			     NULL, RDF_OBJECT_LITERAL, unredo, rdf_prev);
3183 
3184   g_free (object);
3185 }
3186 
3187 static void
template_widget_save_alt_resource(GtkWidget * widget,struct editor_data_t * data,gchar * subject,gchar * predicate,struct unredo_t * unredo,struct rdf_t * rdf_prev)3188 template_widget_save_alt_resource (GtkWidget * widget,
3189 				   struct editor_data_t *data,
3190 				   gchar * subject, gchar * predicate,
3191 				   struct unredo_t *unredo,
3192 				   struct rdf_t *rdf_prev)
3193 {
3194   GtkWidget *entry;
3195   gchar *object;
3196 
3197   entry = g_object_get_data (G_OBJECT (widget), "entry");
3198   object = gtk_combo_box_get_active_text (GTK_COMBO_BOX (entry));
3199 
3200   if (!object)
3201     return;
3202 
3203   if (!*object)
3204     {
3205       g_free (object);
3206       return;
3207     }
3208 
3209   template_widget_save_real (widget, data, subject, predicate, object, NULL,
3210 			     NULL, RDF_OBJECT_RESOURCE, unredo, rdf_prev);
3211 
3212   g_free (object);
3213 }
3214 
3215 static void
template_widget_save_other(GtkWidget * widget,struct editor_data_t * data,gchar * subject,gchar * predicate,struct unredo_t * unredo,struct rdf_t * rdf_prev)3216 template_widget_save_other (GtkWidget * widget, struct editor_data_t *data,
3217 			    gchar * subject, gchar * predicate,
3218 			    struct unredo_t *unredo, struct rdf_t *rdf_prev)
3219 {
3220   GtkWidget *entry;
3221   gchar *object;
3222 
3223   entry = g_object_get_data (G_OBJECT (widget), "entry");
3224 
3225   if (GTK_IS_ENTRY (entry))
3226     {
3227       object = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
3228 
3229       if (!object || !*object)
3230 	return;
3231 
3232       template_widget_save_real (widget, data, subject, predicate, object,
3233 				 NULL, NULL, RDF_OBJECT_RESOURCE, unredo,
3234 				 rdf_prev);
3235     }
3236   else
3237     {
3238       GtkWidget *widget_inputs;
3239       GtkWidget *type_resource;
3240       GtkWidget *button;
3241       GtkWidget *value;
3242 
3243       if (!
3244 	  (widget_inputs =
3245 	   g_object_get_data (G_OBJECT (entry), "widget_inputs")))
3246 	return;
3247 
3248       type_resource =
3249 	g_object_get_data (G_OBJECT (entry), "type_resource_input");
3250       value = g_object_get_data (G_OBJECT (entry), "subject_input");
3251 
3252       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type_resource)))
3253 	{
3254 	  object = (gchar *) gtk_entry_get_text (GTK_ENTRY (value));
3255 	  if (!object || !*object)
3256 	    return;
3257 
3258 	  object = g_strdup (object);
3259 
3260 	  template_widget_save_real (widget, data, subject, predicate, object,
3261 				     NULL, NULL, RDF_OBJECT_RESOURCE, unredo,
3262 				     rdf_prev);
3263 	}
3264       else
3265 	{
3266 	  object = (gchar *) gtk_entry_get_text (GTK_ENTRY (value));
3267 	  if (!object || !*object)
3268 	    object = template_widget_blank (data);
3269 	  else
3270 	    object = g_strdup (object);
3271 
3272 	  template_widget_save_real (widget, data, subject, predicate, object,
3273 				     NULL, NULL, RDF_OBJECT_BLANK, unredo,
3274 				     rdf_prev);
3275 	}
3276 
3277       button = g_object_get_data (G_OBJECT (entry), "toggle_input");
3278       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
3279 	{
3280 	  GList *list, *old;
3281 
3282 	  list = old =
3283 	    gtk_container_get_children (GTK_CONTAINER (widget_inputs));
3284 
3285 	  while (list)
3286 	    {
3287 	      template_widget_save (list->data, data, object, unredo);
3288 	      list = list->next;
3289 	    }
3290 
3291 	  g_list_free (old);
3292 
3293 	  if ((list =
3294 	       g_object_get_data (G_OBJECT (entry), "invisible_inputs")))
3295 	    {
3296 	      struct invisible_t *inv;
3297 
3298 	      while (list)
3299 		{
3300 		  inv = list->data;
3301 
3302 		  template_invisible_save (object, inv->input, data, unredo,
3303 					   inv->rdf);
3304 		  list = list->next;
3305 		}
3306 	    }
3307 	}
3308 
3309       g_free (object);
3310     }
3311 }
3312 
3313 static void
template_widget_save_default(GtkWidget * widget,struct editor_data_t * data,gchar * subject,gchar * predicate,struct unredo_t * unredo,struct rdf_t * rdf_prev)3314 template_widget_save_default (GtkWidget * widget, struct editor_data_t *data,
3315 			      gchar * subject, gchar * predicate,
3316 			      struct unredo_t *unredo, struct rdf_t *rdf_prev)
3317 {
3318   GtkWidget *entry;
3319   GtkWidget *type;
3320   gchar *object;
3321   gchar *lang = NULL;
3322   gchar *datatype = NULL;
3323   enum rdf_object_t object_type = RDF_OBJECT_LITERAL;
3324 
3325   entry = g_object_get_data (G_OBJECT (widget), "entry");
3326 
3327   type = g_object_get_data (G_OBJECT (widget), "type_literal");
3328   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type)) == TRUE)
3329     object_type = RDF_OBJECT_LITERAL;
3330 
3331   type = g_object_get_data (G_OBJECT (widget), "type_resource");
3332   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type)) == TRUE)
3333     object_type = RDF_OBJECT_RESOURCE;
3334 
3335   type = g_object_get_data (G_OBJECT (widget), "type_blanknode");
3336   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type)) == TRUE)
3337     object_type = RDF_OBJECT_BLANK;
3338 
3339   object = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
3340 
3341   if (!object || !*object)
3342     return;
3343 
3344   if ((entry = g_object_get_data (G_OBJECT (widget), "lang")))
3345     {
3346       lang = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
3347 
3348       if (!lang || !*lang)
3349 	lang = NULL;
3350     }
3351 
3352   if ((entry = g_object_get_data (G_OBJECT (widget), "datatype")))
3353     {
3354       datatype = gtk_combo_box_get_active_text (GTK_COMBO_BOX (entry));
3355 
3356       if (!*datatype)
3357 	{
3358 	  g_free (datatype);
3359 	  datatype = NULL;
3360 	}
3361     }
3362 
3363   template_widget_save_real (widget, data, subject, predicate, object, lang,
3364 			     datatype, object_type, unredo, rdf_prev);
3365 
3366   if (datatype)
3367     free (datatype);
3368 }
3369 
3370 static void
template_widget_save_cardinality(GtkWidget * widget,struct editor_data_t * data,gchar * subject,gchar * predicate,struct unredo_t * unredo,struct rdf_t * rdf_prev)3371 template_widget_save_cardinality (GtkWidget * widget,
3372 				  struct editor_data_t *data, gchar * subject,
3373 				  gchar * predicate, struct unredo_t *unredo,
3374 				  struct rdf_t *rdf_prev)
3375 {
3376   GtkWidget *entry;
3377   GtkTreeModel *model;
3378   GtkTreeIter iter;
3379 
3380   entry = g_object_get_data (G_OBJECT (widget), "entry");
3381   model = gtk_tree_view_get_model (GTK_TREE_VIEW (entry));
3382 
3383   if (gtk_tree_model_get_iter_first (model, &iter))
3384     {
3385       do
3386 	{
3387 	  GtkWidget *w;
3388 	  gtk_tree_model_get (model, &iter, 1, &w, -1);
3389 	  template_widget_save (w, data, subject, unredo);
3390 	}
3391       while (gtk_tree_model_iter_next (model, &iter));
3392     }
3393 }
3394 
3395 /* Questa funzione salva il valore di un widget input: */
3396 static void
template_widget_save(GtkWidget * widget,struct editor_data_t * data,gchar * subject,struct unredo_t * unredo)3397 template_widget_save (GtkWidget * widget, struct editor_data_t *data,
3398 		      gchar * subject, struct unredo_t *unredo)
3399 {
3400   gchar *property;
3401   struct template_func_t *func;
3402   struct rdf_t *rdf_prev;
3403 
3404   property = g_object_get_data (G_OBJECT (widget), "rdfs");
3405   func = g_object_get_data (G_OBJECT (widget), "func");
3406   rdf_prev = g_object_get_data (G_OBJECT (widget), "rdf_prev");
3407 
3408   if (func && func->save)
3409     func->save (widget, data, subject, property, unredo, rdf_prev);
3410 }
3411 
3412 /* Gli oggetti invisibili sono semplici semplici: */
3413 static void
template_invisible_save(gchar * subject,struct template_input_t * i,struct editor_data_t * data,struct unredo_t * unredo,struct rdf_t * rdf_prev)3414 template_invisible_save (gchar * subject, struct template_input_t *i,
3415 			 struct editor_data_t *data, struct unredo_t *unredo,
3416 			 struct rdf_t *rdf_prev)
3417 {
3418   enum template_input_typevalue_t typevalue;
3419 
3420   switch (i->typevalue)
3421     {
3422     case TEMPLATE_INPUT_TYPEVALUE_LITERAL:
3423       typevalue = RDF_OBJECT_LITERAL;
3424       break;
3425 
3426     case TEMPLATE_INPUT_TYPEVALUE_RESOURCE:
3427     default:
3428       typevalue = RDF_OBJECT_RESOURCE;
3429       break;
3430     }
3431 
3432   template_widget_save_real (NULL, data, subject, i->rdfs, i->default_value,
3433 			     i->default_language, i->default_datatype,
3434 			     typevalue, unredo, rdf_prev);
3435 }
3436 
3437 /* TEMPLATE SAVE ON WIDGETS *************************************************/
3438 
3439 static void
template_widget_get_literal(GtkWidget * widget,struct template_value_t * value)3440 template_widget_get_literal (GtkWidget * widget,
3441 			     struct template_value_t *value)
3442 {
3443   GtkWidget *entry;
3444   gchar *str;
3445 
3446   entry = g_object_get_data (G_OBJECT (widget), "entry");
3447 
3448   if (GTK_IS_ENTRY (entry))
3449     {
3450       str = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
3451 
3452       if (str && *str)
3453 	value->value = g_strdup (str);
3454 
3455     }
3456   else
3457     {
3458       GtkTextIter start, end;
3459 
3460       gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (entry), &start);
3461       gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (entry), &end);
3462 
3463       value->value =
3464 	gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (entry), &start, &end,
3465 				   FALSE);
3466     }
3467 
3468   if ((entry = g_object_get_data (G_OBJECT (widget), "lang")))
3469     {
3470       str = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
3471 
3472       if (str && *str)
3473 	value->lang = g_strdup (str);
3474     }
3475 
3476   if ((entry = g_object_get_data (G_OBJECT (widget), "datatype")))
3477     {
3478       str = gtk_combo_box_get_active_text (GTK_COMBO_BOX (entry));
3479 
3480       if (str && *str)
3481 	value->datatype = g_strdup (str);
3482 
3483       if (str)
3484 	g_free (str);
3485     }
3486 
3487   value->type = RDF_OBJECT_LITERAL;
3488 }
3489 
3490 static void
template_widget_get_resource(GtkWidget * widget,struct template_value_t * value)3491 template_widget_get_resource (GtkWidget * widget,
3492 			      struct template_value_t *value)
3493 {
3494   GtkWidget *entry;
3495   gchar *object;
3496 
3497   entry = g_object_get_data (G_OBJECT (widget), "entry");
3498 
3499   object = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
3500 
3501   if (object && *object)
3502     value->value = g_strdup (object);
3503 
3504   value->type = RDF_OBJECT_RESOURCE;
3505 }
3506 
3507 static void
template_widget_get_alt_literal(GtkWidget * widget,struct template_value_t * value)3508 template_widget_get_alt_literal (GtkWidget * widget,
3509 				 struct template_value_t *value)
3510 {
3511   GtkWidget *entry;
3512   gchar *object;
3513 
3514   entry = g_object_get_data (G_OBJECT (widget), "entry");
3515 
3516   object = gtk_combo_box_get_active_text (GTK_COMBO_BOX (entry));
3517 
3518   if (!object)
3519     return;
3520 
3521   if (!*object)
3522     {
3523       g_free (object);
3524       return;
3525     }
3526 
3527   value->value = object;
3528   value->type = RDF_OBJECT_LITERAL;
3529 }
3530 
3531 static void
template_widget_get_alt_resource(GtkWidget * widget,struct template_value_t * value)3532 template_widget_get_alt_resource (GtkWidget * widget,
3533 				  struct template_value_t *value)
3534 {
3535   GtkWidget *entry;
3536   gchar *object;
3537 
3538   entry = g_object_get_data (G_OBJECT (widget), "entry");
3539 
3540   object = gtk_combo_box_get_active_text (GTK_COMBO_BOX (entry));
3541 
3542   if (!object)
3543     return;
3544 
3545   if (!*object)
3546     {
3547       g_free (object);
3548       return;
3549     }
3550 
3551   value->value = object;
3552   value->type = RDF_OBJECT_RESOURCE;
3553 }
3554 
3555 static void
template_widget_get_other(GtkWidget * widget,struct template_value_t * value)3556 template_widget_get_other (GtkWidget * widget, struct template_value_t *value)
3557 {
3558   GtkWidget *entry;
3559   gchar *object;
3560 
3561   entry = g_object_get_data (G_OBJECT (widget), "entry");
3562 
3563   if (GTK_IS_ENTRY (entry))
3564     {
3565       object = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
3566 
3567       if (object && *object)
3568 	value->value = g_strdup (object);
3569 
3570       value->type = RDF_OBJECT_RESOURCE;
3571     }
3572 
3573   else
3574     {
3575       GtkWidget *type_resource;
3576 
3577       type_resource =
3578 	g_object_get_data (G_OBJECT (entry), "type_resource_input");
3579 
3580       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type_resource)))
3581 	value->type = RDF_OBJECT_RESOURCE;
3582 
3583       else
3584 	value->type = RDF_OBJECT_BLANK;
3585     }
3586 }
3587 
3588 static void
template_widget_get_default(GtkWidget * widget,struct template_value_t * value)3589 template_widget_get_default (GtkWidget * widget,
3590 			     struct template_value_t *value)
3591 {
3592   GtkWidget *entry;
3593   GtkWidget *type;
3594   gchar *str;
3595 
3596   entry = g_object_get_data (G_OBJECT (widget), "entry");
3597 
3598   str = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
3599 
3600   if (str && *str)
3601     value->value = g_strdup (str);
3602 
3603   type = g_object_get_data (G_OBJECT (widget), "type_literal");
3604   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type)) == TRUE)
3605     value->type = RDF_OBJECT_LITERAL;
3606 
3607   type = g_object_get_data (G_OBJECT (widget), "type_resource");
3608   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type)) == TRUE)
3609     value->type = RDF_OBJECT_RESOURCE;
3610 
3611   type = g_object_get_data (G_OBJECT (widget), "type_blanknode");
3612   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type)) == TRUE)
3613     value->type = RDF_OBJECT_BLANK;
3614 
3615   if ((entry = g_object_get_data (G_OBJECT (widget), "lang")))
3616     {
3617       str = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
3618 
3619       if (str && *str)
3620 	value->lang = g_strdup (str);
3621     }
3622 
3623   if ((entry = g_object_get_data (G_OBJECT (widget), "datatype")))
3624     {
3625       str = gtk_combo_box_get_active_text (GTK_COMBO_BOX (entry));
3626 
3627       if (str && *str)
3628 	value->datatype = g_strdup (str);
3629 
3630       if (str)
3631 	g_free (str);
3632     }
3633 }
3634 
3635 static void
template_widget_save_on(GtkWidget * widget)3636 template_widget_save_on (GtkWidget * widget)
3637 {
3638   struct template_func_t *func;
3639   struct template_value_t *value;
3640 
3641   if ((value = g_object_get_data (G_OBJECT (widget), "saved")))
3642     {
3643       g_object_steal_data (G_OBJECT (widget), "saved");
3644       template_value_free (value);
3645     }
3646 
3647   value = g_malloc0 (sizeof (struct template_value_t));
3648 
3649   func = g_object_get_data (G_OBJECT (widget), "func");
3650   if (func && func->get)
3651     func->get (widget, value);
3652 
3653   g_object_set_data (G_OBJECT (widget), "saved", value);
3654 }
3655 
3656 /* TEMPLATE SAVE OFF WIDGETS ***********************************************/
3657 
3658 static void
template_widget_save_off(GtkWidget * widget)3659 template_widget_save_off (GtkWidget * widget)
3660 {
3661   struct template_value_t *value;
3662 
3663   if ((value = g_object_get_data (G_OBJECT (widget), "saved")))
3664     {
3665       g_object_steal_data (G_OBJECT (widget), "saved");
3666       template_value_free (value);
3667     }
3668 }
3669 
3670 /* TEMPLATE SET WIDGETS ***********************************************/
3671 
3672 static void
template_widget_set_literal(GtkWidget * widget,struct template_value_t * value)3673 template_widget_set_literal (GtkWidget * widget,
3674 			     struct template_value_t *value)
3675 {
3676   GtkWidget *entry;
3677 
3678   if (value->value
3679       && (entry = g_object_get_data (G_OBJECT (widget), "entry")))
3680     {
3681       if (GTK_IS_ENTRY (entry))
3682 	gtk_entry_set_text (GTK_ENTRY (entry), value->value);
3683       else
3684 	{
3685 	  GtkTextIter start, end;
3686 
3687 	  gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (entry), &start);
3688 	  gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (entry), &end);
3689 	  gtk_text_buffer_delete (GTK_TEXT_BUFFER (entry), &start, &end);
3690 
3691 	  gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (entry), &start);
3692 	  gtk_text_buffer_insert (GTK_TEXT_BUFFER (entry), &start,
3693 				  value->value, -1);
3694 	}
3695     }
3696 
3697   if (value->lang
3698       && ((entry = g_object_get_data (G_OBJECT (widget), "lang"))))
3699     gtk_entry_set_text (GTK_ENTRY (entry), value->lang);
3700 
3701   if (value->datatype
3702       && (entry = g_object_get_data (G_OBJECT (widget), "datatype")))
3703     gtk_combo_box_set_active (GTK_COMBO_BOX (entry),
3704 			      datatype_id (value->datatype));
3705 }
3706 
3707 static void
template_widget_set_resource(GtkWidget * widget,struct template_value_t * value)3708 template_widget_set_resource (GtkWidget * widget,
3709 			      struct template_value_t *value)
3710 {
3711   GtkWidget *entry;
3712 
3713   if (value->value
3714       && (entry = g_object_get_data (G_OBJECT (widget), "entry")))
3715     gtk_entry_set_text (GTK_ENTRY (entry), value->value);
3716 }
3717 
3718 static void
template_widget_set_alt_literal(GtkWidget * widget,struct template_value_t * value)3719 template_widget_set_alt_literal (GtkWidget * widget,
3720 				 struct template_value_t *value)
3721 {
3722   GtkTreeModel *model;
3723   GtkTreeIter iter;
3724   gint ok = 0;
3725   gint id = 0;
3726   GtkWidget *entry;
3727 
3728   entry = g_object_get_data (G_OBJECT (widget), "entry");
3729   model = gtk_combo_box_get_model (GTK_COMBO_BOX (entry));
3730 
3731   if (gtk_tree_model_get_iter_first (model, &iter))
3732     {
3733 
3734       do
3735 	{
3736 	  gchar *what;
3737 
3738 	  gtk_tree_model_get (model, &iter, 0, &what, -1);
3739 
3740 	  if (!strcmp (what, value->value))
3741 	    {
3742 	      ok = 1;
3743 	      g_free (what);
3744 	      break;
3745 	    }
3746 
3747 
3748 	  g_free (what);
3749 	  id++;
3750 	}
3751       while (gtk_tree_model_iter_next (model, &iter));
3752     }
3753 
3754   if (ok)
3755     gtk_combo_box_set_active (GTK_COMBO_BOX (entry), id);
3756   else
3757     {
3758       gtk_combo_box_append_text (GTK_COMBO_BOX (entry), value->value);
3759       gtk_combo_box_set_active (GTK_COMBO_BOX (entry), id + 1);
3760     }
3761 }
3762 
3763 static void
template_widget_set_alt_resource(GtkWidget * widget,struct template_value_t * value)3764 template_widget_set_alt_resource (GtkWidget * widget,
3765 				  struct template_value_t *value)
3766 {
3767   GtkTreeModel *model;
3768   GtkTreeIter iter;
3769   gint ok = 0;
3770   gint id = 0;
3771   GtkWidget *entry;
3772 
3773   entry = g_object_get_data (G_OBJECT (widget), "entry");
3774   model = gtk_combo_box_get_model (GTK_COMBO_BOX (entry));
3775 
3776   if (gtk_tree_model_get_iter_first (model, &iter))
3777     {
3778 
3779       do
3780 	{
3781 	  gchar *what;
3782 
3783 	  gtk_tree_model_get (model, &iter, 0, &what, -1);
3784 
3785 	  if (!strcmp (what, value->value))
3786 	    {
3787 	      ok = 1;
3788 	      g_free (what);
3789 	      break;
3790 	    }
3791 
3792 
3793 	  g_free (what);
3794 	  id++;
3795 	}
3796       while (gtk_tree_model_iter_next (model, &iter));
3797     }
3798 
3799   if (ok)
3800     gtk_combo_box_set_active (GTK_COMBO_BOX (entry), id);
3801   else
3802     {
3803       gtk_combo_box_append_text (GTK_COMBO_BOX (entry), value->value);
3804       gtk_combo_box_set_active (GTK_COMBO_BOX (entry), id + 1);
3805     }
3806 }
3807 
3808 static void
template_widget_set_other(GtkWidget * widget,struct template_value_t * value)3809 template_widget_set_other (GtkWidget * widget, struct template_value_t *value)
3810 {
3811   GtkWidget *entry;
3812 
3813   entry = g_object_get_data (G_OBJECT (widget), "entry");
3814 
3815   if (GTK_IS_ENTRY (entry) && value->value)
3816     gtk_entry_set_text (GTK_ENTRY (entry), value->value);
3817 }
3818 
3819 static void
template_widget_set_default(GtkWidget * widget,struct template_value_t * value)3820 template_widget_set_default (GtkWidget * widget,
3821 			     struct template_value_t *value)
3822 {
3823   GtkWidget *entry;
3824   GtkWidget *type;
3825 
3826   switch (value->type)
3827     {
3828     case RDF_OBJECT_LITERAL:
3829       type = g_object_get_data (G_OBJECT (widget), "type_literal");
3830       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (type), TRUE);
3831       break;
3832 
3833     case RDF_OBJECT_RESOURCE:
3834       type = g_object_get_data (G_OBJECT (widget), "type_resource");
3835       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (type), TRUE);
3836       break;
3837 
3838     case RDF_OBJECT_BLANK:
3839       type = g_object_get_data (G_OBJECT (widget), "type_blanknode");
3840       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (type), TRUE);
3841       break;
3842     }
3843 
3844   if (value->value)
3845     {
3846       entry = g_object_get_data (G_OBJECT (widget), "entry");
3847       gtk_entry_set_text (GTK_ENTRY (entry), value->value);
3848     }
3849 
3850   if (value->lang)
3851     {
3852       entry = g_object_get_data (G_OBJECT (widget), "lang");
3853       gtk_entry_set_text (GTK_ENTRY (entry), value->lang);
3854     }
3855 
3856   if (value->datatype)
3857     {
3858       entry = g_object_get_data (G_OBJECT (widget), "datatype");
3859       gtk_combo_box_set_active (GTK_COMBO_BOX (entry),
3860 				datatype_id (value->datatype));
3861     }
3862 }
3863 
3864 static void
template_widget_set(GtkWidget * widget,struct template_value_t * value)3865 template_widget_set (GtkWidget * widget, struct template_value_t *value)
3866 {
3867   struct template_func_t *func;
3868 
3869   func = g_object_get_data (G_OBJECT (widget), "func");
3870 
3871   if (func && func->set)
3872     func->set (widget, value);
3873 }
3874 
3875 static void
template_widget_save_reset(GtkWidget * widget)3876 template_widget_save_reset (GtkWidget * widget)
3877 {
3878   struct template_value_t *value;
3879 
3880   if (!(value = g_object_get_data (G_OBJECT (widget), "saved")))
3881     return;
3882 
3883   template_widget_set (widget, value);
3884 
3885   template_value_free (value);
3886   g_object_steal_data (G_OBJECT (widget), "saved");
3887 }
3888 
3889 /* TEMPLATE IS YOUR WIDGETS ***********************************************/
3890 
3891 static gboolean
template_widget_is_your_literal(GtkWidget * widget,struct rdf_t * rdf,GList ** dummy)3892 template_widget_is_your_literal (GtkWidget * widget, struct rdf_t *rdf,
3893 				 GList ** dummy)
3894 {
3895   gchar *predicate;
3896   GtkWidget *entry;
3897 
3898   if (rdf->object_type != RDF_OBJECT_LITERAL)
3899     return FALSE;
3900 
3901   predicate = g_object_get_data (G_OBJECT (widget), "rdfs");
3902   if (!predicate || strcmp (predicate, rdf->predicate))
3903     return FALSE;
3904 
3905   entry = g_object_get_data (G_OBJECT (widget), "entry");
3906 
3907   if (GTK_IS_ENTRY (entry))
3908     gtk_entry_set_text (GTK_ENTRY (entry), rdf->object);
3909 
3910   else
3911     {
3912       GtkTextIter start, end;
3913 
3914       gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (entry), &start);
3915       gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (entry), &end);
3916       gtk_text_buffer_delete (GTK_TEXT_BUFFER (entry), &start, &end);
3917 
3918       gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (entry), &start);
3919       gtk_text_buffer_insert (GTK_TEXT_BUFFER (entry), &start, rdf->object,
3920 			      -1);
3921     }
3922 
3923   if (rdf->lang && (entry = g_object_get_data (G_OBJECT (widget), "lang")))
3924     gtk_entry_set_text (GTK_ENTRY (entry), rdf->lang);
3925 
3926   if (rdf->datatype
3927       && (entry = g_object_get_data (G_OBJECT (widget), "datatype")))
3928     gtk_combo_box_set_active (GTK_COMBO_BOX (entry),
3929 			      datatype_id (rdf->datatype));
3930 
3931   return TRUE;
3932 }
3933 
3934 static gboolean
template_widget_is_your_resource(GtkWidget * widget,struct rdf_t * rdf,GList ** dummy)3935 template_widget_is_your_resource (GtkWidget * widget, struct rdf_t *rdf,
3936 				  GList ** dummy)
3937 {
3938   gchar *predicate;
3939   GtkWidget *entry;
3940 
3941   if (rdf->object_type != RDF_OBJECT_RESOURCE)
3942     return FALSE;
3943 
3944   predicate = g_object_get_data (G_OBJECT (widget), "rdfs");
3945   if (!predicate || strcmp (predicate, rdf->predicate))
3946     return FALSE;
3947 
3948   entry = g_object_get_data (G_OBJECT (widget), "entry");
3949   gtk_entry_set_text (GTK_ENTRY (entry), rdf->object);
3950 
3951   return TRUE;
3952 }
3953 
3954 static gboolean
template_widget_is_your_alt_literal(GtkWidget * widget,struct rdf_t * rdf,GList ** dummy)3955 template_widget_is_your_alt_literal (GtkWidget * widget, struct rdf_t *rdf,
3956 				     GList ** dummy)
3957 {
3958   GtkTreeModel *model;
3959   GtkTreeIter iter;
3960   gint ok = 0;
3961   gint id = 0;
3962   GtkWidget *entry;
3963   gchar *predicate;
3964 
3965   if (rdf->object_type != RDF_OBJECT_LITERAL)
3966     return FALSE;
3967 
3968   predicate = g_object_get_data (G_OBJECT (widget), "rdfs");
3969   if (!predicate || strcmp (predicate, rdf->predicate))
3970     return FALSE;
3971 
3972   entry = g_object_get_data (G_OBJECT (widget), "entry");
3973   model = gtk_combo_box_get_model (GTK_COMBO_BOX (entry));
3974 
3975   if (gtk_tree_model_get_iter_first (model, &iter))
3976     {
3977 
3978       do
3979 	{
3980 	  gchar *what;
3981 
3982 	  gtk_tree_model_get (model, &iter, 0, &what, -1);
3983 
3984 	  if (!strcmp (what, rdf->object))
3985 	    {
3986 	      ok = 1;
3987 	      g_free (what);
3988 	      break;
3989 	    }
3990 
3991 
3992 	  g_free (what);
3993 	  id++;
3994 	}
3995       while (gtk_tree_model_iter_next (model, &iter));
3996     }
3997 
3998   if (ok)
3999     gtk_combo_box_set_active (GTK_COMBO_BOX (entry), id);
4000   else
4001     {
4002       gtk_combo_box_append_text (GTK_COMBO_BOX (entry), rdf->object);
4003       gtk_combo_box_set_active (GTK_COMBO_BOX (entry), id + 1);
4004     }
4005 
4006   return TRUE;
4007 }
4008 
4009 static gboolean
template_widget_is_your_alt_resource(GtkWidget * widget,struct rdf_t * rdf,GList ** dummy)4010 template_widget_is_your_alt_resource (GtkWidget * widget, struct rdf_t *rdf,
4011 				      GList ** dummy)
4012 {
4013   GtkTreeModel *model;
4014   GtkTreeIter iter;
4015   gint ok = 0;
4016   gint id = 0;
4017   GtkWidget *entry;
4018   gchar *predicate;
4019 
4020   if (rdf->object_type != RDF_OBJECT_RESOURCE)
4021     return FALSE;
4022 
4023   predicate = g_object_get_data (G_OBJECT (widget), "rdfs");
4024   if (!predicate || strcmp (predicate, rdf->predicate))
4025     return FALSE;
4026 
4027   entry = g_object_get_data (G_OBJECT (widget), "entry");
4028   model = gtk_combo_box_get_model (GTK_COMBO_BOX (entry));
4029 
4030   if (gtk_tree_model_get_iter_first (model, &iter))
4031     {
4032 
4033       do
4034 	{
4035 	  gchar *what;
4036 
4037 	  gtk_tree_model_get (model, &iter, 0, &what, -1);
4038 
4039 	  if (!strcmp (what, rdf->object))
4040 	    {
4041 	      ok = 1;
4042 	      g_free (what);
4043 	      break;
4044 	    }
4045 
4046 
4047 	  g_free (what);
4048 	  id++;
4049 	}
4050       while (gtk_tree_model_iter_next (model, &iter));
4051     }
4052 
4053   if (ok)
4054     gtk_combo_box_set_active (GTK_COMBO_BOX (entry), id);
4055   else
4056     {
4057       gtk_combo_box_append_text (GTK_COMBO_BOX (entry), rdf->object);
4058       gtk_combo_box_set_active (GTK_COMBO_BOX (entry), id + 1);
4059     }
4060 
4061   return TRUE;
4062 }
4063 
4064 static gboolean
template_widget_is_your_default(GtkWidget * widget,struct rdf_t * rdf,GList ** dummy)4065 template_widget_is_your_default (GtkWidget * widget, struct rdf_t *rdf,
4066 				 GList ** dummy)
4067 {
4068   GtkWidget *entry;
4069   GtkWidget *type;
4070   gchar *predicate;
4071 
4072   predicate = g_object_get_data (G_OBJECT (widget), "rdfs");
4073   if (!predicate || strcmp (predicate, rdf->predicate))
4074     return FALSE;
4075 
4076   switch (rdf->object_type)
4077     {
4078     case RDF_OBJECT_LITERAL:
4079       type = g_object_get_data (G_OBJECT (widget), "type_literal");
4080       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (type), TRUE);
4081       break;
4082 
4083     case RDF_OBJECT_RESOURCE:
4084       type = g_object_get_data (G_OBJECT (widget), "type_resource");
4085       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (type), TRUE);
4086       break;
4087 
4088     case RDF_OBJECT_BLANK:
4089       type = g_object_get_data (G_OBJECT (widget), "type_blanknode");
4090       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (type), TRUE);
4091       break;
4092     }
4093 
4094   entry = g_object_get_data (G_OBJECT (widget), "entry");
4095   gtk_entry_set_text (GTK_ENTRY (entry), rdf->object);
4096 
4097   if (rdf->lang && (entry = g_object_get_data (G_OBJECT (widget), "lang")))
4098     gtk_entry_set_text (GTK_ENTRY (entry), rdf->lang);
4099 
4100   if (rdf->datatype
4101       && (entry = g_object_get_data (G_OBJECT (widget), "datatype")))
4102     gtk_combo_box_set_active (GTK_COMBO_BOX (entry),
4103 			      datatype_id (rdf->datatype));
4104 
4105   return TRUE;
4106 }
4107 
4108 static gboolean
template_widget_is_your_other(GtkWidget * widget,struct rdf_t * rdf,GList ** other)4109 template_widget_is_your_other (GtkWidget * widget, struct rdf_t *rdf,
4110 			       GList ** other)
4111 {
4112   GtkWidget *entry;
4113   GtkWidget *widget_inputs;
4114   GtkWidget *dialog;
4115   GtkWidget *type_resource;
4116   GtkWidget *type_blanknode;
4117   GtkWidget *object;
4118   GtkWidget *toggle;
4119   gchar *predicate;
4120   GList *resources;
4121   GList *blanks;
4122   GList *invisible;
4123   GList *list;
4124   struct template_t *template;
4125   gint len;
4126 
4127   if (rdf->object_type != RDF_OBJECT_RESOURCE
4128       && rdf->object_type != RDF_OBJECT_BLANK)
4129     return FALSE;
4130 
4131   predicate = g_object_get_data (G_OBJECT (widget), "rdfs");
4132   if (!predicate || strcmp (predicate, rdf->predicate))
4133     return FALSE;
4134 
4135   entry = g_object_get_data (G_OBJECT (widget), "entry");
4136 
4137   if (GTK_IS_ENTRY (entry))
4138     {
4139       gtk_entry_set_text (GTK_ENTRY (entry), rdf->object);
4140       return TRUE;
4141     }
4142 
4143   resources = g_object_get_data (G_OBJECT (entry), "resources");
4144   blanks = g_object_get_data (G_OBJECT (entry), "blanks");
4145   template = g_object_get_data (G_OBJECT (entry), "template");
4146 
4147   if (!(widget_inputs = template_open_real (resources, blanks, template)))
4148     return FALSE;
4149 
4150   dialog =
4151     template_run_create (widget_inputs, template, resources, blanks,
4152 			 &type_resource, &type_blanknode, &object, &toggle);
4153   gtk_widget_hide (dialog);
4154 
4155   gtk_entry_set_text (GTK_ENTRY (object), rdf->object);
4156 
4157   if (rdf->object_type == RDF_OBJECT_RESOURCE)
4158     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (type_resource), TRUE);
4159   else
4160     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (type_blanknode), TRUE);
4161 
4162   gtk_entry_set_text (GTK_ENTRY (object), rdf->object);
4163 
4164   len = g_list_length (*other);
4165 
4166   if ((list = gtk_container_get_children (GTK_CONTAINER (widget_inputs))))
4167     {
4168       GList *sorted = template_edit_set_sort (list);
4169       g_list_free (list);
4170 
4171       template_edit_set (&sorted, other, rdf->object);
4172 
4173       if (sorted)
4174 	g_list_free (sorted);
4175     }
4176 
4177   if (len == g_list_length (*other))
4178     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), FALSE);
4179   else
4180     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), TRUE);
4181 
4182   g_object_set_data (G_OBJECT (entry), "widget_inputs", widget_inputs);
4183   g_object_set_data (G_OBJECT (entry), "subject_input", object);
4184   g_object_set_data (G_OBJECT (entry), "type_resource_input", type_resource);
4185   g_object_set_data (G_OBJECT (entry), "type_blanknode_input",
4186 		     type_blanknode);
4187   g_object_set_data (G_OBJECT (entry), "type_blanknode_a_input", 0);
4188   g_object_set_data (G_OBJECT (entry), "toggle_input", toggle);
4189 
4190   invisible = NULL;
4191   template_edit_invisible (&invisible, other, rdf->object, template);
4192   g_object_set_data (G_OBJECT (entry), "invisible_inputs", invisible);
4193 
4194   return TRUE;
4195 }
4196 
4197 static gboolean
template_widget_is_your_cardinality(GtkWidget * widget,struct rdf_t * rdf,GList ** other)4198 template_widget_is_your_cardinality (GtkWidget * widget, struct rdf_t *rdf,
4199 				     GList ** other)
4200 {
4201   GtkWidget *entry;
4202   GtkListStore *model;
4203   GtkTreeIter iter;
4204   GtkWidget *w;
4205   GtkWidget *del;
4206   GList *resources;
4207   GList *blanks;
4208   struct template_input_t *input;
4209   gchar *predicate;
4210   gchar *name;
4211 
4212   predicate = g_object_get_data (G_OBJECT (widget), "rdfs");
4213   if (!predicate || strcmp (predicate, rdf->predicate))
4214     return FALSE;
4215 
4216   entry = g_object_get_data (G_OBJECT (widget), "entry");
4217   input = g_object_get_data (G_OBJECT (entry), "input");
4218 
4219   switch (input->typevalue)
4220     {
4221     case TEMPLATE_INPUT_TYPEVALUE_RESOURCE:
4222     case TEMPLATE_INPUT_TYPEVALUE_ALT_RESOURCE:
4223       if (rdf->object_type != RDF_OBJECT_RESOURCE)
4224 	return FALSE;
4225       break;
4226 
4227     case TEMPLATE_INPUT_TYPEVALUE_LITERAL:
4228     case TEMPLATE_INPUT_TYPEVALUE_ALT_LITERAL:
4229       if (rdf->object_type != RDF_OBJECT_LITERAL)
4230 	return FALSE;
4231       break;
4232 
4233     default:
4234       break;
4235     }
4236 
4237   resources = g_object_get_data (G_OBJECT (entry), "resources");
4238   blanks = g_object_get_data (G_OBJECT (entry), "blanks");
4239 
4240   w = template_widget_create (resources, blanks, input, FALSE
4241 #ifdef USE_JS
4242 			      , g_object_get_data (G_OBJECT (widget), "js")
4243 #endif
4244     );
4245 
4246   template_widget_is_your (w, rdf, other);
4247 
4248   model = (GtkListStore *) gtk_tree_view_get_model (GTK_TREE_VIEW (entry));
4249   gtk_list_store_append (model, &iter);
4250 
4251   name = template_widget_name (w);
4252   gtk_list_store_set (model, &iter, 0, name, 1, w, -1);
4253   g_free (name);
4254 
4255   if (!GTK_IS_BUTTON (w))
4256     template_widget_standalone (w);
4257 
4258   /* Disattivo o attivo i pulsanti: */
4259   input = g_object_get_data (G_OBJECT (entry), "input");
4260   if (input->max_cardinality > 0
4261       && gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model),
4262 					 NULL) >= input->max_cardinality)
4263     gtk_widget_set_sensitive (widget, FALSE);
4264 
4265   del = g_object_get_data (G_OBJECT (entry), "del");
4266   gtk_widget_set_sensitive (del, TRUE);
4267 
4268   return TRUE;
4269 }
4270 
4271 static gboolean
template_widget_is_your(GtkWidget * widget,struct rdf_t * rdf,GList ** other)4272 template_widget_is_your (GtkWidget * widget, struct rdf_t *rdf,
4273 			 GList ** other)
4274 {
4275   struct template_func_t *func;
4276 
4277   func = g_object_get_data (G_OBJECT (widget), "func");
4278 
4279   if (func && func->is_your && func->is_your (widget, rdf, other) == TRUE)
4280     {
4281       g_object_set_data (G_OBJECT (widget), "rdf_prev", rdf);
4282       return TRUE;
4283     }
4284 
4285   return FALSE;
4286 }
4287 
4288 /* TEMPLATE CREATE WIDGETS ***************************************************/
4289 
4290 static void
template_widget_create_literal(struct template_input_t * input,GList * resources,GList * blanks,GtkWidget * table,gint * line,GtkWidget * top)4291 template_widget_create_literal (struct template_input_t *input,
4292 				GList * resources, GList * blanks,
4293 				GtkWidget * table, gint * line,
4294 				GtkWidget * top)
4295 {
4296   struct template_func_t *func;
4297   GtkWidget *label;
4298   GtkWidget *entry;
4299   GtkWidget *lang;
4300   GtkWidget *datatype;
4301 
4302   label = gtk_label_new (_("String:"));
4303   gtk_table_attach (GTK_TABLE (table), label, 0, 1, *line, *line + 1,
4304 		    (GtkAttachOptions) (GTK_FILL),
4305 		    (GtkAttachOptions) (0), 5, 0);
4306 
4307   if (input->longtext == FALSE)
4308     {
4309       entry = gtk_entry_new ();
4310       gtk_table_attach (GTK_TABLE (table), entry, 1, 2, *line, *line + 1,
4311 			(GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
4312 			(GtkAttachOptions) (0), 5, 0);
4313 
4314       if (input->default_value)
4315 	gtk_entry_set_text (GTK_ENTRY (entry), input->default_value);
4316     }
4317 
4318   else
4319     {
4320       GtkWidget *text;
4321       GtkWidget *scrolledwindow;
4322 
4323       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
4324       gtk_table_attach (GTK_TABLE (table), scrolledwindow, 1, 2, *line,
4325 			*line + 1, (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
4326 			(GtkAttachOptions) (0), 5, 0);
4327       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
4328 				      GTK_POLICY_AUTOMATIC,
4329 				      GTK_POLICY_AUTOMATIC);
4330 
4331 
4332       entry = (GtkWidget *) gtk_text_buffer_new (NULL);
4333 
4334       text = gtk_text_view_new_with_buffer (GTK_TEXT_BUFFER (entry));
4335       gtk_text_view_set_editable (GTK_TEXT_VIEW (text), TRUE);
4336       gtk_container_add (GTK_CONTAINER (scrolledwindow), text);
4337 
4338       if (input->default_value)
4339 	{
4340 	  GtkTextIter start;
4341 
4342 	  gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (entry), &start);
4343 	  gtk_text_buffer_insert (GTK_TEXT_BUFFER (entry), &start,
4344 				  input->default_value, -1);
4345 	}
4346     }
4347 
4348   g_object_set_data (G_OBJECT (top), "entry", entry);
4349 
4350   if (input->lang)
4351     {
4352       (*line)++;
4353 
4354       label = gtk_label_new (_("Language:"));
4355       gtk_table_attach (GTK_TABLE (table), label, 0, 1, *line, *line + 1,
4356 			(GtkAttachOptions) (GTK_FILL),
4357 			(GtkAttachOptions) (0), 5, 0);
4358 
4359       lang = gtk_entry_new ();
4360       gtk_table_attach (GTK_TABLE (table), lang, 1, 2, *line, *line + 1,
4361 			(GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
4362 			(GtkAttachOptions) (0), 5, 0);
4363 
4364       if (input->default_language)
4365 	gtk_entry_set_text (GTK_ENTRY (lang), input->default_language);
4366 
4367       g_object_set_data (G_OBJECT (top), "lang", lang);
4368     }
4369 
4370   if (input->datatype)
4371     {
4372       gint id;
4373       GtkWidget *frame, *box, *hbox;
4374       struct datatype_t *datatypes = datatype_list ();
4375 
4376       (*line)++;
4377 
4378       frame = gtk_frame_new (NULL);
4379       gtk_table_attach (GTK_TABLE (table), frame, 0, 2, *line, *line + 1,
4380 			(GtkAttachOptions) (GTK_FILL),
4381 			(GtkAttachOptions) (0), 5, 0);
4382 
4383       box = gtk_vbox_new (FALSE, 5);
4384       gtk_container_add (GTK_CONTAINER (frame), box);
4385 
4386       hbox = gtk_hbox_new (FALSE, 0);
4387       gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 5);
4388 
4389       label = gtk_label_new (_("Datatype:"));
4390       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 5);
4391 
4392       datatype = gtk_combo_box_entry_new_text ();
4393       gtk_box_pack_start (GTK_BOX (hbox), datatype, TRUE, TRUE, 5);
4394 
4395       (*line)++;
4396 
4397       label = gtk_label_new ("");
4398       gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 5);
4399       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
4400       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
4401 
4402       gtk_combo_box_append_text (GTK_COMBO_BOX (datatype), datatypes[0].uri);
4403       gtk_combo_box_set_active (GTK_COMBO_BOX (datatype), 0);
4404 
4405       for (id = 1; datatypes[id].uri; id++)
4406 	{
4407 	  gtk_combo_box_append_text (GTK_COMBO_BOX (datatype),
4408 				     datatypes[id].uri);
4409 
4410 	  if (input->default_datatype
4411 	      && !strcmp (input->default_datatype, datatypes[id].uri))
4412 	    gtk_combo_box_set_active (GTK_COMBO_BOX (datatype), id);
4413 	}
4414 
4415       datatype_change (datatype, label);
4416       g_signal_connect_after ((gpointer) datatype, "changed",
4417 			      G_CALLBACK (datatype_change), label);
4418 
4419       g_object_set_data (G_OBJECT (top), "datatype", datatype);
4420     }
4421 
4422   func = g_malloc0 (sizeof (struct template_func_t));
4423 
4424   func->type = TEMPLATE_WIDGET_LITERAL;
4425   func->low_check = template_widget_low_check_literal;
4426   func->high_check = template_widget_high_check_literal;
4427   func->save = template_widget_save_literal;
4428   func->get = template_widget_get_literal;
4429   func->set = template_widget_set_literal;
4430   func->is_your = template_widget_is_your_literal;
4431   func->name = template_widget_name_literal;
4432 
4433   g_object_set_data (G_OBJECT (top), "func", func);
4434 }
4435 
4436 static void
template_widget_create_resource(struct template_input_t * input,GList * resources,GList * blanks,GtkWidget * table,gint * line,GtkWidget * top)4437 template_widget_create_resource (struct template_input_t *input,
4438 				 GList * resources, GList * blanks,
4439 				 GtkWidget * table, gint * line,
4440 				 GtkWidget * top)
4441 {
4442   GtkWidget *label;
4443   GtkWidget *entry;
4444   GtkWidget *hbox;
4445   GtkWidget *button;
4446   GtkWidget *image;
4447   struct template_func_t *func;
4448 
4449   label = gtk_label_new (_("Resource:"));
4450   gtk_table_attach (GTK_TABLE (table), label, 0, 1, *line, *line + 1,
4451 		    (GtkAttachOptions) (GTK_FILL),
4452 		    (GtkAttachOptions) (0), 5, 0);
4453 
4454   hbox = gtk_hbox_new (FALSE, 0);
4455 
4456   entry = gtk_entry_new ();
4457   gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
4458 
4459   if (input->default_value)
4460     gtk_entry_set_text (GTK_ENTRY (entry), input->default_value);
4461 
4462   button = gtk_button_new ();
4463   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
4464   g_object_set_data (G_OBJECT (button), "list", resources);
4465   g_signal_connect ((gpointer) button, "clicked",
4466 		    G_CALLBACK (search_resources), entry);
4467 
4468   image = gtk_image_new_from_stock ("gtk-find", GTK_ICON_SIZE_MENU);
4469   gtk_container_add (GTK_CONTAINER (button), image);
4470 
4471   gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, *line, *line + 1,
4472 		    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
4473 		    (GtkAttachOptions) (0), 5, 0);
4474 
4475   func = g_malloc0 (sizeof (struct template_func_t));
4476 
4477   func->type = TEMPLATE_WIDGET_RESOURCE;
4478   func->high_check = template_widget_high_check_resource;
4479   func->save = template_widget_save_resource;
4480   func->get = template_widget_get_resource;
4481   func->set = template_widget_set_resource;
4482   func->is_your = template_widget_is_your_resource;
4483   func->name = template_widget_name_resource;
4484 
4485   g_object_set_data (G_OBJECT (top), "func", func);
4486   g_object_set_data (G_OBJECT (top), "entry", entry);
4487 }
4488 
4489 static void
template_widget_create_alt_literal(struct template_input_t * input,GList * resources,GList * blanks,GtkWidget * table,gint * line,GtkWidget * top)4490 template_widget_create_alt_literal (struct template_input_t *input,
4491 				    GList * resources, GList * blanks,
4492 				    GtkWidget * table, gint * line,
4493 				    GtkWidget * top)
4494 {
4495   GtkWidget *label;
4496   GtkWidget *entry;
4497   GList *list;
4498   gint id = 0;
4499   struct template_func_t *func;
4500 
4501   label = gtk_label_new (_("Literal:"));
4502   gtk_table_attach (GTK_TABLE (table), label, 0, 1, *line, *line + 1,
4503 		    (GtkAttachOptions) (GTK_FILL),
4504 		    (GtkAttachOptions) (0), 5, 0);
4505 
4506   entry = gtk_combo_box_entry_new_text ();
4507 
4508   list = input->alt_typevalue;
4509   id = 0;
4510 
4511   while (list)
4512     {
4513       gtk_combo_box_append_text (GTK_COMBO_BOX (entry), list->data);
4514 
4515       if (input->default_value
4516 	  && !strcmp ((gchar *) list->data, input->default_value))
4517 	gtk_combo_box_set_active (GTK_COMBO_BOX (entry), id);
4518 
4519       id++;
4520       list = list->next;
4521     }
4522 
4523   gtk_combo_box_set_active (GTK_COMBO_BOX (entry), 0);
4524 
4525   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, *line, *line + 1,
4526 		    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
4527 		    (GtkAttachOptions) (0), 5, 0);
4528 
4529   func = g_malloc0 (sizeof (struct template_func_t));
4530 
4531   func->type = TEMPLATE_WIDGET_ALT_LITERAL;
4532   func->high_check = template_widget_high_check_alt_literal;
4533   func->save = template_widget_save_alt_literal;
4534   func->get = template_widget_get_alt_literal;
4535   func->set = template_widget_set_alt_literal;
4536   func->is_your = template_widget_is_your_alt_literal;
4537   func->name = template_widget_name_alt_literal;
4538 
4539   g_object_set_data (G_OBJECT (top), "entry", entry);
4540   g_object_set_data (G_OBJECT (top), "func", func);
4541 }
4542 
4543 static void
template_widget_create_alt_resource(struct template_input_t * input,GList * resources,GList * blanks,GtkWidget * table,gint * line,GtkWidget * top)4544 template_widget_create_alt_resource (struct template_input_t *input,
4545 				     GList * resources, GList * blanks,
4546 				     GtkWidget * table, gint * line,
4547 				     GtkWidget * top)
4548 {
4549   GtkWidget *label;
4550   GtkWidget *entry;
4551   GList *list;
4552   gint id = 0;
4553   struct template_func_t *func;
4554 
4555   label = gtk_label_new (_("Resource:"));
4556   gtk_table_attach (GTK_TABLE (table), label, 0, 1, *line, *line + 1,
4557 		    (GtkAttachOptions) (GTK_FILL),
4558 		    (GtkAttachOptions) (0), 5, 0);
4559 
4560   entry = gtk_combo_box_entry_new_text ();
4561 
4562   list = input->alt_typevalue;
4563   id = 0;
4564 
4565   while (list)
4566     {
4567       gtk_combo_box_append_text (GTK_COMBO_BOX (entry), list->data);
4568 
4569       if (input->default_value
4570 	  && !strcmp ((gchar *) list->data, input->default_value))
4571 	gtk_combo_box_set_active (GTK_COMBO_BOX (entry), id);
4572 
4573       id++;
4574       list = list->next;
4575     }
4576 
4577   gtk_combo_box_set_active (GTK_COMBO_BOX (entry), 0);
4578 
4579   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, *line, *line + 1,
4580 		    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
4581 		    (GtkAttachOptions) (0), 5, 0);
4582 
4583   func = g_malloc0 (sizeof (struct template_func_t));
4584 
4585   func->type = TEMPLATE_WIDGET_ALT_RESOURCE;
4586   func->high_check = template_widget_high_check_alt_resource;
4587   func->save = template_widget_save_alt_resource;
4588   func->get = template_widget_get_alt_resource;
4589   func->set = template_widget_set_alt_resource;
4590   func->is_your = template_widget_is_your_alt_resource;
4591   func->name = template_widget_name_alt_resource;
4592 
4593   g_object_set_data (G_OBJECT (top), "entry", entry);
4594   g_object_set_data (G_OBJECT (top), "func", func);
4595   g_object_set_data (G_OBJECT (top), "entry", entry);
4596 }
4597 
4598 static void
template_widget_create_other(struct template_input_t * input,GList * resources,GList * blanks,GtkWidget * table,gint * line,GtkWidget * top)4599 template_widget_create_other (struct template_input_t *input,
4600 			      GList * resources, GList * blanks,
4601 			      GtkWidget * table, gint * line, GtkWidget * top)
4602 {
4603   GtkWidget *label;
4604   GtkWidget *hbox;
4605   GtkWidget *entry;
4606   GtkWidget *button;
4607   GtkWidget *image;
4608   GList *list;
4609   struct template_t *template;
4610   struct template_func_t *func;
4611 
4612   list = template_list;
4613   while (list)
4614     {
4615       template = list->data;
4616 
4617       if (!strcmp (template->uri, input->other_typevalue))
4618 	break;
4619 
4620       list = list->next;
4621     }
4622 
4623   if (!list)
4624     {
4625       label = gtk_label_new (_("Template:"));
4626       gtk_table_attach (GTK_TABLE (table), label, 0, 1, *line,
4627 			*line + 1, (GtkAttachOptions) (GTK_FILL),
4628 			(GtkAttachOptions) (0), 5, 0);
4629 
4630       hbox = gtk_hbox_new (FALSE, 0);
4631 
4632       entry = gtk_entry_new ();
4633       gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
4634 
4635       button = gtk_button_new ();
4636       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
4637       g_object_set_data (G_OBJECT (button), "list", resources);
4638       g_signal_connect ((gpointer) button, "clicked",
4639 			G_CALLBACK (search_resources), entry);
4640 
4641       image = gtk_image_new_from_stock ("gtk-find", GTK_ICON_SIZE_MENU);
4642       gtk_container_add (GTK_CONTAINER (button), image);
4643 
4644       gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, *line,
4645 			*line + 1,
4646 			(GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
4647 			(GtkAttachOptions) (0), 5, 0);
4648     }
4649   else
4650     {
4651       entry = gtk_button_new_with_label (template->name);
4652       g_object_set_data (G_OBJECT (entry), "resources", resources);
4653       g_object_set_data (G_OBJECT (entry), "blanks", blanks);
4654       g_object_set_data (G_OBJECT (entry), "template", template);
4655       g_signal_connect ((gpointer) entry, "clicked",
4656 			G_CALLBACK (template_run), template);
4657 
4658       gtk_table_attach (GTK_TABLE (table), entry, 0, 2, *line,
4659 			*line + 1,
4660 			(GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
4661 			(GtkAttachOptions) (0), 5, 0);
4662     }
4663 
4664   func = g_malloc0 (sizeof (struct template_func_t));
4665 
4666   func->type = TEMPLATE_WIDGET_OTHER;
4667   func->low_check = template_widget_low_check_other;
4668   func->high_check = template_widget_high_check_other;
4669   func->save = template_widget_save_other;
4670   func->get = template_widget_get_other;
4671   func->set = template_widget_set_other;
4672   func->is_your = template_widget_is_your_other;
4673   func->name = template_widget_name_other;
4674   func->destroy = template_widget_destroy_other;
4675 
4676   g_object_set_data (G_OBJECT (top), "entry", entry);
4677   g_object_set_data (G_OBJECT (top), "func", func);
4678 }
4679 
4680 /* Questa funzione viene azionata dai radiobutton della tipologia coggetto */
4681 static void
template_widget_create_default_toggled(GtkWidget * w,gpointer dummy)4682 template_widget_create_default_toggled (GtkWidget * w, gpointer dummy)
4683 {
4684   GtkWidget *t_literal;
4685   GtkWidget *t_resource;
4686   GtkWidget *t_blanknode;
4687   GtkWidget *object;
4688   GtkWidget *lang;
4689   GtkWidget *datatype;
4690   GList *resources;
4691   GList *blanks;
4692 
4693   /* Una serie di valori che mi servono: */
4694   t_literal = (GtkWidget *) g_object_get_data (G_OBJECT (w), "literal");
4695   t_resource = (GtkWidget *) g_object_get_data (G_OBJECT (w), "resource");
4696   t_blanknode = (GtkWidget *) g_object_get_data (G_OBJECT (w), "blanknode");
4697   blanks = (GList *) g_object_get_data (G_OBJECT (w), "blank_list");
4698   resources = (GList *) g_object_get_data (G_OBJECT (w), "resources_list");
4699   object = (GtkWidget *) g_object_get_data (G_OBJECT (w), "object");
4700   lang = (GtkWidget *) g_object_get_data (G_OBJECT (w), "lang");
4701   datatype = (GtkWidget *) g_object_get_data (G_OBJECT (w), "datatype");
4702 
4703   /* Se e' stato selezionato un letterale non ci devono essere suggerimenti
4704    * e la lungua e' sensibile:*/
4705   if (w == t_literal)
4706     {
4707       g_object_steal_data (G_OBJECT (object), "list");
4708       gtk_widget_set_sensitive (lang, TRUE);
4709       gtk_widget_set_sensitive (datatype, TRUE);
4710     }
4711 
4712   /* Negli altri casi cambia la tipologia di suggerimento: */
4713   else if (w == t_resource)
4714     {
4715       g_object_set_data (G_OBJECT (object), "list", resources);
4716       gtk_widget_set_sensitive (lang, FALSE);
4717       gtk_widget_set_sensitive (datatype, FALSE);
4718     }
4719 
4720   else
4721     {
4722       g_object_set_data (G_OBJECT (object), "list", blanks);
4723       gtk_widget_set_sensitive (lang, FALSE);
4724       gtk_widget_set_sensitive (datatype, FALSE);
4725     }
4726 }
4727 
4728 static void
template_widget_create_default(struct template_input_t * input,GList * resources,GList * blanks,GtkWidget * table,gint * line,GtkWidget * top)4729 template_widget_create_default (struct template_input_t *input,
4730 				GList * resources, GList * blanks,
4731 				GtkWidget * table, gint * line,
4732 				GtkWidget * top)
4733 {
4734   GtkWidget *label;
4735   GtkWidget *hbox;
4736   GtkWidget *entry;
4737   GtkWidget *lang;
4738   GtkWidget *datatype;
4739   GtkWidget *type_literal;
4740   GtkWidget *type_resource;
4741   GtkWidget *type_blanknode;
4742   GtkWidget *button;
4743   GtkWidget *image;
4744   GtkWidget *frame;
4745   GtkWidget *box;
4746   gint id;
4747   GSList *l = NULL;
4748   struct template_func_t *func;
4749   struct datatype_t *datatypes = datatype_list ();
4750 
4751   label = gtk_label_new (_("Type:"));
4752   gtk_table_attach (GTK_TABLE (table), label, 0, 1, *line, *line + 3,
4753 		    (GtkAttachOptions) (GTK_FILL),
4754 		    (GtkAttachOptions) (0), 5, 0);
4755 
4756   type_literal = gtk_radio_button_new_with_label (NULL, _("Literal"));
4757   gtk_radio_button_set_group (GTK_RADIO_BUTTON (type_literal), l);
4758   l = gtk_radio_button_get_group (GTK_RADIO_BUTTON (type_literal));
4759 
4760   gtk_table_attach (GTK_TABLE (table), type_literal, 1, 2, *line,
4761 		    *line + 1, (GtkAttachOptions) (GTK_FILL),
4762 		    (GtkAttachOptions) (0), 5, 0);
4763 
4764   type_resource = gtk_radio_button_new_with_label (NULL, _("Resource"));
4765   gtk_radio_button_set_group (GTK_RADIO_BUTTON (type_resource), l);
4766   l = gtk_radio_button_get_group (GTK_RADIO_BUTTON (type_resource));
4767 
4768   (*line)++;
4769   gtk_table_attach (GTK_TABLE (table), type_resource, 1, 2, *line,
4770 		    *line + 1, (GtkAttachOptions) (GTK_FILL),
4771 		    (GtkAttachOptions) (0), 5, 0);
4772 
4773   type_blanknode = gtk_radio_button_new_with_label (NULL, _("Blank node"));
4774   gtk_radio_button_set_group (GTK_RADIO_BUTTON (type_blanknode), l);
4775   l = gtk_radio_button_get_group (GTK_RADIO_BUTTON (type_blanknode));
4776 
4777   (*line)++;
4778   gtk_table_attach (GTK_TABLE (table), type_blanknode, 1, 2, *line,
4779 		    *line + 1, (GtkAttachOptions) (GTK_FILL),
4780 		    (GtkAttachOptions) (0), 5, 0);
4781 
4782   (*line)++;
4783   label = gtk_label_new (_("Language:"));
4784   gtk_table_attach (GTK_TABLE (table), label, 0, 1, *line, *line + 1,
4785 		    (GtkAttachOptions) (GTK_FILL),
4786 		    (GtkAttachOptions) (0), 5, 0);
4787 
4788   lang = gtk_entry_new ();
4789   gtk_table_attach (GTK_TABLE (table), lang, 1, 2, *line, *line + 1,
4790 		    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
4791 		    (GtkAttachOptions) (0), 5, 0);
4792   g_object_set_data (G_OBJECT (top), "lang", lang);
4793 
4794   if (input->default_language)
4795     gtk_entry_set_text (GTK_ENTRY (lang), input->default_language);
4796 
4797   (*line)++;
4798 
4799   frame = gtk_frame_new (NULL);
4800   gtk_table_attach (GTK_TABLE (table), frame, 0, 2, *line, *line + 1,
4801 		    (GtkAttachOptions) (GTK_FILL),
4802 		    (GtkAttachOptions) (0), 5, 0);
4803 
4804   box = gtk_vbox_new (FALSE, 5);
4805   gtk_container_add (GTK_CONTAINER (frame), box);
4806 
4807   hbox = gtk_hbox_new (FALSE, 0);
4808   gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 5);
4809 
4810   label = gtk_label_new (_("Datatype:"));
4811   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 5);
4812 
4813   datatype = gtk_combo_box_entry_new_text ();
4814   gtk_box_pack_start (GTK_BOX (hbox), datatype, TRUE, TRUE, 5);
4815 
4816   label = gtk_label_new ("");
4817   gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 5);
4818   gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
4819   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
4820 
4821   gtk_combo_box_append_text (GTK_COMBO_BOX (datatype), datatypes[0].uri);
4822   gtk_combo_box_set_active (GTK_COMBO_BOX (datatype), 0);
4823 
4824   for (id = 1; datatypes[id].uri; id++)
4825     {
4826       gtk_combo_box_append_text (GTK_COMBO_BOX (datatype), datatypes[id].uri);
4827 
4828       if (input->default_datatype
4829 	  && !strcmp (input->default_datatype, datatypes[id].uri))
4830 	gtk_combo_box_set_active (GTK_COMBO_BOX (datatype), id);
4831     }
4832 
4833   datatype_change (datatype, label);
4834   g_signal_connect_after ((gpointer) datatype, "changed",
4835 			  G_CALLBACK (datatype_change), label);
4836 
4837   g_object_set_data (G_OBJECT (top), "datatype", datatype);
4838 
4839   (*line)++;
4840   label = gtk_label_new (_("Value:"));
4841   gtk_table_attach (GTK_TABLE (table), label, 0, 1, *line, *line + 1,
4842 		    (GtkAttachOptions) (GTK_FILL),
4843 		    (GtkAttachOptions) (0), 5, 0);
4844 
4845   hbox = gtk_hbox_new (FALSE, 0);
4846 
4847   entry = gtk_entry_new ();
4848   gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
4849 
4850   if (input->default_value)
4851     gtk_entry_set_text (GTK_ENTRY (entry), input->default_value);
4852 
4853   button = gtk_button_new ();
4854   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
4855   g_object_set_data (G_OBJECT (button), "list", resources);
4856   g_signal_connect ((gpointer) button, "clicked",
4857 		    G_CALLBACK (search_resources), entry);
4858 
4859   image = gtk_image_new_from_stock ("gtk-find", GTK_ICON_SIZE_MENU);
4860   gtk_container_add (GTK_CONTAINER (button), image);
4861 
4862   gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, *line, *line + 1,
4863 		    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
4864 		    (GtkAttachOptions) (0), 5, 0);
4865 
4866   g_object_set_data (G_OBJECT (top), "entry", entry);
4867   g_object_set_data (G_OBJECT (top), "type_literal", type_literal);
4868   g_object_set_data (G_OBJECT (top), "type_resource", type_resource);
4869   g_object_set_data (G_OBJECT (top), "type_blanknode", type_blanknode);
4870 
4871   func = g_malloc0 (sizeof (struct template_func_t));
4872 
4873   func->type = TEMPLATE_WIDGET_DEFAULT;
4874   func->low_check = template_widget_low_check_default;
4875   func->high_check = template_widget_high_check_default;
4876   func->save = template_widget_save_default;
4877   func->get = template_widget_get_default;
4878   func->set = template_widget_set_default;
4879   func->is_your = template_widget_is_your_default;
4880   func->name = template_widget_name_default;
4881 
4882   g_object_set_data (G_OBJECT (top), "entry", entry);
4883   g_object_set_data (G_OBJECT (top), "func", func);
4884 
4885   /* Variabili per le funzioni di callback: */
4886   g_object_set_data (G_OBJECT (type_literal), "literal", type_literal);
4887   g_object_set_data (G_OBJECT (type_literal), "resource", type_resource);
4888   g_object_set_data (G_OBJECT (type_literal), "blanknode", type_blanknode);
4889   g_object_set_data (G_OBJECT (type_literal), "blank_list", blanks);
4890   g_object_set_data (G_OBJECT (type_literal), "resources_list", resources);
4891   g_object_set_data (G_OBJECT (type_literal), "object", button);
4892   g_object_set_data (G_OBJECT (type_literal), "lang", lang);
4893   g_object_set_data (G_OBJECT (type_literal), "datatype", datatype);
4894 
4895   g_object_set_data (G_OBJECT (type_resource), "literal", type_literal);
4896   g_object_set_data (G_OBJECT (type_resource), "resource", type_resource);
4897   g_object_set_data (G_OBJECT (type_resource), "blanknode", type_blanknode);
4898   g_object_set_data (G_OBJECT (type_resource), "blank_list", blanks);
4899   g_object_set_data (G_OBJECT (type_resource), "resources_list", resources);
4900   g_object_set_data (G_OBJECT (type_resource), "object", button);
4901   g_object_set_data (G_OBJECT (type_resource), "lang", lang);
4902   g_object_set_data (G_OBJECT (type_resource), "datatype", datatype);
4903 
4904   g_object_set_data (G_OBJECT (type_blanknode), "literal", type_literal);
4905   g_object_set_data (G_OBJECT (type_blanknode), "resource", type_resource);
4906   g_object_set_data (G_OBJECT (type_blanknode), "blanknode", type_blanknode);
4907   g_object_set_data (G_OBJECT (type_blanknode), "blank_list", blanks);
4908   g_object_set_data (G_OBJECT (type_blanknode), "resources_list", resources);
4909   g_object_set_data (G_OBJECT (type_blanknode), "object", button);
4910   g_object_set_data (G_OBJECT (type_blanknode), "lang", lang);
4911   g_object_set_data (G_OBJECT (type_blanknode), "datatype", datatype);
4912 
4913   g_signal_connect_after ((gpointer) type_literal, "toggled",
4914 			  G_CALLBACK (template_widget_create_default_toggled),
4915 			  NULL);
4916   g_signal_connect_after ((gpointer) type_blanknode, "toggled",
4917 			  G_CALLBACK (template_widget_create_default_toggled),
4918 			  NULL);
4919   g_signal_connect_after ((gpointer) type_resource, "toggled",
4920 			  G_CALLBACK (template_widget_create_default_toggled),
4921 			  NULL);
4922 }
4923 
4924 static void
template_widget_create_cardinality(struct template_input_t * input,GList * resources,GList * blanks,GtkWidget * table,gint * line,GtkWidget * top)4925 template_widget_create_cardinality (struct template_input_t *input,
4926 				    GList * resources, GList * blanks,
4927 				    GtkWidget * table, gint * line,
4928 				    GtkWidget * top)
4929 {
4930   GtkWidget *label;
4931   GtkWidget *entry;
4932   gchar buf[1024];
4933   GtkWidget *scrolledwindow;
4934   GtkListStore *model;
4935   GtkWidget *b_add, *b_del;
4936   GtkTreeSelection *selection;
4937   GtkCellRenderer *renderer;
4938   GtkTreeViewColumn *column;
4939   struct template_func_t *func;
4940 
4941   scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
4942   gtk_table_attach (GTK_TABLE (table), scrolledwindow, 0, 2, *line,
4943 		    *line + 1, (GtkAttachOptions) (GTK_FILL),
4944 		    (GtkAttachOptions) (0), 5, 0);
4945   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
4946 				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
4947   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW
4948 				       (scrolledwindow), GTK_SHADOW_IN);
4949 
4950   model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
4951 
4952   entry = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
4953   gtk_tree_view_set_enable_search (GTK_TREE_VIEW (entry), TRUE);
4954   gtk_container_add (GTK_CONTAINER (scrolledwindow), entry);
4955   g_signal_connect ((gpointer) entry, "row_activated",
4956 		    G_CALLBACK (template_widget_list_select), NULL);
4957 
4958   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (entry));
4959   gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
4960 
4961   gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (entry), TRUE);
4962 
4963   renderer = gtk_cell_renderer_text_new ();
4964   column =
4965     gtk_tree_view_column_new_with_attributes (_("List"), renderer,
4966 					      "text", 0, NULL);
4967   gtk_tree_view_append_column (GTK_TREE_VIEW (entry), column);
4968   gtk_tree_view_column_set_resizable (column, TRUE);
4969 
4970   (*line)++;
4971 
4972   /* Pulsanti per l'aggiunta e la rimozione di elementi: */
4973   b_del = gtk_button_new_from_stock ("gtk-remove");
4974   gtk_widget_set_sensitive (b_del, FALSE);
4975   g_object_set_data (G_OBJECT (b_del), "input", input);
4976 
4977   gtk_table_attach (GTK_TABLE (table), b_del, 0, 1, *line, *line + 1,
4978 		    (GTK_EXPAND | GTK_FILL), 0, 5, 0);
4979   g_signal_connect (G_OBJECT (b_del), "clicked",
4980 		    G_CALLBACK (template_widget_list_remove), entry);
4981 
4982   b_add = gtk_button_new_from_stock ("gtk-add");
4983   g_object_set_data (G_OBJECT (b_add), "del", b_del);
4984   g_object_set_data (G_OBJECT (b_add), "input", input);
4985   g_object_set_data (G_OBJECT (b_add), "resources", resources);
4986   g_object_set_data (G_OBJECT (b_add), "blanks", blanks);
4987 
4988 #ifdef USE_JS
4989   g_object_set_data (G_OBJECT (b_add), "js",
4990 		     g_object_get_data (G_OBJECT (top), "js"));
4991 #endif
4992 
4993   g_object_set_data (G_OBJECT (b_del), "add", b_add);
4994 
4995   gtk_table_attach (GTK_TABLE (table), b_add, 1, 2, *line, *line + 1,
4996 		    (GTK_EXPAND | GTK_FILL), 0, 5, 0);
4997   g_signal_connect (G_OBJECT (b_add), "clicked",
4998 		    G_CALLBACK (template_widget_list_add), entry);
4999 
5000   /* Informazioni sulla cardinalita': */
5001   (*line)++;
5002   g_snprintf (buf, sizeof (buf), _("Min Card.: %d"), input->min_cardinality);
5003   label = gtk_label_new (buf);
5004   gtk_table_attach (GTK_TABLE (table), label, 0, 1, *line, *line + 1,
5005 		    (GtkAttachOptions) (GTK_FILL),
5006 		    (GtkAttachOptions) (0), 5, 0);
5007 
5008   if (input->max_cardinality <= 0)
5009     g_snprintf (buf, sizeof (buf), _("Max Card.: infinite"));
5010   else
5011     g_snprintf (buf, sizeof (buf), _("Max Card.: %d"),
5012 		input->max_cardinality);
5013 
5014   label = gtk_label_new (buf);
5015   gtk_table_attach (GTK_TABLE (table), label, 1, 2, *line, *line + 1,
5016 		    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
5017 		    (GtkAttachOptions) (0), 5, 0);
5018 
5019   g_object_set_data (G_OBJECT (top), "entry", entry);
5020   g_object_set_data (G_OBJECT (entry), "input", input);
5021   g_object_set_data (G_OBJECT (entry), "resources", resources);
5022   g_object_set_data (G_OBJECT (entry), "blanks", blanks);
5023   g_object_set_data (G_OBJECT (entry), "del", b_del);
5024 
5025   func = g_malloc0 (sizeof (struct template_func_t));
5026 
5027   func->type = TEMPLATE_WIDGET_CARDINALITY;
5028   func->high_check = template_widget_high_check_cardinality;
5029   func->save = template_widget_save_cardinality;
5030   func->is_your = template_widget_is_your_cardinality;
5031   func->destroy = template_widget_destroy_cardinality;
5032 
5033   g_object_set_data (G_OBJECT (top), "func", func);
5034 }
5035 
5036 /* Questa funzione crea l'oggetto di un input per template: */
5037 static GtkWidget *
template_widget_create(GList * resources,GList * blanks,struct template_input_t * input,gboolean cardinality,struct js_t * js)5038 template_widget_create (GList * resources, GList * blanks,
5039 			struct template_input_t *input, gboolean cardinality
5040 #ifdef USE_JS
5041 			, struct js_t *js
5042 #endif
5043   )
5044 {
5045   GtkWidget *frame;
5046   GtkWidget *table;
5047   GtkWidget *event;
5048   GtkWidget *label;
5049   gint line = 0;
5050   struct info_box_t *label_value = NULL;
5051   struct info_box_t *comment_value = NULL;
5052   GList *list;
5053 
5054   frame = gtk_frame_new (NULL);
5055 #ifdef USE_JS
5056   g_object_set_data (G_OBJECT (frame), "js", js);
5057 #endif
5058 
5059   /* Cerco il label piu' appropriato: */
5060   list = input->labels;
5061   while (list)
5062     {
5063       label_value = list->data;
5064 
5065       if (!label_value->lang)
5066 	break;
5067 
5068       list = list->next;
5069     }
5070 
5071   if (!list)
5072     label_value = input->labels->data;
5073 
5074   event = gtk_event_box_new ();
5075   gtk_widget_set_events (event, GDK_BUTTON_PRESS_MASK);
5076   g_signal_connect (G_OBJECT (event), "enter-notify-event",
5077 		    G_CALLBACK (info_box_enter), NULL);
5078   g_signal_connect (G_OBJECT (event), "leave-notify-event",
5079 		    G_CALLBACK (info_box_leave), NULL);
5080   g_signal_connect (G_OBJECT (event), "button_press_event",
5081 		    G_CALLBACK (info_box_popup_show), input->labels);
5082   g_signal_connect (G_OBJECT (event), "button_release_event",
5083 		    G_CALLBACK (info_box_popup_hide), NULL);
5084 
5085   gtk_frame_set_label_widget (GTK_FRAME (frame), event);
5086 
5087   /* Grassetto se la cardinalita' minima e' > di 0: */
5088   if (cardinality == TRUE && input->min_cardinality > 0)
5089     {
5090       gchar *s;
5091       gchar *str;
5092 
5093       str = markup (label_value->value);
5094       s = g_strdup_printf ("<b>%s</b>", str);
5095       g_free (str);
5096 
5097       label = gtk_label_new (s);
5098       g_free (s);
5099 
5100       gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
5101       g_object_set_data (G_OBJECT (event), "bold", (gpointer) TRUE);
5102     }
5103   else
5104     {
5105       gchar *str;
5106 
5107       str = markup (label_value->value);
5108       label = gtk_label_new (str);
5109       g_free (str);
5110     }
5111 
5112   gtk_container_add (GTK_CONTAINER (event), label);
5113 
5114   table = gtk_table_new (0, 0, FALSE);
5115   gtk_container_add (GTK_CONTAINER (frame), table);
5116 
5117   /* Se la cardinalita' mi impone 1 elemento come massimo allora: */
5118   if (cardinality == FALSE
5119       || (input->min_cardinality <= 1 && input->max_cardinality == 1))
5120     {
5121       switch (input->typevalue)
5122 	{
5123 	  /* Se e' un letterale, valore e lingua: */
5124 	case TEMPLATE_INPUT_TYPEVALUE_LITERAL:
5125 	  template_widget_create_literal (input, resources, blanks, table,
5126 					  &line, frame);
5127 	  break;
5128 
5129 	  /* Se e' una risorsa un combobox con suggerimenti: */
5130 	case TEMPLATE_INPUT_TYPEVALUE_RESOURCE:
5131 	  template_widget_create_resource (input, resources, blanks, table,
5132 					   &line, frame);
5133 	  break;
5134 
5135 	  /* Se e' un'alternativa genero una combobox: */
5136 	case TEMPLATE_INPUT_TYPEVALUE_ALT_RESOURCE:
5137 	  template_widget_create_alt_resource (input, resources, blanks,
5138 					       table, &line, frame);
5139 	  break;
5140 
5141 	case TEMPLATE_INPUT_TYPEVALUE_ALT_LITERAL:
5142 	  template_widget_create_alt_literal (input, resources, blanks, table,
5143 					      &line, frame);
5144 	  break;
5145 
5146 	  /* Se devo richiamare un altro template: */
5147 	case TEMPLATE_INPUT_TYPEVALUE_OTHER:
5148 	  template_widget_create_other (input, resources, blanks, table,
5149 					&line, frame);
5150 	  break;
5151 
5152 	  /* Altrimenti scelta multipla: */
5153 	default:
5154 	  template_widget_create_default (input, resources, blanks, table,
5155 					  &line, frame);
5156 	  break;
5157 	}
5158     }
5159 
5160   /* Cardinalita' maggiore di 1: */
5161   else
5162     template_widget_create_cardinality (input, resources, blanks, table,
5163 					&line, frame);
5164 
5165   /* Se ho un commento da mostrare lo mostro: */
5166   if (input->comments)
5167     {
5168       gchar *str;
5169 
5170       line++;
5171 
5172       /* Cerco il commento piu' appropriato: */
5173       list = input->comments;
5174       while (list)
5175 	{
5176 	  comment_value = list->data;
5177 
5178 	  if (!comment_value->lang)
5179 	    break;
5180 
5181 	  list = list->next;
5182 	}
5183 
5184       if (!list)
5185 	comment_value = input->comments->data;
5186 
5187       label = gtk_label_new (_("Comment:"));
5188       gtk_table_attach (GTK_TABLE (table), label, 0, 1, line, line + 1,
5189 			(GtkAttachOptions) (GTK_FILL),
5190 			(GtkAttachOptions) (0), 5, 0);
5191 
5192       event = gtk_event_box_new ();
5193       gtk_widget_set_events (event, GDK_BUTTON_PRESS_MASK);
5194       g_signal_connect (G_OBJECT (event), "enter-notify-event",
5195 			G_CALLBACK (info_box_enter), NULL);
5196       g_signal_connect (G_OBJECT (event), "leave-notify-event",
5197 			G_CALLBACK (info_box_leave), NULL);
5198       g_signal_connect (G_OBJECT (event), "button_press_event",
5199 			G_CALLBACK (info_box_popup_show), input->comments);
5200       g_signal_connect (G_OBJECT (event), "button_release_event",
5201 			G_CALLBACK (info_box_popup_hide), NULL);
5202 
5203       gtk_table_attach (GTK_TABLE (table), event, 1, 2, line, line + 1,
5204 			(GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
5205 			(GtkAttachOptions) (0), 5, 0);
5206 
5207       str = markup (comment_value->value);
5208       label = gtk_label_new (str);
5209       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
5210       gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
5211       g_free (str);
5212 
5213       gtk_container_add (GTK_CONTAINER (event), label);
5214     }
5215 
5216   g_object_set_data (G_OBJECT (frame), "label", label_value->value);
5217   g_object_set_data (G_OBJECT (frame), "min_cardinality",
5218 		     (gpointer) input->min_cardinality);
5219   g_object_set_data (G_OBJECT (frame), "rdfs", input->rdfs);
5220   g_object_set_data (G_OBJECT (frame), "typevalue",
5221 		     (gpointer) input->typevalue);
5222 
5223   if (input->function_check)
5224     g_object_set_data (G_OBJECT (frame), "function_check",
5225 		       (gpointer) input->function_check);
5226 
5227   if (input->function_destroy)
5228     g_object_set_data (G_OBJECT (frame), "function_destroy",
5229 		       (gpointer) input->function_destroy);
5230 
5231   if (input->function_save)
5232     g_object_set_data (G_OBJECT (frame), "function_save",
5233 		       (gpointer) input->function_save);
5234 
5235   if (input->function_init)
5236     {
5237 #ifdef USE_JS
5238       template_js_evaluate (js, frame, input->function_init);
5239 #else
5240       fprintf (stderr,
5241 	       "WARNING: Javascript not supported on this computer\n");
5242 #endif
5243     }
5244 
5245   return frame;
5246 }
5247 
5248 /* RUN OTHER TEMPLATE *******************************************************/
5249 static void
template_run_toggled(GtkWidget * w,GtkWidget * sw)5250 template_run_toggled (GtkWidget * w, GtkWidget * sw)
5251 {
5252   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)) == TRUE)
5253     gtk_widget_set_sensitive (sw, TRUE);
5254   else
5255     gtk_widget_set_sensitive (sw, FALSE);
5256 }
5257 
5258 static GtkWidget *
template_run_create(GtkWidget * widget_inputs,struct template_t * t,GList * resources,GList * blanks,GtkWidget ** type_resource,GtkWidget ** type_blanknode,GtkWidget ** object,GtkWidget ** toggle)5259 template_run_create (GtkWidget * widget_inputs, struct template_t *t,
5260 		     GList * resources, GList * blanks,
5261 		     GtkWidget ** type_resource, GtkWidget ** type_blanknode,
5262 		     GtkWidget ** object, GtkWidget ** toggle)
5263 {
5264   GtkWidget *button;
5265   GtkWidget *sw;
5266   GtkWidget *label;
5267   GtkWidget *frame;
5268   GtkWidget *image;
5269   GtkWidget *vbox, *box, *hbox;
5270   GtkWidget *dialog;
5271   gchar s[1024];
5272   GSList *l;
5273 
5274   dialog = gtk_dialog_new ();
5275 
5276   g_snprintf (s, sizeof (s), "%s %s - %s: %s %s", PACKAGE, VERSION,
5277 	      _("Template"), t->name, t->version);
5278   gtk_window_set_title (GTK_WINDOW (dialog), s);
5279 
5280   gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
5281   gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
5282   gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5283   gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
5284 
5285   label = gtk_label_new (_("<b>Type</b>"));
5286   gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
5287 
5288   frame = gtk_frame_new (NULL);
5289   gtk_frame_set_label_widget (GTK_FRAME (frame), label);
5290   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, FALSE,
5291 		      FALSE, 5);
5292 
5293   vbox = gtk_vbox_new (FALSE, 0);
5294   gtk_container_add (GTK_CONTAINER (frame), vbox);
5295 
5296   box = gtk_hbox_new (FALSE, 5);
5297   gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 5);
5298 
5299   label = gtk_label_new ("Type: ");
5300   gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 5);
5301 
5302   /* Possibilita' delle tipologie per l'input: */
5303   l = NULL;
5304   *type_resource = gtk_radio_button_new_with_label (NULL, _("Resource"));
5305   gtk_radio_button_set_group (GTK_RADIO_BUTTON (*type_resource), l);
5306   l = gtk_radio_button_get_group (GTK_RADIO_BUTTON (*type_resource));
5307   gtk_box_pack_start (GTK_BOX (box), *type_resource, TRUE, TRUE, 3);
5308 
5309   *type_blanknode = gtk_radio_button_new_with_label (NULL, _("Blank node"));
5310   gtk_radio_button_set_group (GTK_RADIO_BUTTON (*type_blanknode), l);
5311   l = gtk_radio_button_get_group (GTK_RADIO_BUTTON (*type_blanknode));
5312   gtk_box_pack_start (GTK_BOX (box), *type_blanknode, TRUE, TRUE, 3);
5313 
5314   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (*type_resource), TRUE);
5315 
5316   box = gtk_hbox_new (FALSE, 5);
5317   gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 5);
5318 
5319   label = gtk_label_new (_("Value: "));
5320   gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 5);
5321 
5322   hbox = gtk_hbox_new (FALSE, 0);
5323   gtk_box_pack_start (GTK_BOX (box), hbox, TRUE, TRUE, 5);
5324 
5325   *object = gtk_entry_new ();
5326   gtk_box_pack_start (GTK_BOX (hbox), *object, TRUE, TRUE, 0);
5327 
5328   button = gtk_button_new ();
5329   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
5330   g_object_set_data (G_OBJECT (button), "list", resources);
5331   g_signal_connect ((gpointer) button, "clicked",
5332 		    G_CALLBACK (search_resources), object);
5333 
5334   image = gtk_image_new_from_stock ("gtk-find", GTK_ICON_SIZE_MENU);
5335   gtk_container_add (GTK_CONTAINER (button), image);
5336 
5337   label = gtk_label_new (_("<b>Template</b>"));
5338   gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
5339 
5340   *toggle = gtk_check_button_new ();
5341   gtk_container_add (GTK_CONTAINER (*toggle), label);
5342   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (*toggle), TRUE);
5343 
5344   frame = gtk_frame_new (NULL);
5345   gtk_frame_set_label_widget (GTK_FRAME (frame), *toggle);
5346   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, TRUE,
5347 		      TRUE, 5);
5348 
5349   sw = gtk_scrolled_window_new (NULL, NULL);
5350   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
5351 				       GTK_SHADOW_ETCHED_IN);
5352   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
5353 				  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
5354 
5355   g_signal_connect_after ((gpointer) * toggle, "toggled",
5356 			  G_CALLBACK (template_run_toggled), sw);
5357 
5358   gtk_container_add (GTK_CONTAINER (frame), sw);
5359 
5360   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw),
5361 					 widget_inputs);
5362 
5363   button = gtk_button_new_from_stock ("gtk-no");
5364   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button,
5365 				GTK_RESPONSE_CLOSE);
5366 
5367   gtk_widget_set_can_default(button, TRUE);
5368 
5369   button = gtk_button_new_from_stock ("gtk-ok");
5370   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK);
5371 
5372   gtk_widget_set_can_default(button, TRUE);
5373 
5374   template_set_size (dialog, sw, widget_inputs);
5375 
5376   return dialog;
5377 }
5378 
5379 static gboolean
template_run(GtkWidget * widget,struct template_t * t)5380 template_run (GtkWidget * widget, struct template_t *t)
5381 {
5382   GtkWidget *dialog;
5383   GtkWidget *object;
5384   GtkWidget *widget_inputs;
5385   GtkWidget *type_resource;
5386   GtkWidget *type_blanknode;
5387   GtkWidget *toggle;
5388   GList *resources;
5389   GList *blanks;
5390   gint ret;
5391   gint automatic;
5392 
5393   if ((widget_inputs =
5394        g_object_get_data (G_OBJECT (widget), "widget_inputs")))
5395     {
5396       gchar *object_saved;
5397       gboolean toggle_saved;
5398       gboolean type_resource_saved;
5399 
5400       object = g_object_get_data (G_OBJECT (widget), "subject_input");
5401       type_resource =
5402 	g_object_get_data (G_OBJECT (widget), "type_resource_input");
5403       type_blanknode =
5404 	g_object_get_data (G_OBJECT (widget), "type_blanknode_input");
5405       automatic =
5406 	(gint) g_object_get_data (G_OBJECT (widget),
5407 				  "type_blanknode_a_input");
5408       toggle = g_object_get_data (G_OBJECT (widget), "toggle_input");
5409 
5410       /* Salvo i dati precedenti: */
5411       object_saved = (gchar *) gtk_entry_get_text (GTK_ENTRY (object));
5412       if (object_saved)
5413 	object_saved = g_strdup (object_saved);
5414 
5415       toggle_saved =
5416 	gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle));
5417 
5418       type_resource_saved =
5419 	gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type_resource));
5420 
5421       gtk_container_foreach (GTK_CONTAINER (widget_inputs),
5422 			     (GtkCallback) template_widget_save_on, NULL);
5423 
5424       dialog = gtk_widget_get_toplevel (widget_inputs);
5425       gtk_widget_show_all (dialog);
5426 
5427       while ((ret = gtk_dialog_run (GTK_DIALOG (dialog))) == GTK_RESPONSE_OK)
5428 	{
5429 
5430 	  /* Se e' attiva la tipologia risorsa: */
5431 	  if (gtk_toggle_button_get_active
5432 	      (GTK_TOGGLE_BUTTON (type_resource)))
5433 	    {
5434 	      gchar *text;
5435 
5436 	      text = (gchar *) gtk_entry_get_text (GTK_ENTRY (object));
5437 	      if (!text || !*text)
5438 		{
5439 		  dialog_msg (_("No a compatible resource!"));
5440 		  continue;
5441 		}
5442 	    }
5443 
5444 	  /* Se e' invece e' attivo il blank node: */
5445 	  else if (!automatic
5446 		   &&
5447 		   gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
5448 						 (type_blanknode)))
5449 	    {
5450 	      gchar *text;
5451 
5452 	      text = (gchar *) gtk_entry_get_text (GTK_ENTRY (object));
5453 	      if (!text || !*text)
5454 		{
5455 		  if (dialog_ask
5456 		      (_
5457 		       ("No a compatible blank node. Do you want create a automatic name?"))
5458 		      != GTK_RESPONSE_OK)
5459 		    continue;
5460 		  else
5461 		    automatic = 1;
5462 		}
5463 	    }
5464 
5465 	  /* Controllo TUTTI i widget di input: */
5466 	  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)))
5467 	    {
5468 	      GList *old, *list;
5469 
5470 	      list = old =
5471 		gtk_container_get_children (GTK_CONTAINER (widget_inputs));
5472 
5473 	      while (list)
5474 		{
5475 		  if (template_widget_check (list->data))
5476 		    break;
5477 
5478 		  list = list->next;
5479 		}
5480 
5481 	      /* Si lamenta la funzione widget_check, quindi io devo solo
5482 	       * continuare: */
5483 	      if (list)
5484 		{
5485 		  g_list_free (old);
5486 		  continue;
5487 		}
5488 
5489 	      g_list_free (old);
5490 	    }
5491 
5492 	  break;
5493 	}
5494 
5495       /* Analizzo la risposta: */
5496       switch (ret)
5497 	{
5498 
5499 	  /* Se e' OK: */
5500 	case GTK_RESPONSE_OK:
5501 	  gtk_container_foreach (GTK_CONTAINER (widget_inputs),
5502 				 (GtkCallback) template_widget_save_off,
5503 				 NULL);
5504 	  if (object_saved)
5505 	    g_free (object_saved);
5506 
5507 	  gtk_widget_hide (dialog);
5508 	  break;
5509 
5510 	default:
5511 	  /* Rimetto i dati com'erano prima se non si vuole salvarli: */
5512 	  gtk_container_foreach (GTK_CONTAINER (widget_inputs),
5513 				 (GtkCallback) template_widget_save_reset,
5514 				 NULL);
5515 
5516 	  gtk_entry_set_text (GTK_ENTRY (object),
5517 			      object_saved ? object_saved : "");
5518 	  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
5519 					toggle_saved);
5520 	  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (type_resource),
5521 					type_resource_saved);
5522 
5523 	  if (object_saved)
5524 	    g_free (object_saved);
5525 
5526 	  gtk_widget_hide (dialog);
5527 	  break;
5528 	}
5529 
5530       return TRUE;
5531     }
5532 
5533   resources = g_object_get_data (G_OBJECT (widget), "resources");
5534   blanks = g_object_get_data (G_OBJECT (widget), "blanks");
5535 
5536   if (!(widget_inputs = template_open_real (resources, blanks, t)))
5537     return FALSE;
5538 
5539   dialog =
5540     template_run_create (widget_inputs, t, resources, blanks, &type_resource,
5541 			 &type_blanknode, &object, &toggle);
5542   gtk_window_set_transient_for (GTK_WINDOW (dialog),
5543 				GTK_WINDOW (gtk_widget_get_toplevel
5544 					    (widget)));
5545   gtk_widget_show_all (dialog);
5546 
5547   automatic = 0;
5548   while ((ret = gtk_dialog_run (GTK_DIALOG (dialog))) == GTK_RESPONSE_OK)
5549     {
5550       GList *list, *old;
5551       GList *invisible;
5552 
5553       /* Se e' attiva la tipologia risorsa: */
5554       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (type_resource)))
5555 	{
5556 	  gchar *text;
5557 
5558 	  text = (gchar *) gtk_entry_get_text (GTK_ENTRY (object));
5559 	  if (!text || !*text)
5560 	    {
5561 	      dialog_msg (_("No a compatible resource!"));
5562 	      continue;
5563 	    }
5564 	}
5565 
5566       /* Se e' invece e' attivo il blank node: */
5567       else if (!automatic
5568 	       &&
5569 	       gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
5570 					     (type_blanknode)))
5571 	{
5572 	  gchar *text;
5573 
5574 	  text = (gchar *) gtk_entry_get_text (GTK_ENTRY (object));
5575 	  if (!text || !*text)
5576 	    {
5577 	      if (dialog_ask
5578 		  (_
5579 		   ("No a compatible blank node. Do you want create a automatic name?"))
5580 		  != GTK_RESPONSE_OK)
5581 		continue;
5582 	      else
5583 		automatic = 1;
5584 	    }
5585 	}
5586 
5587       /* Controllo TUTTI i widget di input: */
5588       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)))
5589 	{
5590 	  list = old =
5591 	    gtk_container_get_children (GTK_CONTAINER (widget_inputs));
5592 
5593 	  while (list)
5594 	    {
5595 	      if (template_widget_check (list->data))
5596 		break;
5597 
5598 	      list = list->next;
5599 	    }
5600 
5601 	  /* Si lamenta la funzione widget_check, quindi io devo solo
5602 	   * continuare: */
5603 	  if (list)
5604 	    {
5605 	      g_list_free (old);
5606 	      continue;
5607 	    }
5608 
5609 	  g_list_free (old);
5610 	}
5611 
5612       g_object_set_data (G_OBJECT (widget), "widget_inputs", widget_inputs);
5613       gtk_widget_hide (dialog);
5614 
5615       invisible = NULL;
5616       list = t->input;
5617       while (list)
5618 	{
5619 	  struct template_input_t *input = list->data;
5620 
5621 	  if (!input->visible)
5622 	    {
5623 	      struct invisible_t *inv =
5624 		g_malloc0 (sizeof (struct invisible_t));
5625 
5626 	      inv->input = input;
5627 	      invisible = g_list_append (invisible, inv);
5628 	    }
5629 
5630 	  list = list->next;
5631 	}
5632 
5633       g_object_set_data (G_OBJECT (widget), "invisible_inputs", invisible);
5634       g_object_set_data (G_OBJECT (widget), "subject_input", object);
5635       g_object_set_data (G_OBJECT (widget), "type_resource_input",
5636 			 type_resource);
5637       g_object_set_data (G_OBJECT (widget), "type_blanknode_input",
5638 			 type_blanknode);
5639       g_object_set_data (G_OBJECT (widget), "type_blanknode_a_input",
5640 			 (gpointer) automatic);
5641       g_object_set_data (G_OBJECT (widget), "toggle_input", toggle);
5642       break;
5643     }
5644 
5645   if (ret != GTK_RESPONSE_OK)
5646     {
5647       gtk_widget_destroy (dialog);
5648       return FALSE;
5649     }
5650 
5651   return TRUE;
5652 }
5653 
5654 /* TEMPLATE EDIT ************************************************************/
5655 static void
template_edit_set(GList ** widget_inputs,GList ** rdf,gchar * subject)5656 template_edit_set (GList ** widget_inputs, GList ** rdf, gchar * subject)
5657 {
5658   GList *list;
5659   GList *widget;
5660 
5661   /* TODO: per ogni widget, fare tripletta... */
5662   widget = *widget_inputs;
5663   while (widget)
5664     {
5665 
5666       /* Per ogni singola tripletta: */
5667       list = *rdf;
5668       while (list)
5669 	{
5670 	  struct rdf_t *r = list->data;
5671 
5672 	  /* Se ha lo stesso soggetto richiesto: */
5673 	  if (!strcmp (r->subject, subject))
5674 	    {
5675 	      /* Rimuovo per eventuali problemi di ricorsione: */
5676 	      list = list->next;
5677 	      *rdf = g_list_remove (*rdf, r);
5678 
5679 	      /* Se coincide e viene assegnato: */
5680 	      if (template_widget_is_your (widget->data, r, rdf) == TRUE)
5681 		{
5682 		  struct template_func_t *func;
5683 
5684 		  if ((func =
5685 		       g_object_get_data (G_OBJECT (widget->data), "func")))
5686 		    {
5687 
5688 		      /* Se e' una tipologia diversa da cardinality, rimuovo: */
5689 		      if (func->type != TEMPLATE_WIDGET_CARDINALITY)
5690 			*widget_inputs =
5691 			  g_list_remove (*widget_inputs, widget->data);
5692 		    }
5693 
5694 		  template_edit_set (widget_inputs, rdf, subject);
5695 		  return;
5696 		}
5697 
5698 	      *rdf = g_list_prepend (*rdf, r);
5699 	      continue;
5700 	    }
5701 
5702 	  list = list->next;
5703 	}
5704 
5705       widget = widget->next;
5706     }
5707 }
5708 
5709 static gint
template_edit_set_sort_func(GtkWidget * a,GtkWidget * b)5710 template_edit_set_sort_func (GtkWidget * a, GtkWidget * b)
5711 {
5712   gint mca = (gboolean) g_object_get_data (G_OBJECT (a), "min_cardinality");
5713   gint mcb = (gboolean) g_object_get_data (G_OBJECT (b), "min_cardinality");
5714 
5715   if (mca >= mcb)
5716     return 0;
5717   return 1;
5718 }
5719 
5720 static GList *
template_edit_set_sort(GList * widgets)5721 template_edit_set_sort (GList * widgets)
5722 {
5723   GList *copy = g_list_copy (widgets);
5724   return g_list_sort (copy, (GCompareFunc) template_edit_set_sort_func);
5725 }
5726 
5727 static void
template_edit_subject_activated(GtkWidget * w,GtkTreePath * p,GtkTreeViewColumn * c,GtkWidget * dialog)5728 template_edit_subject_activated (GtkWidget * w, GtkTreePath * p,
5729 				 GtkTreeViewColumn * c, GtkWidget * dialog)
5730 {
5731   gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
5732 }
5733 
5734 static gchar *
template_edit_subject(GList * list)5735 template_edit_subject (GList * list)
5736 {
5737   GtkWidget *window, *hbox, *scrolledwindow, *treeview, *button, *frame;
5738   GtkListStore *model;
5739   GtkTreeIter iter;
5740   GtkCellRenderer *renderer;
5741   GtkTreeSelection *selection;
5742   GtkTreeViewColumn *column;
5743   gchar s[1024];
5744   gchar *ret = NULL;
5745   GList *subjects = NULL, *tmp;
5746 
5747   while (list)
5748     {
5749       struct rdf_t *rdf = list->data;
5750 
5751       for (tmp = subjects; tmp; tmp = tmp->next)
5752 	if (!strcmp (rdf->subject, tmp->data))
5753 	  break;
5754 
5755       if (!tmp)
5756 	subjects = g_list_append (subjects, rdf->subject);
5757 
5758       list = list->next;
5759     }
5760 
5761   if (g_list_length (subjects) == 1)
5762     {
5763       ret = g_strdup (subjects->data);
5764       g_list_free (subjects);
5765       return ret;
5766     }
5767 
5768   g_snprintf (s, sizeof (s), "%s %s - %s", PACKAGE, VERSION,
5769 	      _("Template edit..."));
5770 
5771   window = gtk_dialog_new ();
5772   gtk_window_set_title (GTK_WINDOW (window), s);
5773   gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DIALOG);
5774   gtk_window_set_modal (GTK_WINDOW (window), TRUE);
5775   gtk_window_set_transient_for (GTK_WINDOW (window), main_window ());
5776   gtk_widget_set_size_request (window, 400, 200);
5777 
5778   hbox = gtk_hbox_new (FALSE, 0);
5779   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox, TRUE, TRUE,
5780 		      0);
5781 
5782   frame = gtk_frame_new (_("Select the Subject"));
5783   gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
5784 
5785   scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
5786   gtk_container_add (GTK_CONTAINER (frame), scrolledwindow);
5787   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
5788 				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
5789   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
5790 				       GTK_SHADOW_IN);
5791 
5792   model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
5793 
5794   treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
5795   gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), TRUE);
5796   gtk_container_add (GTK_CONTAINER (scrolledwindow), treeview);
5797   g_signal_connect ((gpointer) treeview, "row_activated",
5798 		    G_CALLBACK (template_edit_subject_activated), window);
5799 
5800 
5801   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
5802   gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
5803 
5804   gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
5805 
5806   renderer = gtk_cell_renderer_text_new ();
5807   column =
5808     gtk_tree_view_column_new_with_attributes (_("Subject"), renderer, "text",
5809 					      0, NULL);
5810   gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
5811   gtk_tree_view_column_set_resizable (column, TRUE);
5812 
5813   button = gtk_button_new_from_stock ("gtk-cancel");
5814   gtk_dialog_add_action_widget (GTK_DIALOG (window), button,
5815 				GTK_RESPONSE_CANCEL);
5816   gtk_widget_set_can_default(button, TRUE);
5817 
5818   button = gtk_button_new_from_stock ("gtk-ok");
5819   gtk_dialog_add_action_widget (GTK_DIALOG (window), button, GTK_RESPONSE_OK);
5820   gtk_widget_set_can_default(button, TRUE);
5821 
5822   tmp = subjects;
5823   while (tmp)
5824     {
5825       gtk_list_store_append (model, &iter);
5826       gtk_list_store_set (model, &iter, 0,
5827 			  strcmp (tmp->data,
5828 				  THIS_DOCUMENT) ? tmp->
5829 			  data : _("This Document"), 1, tmp->data, -1);
5830       tmp = tmp->next;
5831     }
5832 
5833   g_list_free (subjects);
5834 
5835   gtk_widget_show_all (window);
5836 
5837   while ((gtk_dialog_run (GTK_DIALOG (window))) == GTK_RESPONSE_OK)
5838     {
5839       if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
5840 	{
5841 	  dialog_msg (_("Select a Subject!"));
5842 	  continue;
5843 	}
5844 
5845       gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 1, &ret, -1);
5846       break;
5847     }
5848 
5849   g_object_unref (model);
5850   gtk_widget_destroy (window);
5851   return ret;
5852 }
5853 
5854 /* Questa funzione controlla l'esistenza delle triplette invisibli: */
5855 static void
template_edit_invisible(GList ** invisible,GList ** rdf,gchar * subject,struct template_t * t)5856 template_edit_invisible (GList ** invisible, GList ** rdf, gchar * subject,
5857 			 struct template_t *t)
5858 {
5859   GList *list = t->input;
5860   struct invisible_t *inv;
5861 
5862   /* Per ogni input: */
5863   while (list)
5864     {
5865       struct template_input_t *input = list->data;
5866 
5867       /* Se e' un invisibile: */
5868       if (!input->visible)
5869 	{
5870 
5871 	  /* Controllo se esiste all'interno dell'elenco: */
5872 	  GList *tmp = *rdf;
5873 	  while (tmp)
5874 	    {
5875 	      struct rdf_t *r = tmp->data;
5876 
5877 	      /* Se lo trovo creo un input invisibile con la tripletta
5878 	       * e la rimuovo dall'elenco: */
5879 	      if (!strcmp (r->subject, subject)
5880 		  && !strcmp (r->predicate, input->rdfs)
5881 		  && !strcmp (r->object, input->default_value))
5882 		{
5883 		  inv = g_malloc0 (sizeof (struct invisible_t));
5884 		  inv->input = input;
5885 		  inv->rdf = r;
5886 
5887 		  *invisible = g_list_append (*invisible, inv);
5888 		  *rdf = g_list_remove (*rdf, r);
5889 		  break;
5890 		}
5891 
5892 	      tmp = tmp->next;
5893 	    }
5894 
5895 	  /* Se non lo trovo, lo metto come nuovo da mettere: */
5896 	  if (!tmp)
5897 	    {
5898 	      inv = g_malloc0 (sizeof (struct invisible_t));
5899 	      inv->input = input;
5900 	      inv->rdf = NULL;
5901 	      *invisible = g_list_append (*invisible, inv);
5902 	    }
5903 	}
5904 
5905       list = list->next;
5906     }
5907 }
5908 
5909 static void
template_edit_dialog(GList * rdf,gint len)5910 template_edit_dialog (GList * rdf, gint len)
5911 {
5912   GtkWidget *dialog;
5913   GtkWidget *hbox;
5914   GtkWidget *image;
5915   GtkWidget *label;
5916   GtkWidget *button;
5917   GtkWidget *scrolledwindow;
5918   GtkWidget *treeview;
5919   GtkTreeSelection *selection;
5920   GtkCellRenderer *renderer;
5921   GtkTreeViewColumn *column;
5922   GtkWidget *frame;
5923   GtkListStore *model;
5924   GtkTreeIter iter;
5925   gchar s[1024];
5926   gint i;
5927 
5928   dialog = gtk_dialog_new ();
5929   g_snprintf (s, sizeof (s), "%s %s - %s", PACKAGE, VERSION,
5930 	      _("Information..."));
5931   gtk_window_set_title (GTK_WINDOW (dialog), s);
5932   gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
5933   gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
5934   gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5935   gtk_window_set_transient_for (GTK_WINDOW (dialog), main_window ());
5936   gtk_widget_set_size_request (dialog, 400, 200);
5937 
5938   hbox = gtk_hbox_new (FALSE, 8);
5939   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, FALSE, FALSE,
5940 		      0);
5941 
5942   image = gtk_image_new_from_stock ("gtk-dialog-info", GTK_ICON_SIZE_DIALOG);
5943   gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
5944 
5945   i = g_list_length (rdf);
5946   g_snprintf (s, sizeof (s), _("Set %d of %d RDF triples"), len - i, len);
5947 
5948   label = gtk_label_new (s);
5949   gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
5950 
5951   frame = gtk_frame_new (_("RDF triples ignored"));
5952   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, TRUE, TRUE,
5953 		      0);
5954 
5955   scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
5956   gtk_container_add (GTK_CONTAINER (frame), scrolledwindow);
5957   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
5958 				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
5959   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
5960 				       GTK_SHADOW_IN);
5961 
5962   model = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
5963 
5964   treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
5965   gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), TRUE);
5966   gtk_container_add (GTK_CONTAINER (scrolledwindow), treeview);
5967 
5968   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
5969   gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
5970 
5971   gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
5972 
5973   renderer = gtk_cell_renderer_text_new ();
5974   column =
5975     gtk_tree_view_column_new_with_attributes (_("Subject"), renderer, "text",
5976 					      0, NULL);
5977   gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
5978   gtk_tree_view_column_set_resizable (column, TRUE);
5979 
5980   renderer = gtk_cell_renderer_text_new ();
5981   column =
5982     gtk_tree_view_column_new_with_attributes (_("Predicate"), renderer,
5983 					      "text", 1, NULL);
5984   gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
5985   gtk_tree_view_column_set_resizable (column, TRUE);
5986 
5987   renderer = gtk_cell_renderer_text_new ();
5988   column =
5989     gtk_tree_view_column_new_with_attributes (_("Object"), renderer, "text",
5990 					      2, NULL);
5991   gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
5992   gtk_tree_view_column_set_resizable (column, TRUE);
5993 
5994   while (rdf)
5995     {
5996       struct rdf_t *r = rdf->data;
5997 
5998       gtk_list_store_append (model, &iter);
5999       gtk_list_store_set (model, &iter, 0, r->subject, 1, r->predicate, 2,
6000 			  r->object, -1);
6001 
6002       rdf = rdf->next;
6003     }
6004 
6005   button = gtk_button_new_from_stock ("gtk-ok");
6006   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK);
6007 
6008   gtk_widget_set_can_default(button, TRUE);
6009 
6010   gtk_widget_show_all (dialog);
6011   gtk_dialog_run (GTK_DIALOG (dialog));
6012   gtk_widget_destroy (dialog);
6013 }
6014 
6015 void
template_edit(GtkWidget * w,struct template_t * t)6016 template_edit (GtkWidget * w, struct template_t *t)
6017 {
6018   struct editor_data_t *data = editor_get_data ();
6019   GtkWidget *dialog;
6020   GtkWidget *vbox, *hbox, *gbox;
6021   GtkWidget *image;
6022   GtkWidget *frame;
6023   GtkWidget *button;
6024   GtkWidget *label;
6025   GtkWidget *subject;
6026   GtkWidget *sw;
6027   GtkWidget *button_subject;
6028   GtkWidget *button_subject_this;
6029   GtkWidget *widget_inputs;
6030   GList *list, *tmp, *invisible;
6031   GSList *l;
6032   GList *resources;
6033   GList *blanks;
6034   gchar s[1024];
6035   gchar *s_str;
6036   gint len;
6037 
6038   if (!data || !data->rdf)
6039     {
6040       dialog_msg (_("This document is empty!"));
6041       return;
6042     }
6043 
6044   /* Rimuovo i template remoti chiesti precedentemente: */
6045   template_remote_init ();
6046 
6047   if (!(s_str = template_edit_subject (data->rdf)))
6048     return;
6049 
6050   resources = create_resources (data);
6051   resources = create_resources_by_rdfs (resources);
6052   blanks = create_blank (data);
6053 
6054   if (!(widget_inputs = template_open_real (resources, blanks, t)))
6055     {
6056       g_list_free (resources);
6057       g_list_free (blanks);
6058       g_free (s_str);
6059       return;
6060     }
6061 
6062   /* Creo una copia della lista perche' queste vado pezzo per pezzo a
6063    * rimuoverle: */
6064   for (tmp = NULL, list = data->rdf; list; list = list->next)
6065     tmp = g_list_append (tmp, list->data);
6066 
6067   len = g_list_length (tmp);
6068 
6069   /* Questa funzione imposta i valori delle varie triplette all'interno
6070    * dei widget */
6071   if ((list = gtk_container_get_children (GTK_CONTAINER (widget_inputs))))
6072     {
6073       GList *sorted = template_edit_set_sort (list);
6074       g_list_free (list);
6075 
6076       template_edit_set (&sorted, &tmp, s_str);
6077 
6078       if (sorted)
6079 	g_list_free (sorted);
6080     }
6081 
6082   /* Rimuovo gli elementi invisibili: */
6083   invisible = NULL;
6084   template_edit_invisible (&invisible, &tmp, s_str, t);
6085 
6086   template_edit_dialog (tmp, len);
6087   g_list_free (tmp);
6088 
6089   dialog = gtk_dialog_new ();
6090 
6091   g_snprintf (s, sizeof (s), "%s %s - %s: %s %s", PACKAGE, VERSION,
6092 	      _("Template"), t->name, t->version);
6093   gtk_window_set_title (GTK_WINDOW (dialog), s);
6094 
6095   gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
6096   gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
6097   gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6098   gtk_window_set_transient_for (GTK_WINDOW (dialog), main_window ());
6099   gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
6100 
6101   label = gtk_label_new (_("<b>Subject</b>"));
6102   gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
6103 
6104   frame = gtk_frame_new (NULL);
6105   gtk_frame_set_label_widget (GTK_FRAME (frame), label);
6106   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, FALSE,
6107 		      FALSE, 5);
6108 
6109   vbox = gtk_vbox_new (FALSE, 3);
6110   gtk_container_add (GTK_CONTAINER (frame), vbox);
6111 
6112   gbox = gtk_hbox_new (FALSE, 0);
6113   gtk_box_pack_start (GTK_BOX (vbox), gbox, FALSE, FALSE, 0);
6114 
6115   l = NULL;
6116   button = gtk_radio_button_new_with_label (NULL, _("Resource: "));
6117   button_subject = button;
6118   gtk_radio_button_set_group (GTK_RADIO_BUTTON (button), l);
6119   l = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
6120   gtk_box_pack_start (GTK_BOX (gbox), button, FALSE, FALSE, 3);
6121 
6122   hbox = gtk_hbox_new (FALSE, 0);
6123   gtk_box_pack_start (GTK_BOX (gbox), hbox, TRUE, TRUE, 5);
6124 
6125   /* Creazione soggetto con freccia: */
6126   subject = gtk_entry_new ();
6127   gtk_box_pack_start (GTK_BOX (hbox), subject, TRUE, TRUE, 0);
6128 
6129   button = gtk_button_new ();
6130   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
6131   g_object_set_data (G_OBJECT (button), "list", resources);
6132   g_signal_connect ((gpointer) button, "clicked",
6133 		    G_CALLBACK (search_resources), subject);
6134 
6135   image = gtk_image_new_from_stock ("gtk-find", GTK_ICON_SIZE_MENU);
6136   gtk_container_add (GTK_CONTAINER (button), image);
6137 
6138   gbox = gtk_hbox_new (FALSE, 0);
6139   gtk_box_pack_start (GTK_BOX (vbox), gbox, FALSE, FALSE, 0);
6140 
6141   button = gtk_radio_button_new_with_label (NULL, _("This document"));
6142   button_subject_this = button;
6143   gtk_radio_button_set_group (GTK_RADIO_BUTTON (button), l);
6144   l = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
6145   gtk_box_pack_start (GTK_BOX (gbox), button, TRUE, TRUE, 3);
6146 
6147   if (!strcmp (s_str, THIS_DOCUMENT))
6148     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
6149   else
6150     gtk_entry_set_text (GTK_ENTRY (subject), s_str);
6151 
6152   sw = gtk_scrolled_window_new (NULL, NULL);
6153   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
6154 				       GTK_SHADOW_ETCHED_IN);
6155   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
6156 				  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
6157 
6158   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), sw, TRUE, TRUE, 5);
6159 
6160   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw),
6161 					 widget_inputs);
6162 
6163   button = gtk_button_new_from_stock ("gtk-no");
6164   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button,
6165 				GTK_RESPONSE_CLOSE);
6166 
6167   gtk_widget_set_can_default(button, TRUE);
6168 
6169   button = gtk_button_new_from_stock ("gtk-ok");
6170   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK);
6171 
6172   gtk_widget_set_can_default(button, TRUE);
6173 
6174   template_set_size (dialog, sw, widget_inputs);
6175   gtk_widget_show_all (dialog);
6176 
6177   while (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
6178     {
6179       GList *old;
6180       gchar *text;
6181       struct unredo_t *unredo;
6182 
6183       /* Check del soggetto: */
6184       if (gtk_toggle_button_get_active
6185 	  (GTK_TOGGLE_BUTTON (button_subject_this)) == TRUE)
6186 	text = THIS_DOCUMENT;
6187       else
6188 	text = (gchar *) gtk_entry_get_text (GTK_ENTRY (subject));
6189 
6190       if (!text || !*text)
6191 	{
6192 	  dialog_msg (_("Invalid subject!"));
6193 	  continue;
6194 	}
6195 
6196       text = g_strdup (text);
6197 
6198       /* Controllo TUTTI i widget di input: */
6199       list = old = gtk_container_get_children (GTK_CONTAINER (widget_inputs));
6200 
6201       while (list)
6202 	{
6203 	  if (template_widget_check (list->data))
6204 	    break;
6205 
6206 	  list = list->next;
6207 	}
6208 
6209       /* Si lamenta la funzione widget_check, quindi io devo solo
6210        * continuare: */
6211       if (list)
6212 	{
6213 	  g_free (text);
6214 	  g_list_free (old);
6215 	  continue;
6216 	}
6217 
6218       /* A questo punto inserisco, quindi undo: */
6219       unredo = unredo_new (data, UNREDO_TYPE_CHANGE);
6220 
6221       list = old;
6222       while (list)
6223 	{
6224 	  /* Funzione che fa l'inserimento: */
6225 	  template_widget_save (list->data, data, text, unredo);
6226 	  list = list->next;
6227 	}
6228 
6229       /* Tutto quello che riguarda le triplette invisibili: */
6230       if (invisible)
6231 	{
6232 	  struct invisible_t *inv;
6233 
6234 	  /* Per ogni input invisible: */
6235 	  list = invisible;
6236 	  while (list)
6237 	    {
6238 	      inv = list->data;
6239 	      template_invisible_save (text, inv->input, data, unredo,
6240 				       inv->rdf);
6241 
6242 	      /* Libero memoria: */
6243 	      g_free (inv);
6244 	      list = list->next;
6245 	    }
6246 
6247 	  /* Distruggo la lista degli invisibli: */
6248 	  g_list_free (invisible);
6249 	}
6250 
6251       g_list_foreach (old, (GFunc) template_widget_destroy, NULL);
6252       g_list_free (old);
6253 
6254       g_free (text);
6255       data->changed = TRUE;
6256 
6257       /* Refreshio i namespace e li rigenero */
6258       g_list_foreach (data->namespace, (GFunc) namespace_free, NULL);
6259       g_list_free (data->namespace);
6260 
6261       namespace_parse (data->rdf, &data->namespace);
6262 
6263       editor_refresh (data);
6264       break;
6265     }
6266 
6267   /* Libero memoria: */
6268   g_list_free (resources);
6269   g_list_free (blanks);
6270   g_free (s_str);
6271 
6272   gtk_widget_destroy (dialog);
6273 }
6274 
6275 /* JAVASCRIPT ****************************************************************/
6276 #ifdef USE_JS
6277 static gboolean
template_js_evaluate(struct js_t * js,GtkWidget * widget,gchar * func)6278 template_js_evaluate (struct js_t *js, GtkWidget * widget, gchar * func)
6279 {
6280   js_current_widget (js, widget);
6281   return js_evaluate (js, func);
6282 }
6283 #endif
6284 
6285 /* VALUE FUNCTIONS ***********************************************************/
6286 
6287 struct template_value_t *
template_value_new(GtkWidget * widget)6288 template_value_new (GtkWidget * widget)
6289 {
6290   struct template_func_t *func;
6291   struct template_value_t *value;
6292 
6293   value = g_malloc0 (sizeof (struct template_value_t));
6294 
6295   func = g_object_get_data (G_OBJECT (widget), "func");
6296   if (func && func->get)
6297     func->get (widget, value);
6298 
6299   return value;
6300 }
6301 
6302 void
template_value_set(GtkWidget * w,struct template_value_t * value)6303 template_value_set (GtkWidget * w, struct template_value_t *value)
6304 {
6305   template_widget_save_off (w);
6306   template_widget_set (w, value);
6307 }
6308 
6309 void
template_value_free(struct template_value_t * saved)6310 template_value_free (struct template_value_t *saved)
6311 {
6312   if (!saved)
6313     return;
6314 
6315   if (saved->value)
6316     g_free (saved->value);
6317 
6318   if (saved->lang)
6319     g_free (saved->lang);
6320 
6321   if (saved->datatype)
6322     g_free (saved->datatype);
6323 
6324   g_free (saved);
6325 }
6326 
6327 /* EOF ?!? */
6328 
6329 /*
6330  * Il lonfo - Fosco Maraini
6331  *
6332  * Il lonfo non vaterca né gluisce
6333  * e molto raramente barigatta,
6334  * ma quando soffia il bego a bisce bisce
6335  * sdilenca un poco, e gnagio s'archipatta.
6336  *
6337  * E' frusco il lonfo! E' pieno di lupigna
6338  * arrafferia malversa e sofolenta!
6339  *
6340  * Se cionfi ti sbiduglia e t'arrupigna
6341  * se lugri ti botalla e ti criventa.
6342  *
6343  * Eppure il vecchio lonfo ammargelluto
6344  * che bete e zugghia e fonca nei trombazzi
6345  * fa lègica busìa, fa gisbuto;
6346  * e quasi quasi in segno di sberdazzi
6347  * gli affarferesti un gniffo. Ma lui zuto
6348  * t'alloppa, ti sbernecchia; e tu l'accazzi.
6349  *
6350  */
6351 
6352 /* EOF */
6353