1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /* window.c
3 * Copyright (C) 2006 Armin Burgmeier
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 #include "window.h"
21 #include "transform.h"
22 #include "validator.h"
23 #include "element-editor.h"
24
25 #include <libanjuta/anjuta-plugin.h>
26 #include <libanjuta/interfaces/ianjuta-project-chooser.h>
27 #include <stdlib.h>
28 #include <glib.h>
29
30 #include <ctype.h>
31
32 #define BUILDER_FILE PACKAGE_DATA_DIR "/glade/anjuta-class-gen-plugin.ui"
33
34 #define CC_HEADER_TEMPLATE PACKAGE_DATA_DIR "/class-templates/cc-header.tpl"
35 #define CC_SOURCE_TEMPLATE PACKAGE_DATA_DIR "/class-templates/cc-source.tpl"
36
37 #define GO_HEADER_TEMPLATE PACKAGE_DATA_DIR "/class-templates/go-header.tpl"
38 #define GO_SOURCE_TEMPLATE PACKAGE_DATA_DIR "/class-templates/go-source.tpl"
39
40 #define PY_SOURCE_TEMPLATE PACKAGE_DATA_DIR "/class-templates/py-source.tpl"
41
42 #define JS_SOURCE_TEMPLATE PACKAGE_DATA_DIR "/class-templates/js-source.tpl"
43
44 #define VALA_SOURCE_TEMPLATE PACKAGE_DATA_DIR "/class-templates/vala-source.tpl"
45
46 typedef struct _CgWindowPrivate CgWindowPrivate;
47 struct _CgWindowPrivate
48 {
49 GtkBuilder *bxml;
50 GtkWidget *window;
51
52 CgElementEditor *editor_cc;
53
54 CgElementEditor *editor_go_members;
55 CgElementEditor *editor_go_properties;
56 CgElementEditor *editor_go_signals;
57
58 CgElementEditor *editor_py_methods;
59 CgElementEditor *editor_py_constvars;
60
61 CgElementEditor *editor_js_methods;
62 CgElementEditor *editor_js_variables;
63 CgElementEditor *editor_js_imports;
64
65 CgElementEditor *editor_vala_methods;
66 CgElementEditor *editor_vala_properties;
67 CgElementEditor *editor_vala_signals;
68
69 CgValidator *validator;
70 };
71
72 #define CG_WINDOW_PRIVATE(o) \
73 (G_TYPE_INSTANCE_GET_PRIVATE( \
74 (o), \
75 CG_TYPE_WINDOW, \
76 CgWindowPrivate \
77 ))
78
79 enum {
80 PROP_0,
81
82 /* Construct only */
83 PROP_BUILDER_XML
84 };
85
86 static GObjectClass *parent_class = NULL;
87
88 static const gchar *CC_SCOPE_LIST[] =
89 {
90 "public",
91 "protected",
92 "private",
93 NULL
94 };
95
96 static const gchar *CC_IMPLEMENTATION_LIST[] =
97 {
98 "normal",
99 "static",
100 "virtual",
101 NULL
102 };
103
104 static const gchar *GO_SCOPE_LIST[] =
105 {
106 "public",
107 "private",
108 NULL
109 };
110
111 static const gchar *GO_PARAMSPEC_LIST[] =
112 {
113 N_("Guess from type"),
114 "g_param_spec_object",
115 "g_param_spec_pointer",
116 "g_param_spec_enum",
117 "g_param_spec_flags",
118 "g_param_spec_boxed",
119 NULL
120 };
121
122 static const CgElementEditorFlags GO_PROPERTY_FLAGS[] =
123 {
124 { "G_PARAM_READABLE", "R" },
125 { "G_PARAM_WRITABLE", "W" },
126 { "G_PARAM_CONSTRUCT", "C" },
127 { "G_PARAM_CONSTRUCT_ONLY", "CO" },
128 { "G_PARAM_LAX_VALIDATION", "LV" },
129 { "G_PARAM_STATIC_NAME", "SNA" },
130 { "G_PARAM_STATIC_NICK", "SNI" },
131 { "G_PARAM_STATIC_BLURB", "SBL" },
132 { NULL, NULL }
133 };
134
135 static const CgElementEditorFlags GO_SIGNAL_FLAGS[] =
136 {
137 { "G_SIGNAL_RUN_FIRST", "RF" },
138 { "G_SIGNAL_RUN_LAST", "RL" },
139 { "G_SIGNAL_RUN_CLEANUP", "RC" },
140 { "G_SIGNAL_NO_RECURSE", "NR" },
141 { "G_SIGNAL_DETAILED", "D" },
142 { "G_SIGNAL_ACTION", "A" },
143 { "G_SIGNAL_NO_HOOKS", "NH" },
144 { NULL, NULL }
145 };
146
147 static const gchar *VALA_BOOLEAN_LIST[] =
148 {
149 "Yes",
150 "No",
151 NULL
152 };
153
154 static const gchar *VALA_METHSIG_SCOPE_LIST[] =
155 {
156 "public",
157 "private",
158 "protected",
159 NULL
160 }
161 ;
162 static const gchar *VALA_PROP_SCOPE_LIST[] =
163 {
164 "public",
165 "protected",
166 "internal",
167 NULL
168 };
169
170 #if 0
171 static void
172 cg_window_browse_button_clicked_cb (GtkButton *button,
173 gpointer user_data)
174 {
175 GtkWidget *entry;
176 GtkFileChooserDialog *dialog;
177 const gchar *text;
178 gchar *filename;
179
180 entry = GTK_WIDGET (user_data);
181
182 dialog = GTK_FILE_CHOOSER_DIALOG (
183 gtk_file_chooser_dialog_new (
184 "Select A File", /* TODO: Better context for caption */
185 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (button))),
186 GTK_FILE_CHOOSER_ACTION_SAVE,
187 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
188 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL));
189
190 gtk_file_chooser_set_do_overwrite_confirmation (
191 GTK_FILE_CHOOSER(dialog), TRUE);
192
193 text = gtk_entry_get_text (GTK_ENTRY (entry));
194 if (text != NULL)
195 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog), text);
196
197 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
198 {
199 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
200 gtk_entry_set_text (GTK_ENTRY (entry), filename);
201 g_free (filename);
202 }
203
204 gtk_widget_destroy (GTK_WIDGET (dialog));
205 }
206 #endif
207
208 static gchar *
cg_window_fetch_string(CgWindow * window,const gchar * id)209 cg_window_fetch_string (CgWindow *window,
210 const gchar *id)
211 {
212 GtkWidget *widget;
213 CgWindowPrivate *priv;
214
215 priv = CG_WINDOW_PRIVATE (window);
216 widget = GTK_WIDGET (gtk_builder_get_object (priv->bxml, id));
217
218 g_return_val_if_fail (widget != NULL, NULL);
219
220 if (GTK_IS_ENTRY (widget))
221 return g_strdup (gtk_entry_get_text(GTK_ENTRY(widget)));
222 else if (GTK_IS_COMBO_BOX (widget))
223 {
224 GtkTreeIter iter;
225
226 if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter))
227 {
228 GtkTreeModel *model;
229 gchar *text;
230
231 model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
232 g_return_val_if_fail (GTK_IS_LIST_STORE (model), NULL);
233
234 gtk_tree_model_get (model, &iter, 0, &text, -1);
235
236 return text;
237 }
238 else
239 {
240 return NULL;
241 }
242 }
243 else
244 return NULL;
245 }
246
247 static gint
cg_window_fetch_integer(CgWindow * window,const gchar * id)248 cg_window_fetch_integer (CgWindow *window,
249 const gchar *id)
250 {
251 GtkWidget *widget;
252 CgWindowPrivate *priv;
253
254 priv = CG_WINDOW_PRIVATE(window);
255 widget = GTK_WIDGET (gtk_builder_get_object (priv->bxml, id));
256
257 g_return_val_if_fail(widget != NULL, 0);
258
259 if (GTK_IS_SPIN_BUTTON(widget))
260 return gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( widget));
261 else if (GTK_IS_ENTRY (widget))
262 return strtol (gtk_entry_get_text (GTK_ENTRY (widget)), NULL, 0);
263 else if (GTK_IS_COMBO_BOX (widget))
264 return gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
265 else
266 return 0;
267 }
268
269 static gboolean
cg_window_fetch_boolean(CgWindow * window,const gchar * id)270 cg_window_fetch_boolean (CgWindow *window,
271 const gchar *id)
272 {
273 GtkWidget *widget;
274 CgWindowPrivate *priv;
275
276 priv = CG_WINDOW_PRIVATE (window);
277 widget = GTK_WIDGET (gtk_builder_get_object (priv->bxml, id));
278
279 g_return_val_if_fail (widget != NULL, FALSE);
280
281 if (GTK_IS_TOGGLE_BUTTON (widget))
282 return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
283 else
284 return FALSE;
285 }
286
287 static void
cg_window_set_heap_value(CgWindow * window,GHashTable * values,GType type,const gchar * name,const gchar * id)288 cg_window_set_heap_value (CgWindow *window,
289 GHashTable *values,
290 GType type,
291 const gchar *name,
292 const gchar *id)
293 {
294 gint int_value;
295 gchar *text;
296
297 switch (type)
298 {
299 case G_TYPE_STRING:
300 text = cg_window_fetch_string (window, id);
301 g_hash_table_insert (values, (gchar*)name, text);
302 break;
303 case G_TYPE_INT:
304 int_value = cg_window_fetch_integer (window, id);
305 g_hash_table_insert (values, (gchar*)name, g_strdup_printf ("%d", int_value));
306 break;
307 case G_TYPE_BOOLEAN:
308 text = g_strdup (cg_window_fetch_boolean (window, id) ? "1" : "0");
309 g_hash_table_insert (values, (gchar*)name, text);
310 break;
311 default:
312 break;
313 }
314 }
315
316 static void
cg_window_validate_cc(CgWindow * window)317 cg_window_validate_cc (CgWindow *window)
318 {
319 CgWindowPrivate *priv;
320 priv = CG_WINDOW_PRIVATE(window);
321
322 if (priv->validator != NULL) g_object_unref (G_OBJECT (priv->validator));
323
324 priv->validator = cg_validator_new (
325 GTK_WIDGET (gtk_builder_get_object (priv->bxml, "create_button")),
326 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "cc_name")),
327 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "header_file")),
328 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "source_file")), NULL);
329 }
330
331 static void
cg_window_validate_go(CgWindow * window)332 cg_window_validate_go (CgWindow *window)
333 {
334 CgWindowPrivate *priv;
335 priv = CG_WINDOW_PRIVATE (window);
336
337 if (priv->validator != NULL) g_object_unref (G_OBJECT (priv->validator));
338
339 priv->validator = cg_validator_new (
340 GTK_WIDGET (gtk_builder_get_object (priv->bxml, "create_button")),
341 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "go_name")),
342 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "go_prefix")),
343 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "go_type")),
344 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "go_func_prefix")),
345 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "header_file")),
346 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "source_file")), NULL);
347 }
348
349 static void
cg_window_validate_py(CgWindow * window)350 cg_window_validate_py (CgWindow *window)
351 {
352 CgWindowPrivate *priv;
353 priv = CG_WINDOW_PRIVATE (window);
354
355 if (priv->validator != NULL) g_object_unref (G_OBJECT (priv->validator));
356
357 priv->validator = cg_validator_new (
358 GTK_WIDGET (gtk_builder_get_object (priv->bxml, "create_button")),
359 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "py_name")), NULL);
360 }
361
362 static void
cg_window_validate_js(CgWindow * window)363 cg_window_validate_js (CgWindow *window)
364 {
365 CgWindowPrivate *priv;
366 priv = CG_WINDOW_PRIVATE (window);
367
368 if (priv->validator != NULL) g_object_unref (G_OBJECT (priv->validator));
369
370 priv->validator = cg_validator_new (
371 GTK_WIDGET (gtk_builder_get_object (priv->bxml, "create_button")),
372 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "js_name")),
373 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "source_file")), NULL);
374 }
375
376 static void
cg_window_validate_vala(CgWindow * window)377 cg_window_validate_vala (CgWindow *window)
378 {
379 CgWindowPrivate *priv;
380 priv = CG_WINDOW_PRIVATE (window);
381
382 if (priv->validator != NULL) g_object_unref (G_OBJECT (priv->validator));
383
384 priv->validator = cg_validator_new (
385 GTK_WIDGET (gtk_builder_get_object (priv->bxml, "create_button")),
386 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "vala_name")),
387 GTK_ENTRY (gtk_builder_get_object (priv->bxml, "source_file")), NULL);
388 }
389
390
391 static void
cg_window_header_file_entry_set_sensitive(gpointer user_data,gboolean sensitive)392 cg_window_header_file_entry_set_sensitive (gpointer user_data, gboolean sensitive)
393 {
394 CgWindow *window;
395 CgWindowPrivate *priv;
396
397 GtkWidget *file_header;
398
399 window = CG_WINDOW (user_data);
400 priv = CG_WINDOW_PRIVATE (window);
401
402 file_header = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "header_file"));
403
404 gtk_widget_set_sensitive (file_header, sensitive);
405 }
406
407 static void
cg_window_top_notebook_switch_page_cb(G_GNUC_UNUSED GtkNotebook * notebook,G_GNUC_UNUSED GtkWidget * page,guint page_num,gpointer user_data)408 cg_window_top_notebook_switch_page_cb (G_GNUC_UNUSED GtkNotebook *notebook,
409 G_GNUC_UNUSED GtkWidget *page,
410 guint page_num,
411 gpointer user_data)
412 {
413 CgWindow *window;
414 window = CG_WINDOW(user_data);
415
416 switch(page_num)
417 {
418 case 0:
419 cg_window_header_file_entry_set_sensitive (user_data, TRUE);
420 cg_window_validate_cc (window);
421 break;
422 case 1:
423 cg_window_header_file_entry_set_sensitive (user_data, TRUE);
424 cg_window_validate_go (window);
425 break;
426 case 2: /* Python */
427 cg_window_header_file_entry_set_sensitive (user_data, FALSE);
428 cg_window_validate_py (window);
429 break;
430 case 3: /* JavaScript */
431 cg_window_header_file_entry_set_sensitive (user_data, FALSE);
432 cg_window_validate_js (window);
433 break;
434 case 4: /* Vala */
435 cg_window_header_file_entry_set_sensitive (user_data, FALSE);
436 cg_window_validate_vala (window);
437 break;
438 default:
439 g_assert_not_reached ();
440 break;
441 }
442 }
443
444 static gchar *
cg_window_class_name_to_file_name(const gchar * class_name)445 cg_window_class_name_to_file_name (const gchar *class_name)
446 {
447 return cg_transform_custom_c_type (class_name, FALSE, '-');
448 }
449
450 static void
cg_window_add_project_parent_changed_cb(GtkWidget * project_combo,gpointer user_data)451 cg_window_add_project_parent_changed_cb (GtkWidget *project_combo, gpointer user_data)
452 {
453 CgWindow *window;
454 CgWindowPrivate *priv;
455 gboolean active = TRUE;
456 GtkWidget *widget;
457
458 window = CG_WINDOW (user_data);
459 priv = CG_WINDOW_PRIVATE (window);
460
461 widget = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "add_project"));
462 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
463 {
464 GFile *file;
465 widget = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "add_project_parent"));
466
467 file = ianjuta_project_chooser_get_selected (IANJUTA_PROJECT_CHOOSER (widget), NULL);
468 active = file != NULL;
469 }
470
471 widget = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "create_button"));
472 gtk_widget_set_sensitive (widget, active);
473 }
474
475 static void
cg_window_add_project_toggled_cb(GtkToggleButton * button,gpointer user_data)476 cg_window_add_project_toggled_cb (GtkToggleButton *button,
477 gpointer user_data)
478 {
479 CgWindow *window;
480 CgWindowPrivate *priv;
481 GtkWidget *widget;
482 gboolean sensitive;
483
484 window = CG_WINDOW (user_data);
485 priv = CG_WINDOW_PRIVATE (window);
486
487 sensitive = gtk_toggle_button_get_active (button);
488 widget = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "add_repository"));
489 gtk_widget_set_sensitive (widget, sensitive);
490 if (!sensitive)
491 {
492 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget),
493 FALSE);
494 }
495 widget = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "add_project_parent"));
496 gtk_widget_set_sensitive (widget, sensitive);
497
498 cg_window_add_project_parent_changed_cb (NULL, window);
499 }
500
501 static void
cg_window_cc_name_changed_cb(GtkEntry * entry,gpointer user_data)502 cg_window_cc_name_changed_cb (GtkEntry *entry,
503 gpointer user_data)
504 {
505 CgWindow *window;
506 CgWindowPrivate *priv;
507
508 GtkWidget *file_header;
509 GtkWidget *file_source;
510 gchar* str_filebase;
511 gchar* str_fileheader;
512 gchar* str_filesource;
513
514 window = CG_WINDOW (user_data);
515 priv = CG_WINDOW_PRIVATE (window);
516
517 file_header = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "header_file"));
518 file_source = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "source_file"));
519
520 str_filebase = cg_window_class_name_to_file_name (
521 gtk_entry_get_text (GTK_ENTRY (entry)));
522
523 str_fileheader = g_strconcat (str_filebase, ".h", NULL);
524 str_filesource = g_strconcat (str_filebase, ".cc", NULL);
525 g_free (str_filebase);
526
527 gtk_entry_set_text (GTK_ENTRY (file_header), str_fileheader);
528 gtk_entry_set_text (GTK_ENTRY (file_source), str_filesource);
529
530 g_free (str_fileheader);
531 g_free (str_filesource);
532 }
533
534 static void
cg_window_go_name_changed_cb(GtkEntry * entry,gpointer user_data)535 cg_window_go_name_changed_cb (GtkEntry *entry,
536 gpointer user_data)
537 {
538 CgWindow *window;
539 CgWindowPrivate *priv;
540
541 GtkWidget *type_prefix;
542 GtkWidget *type_name;
543 GtkWidget *func_prefix;
544
545 gchar *str_type_prefix;
546 gchar *str_type_name;
547 gchar *str_func_prefix;
548 const gchar *name;
549
550 GtkWidget *file_header;
551 GtkWidget *file_source;
552 gchar* str_filebase;
553 gchar* str_fileheader;
554 gchar* str_filesource;
555
556 window = CG_WINDOW (user_data);
557 priv = CG_WINDOW_PRIVATE (window);
558
559 type_prefix = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "go_prefix"));
560 type_name = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "go_type"));
561 func_prefix = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "go_func_prefix"));
562
563 file_header = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "header_file"));
564 file_source = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "source_file"));
565
566 name = gtk_entry_get_text (GTK_ENTRY (entry));
567 cg_transform_custom_c_type_to_g_type (name, &str_type_prefix,
568 &str_type_name, &str_func_prefix);
569
570 gtk_entry_set_text (GTK_ENTRY (type_prefix), str_type_prefix);
571 gtk_entry_set_text (GTK_ENTRY (type_name), str_type_name);
572 gtk_entry_set_text (GTK_ENTRY (func_prefix), str_func_prefix);
573
574 g_free (str_type_prefix);
575 g_free (str_type_name);
576 g_free (str_func_prefix);
577
578 str_filebase = cg_window_class_name_to_file_name (name);
579 str_fileheader = g_strconcat (str_filebase, ".h", NULL);
580 str_filesource = g_strconcat (str_filebase, ".c", NULL);
581 g_free (str_filebase);
582
583 gtk_entry_set_text (GTK_ENTRY (file_header), str_fileheader);
584 gtk_entry_set_text (GTK_ENTRY (file_source), str_filesource);
585
586 g_free (str_fileheader);
587 g_free (str_filesource);
588 }
589
590 static void
cg_window_dynamic_name_changed_cb(GtkEntry * entry,gpointer user_data,const gchar * file_ending)591 cg_window_dynamic_name_changed_cb (GtkEntry *entry,
592 gpointer user_data,
593 const gchar *file_ending)
594 {
595 CgWindow *window;
596 CgWindowPrivate *priv;
597
598 GtkWidget *file_header;
599 GtkWidget *file_source;
600 gchar* str_filebase;
601 gchar* str_filesource;
602
603 window = CG_WINDOW (user_data);
604 priv = CG_WINDOW_PRIVATE (window);
605
606 file_header = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "header_file"));
607 file_source = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "source_file"));
608
609 str_filebase = cg_window_class_name_to_file_name (
610 gtk_entry_get_text (GTK_ENTRY (entry)));
611
612 str_filesource = g_strconcat (str_filebase, file_ending, NULL);
613 g_free (str_filebase);
614
615 gtk_entry_set_text (GTK_ENTRY (file_header), str_filesource);
616 gtk_entry_set_text (GTK_ENTRY (file_source), str_filesource);
617
618 g_free (str_filesource);
619 }
620
621 static void
cg_window_py_name_changed_cb(GtkEntry * entry,gpointer user_data)622 cg_window_py_name_changed_cb (GtkEntry *entry,
623 gpointer user_data)
624 {
625 cg_window_dynamic_name_changed_cb (entry, user_data, ".py");
626 }
627
628 static void
cg_window_js_name_changed_cb(GtkEntry * entry,gpointer user_data)629 cg_window_js_name_changed_cb (GtkEntry *entry,
630 gpointer user_data)
631 {
632 cg_window_dynamic_name_changed_cb (entry, user_data, ".js");
633 }
634
635 static void
cg_window_js_is_subclass_changed_cb(GtkEntry * entry,gpointer user_data)636 cg_window_js_is_subclass_changed_cb (GtkEntry *entry,
637 gpointer user_data)
638 {
639 CgWindow *window;
640 CgWindowPrivate *priv;
641
642 GtkWidget *is_subclass;
643 GtkWidget *entry_base_class;
644 GtkWidget *label_base_class;
645
646 window = CG_WINDOW (user_data);
647 priv = CG_WINDOW_PRIVATE (window);
648
649 is_subclass = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "js_is_subclass"));
650 entry_base_class = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "js_base"));
651 label_base_class = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "lbl_js_base"));
652
653 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (is_subclass)) == TRUE)
654 {
655 gtk_editable_set_editable (GTK_EDITABLE (entry_base_class), TRUE);
656 gtk_widget_set_sensitive (label_base_class, TRUE);
657 }
658 else
659 {
660 gtk_editable_set_editable (GTK_EDITABLE (entry_base_class), FALSE);
661 gtk_widget_set_sensitive (label_base_class, FALSE);
662 }
663 }
664
665 static void
cg_window_vala_name_changed_cb(GtkEntry * entry,gpointer user_data)666 cg_window_vala_name_changed_cb (GtkEntry *entry,
667 gpointer user_data)
668 {
669 cg_window_dynamic_name_changed_cb (entry, user_data, ".vala");
670 }
671
672 #if 0
673 static void
674 cg_window_associate_browse_button (GladeXML *xml,
675 const gchar *button_id,
676 const gchar *entry_id)
677 {
678 GtkWidget *button;
679 GtkWidget *entry;
680
681 button = glade_xml_get_widget (xml, button_id);
682 entry = glade_xml_get_widget (xml, entry_id);
683
684 g_return_if_fail (GTK_IS_BUTTON (button) && GTK_IS_ENTRY (entry));
685
686 g_signal_connect(G_OBJECT(button), "clicked",
687 G_CALLBACK(cg_window_browse_button_clicked_cb), entry);
688 }
689 #endif
690
691 static void
cg_window_set_builder(CgWindow * window,GtkBuilder * xml)692 cg_window_set_builder (CgWindow *window,
693 GtkBuilder *xml)
694 {
695 CgWindowPrivate *priv;
696 priv = CG_WINDOW_PRIVATE (window);
697
698 priv->bxml = xml;
699 g_object_ref (priv->bxml);
700
701 priv->window = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "classgen_main"));
702
703 #if 0
704 cg_window_associate_browse_button (priv->gxml, "browse_header",
705 "header_file");
706
707 cg_window_associate_browse_button (priv->gxml, "browse_source",
708 "source_file");
709 #endif
710
711 priv->editor_cc = cg_element_editor_new (
712 GTK_TREE_VIEW (gtk_builder_get_object (priv->bxml, "cc_elements")),
713 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "cc_elements_add")),
714 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "cc_elements_remove")),
715 5,
716 _("Scope"), CG_ELEMENT_EDITOR_COLUMN_LIST, CC_SCOPE_LIST,
717 _("Implementation"), CG_ELEMENT_EDITOR_COLUMN_LIST, CC_IMPLEMENTATION_LIST,
718 _("Type"), CG_ELEMENT_EDITOR_COLUMN_STRING,
719 _("Name"), CG_ELEMENT_EDITOR_COLUMN_STRING,
720 _("Arguments"), CG_ELEMENT_EDITOR_COLUMN_ARGUMENTS);
721
722 priv->editor_go_members = cg_element_editor_new (
723 GTK_TREE_VIEW (gtk_builder_get_object (priv->bxml, "go_members")),
724 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "go_members_add")),
725 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "go_members_remove")),
726 4,
727 _("Scope"), CG_ELEMENT_EDITOR_COLUMN_LIST, GO_SCOPE_LIST,
728 _("Type"), CG_ELEMENT_EDITOR_COLUMN_STRING,
729 _("Name"), CG_ELEMENT_EDITOR_COLUMN_STRING,
730 _("Arguments"), CG_ELEMENT_EDITOR_COLUMN_ARGUMENTS);
731
732 priv->editor_go_properties = cg_element_editor_new(
733 GTK_TREE_VIEW (gtk_builder_get_object (priv->bxml, "go_properties")),
734 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "go_properties_add")),
735 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "go_properties_remove")),
736 7,
737 _("Name"), CG_ELEMENT_EDITOR_COLUMN_STRING,
738 _("Nick"), CG_ELEMENT_EDITOR_COLUMN_STRING,
739 _("Blurb"), CG_ELEMENT_EDITOR_COLUMN_STRING,
740 _("GType"), CG_ELEMENT_EDITOR_COLUMN_STRING,
741 _("ParamSpec"), CG_ELEMENT_EDITOR_COLUMN_LIST, GO_PARAMSPEC_LIST,
742 _("Default"), CG_ELEMENT_EDITOR_COLUMN_STRING,
743 _("Flags"), CG_ELEMENT_EDITOR_COLUMN_FLAGS, GO_PROPERTY_FLAGS);
744
745 priv->editor_go_signals = cg_element_editor_new(
746 GTK_TREE_VIEW (gtk_builder_get_object (priv->bxml, "go_signals")),
747 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "go_signals_add")),
748 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "go_signals_remove")),
749 5,
750 _("Type"), CG_ELEMENT_EDITOR_COLUMN_STRING,
751 _("Name"), CG_ELEMENT_EDITOR_COLUMN_STRING,
752 _("Arguments"), CG_ELEMENT_EDITOR_COLUMN_ARGUMENTS, /* Somehow redundant with marshaller, but required for default handler */
753 _("Flags"), CG_ELEMENT_EDITOR_COLUMN_FLAGS, GO_SIGNAL_FLAGS,
754 _("Marshaller"), CG_ELEMENT_EDITOR_COLUMN_STRING);
755
756 priv->editor_py_methods = cg_element_editor_new (
757 GTK_TREE_VIEW (gtk_builder_get_object (priv->bxml, "py_methods")),
758 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "py_methods_add")),
759 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "py_methods_remove")),
760 2,
761 _("Name"), CG_ELEMENT_EDITOR_COLUMN_STRING,
762 _("Arguments"), CG_ELEMENT_EDITOR_COLUMN_ARGUMENTS);
763
764 priv->editor_py_constvars = cg_element_editor_new (
765 GTK_TREE_VIEW (gtk_builder_get_object (priv->bxml, "py_constvars")),
766 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "py_constvars_add")),
767 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "py_constvars_remove")),
768 2,
769 _("Name"), CG_ELEMENT_EDITOR_COLUMN_STRING,
770 _("Value"), CG_ELEMENT_EDITOR_COLUMN_STRING);
771
772 priv->editor_js_methods = cg_element_editor_new (
773 GTK_TREE_VIEW (gtk_builder_get_object (priv->bxml, "js_methods")),
774 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "js_methods_add")),
775 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "js_methods_remove")),
776 2,
777 _("Name"), CG_ELEMENT_EDITOR_COLUMN_STRING,
778 _("Arguments"), CG_ELEMENT_EDITOR_COLUMN_ARGUMENTS);
779
780 priv->editor_js_variables = cg_element_editor_new (
781 GTK_TREE_VIEW (gtk_builder_get_object (priv->bxml, "js_variables")),
782 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "js_variables_add")),
783 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "js_variables_remove")),
784 2,
785 _("Name"), CG_ELEMENT_EDITOR_COLUMN_STRING,
786 _("Value"), CG_ELEMENT_EDITOR_COLUMN_STRING);
787
788 priv->editor_js_imports = cg_element_editor_new (
789 GTK_TREE_VIEW (gtk_builder_get_object (priv->bxml, "js_imports")),
790 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "js_imports_add")),
791 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "js_imports_remove")),
792 2,
793 _("Name"), CG_ELEMENT_EDITOR_COLUMN_STRING,
794 _("Module"), CG_ELEMENT_EDITOR_COLUMN_STRING);
795
796 priv->editor_vala_methods = cg_element_editor_new (
797 GTK_TREE_VIEW (gtk_builder_get_object (priv->bxml, "vala_methods")),
798 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "vala_methods_add")),
799 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "vala_methods_remove")),
800 4,
801 _("Scope"), CG_ELEMENT_EDITOR_COLUMN_LIST, VALA_METHSIG_SCOPE_LIST,
802 _("Type"), CG_ELEMENT_EDITOR_COLUMN_STRING,
803 _("Name"), CG_ELEMENT_EDITOR_COLUMN_STRING,
804 _("Arguments"), CG_ELEMENT_EDITOR_COLUMN_ARGUMENTS);
805
806 priv->editor_vala_properties = cg_element_editor_new (
807 GTK_TREE_VIEW (gtk_builder_get_object (priv->bxml, "vala_properties")),
808 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "vala_properties_add")),
809 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "vala_properties_remove")),
810 7,
811 _("Scope"), CG_ELEMENT_EDITOR_COLUMN_LIST, VALA_PROP_SCOPE_LIST,
812 _("Type"), CG_ELEMENT_EDITOR_COLUMN_STRING,
813 _("Name"), CG_ELEMENT_EDITOR_COLUMN_STRING,
814 _("Automatic"), CG_ELEMENT_EDITOR_COLUMN_LIST, VALA_BOOLEAN_LIST,
815 _("Getter"), CG_ELEMENT_EDITOR_COLUMN_LIST, VALA_BOOLEAN_LIST,
816 _("Setter"), CG_ELEMENT_EDITOR_COLUMN_LIST, VALA_BOOLEAN_LIST,
817 _("Value"), CG_ELEMENT_EDITOR_COLUMN_STRING);
818
819 priv->editor_vala_signals = cg_element_editor_new (
820 GTK_TREE_VIEW (gtk_builder_get_object (priv->bxml, "vala_signals")),
821 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "vala_signals_add")),
822 GTK_BUTTON (gtk_builder_get_object (priv->bxml, "vala_signals_remove")),
823 3,
824 _("Scope"), CG_ELEMENT_EDITOR_COLUMN_LIST, VALA_METHSIG_SCOPE_LIST,
825 _("Name"), CG_ELEMENT_EDITOR_COLUMN_STRING,
826 _("Arguments"), CG_ELEMENT_EDITOR_COLUMN_ARGUMENTS);
827
828 /* Active item property in glade cannot be set because no GtkTreeModel
829 * is assigned. */
830 gtk_combo_box_set_active (
831 GTK_COMBO_BOX (gtk_builder_get_object (priv->bxml, "license")), 0);
832
833 gtk_combo_box_set_active (
834 GTK_COMBO_BOX (gtk_builder_get_object (priv->bxml, "cc_inheritance")),
835 0);
836 g_signal_connect (
837 G_OBJECT (gtk_builder_get_object (priv->bxml, "py_name")), "changed",
838 G_CALLBACK (cg_window_py_name_changed_cb), window);
839
840 g_signal_connect (
841 G_OBJECT (gtk_builder_get_object (priv->bxml, "vala_name")), "changed",
842 G_CALLBACK (cg_window_vala_name_changed_cb), window);
843
844 gtk_combo_box_set_active (
845 GTK_COMBO_BOX (gtk_builder_get_object (priv->bxml, "vala_class_scope")),
846 0);
847
848 /* This revalidates the appropriate validator */
849 g_signal_connect (
850 G_OBJECT (gtk_builder_get_object (priv->bxml, "top_notebook")),
851 "switch-page", G_CALLBACK (cg_window_top_notebook_switch_page_cb),
852 window);
853
854 g_signal_connect (
855 G_OBJECT (gtk_builder_get_object (priv->bxml, "go_name")), "changed",
856 G_CALLBACK (cg_window_go_name_changed_cb), window);
857
858 g_signal_connect (
859 G_OBJECT (gtk_builder_get_object (priv->bxml, "cc_name")), "changed",
860 G_CALLBACK (cg_window_cc_name_changed_cb), window);
861
862 g_signal_connect (
863 G_OBJECT (gtk_builder_get_object (priv->bxml, "js_name")), "changed",
864 G_CALLBACK (cg_window_js_name_changed_cb), window);
865
866 g_signal_connect (
867 G_OBJECT (gtk_builder_get_object (priv->bxml, "js_is_subclass")), "toggled",
868 G_CALLBACK (cg_window_js_is_subclass_changed_cb), window);
869
870 g_signal_connect (
871 G_OBJECT (gtk_builder_get_object (priv->bxml, "add_project")), "toggled",
872 G_CALLBACK (cg_window_add_project_toggled_cb), window);
873
874 g_signal_connect (
875 G_OBJECT (gtk_builder_get_object (priv->bxml, "add_project_parent")), "changed",
876 G_CALLBACK (cg_window_add_project_parent_changed_cb), window);
877
878 cg_window_add_project_toggled_cb (GTK_TOGGLE_BUTTON (
879 gtk_builder_get_object (priv->bxml, "add_project")), window);
880
881 /* Selected page is CC */
882 cg_window_validate_cc (window);
883 }
884
885 static void
cg_window_cc_transform_func(GHashTable * table,G_GNUC_UNUSED gpointer user_data)886 cg_window_cc_transform_func (GHashTable *table,
887 G_GNUC_UNUSED gpointer user_data)
888 {
889 cg_transform_arguments (table, "Arguments", FALSE);
890 }
891
892 static void
cg_window_go_members_transform_func(GHashTable * table,gpointer user_data)893 cg_window_go_members_transform_func (GHashTable *table,
894 gpointer user_data)
895 {
896 CgWindow *window;
897 gchar *name;
898 gchar *func_prefix;
899
900 /* Strip of func prefix of members if they contain any, the prefix
901 * is added by the autogen template. */
902 window = CG_WINDOW (user_data);
903 name = g_hash_table_lookup (table, "Name");
904 func_prefix = cg_window_fetch_string (window, "go_func_prefix");
905
906 if (g_str_has_prefix (name, func_prefix))
907 {
908 name = g_strdup (name + strlen (func_prefix) + 1);
909 g_hash_table_insert (table, "Name", name);
910 }
911
912 g_free (func_prefix);
913 cg_transform_arguments (table, "Arguments", TRUE);
914 }
915
916 static void
cg_window_go_properties_transform_func(GHashTable * table,G_GNUC_UNUSED gpointer user_data)917 cg_window_go_properties_transform_func (GHashTable *table,
918 G_GNUC_UNUSED gpointer user_data)
919 {
920 gchar *paramspec;
921
922 cg_transform_string (table, "Name");
923 cg_transform_string (table, "Nick");
924 cg_transform_string (table, "Blurb");
925
926 cg_transform_guess_paramspec (table, "ParamSpec",
927 "Type", N_(GO_PARAMSPEC_LIST[0]));
928
929 cg_transform_flags (table, "Flags", GO_PROPERTY_FLAGS);
930
931 paramspec = g_hash_table_lookup (table, "ParamSpec");
932 if (paramspec && (strcmp (paramspec, "g_param_spec_string") == 0))
933 cg_transform_string (table, "Default");
934 }
935
936 static void
cg_window_go_signals_transform_func(GHashTable * table,gpointer user_data)937 cg_window_go_signals_transform_func (GHashTable *table,
938 gpointer user_data)
939 {
940 CgWindow *window;
941
942 gchar *type;
943 guint arg_count;
944
945 gchar *gtype_prefix;
946 gchar *gtype_suffix;
947 gchar *name;
948 gchar *self_type;
949
950 window = CG_WINDOW (user_data);
951
952 cg_transform_string (table, "Name");
953
954 /* Provide GType of return type */
955 type = g_hash_table_lookup (table, "Type");
956 if (type != NULL)
957 {
958 cg_transform_c_type_to_g_type (type, >ype_prefix, >ype_suffix);
959 g_hash_table_insert (table, "GTypePrefix", gtype_prefix);
960 g_hash_table_insert (table, "GTypeSuffix", gtype_suffix);
961 }
962
963 cg_transform_arguments (table, "Arguments", TRUE);
964
965 /* Add self as signal's first argument */
966 name = cg_window_fetch_string (window, "go_name");
967 self_type = g_strconcat (name, "*", NULL);
968 g_free (name);
969
970 cg_transform_first_argument (table, "Arguments", self_type);
971 g_free (self_type);
972
973 /* Provide GTypes and amount of arguments */
974 arg_count = cg_transform_arguments_to_gtypes (table, "Arguments",
975 "ArgumentGTypes");
976
977 g_hash_table_insert (table, "ArgumentCount",
978 g_strdup_printf ("%u", arg_count));
979
980 cg_transform_flags (table, "Flags", GO_SIGNAL_FLAGS);
981 }
982
983 static void
cg_window_py_methods_transform_func(GHashTable * table,G_GNUC_UNUSED gpointer user_data)984 cg_window_py_methods_transform_func (GHashTable *table,
985 G_GNUC_UNUSED gpointer user_data)
986 {
987 cg_transform_python_arguments (table, "Arguments");
988 }
989
990 static void
cg_window_py_constvars_transform_func(GHashTable * table,G_GNUC_UNUSED gpointer user_data)991 cg_window_py_constvars_transform_func (GHashTable *table,
992 G_GNUC_UNUSED gpointer user_data)
993 {
994 cg_transform_string (table, "Value");
995 }
996
997 static void
cg_window_js_methods_transform_func(GHashTable * table,G_GNUC_UNUSED gpointer user_data)998 cg_window_js_methods_transform_func (GHashTable *table,
999 G_GNUC_UNUSED gpointer user_data)
1000 {
1001 cg_transform_arguments (table, "Arguments", FALSE);
1002 }
1003
1004 static void
cg_window_js_variables_transform_func(GHashTable * table,G_GNUC_UNUSED gpointer user_data)1005 cg_window_js_variables_transform_func (GHashTable *table,
1006 G_GNUC_UNUSED gpointer user_data)
1007 {
1008
1009 cg_transform_string (table, "Name");
1010 }
1011
1012 static void
cg_window_js_imports_transform_func(GHashTable * table,G_GNUC_UNUSED gpointer user_data)1013 cg_window_js_imports_transform_func (GHashTable *table,
1014 G_GNUC_UNUSED gpointer user_data)
1015 {
1016 cg_transform_string (table, "Name");
1017 }
1018
1019 static void
vala_transform_scope_func(GHashTable * table,G_GNUC_UNUSED gpointer user_data)1020 vala_transform_scope_func (GHashTable *table,
1021 G_GNUC_UNUSED gpointer user_data)
1022 {
1023 gchar *scope;
1024
1025 scope = g_hash_table_lookup (table, "Scope");
1026 if (scope == NULL)
1027 {
1028 g_hash_table_insert (table, "Scope",
1029 g_strdup_printf("public"));
1030 }
1031 }
1032
1033 static void
cg_window_vala_methods_transform_func(GHashTable * table,G_GNUC_UNUSED gpointer user_data)1034 cg_window_vala_methods_transform_func (GHashTable *table,
1035 G_GNUC_UNUSED gpointer user_data)
1036 {
1037 cg_transform_string (table, "Name");
1038 cg_transform_arguments (table, "Arguments", FALSE);
1039
1040 vala_transform_scope_func (table, user_data);
1041 }
1042
1043 static void
cg_window_vala_signals_transform_func(GHashTable * table,G_GNUC_UNUSED gpointer user_data)1044 cg_window_vala_signals_transform_func (GHashTable *table,
1045 G_GNUC_UNUSED gpointer user_data)
1046 {
1047 cg_transform_string (table, "Name");
1048 cg_transform_arguments (table, "Arguments", FALSE);
1049
1050 vala_transform_scope_func (table, user_data);
1051 }
1052
1053 static void
cg_window_vala_properties_transform_func(GHashTable * table,G_GNUC_UNUSED gpointer user_data)1054 cg_window_vala_properties_transform_func (GHashTable *table,
1055 G_GNUC_UNUSED gpointer user_data)
1056 {
1057 cg_transform_string (table, "Name");
1058 cg_transform_string (table, "Value");
1059
1060 vala_transform_scope_func (table, user_data);
1061 }
1062
1063 #if 0
1064 static gboolean
1065 cg_window_scope_condition_func (const gchar **elements,
1066 gpointer user_data)
1067 {
1068 /* Matches all members in the given scope */
1069 if (elements[0] == NULL) return FALSE;
1070 if (strcmp (elements[0], (const gchar *) user_data) == 0) return TRUE;
1071 return FALSE;
1072 }
1073 #endif
1074
1075 static gboolean
cg_window_scope_with_args_condition_func(const gchar ** elements,gpointer user_data)1076 cg_window_scope_with_args_condition_func (const gchar **elements,
1077 gpointer user_data)
1078 {
1079 /* Matches all members in the given scope that have arguments set */
1080 if (elements[0] == NULL) return FALSE;
1081 if (elements[3] == NULL || *(elements[3]) == '\0') return FALSE;
1082 if (strcmp (elements[0], (const gchar *) user_data) != 0) return FALSE;
1083 return TRUE;
1084 }
1085
1086 static gboolean
cg_window_scope_without_args_condition_func(const gchar ** elements,gpointer user_data)1087 cg_window_scope_without_args_condition_func (const gchar **elements,
1088 gpointer user_data)
1089 {
1090 /* Matches all members in the given scope that have no arguments set */
1091 if (elements[0] == NULL) return FALSE;
1092 if (elements[3] != NULL && *(elements[3]) != '\0') return FALSE;
1093 if (strcmp(elements[0], (const gchar *) user_data) != 0) return FALSE;
1094 return TRUE;
1095 }
1096
1097 static void
cg_window_init(CgWindow * window)1098 cg_window_init (CgWindow *window)
1099 {
1100 CgWindowPrivate *priv;
1101 priv = CG_WINDOW_PRIVATE (window);
1102
1103 priv->bxml = NULL;
1104 priv->window = NULL;
1105
1106 priv->editor_cc = NULL;
1107 priv->editor_go_members = NULL;
1108 priv->editor_go_properties = NULL;
1109 priv->editor_go_signals = NULL;
1110 priv->editor_py_methods = NULL;
1111 priv->editor_py_constvars = NULL;
1112 priv->editor_js_methods = NULL;
1113 priv->editor_js_variables = NULL;
1114 priv->editor_js_imports = NULL;
1115 priv->editor_vala_methods = NULL;
1116 priv->editor_vala_properties = NULL;
1117 priv->editor_vala_signals = NULL;
1118
1119 priv->validator = NULL;
1120 }
1121
1122 static void
cg_window_finalize(GObject * object)1123 cg_window_finalize (GObject *object)
1124 {
1125 CgWindow *window;
1126 CgWindowPrivate *priv;
1127
1128 window = CG_WINDOW (object);
1129 priv = CG_WINDOW_PRIVATE (window);
1130
1131 if (priv->editor_cc != NULL)
1132 g_object_unref (G_OBJECT (priv->editor_cc));
1133 if (priv->editor_go_members != NULL)
1134 g_object_unref (G_OBJECT (priv->editor_go_members));
1135 if (priv->editor_go_properties != NULL)
1136 g_object_unref (G_OBJECT (priv->editor_go_properties));
1137 if (priv->editor_go_signals != NULL)
1138 g_object_unref (G_OBJECT (priv->editor_go_signals));
1139 if (priv->editor_py_methods != NULL)
1140 g_object_unref (G_OBJECT (priv->editor_py_methods));
1141 if (priv->editor_py_constvars != NULL)
1142 g_object_unref (G_OBJECT (priv->editor_py_constvars));
1143 if (priv->editor_js_methods != NULL)
1144 g_object_unref (G_OBJECT (priv->editor_js_methods));
1145 if (priv->editor_js_variables != NULL)
1146 g_object_unref (G_OBJECT (priv->editor_js_variables));
1147 if (priv->editor_js_imports != NULL)
1148 g_object_unref (G_OBJECT (priv->editor_js_imports));
1149 if (priv->editor_vala_methods != NULL)
1150 g_object_unref (G_OBJECT (priv->editor_vala_methods));
1151 if (priv->editor_vala_properties != NULL)
1152 g_object_unref (G_OBJECT (priv->editor_vala_properties));
1153 if (priv->editor_vala_signals != NULL)
1154 g_object_unref (G_OBJECT (priv->editor_vala_signals));
1155
1156 if (priv->validator != NULL)
1157 g_object_unref (G_OBJECT (priv->validator));
1158
1159 if (priv->bxml != NULL)
1160 g_object_unref (G_OBJECT (priv->bxml));
1161
1162 gtk_widget_destroy(priv->window);
1163
1164 G_OBJECT_CLASS (parent_class)->finalize (object);
1165 }
1166
1167 static void
cg_window_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)1168 cg_window_set_property (GObject *object,
1169 guint prop_id,
1170 const GValue *value,
1171 GParamSpec *pspec)
1172 {
1173 CgWindow *window;
1174
1175 g_return_if_fail (CG_IS_WINDOW (object));
1176
1177 window = CG_WINDOW (object);
1178
1179 switch (prop_id)
1180 {
1181 case PROP_BUILDER_XML:
1182 cg_window_set_builder (window,
1183 GTK_BUILDER (g_value_get_object (value)));
1184 break;
1185 default:
1186 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1187 break;
1188 }
1189 }
1190
1191 static void
cg_window_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)1192 cg_window_get_property (GObject *object,
1193 guint prop_id,
1194 GValue *value,
1195 GParamSpec *pspec)
1196 {
1197 CgWindow *window;
1198 CgWindowPrivate *priv;
1199
1200 g_return_if_fail (CG_IS_WINDOW (object));
1201
1202 window = CG_WINDOW (object);
1203 priv = CG_WINDOW_PRIVATE (window);
1204
1205 switch (prop_id)
1206 {
1207 case PROP_BUILDER_XML:
1208 g_value_set_object (value, G_OBJECT (priv->bxml));
1209 break;
1210 default:
1211 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1212 break;
1213 }
1214 }
1215
1216 static void
cg_window_class_init(CgWindowClass * klass)1217 cg_window_class_init (CgWindowClass *klass)
1218 {
1219 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1220 parent_class = g_type_class_peek_parent (klass);
1221
1222 g_type_class_add_private (klass, sizeof (CgWindowPrivate));
1223
1224 object_class->finalize = cg_window_finalize;
1225 object_class->set_property = cg_window_set_property;
1226 object_class->get_property = cg_window_get_property;
1227
1228 g_object_class_install_property (object_class,
1229 PROP_BUILDER_XML,
1230 g_param_spec_object ("builder-xml",
1231 "GtkBuilder",
1232 _("XML description of the user interface"),
1233 G_TYPE_OBJECT,
1234 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
1235 }
1236
1237 GType
cg_window_get_type(void)1238 cg_window_get_type (void)
1239 {
1240 static GType our_type = 0;
1241
1242 if (our_type == 0)
1243 {
1244 static const GTypeInfo our_info =
1245 {
1246 sizeof (CgWindowClass),
1247 (GBaseInitFunc) NULL,
1248 (GBaseFinalizeFunc) NULL,
1249 (GClassInitFunc) cg_window_class_init,
1250 NULL,
1251 NULL,
1252 sizeof (CgWindow),
1253 0,
1254 (GInstanceInitFunc) cg_window_init,
1255 NULL
1256 };
1257
1258 our_type = g_type_register_static (G_TYPE_OBJECT, "CgWindow",
1259 &our_info, 0);
1260 }
1261
1262 return our_type;
1263 }
1264
1265 CgWindow *
cg_window_new(void)1266 cg_window_new (void)
1267 {
1268 GtkBuilder *bxml = gtk_builder_new();
1269 GObject *window;
1270 GError* error = NULL;
1271
1272 if (!gtk_builder_add_from_file (bxml, BUILDER_FILE, &error))
1273 {
1274 g_warning ("Couldn't load builder file: %s", error->message);
1275 g_error_free (error);
1276 return NULL;
1277 }
1278
1279 window = g_object_new (CG_TYPE_WINDOW, "builder-xml", bxml, NULL);
1280 return CG_WINDOW (window);
1281 }
1282
1283 GtkDialog *
cg_window_get_dialog(CgWindow * window)1284 cg_window_get_dialog (CgWindow *window)
1285 {
1286 return GTK_DIALOG (CG_WINDOW_PRIVATE (window)->window);
1287 }
1288
1289 GHashTable *
cg_window_create_value_heap(CgWindow * window)1290 cg_window_create_value_heap (CgWindow *window)
1291 {
1292 static const gchar *LICENSES[] = {
1293 "gpl",
1294 "lgpl",
1295 "bsd",
1296 "none"
1297 };
1298
1299 CgWindowPrivate *priv;
1300 GHashTable *values;
1301 gint license_index;
1302
1303 GtkNotebook *notebook;
1304
1305 gchar *header_file;
1306 gchar *source_file;
1307
1308 gchar *text;
1309 gchar *base_prefix;
1310 gchar *base_suffix;
1311
1312 priv = CG_WINDOW_PRIVATE (window);
1313 notebook = GTK_NOTEBOOK (gtk_builder_get_object (priv->bxml,
1314 "top_notebook"));
1315
1316 values = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_free);
1317
1318 switch (gtk_notebook_get_current_page (notebook))
1319 {
1320 case 0: /* cc */
1321 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1322 "ClassName", "cc_name");
1323 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1324 "BaseClass", "cc_base");
1325 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1326 "Inheritance", "cc_inheritance");
1327 cg_window_set_heap_value (window, values, G_TYPE_BOOLEAN,
1328 "Headings", "cc_headings");
1329 cg_window_set_heap_value (window, values, G_TYPE_BOOLEAN,
1330 "Inline", "cc_inline");
1331
1332 cg_element_editor_set_values (priv->editor_cc, "Elements", values,
1333 cg_window_cc_transform_func, window,
1334 "Scope", "Implementation", "Type",
1335 "Name", "Arguments");
1336
1337 break;
1338 case 1: /* GObject */
1339 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1340 "ClassName", "go_name");
1341 cg_window_set_heap_value(window, values, G_TYPE_STRING,
1342 "BaseClass", "go_base");
1343 cg_window_set_heap_value(window, values, G_TYPE_STRING,
1344 "TypePrefix", "go_prefix");
1345 cg_window_set_heap_value(window, values, G_TYPE_STRING,
1346 "TypeSuffix", "go_type");
1347
1348 /* Store GType of base class which is also required */
1349 text = cg_window_fetch_string (window, "go_base");
1350 cg_transform_custom_c_type_to_g_type (text, &base_prefix,
1351 &base_suffix, NULL);
1352
1353 g_free (text);
1354
1355 g_hash_table_insert (values, "BaseTypePrefix", base_prefix);
1356
1357 g_hash_table_insert (values, "BaseTypeSuffix", base_suffix);
1358
1359 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1360 "FuncPrefix", "go_func_prefix");
1361
1362 cg_window_set_heap_value (window, values, G_TYPE_BOOLEAN,
1363 "Headings", "go_headings");
1364
1365 cg_element_editor_set_values (priv->editor_go_members, "Members",
1366 values,
1367 cg_window_go_members_transform_func,
1368 window, "Scope", "Type", "Name",
1369 "Arguments");
1370
1371 /* These count the amount of members that match certain conditions
1372 * and that would be relatively hard to find out in the autogen
1373 * file (at least with my limited autogen skills). These are the
1374 * number of private respectively public member functions (arguments
1375 * set) and variables (no arguments set). */
1376 cg_element_editor_set_value_count (priv->editor_go_members,
1377 "PrivateFunctionCount", values,
1378 cg_window_scope_with_args_condition_func, "private");
1379
1380 cg_element_editor_set_value_count (priv->editor_go_members,
1381 "PrivateVariableCount", values,
1382 cg_window_scope_without_args_condition_func, "private");
1383
1384 cg_element_editor_set_value_count (priv->editor_go_members,
1385 "PublicFunctionCount", values,
1386 cg_window_scope_with_args_condition_func, "public");
1387
1388 cg_element_editor_set_value_count (priv->editor_go_members,
1389 "PublicVariableCount", values,
1390 cg_window_scope_without_args_condition_func, "public");
1391
1392 cg_element_editor_set_values (priv->editor_go_properties, "Properties",
1393 values,
1394 cg_window_go_properties_transform_func,
1395 window, "Name", "Nick", "Blurb", "Type",
1396 "ParamSpec", "Default", "Flags");
1397
1398 cg_element_editor_set_values (priv->editor_go_signals, "Signals",
1399 values,
1400 cg_window_go_signals_transform_func,
1401 window, "Type", "Name", "Arguments",
1402 "Flags", "Marshaller");
1403
1404 break;
1405 case 2: /* Python */
1406 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1407 "ClassName", "py_name");
1408 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1409 "BaseClass", "py_base");
1410 cg_window_set_heap_value (window, values, G_TYPE_BOOLEAN,
1411 "Headings", "py_headings");
1412 cg_element_editor_set_values (priv->editor_py_methods, "Methods", values,
1413 cg_window_py_methods_transform_func,
1414 window, "Name", "Arguments");
1415 cg_element_editor_set_values (priv->editor_py_constvars, "Constvars",
1416 values,
1417 cg_window_py_constvars_transform_func,
1418 window, "Name", "Value");
1419 break;
1420 case 3: /* JavaScript */
1421 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1422 "ClassName", "js_name");
1423 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1424 "BaseClass", "js_base");
1425 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1426 "Initargs", "js_initargs");
1427 cg_window_set_heap_value (window, values, G_TYPE_BOOLEAN,
1428 "Headings", "js_headings");
1429 cg_element_editor_set_values (priv->editor_js_methods, "Methods", values,
1430 cg_window_js_methods_transform_func,
1431 window, "Name", "Arguments");
1432 cg_element_editor_set_values (priv->editor_js_variables, "Variables",
1433 values,
1434 cg_window_js_variables_transform_func,
1435 window, "Name", "Value");
1436 cg_element_editor_set_values (priv->editor_js_imports, "Imports",
1437 values,
1438 cg_window_js_imports_transform_func,
1439 window, "Name", "Module");
1440 break;
1441 case 4: /* Vala */
1442 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1443 "ClassName", "vala_name");
1444 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1445 "BaseClass", "vala_base");
1446 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1447 "ClassScope", "vala_class_scope");
1448 cg_window_set_heap_value (window, values, G_TYPE_BOOLEAN,
1449 "Headings", "vala_headings");
1450 cg_element_editor_set_values (priv->editor_vala_methods, "Methods", values,
1451 cg_window_vala_methods_transform_func,
1452 window, "Scope", "Type", "Name", "Arguments");
1453 cg_element_editor_set_values (priv->editor_vala_properties, "Properties", values,
1454 cg_window_vala_properties_transform_func,
1455 window, "Scope", "Type", "Name", "Automatic",
1456 "Getter", "Setter", "Value");
1457 cg_element_editor_set_values (priv->editor_vala_signals, "Signals", values,
1458 cg_window_vala_signals_transform_func,
1459 window, "Scope", "Name", "Arguments");
1460 break;
1461 default:
1462 g_assert_not_reached ();
1463 break;
1464 }
1465
1466 cg_window_set_heap_value (window, values, G_TYPE_STRING,
1467 "AuthorName", "author_name");
1468
1469 cg_window_set_heap_value(window, values, G_TYPE_STRING,
1470 "AuthorEmail", "author_email");
1471
1472 license_index = cg_window_fetch_integer (window, "license");
1473 g_hash_table_insert (values, "License", g_strdup (LICENSES[license_index]));
1474
1475 header_file = cg_window_get_header_file (window) != NULL ? g_path_get_basename (cg_window_get_header_file (window)) : NULL;
1476 source_file = g_path_get_basename (cg_window_get_source_file (window));
1477
1478 g_hash_table_insert (values, "HeaderFile", header_file);
1479
1480 g_hash_table_insert (values, "SourceFile", source_file);
1481
1482 return values;
1483 }
1484
1485 const gchar *
cg_window_get_header_template(CgWindow * window)1486 cg_window_get_header_template (CgWindow *window)
1487 {
1488 CgWindowPrivate *priv;
1489 GtkNotebook *notebook;
1490
1491 priv = CG_WINDOW_PRIVATE (window);
1492 notebook = GTK_NOTEBOOK (gtk_builder_get_object (priv->bxml,
1493 "top_notebook"));
1494
1495 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
1496
1497 switch(gtk_notebook_get_current_page (notebook))
1498 {
1499 case 0:
1500 return CC_HEADER_TEMPLATE;
1501 case 1:
1502 return GO_HEADER_TEMPLATE;
1503 case 2: /* Python */
1504 return NULL;
1505 case 3: /* JavaScript */
1506 return NULL;
1507 case 4: /* Vala */
1508 return NULL;
1509 default:
1510 g_assert_not_reached ();
1511 return NULL;
1512 }
1513 }
1514
1515 const gchar *
cg_window_get_header_file(CgWindow * window)1516 cg_window_get_header_file(CgWindow *window)
1517 {
1518 CgWindowPrivate *priv;
1519 GtkEntry *entry;
1520
1521 priv = CG_WINDOW_PRIVATE (window);
1522 entry = GTK_ENTRY (gtk_builder_get_object (priv->bxml, "header_file"));
1523
1524 g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
1525 return gtk_widget_get_sensitive (GTK_WIDGET (entry)) == TRUE ? gtk_entry_get_text (entry) : NULL;
1526 }
1527
1528 const gchar *
cg_window_get_source_template(CgWindow * window)1529 cg_window_get_source_template(CgWindow *window)
1530 {
1531 CgWindowPrivate *priv;
1532 GtkNotebook *notebook;
1533
1534 priv = CG_WINDOW_PRIVATE (window);
1535 notebook = GTK_NOTEBOOK (gtk_builder_get_object (priv->bxml,
1536 "top_notebook"));
1537
1538 g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
1539
1540 switch(gtk_notebook_get_current_page (notebook))
1541 {
1542 case 0:
1543 return CC_SOURCE_TEMPLATE;
1544 case 1:
1545 return GO_SOURCE_TEMPLATE;
1546 case 2:
1547 return PY_SOURCE_TEMPLATE;
1548 case 3: /* JavaScript */
1549 return JS_SOURCE_TEMPLATE;
1550 case 4: /* Vala */
1551 return VALA_SOURCE_TEMPLATE;
1552 default:
1553 g_assert_not_reached ();
1554 return NULL;
1555 }
1556 }
1557
1558 const gchar *
cg_window_get_source_file(CgWindow * window)1559 cg_window_get_source_file (CgWindow *window)
1560 {
1561 CgWindowPrivate *priv;
1562 GtkEntry *entry;
1563
1564 priv = CG_WINDOW_PRIVATE (window);
1565 entry = GTK_ENTRY (gtk_builder_get_object (priv->bxml, "source_file"));
1566
1567 g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
1568 return gtk_entry_get_text (entry);
1569 }
1570
1571 GFile *
cg_window_get_selected_target(CgWindow * window)1572 cg_window_get_selected_target (CgWindow *window)
1573 {
1574 CgWindowPrivate *priv;
1575 IAnjutaProjectChooser *chooser;
1576
1577 priv = CG_WINDOW_PRIVATE (window);
1578 chooser = IANJUTA_PROJECT_CHOOSER (gtk_builder_get_object (priv->bxml, "add_project_parent"));
1579
1580 return ianjuta_project_chooser_get_selected (chooser, NULL);
1581 }
1582
1583 void
cg_window_set_add_to_project(CgWindow * window,gboolean enable)1584 cg_window_set_add_to_project (CgWindow *window,
1585 gboolean enable)
1586 {
1587 CgWindowPrivate *priv;
1588 GtkCheckButton *button;
1589
1590 priv = CG_WINDOW_PRIVATE (window);
1591 button = GTK_CHECK_BUTTON (gtk_builder_get_object (priv->bxml,
1592 "add_project"));
1593
1594 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), enable);
1595 }
1596
1597 void
cg_window_set_add_to_repository(CgWindow * window,gboolean enable)1598 cg_window_set_add_to_repository (CgWindow *window,
1599 gboolean enable)
1600 {
1601 CgWindowPrivate *priv;
1602 GtkCheckButton *button;
1603
1604 priv = CG_WINDOW_PRIVATE (window);
1605 button = GTK_CHECK_BUTTON (gtk_builder_get_object (priv->bxml,
1606 "add_repository"));
1607
1608 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), enable);
1609 }
1610
1611 gboolean
cg_window_get_add_to_project(CgWindow * window)1612 cg_window_get_add_to_project(CgWindow *window)
1613 {
1614 return cg_window_fetch_boolean (window, "add_project");
1615 }
1616
1617 gboolean
cg_window_get_add_to_repository(CgWindow * window)1618 cg_window_get_add_to_repository (CgWindow *window)
1619 {
1620 return cg_window_fetch_boolean (window, "add_repository");
1621 }
1622
1623 void
cg_window_enable_add_to_project(CgWindow * window,gboolean enable)1624 cg_window_enable_add_to_project (CgWindow *window,
1625 gboolean enable)
1626 {
1627 CgWindowPrivate *priv;
1628 GtkWidget *widget;
1629
1630 priv = CG_WINDOW_PRIVATE (window);
1631 widget = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "add_project"));
1632 gtk_widget_set_sensitive (widget, enable);
1633 widget = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "add_project_parent"));
1634 gtk_widget_set_sensitive (widget, enable);
1635 }
1636
1637 void
cg_window_set_project_model(CgWindow * window,IAnjutaProjectManager * manager)1638 cg_window_set_project_model (CgWindow *window, IAnjutaProjectManager *manager)
1639 {
1640 CgWindowPrivate *priv;
1641 GtkWidget *widget;
1642
1643 priv = CG_WINDOW_PRIVATE (window);
1644 widget = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "add_project_parent"));
1645 ianjuta_project_chooser_set_project_model (IANJUTA_PROJECT_CHOOSER (widget),
1646 IANJUTA_PROJECT_MANAGER (manager),
1647 ANJUTA_PROJECT_SOURCE,
1648 NULL);
1649 }
1650
1651 void
cg_window_enable_add_to_repository(CgWindow * window,gboolean enable)1652 cg_window_enable_add_to_repository (CgWindow *window,
1653 gboolean enable)
1654 {
1655 CgWindowPrivate *priv;
1656 GtkWidget *widget;
1657
1658 priv = CG_WINDOW_PRIVATE (window);
1659 widget = GTK_WIDGET (gtk_builder_get_object (priv->bxml, "add_repository"));
1660
1661 gtk_widget_set_sensitive (widget, enable);
1662 }
1663
1664 void
cg_window_set_author(CgWindow * window,const gchar * author)1665 cg_window_set_author (CgWindow *window,
1666 const gchar *author)
1667 {
1668 CgWindowPrivate* priv;
1669 GtkEntry* entry;
1670
1671 priv = CG_WINDOW_PRIVATE (window);
1672 entry = GTK_ENTRY(gtk_builder_get_object (priv->bxml, "author_name"));
1673
1674 gtk_entry_set_text (entry, author);
1675 }
1676
1677 void
cg_window_set_email(CgWindow * window,const gchar * email)1678 cg_window_set_email (CgWindow *window,
1679 const gchar *email)
1680 {
1681 CgWindowPrivate* priv;
1682 GtkEntry* entry;
1683
1684 priv = CG_WINDOW_PRIVATE (window);
1685 entry = GTK_ENTRY(gtk_builder_get_object (priv->bxml, "author_email"));
1686
1687 gtk_entry_set_text (entry, email);
1688 }
1689