34PLUGIN_SET_INFO(
_(
"Class Builder"),
_(
"Creates source files for new class types."), VERSION,
35 "Alexander Rodin, Ondrej Donek, the Geany developer team")
102#ifndef {header_guard}\n\
103#define {header_guard}\n\
105class {class_name}{base_decl}\n\
112 /* add your private declarations */\n\
115#endif /* {header_guard} */ \n\
119#include \"{header}\"\n\
126#ifndef {header_guard}_\n\
127#define {header_guard}_ 1\n\
131#define {namespace_up}TYPE_{class_name_up} ({namespace_low}{class_name_low}_get_type ())\n\
132#define {namespace_up}{class_name_up}(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), {namespace_up}TYPE_{class_name_up}, {namespace}{class_name}))\n\
133#define {namespace_up}{class_name_up}_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), {namespace_up}TYPE_{class_name_up}, {namespace}{class_name}Class))\n\
134#define {namespace_up}IS_{class_name_up}(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), {namespace_up}TYPE_{class_name_up}))\n\
135#define {namespace_up}IS_{class_name_up}_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), {namespace_up}TYPE_{class_name_up}))\n\
136#define {namespace_up}{class_name_up}_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), {namespace_up}TYPE_{class_name_up}, {namespace}{class_name}Class))\n\
138typedef struct {namespace}{class_name}_ {namespace}{class_name};\n\
139typedef struct {namespace}{class_name}Class_ {namespace}{class_name}Class;\n\
140typedef struct {namespace}{class_name}Private_ {namespace}{class_name}Private;\n\
142struct {namespace}{class_name}_\n\
144 {base_name} parent;\n\
145 /* add your public declarations here */\n\
146 {namespace}{class_name}Private *priv;\n\
149struct {namespace}{class_name}Class_\n\
151 {base_name}Class parent_class;\n\
154GType {namespace_low}{class_name_low}_get_type (void);\n\n\
159#endif /* {header_guard}_ */\n\
163#include \"{header}\"\n\
165struct {namespace}{class_name}Private_\n\
167 /* add your private declarations here */\n\
168 gpointer delete_me;\n\
173G_DEFINE_TYPE ({namespace}{class_name}, {namespace_low}{class_name_low}, {base_gtype})\n\
176{namespace_low}{class_name_low}_class_init ({namespace}{class_name}Class *klass)\n\
178 {gtk_destructor_registration}\n\
179 g_type_class_add_private ((gpointer)klass, sizeof ({namespace}{class_name}Private));\n\
185{namespace_low}{class_name_low}_init ({namespace}{class_name} *self)\n\
187 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, {namespace_up}TYPE_{class_name_up}, {namespace}{class_name}Private);\n\
193static const gchar templates_php_class_source[] =
"<?php\n\
197{abstract_decl}class {class_name}{base_decl}{implements_decl}\n{\n\
206static void cc_dlg_on_set_sensitive_toggled(GtkWidget *toggle_button, GtkWidget *target_widget);
215free_pointers(gsize arg_count, ...)
221 va_start(a, arg_count);
222 for (i = 0; i < arg_count; i++)
224 ptr = va_arg(a, gpointer);
227 ptr = va_arg(a, gpointer);
229 g_warning(
"Wrong arg_count!");
235get_template_class_header(
ClassInfo *class_info)
237 gchar *fileheader =
NULL;
238 GString *
template =
NULL;
240 switch (class_info->
type)
277 return g_string_free(
template, FALSE);
284get_template_class_source(
ClassInfo *class_info)
286 gchar *fileheader =
NULL;
287 GString *
template =
NULL;
289 switch (class_info->
type)
329 template = g_string_new(templates_php_class_source);
346 return g_string_free(
template, FALSE);
352static GtkWidget *cc_option_label_new(
const gchar *
text)
357 align = gtk_alignment_new(0.0, 0.5, 1.0, 1.0);
358 gtk_alignment_set_padding(GTK_ALIGNMENT(align), 0, 0, 12, 0);
361 gtk_misc_set_alignment(GTK_MISC(
label), 0.0, 0.5);
369static GtkWidget *cc_table_attach_section_label(GtkWidget *table,
const gchar *
text,
370 guint row, gboolean top_padding)
373 GtkWidget *
label, *align;
376 markup = g_markup_printf_escaped(
"<b>%s</b>",
text);
377 gtk_label_set_markup(GTK_LABEL(
label), markup);
379 gtk_misc_set_alignment(GTK_MISC(
label), 0.0, 0.5);
381 align = gtk_alignment_new(0.0, 0.5, 1.0, 1.0);
383 gtk_alignment_set_padding(GTK_ALIGNMENT(align), 6, 0, 0, 0);
386 gtk_table_attach(GTK_TABLE(table), align,
388 GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
395static GtkWidget *cc_table_attach_option_label(GtkWidget *table,
const gchar *
text, guint row)
397 GtkWidget *opt_label = cc_option_label_new(
text);
398 gtk_table_attach(GTK_TABLE(table), opt_label,
400 GTK_FILL|GTK_SHRINK, GTK_FILL|GTK_SHRINK, 0, 0);
408static GtkWidget *cc_table_attach_option_entry(GtkWidget *table,
const gchar *
text, guint row)
412 label = cc_table_attach_option_label(table,
text, row);
413 entry = gtk_entry_new();
414 g_object_set_data(G_OBJECT(
entry),
"label",
label);
415 gtk_table_attach(GTK_TABLE(table),
entry,
417 GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
421static void show_dialog_create_class(gint type)
424 GtkWidget *main_box, *table, *
label, *hdr_hbox;
425 GtkWidget *opt_table, *align;
431 cc_dlg->
dialog = gtk_dialog_new_with_buttons(
_(
"Create Class"),
432 GTK_WINDOW(
geany->main_widgets->window),
434 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
435 GTK_STOCK_OK, GTK_RESPONSE_OK,
441 gtk_window_set_title(GTK_WINDOW(cc_dlg->
dialog),
_(
"Create C++ Class"));
444 gtk_window_set_title(GTK_WINDOW(cc_dlg->
dialog),
_(
"Create GTK+ Class"));
447 gtk_window_set_title(GTK_WINDOW(cc_dlg->
dialog),
_(
"Create PHP Class"));
451 g_signal_connect_swapped(cc_dlg->
dialog,
"destroy", G_CALLBACK(g_free), (gpointer)cc_dlg);
453 table = gtk_table_new(13, 2, FALSE);
454 gtk_table_set_col_spacings(GTK_TABLE(table), 6);
455 gtk_table_set_row_spacings(GTK_TABLE(table), 6);
458 gtk_box_pack_start(GTK_BOX(main_box), table, TRUE, TRUE, 0);
464 cc_table_attach_section_label(table,
_(
"Namespace"), row++, FALSE);
467 G_CALLBACK(cc_dlg_on_class_namespace_entry_changed), cc_dlg);
471 cc_table_attach_section_label(table,
_(
"Class"), row++, TRUE);
473 cc_table_attach_section_label(table,
_(
"Class"), row++, FALSE);
475 cc_dlg->
class_name_entry = cc_table_attach_option_entry(table,
_(
"Name:"), row++);
477 G_CALLBACK(cc_dlg_on_class_name_entry_changed), cc_dlg);
480 cc_dlg->
header_entry = cc_table_attach_option_entry(table,
_(
"Header file:"), row++);
482 cc_dlg->
source_entry = cc_table_attach_option_entry(table,
_(
"Source file:"), row++);
484 cc_table_attach_section_label(table,
_(
"Inheritance"), row++, TRUE);
486 cc_dlg->
base_name_entry = cc_table_attach_option_entry(table,
_(
"Base class:"), row++);
491 G_CALLBACK(cc_dlg_on_base_name_entry_changed), (gpointer)cc_dlg);
494 cc_dlg->
base_header_entry = cc_table_attach_option_entry(table,
_(
"Base source:"), row++);
497 hdr_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
499 label = cc_table_attach_option_label(table,
_(
"Base header:"), row);
503 gtk_box_pack_start(GTK_BOX(hdr_hbox),
509 gtk_box_pack_start(GTK_BOX(hdr_hbox),
513 gtk_table_attach(GTK_TABLE(table), hdr_hbox,
515 GTK_FILL | GTK_EXPAND,
516 GTK_FILL | GTK_EXPAND,
526 cc_dlg->
base_gtype_entry = cc_table_attach_option_entry(table,
_(
"Base GType:"), row++);
533 cc_table_attach_section_label(table,
_(
"Options"), row++, TRUE);
535 align = gtk_alignment_new(0.0, 0.5, 1.0, 1.0);
536 gtk_alignment_set_padding(GTK_ALIGNMENT(align), 0, 0, 12, 0);
538 opt_table = gtk_table_new(1, 2, FALSE);
539 gtk_table_set_row_spacings(GTK_TABLE(opt_table), 6);
540 gtk_table_set_col_spacings(GTK_TABLE(opt_table), 6);
543 gtk_table_attach(GTK_TABLE(table), align,
553 0, 1, 0, 1, GTK_FILL|GTK_SHRINK, GTK_FILL|GTK_SHRINK, 0, 0);
557 1, 2, 0, 1, GTK_FILL|GTK_SHRINK, GTK_FILL|GTK_SHRINK, 0, 0);
561 gtk_table_resize(GTK_TABLE(opt_table), 2, 2);
564 0, 1, 1, 2, GTK_FILL|GTK_SHRINK, GTK_FILL|GTK_SHRINK, 0, 0);
567 1, 2, 1, 2, GTK_FILL|GTK_SHRINK, GTK_FILL|GTK_SHRINK, 0, 0);
575 _(
"Constructor type:"), row++);
578 G_CALLBACK(cc_dlg_on_set_sensitive_toggled),
582 gtk_table_resize(GTK_TABLE(table), row, 2);
584 gtk_table_resize(GTK_TABLE(table), row, 2);
587 while (gtk_dialog_run(GTK_DIALOG(cc_dlg->
dialog)) == GTK_RESPONSE_OK)
589 if (create_class(cc_dlg))
594 gtk_widget_destroy(cc_dlg->
dialog);
598static void cc_dlg_on_set_sensitive_toggled(GtkWidget *toggle_button, GtkWidget *target_widget)
602 g_return_if_fail(toggle_button !=
NULL);
603 g_return_if_fail(GTK_IS_TOGGLE_BUTTON(toggle_button));
604 g_return_if_fail(target_widget !=
NULL);
605 g_return_if_fail(GTK_IS_WIDGET(target_widget));
607 label = g_object_get_data(G_OBJECT(target_widget),
"label");
609 gtk_widget_set_sensitive(target_widget,
610 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button)));
611 gtk_widget_set_sensitive(
label,
612 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button)));
619 gchar *class_name_down;
620 gchar *class_header =
NULL;
621 gchar *class_source =
NULL;
623 g_return_if_fail(cc_dlg !=
NULL);
625 class_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(cc_dlg->
class_name_entry)));
626 class_name_down = g_ascii_strdown(class_name, -1);
631 class_header = g_strconcat(class_name_down,
".hpp",
NULL);
632 class_source = g_strconcat(class_name_down,
".cpp",
NULL);
637 const gchar *
namespace;
638 gchar *namespace_down;
641 namespace_down = g_ascii_strdown(
namespace, -1);
642 class_header = g_strconcat(namespace_down, class_name_down,
".h",
NULL);
643 class_source = g_strconcat(namespace_down, class_name_down,
".c",
NULL);
644 g_free(namespace_down);
650 class_source = g_strconcat(class_name,
".php",
NULL);
656 gtk_entry_set_text(GTK_ENTRY(cc_dlg->
header_entry), class_header);
658 gtk_entry_set_text(GTK_ENTRY(cc_dlg->
source_entry), class_source);
661 g_free(class_name_down);
662 g_free(class_header);
663 g_free(class_source);
669 cc_dlg_update_file_names(cc_dlg);
677 cc_dlg_update_file_names(cc_dlg);
681static gchar* str_case_split(
const gchar *str, gchar splitter)
685 g_return_val_if_fail(str !=
NULL,
NULL);
689 result = g_string_new(
NULL);
690 g_string_append_c(result, *str);
691 while (*(++str) !=
'\0')
693 if (g_ascii_isupper(*str) && g_ascii_islower(result->str[result->len - 1]))
694 g_string_append_c(result, splitter);
695 g_string_append_c(result, *str);
697 return g_string_free(result, FALSE);
703 gchar *base_name_splitted;
708 g_return_if_fail(GTK_IS_ENTRY(
entry));
709 g_return_if_fail(cc_dlg !=
NULL);
711 base_name_splitted = str_case_split(gtk_entry_get_text(GTK_ENTRY(
entry)),
'_');
712 if (! g_ascii_strncasecmp(gtk_entry_get_text(GTK_ENTRY(
entry)),
"gtk", 3))
715 tmp = g_strdup(
"gtk/gtk.h");
717 tmp = g_strdup(
"glib-object.h");
719 tmp = g_strconcat(gtk_entry_get_text(GTK_ENTRY(
entry)),
".php",
NULL);
721 tmp = g_strconcat(gtk_entry_get_text(GTK_ENTRY(
entry)),
".h",
NULL);
724 base_header = g_strdup(tmp);
726 base_header = g_ascii_strdown(tmp, -1);
735 if (! g_ascii_strncasecmp(gtk_entry_get_text(GTK_ENTRY(
entry)),
"gtk", 3))
736 tmp = g_strdup_printf(
"%.3s_TYPE%s",
738 base_name_splitted + 3);
740 tmp = g_strdup(
"G_TYPE_OBJECT");
742 tmp = g_strconcat(base_name_splitted,
"_TYPE",
NULL);
743 base_gtype = g_ascii_strup(tmp, -1);
750 g_free(base_name_splitted);
762 g_return_val_if_fail(cc_dlg !=
NULL, FALSE);
770 tmp = str_case_split(class_info->
class_name,
'_');
778 class_info->
base_include = g_strdup_printf(
"\n#include %c%s%c\n",
787 class_info->
base_include = g_strdup_printf(
"\nrequire_once \"%s\";\n",
803 switch (class_info->
type)
814 gchar *base_constructor;
817 base_constructor = g_strdup(
"");
819 base_constructor = g_strdup_printf(
"\t: %s()\n", class_info->
base_name);
823 g_free(base_constructor);
833 g_strdup_printf(
"virtual ~%s();\n", class_info->
class_name);
834 class_info->
destructor_impl = g_strdup_printf(
"\n%s::~%s()\n{\n\t\n}\n",
847 if (
EMPTY(class_info->namespace))
854 gchar *tmp_namespace;
855 gchar *tmp_namespace_split;
857 tmp_namespace_split = str_case_split(class_info->namespace,
'_');
858 tmp_namespace = g_strconcat(tmp_namespace_split,
"_",
NULL);
859 class_info->
namespace_up = g_ascii_strup(tmp_namespace, -1);
861 g_free(tmp_namespace);
862 g_free(tmp_namespace_split);
864 class_info->
base_gtype = g_strdup(gtk_entry_get_text(
876 " return g_object_new (%sTYPE_%s, NULL);\n"
890 g_strdup_printf(
"GObjectClass *g_object_class;\n\n"
891 " g_object_class = G_OBJECT_CLASS (klass);\n\n"
892 " g_object_class->finalize = %s%s_finalize;\n",
895 g_strdup_printf(
"static void %s%s_finalize (GObject *object);\n",
899 "%s%s_finalize (GObject *object)\n"
902 " g_return_if_fail (%sIS_%s (object));\n\n"
903 " self = %s%s (object);\n\n"
904 " G_OBJECT_CLASS (%s%s_parent_class)->finalize (object);\n"
907 class_info->namespace, class_info->
class_name,
922 const gchar *tmp_str;
928 class_info->
namespace_decl = g_strdup_printf(
"namespace %s;", tmp_str);
934 class_info->
implements_decl = g_strdup_printf(
" implements %s", tmp_str);
943 "\t * Constructor of class %s.\n"
945 "\t * @return void\n"
947 "\tpublic function __construct()\n"
958 "\t * Constructor of class %s.\n"
960 "\t * @return void\n"
962 "\tprotected function __construct()\n"
975 "\t * Destructor of class %s.\n"
977 "\t * @return void\n"
979 "\tpublic function __destruct()\n"
997 "\t * Holds instance of self.\n"
1001 "\tprotected static $kInstance = null;\n\n"
1003 "\t * Returns instance of self.\n"
1007 "\tpublic static function getInstance() {\n"
1008 "\t\tif(!(self::$kInstance instanceof %s)) {\n"
1009 "\t\t\tself::$kInstance = new self();\n"
1011 "\t\treturn self::$kInstance;\n"
1027 text = get_template_class_source(class_info);
1036 text = get_template_class_header(class_info);
1042 free_pointers(24, tmp, class_info->namespace, class_info->
namespace_up,
1056on_menu_create_cpp_class_activate (GtkMenuItem *menuitem,
1064on_menu_create_gtk_class_activate (GtkMenuItem *menuitem,
1072on_menu_create_php_class_activate (GtkMenuItem *menuitem,
1081 GtkWidget *menu_create_class1;
1082 GtkWidget *menu_create_class1_menu;
1083 GtkWidget *menu_create_cpp_class;
1084 GtkWidget *menu_create_gtk_class;
1085 GtkWidget *menu_create_php_class;
1090 menu_create_class1_menu = gtk_menu_new ();
1091 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_create_class1), menu_create_class1_menu);
1093 menu_create_cpp_class = gtk_menu_item_new_with_mnemonic (
_(
"_C++ Class..."));
1094 gtk_container_add (GTK_CONTAINER (menu_create_class1_menu), menu_create_cpp_class);
1096 menu_create_gtk_class = gtk_menu_item_new_with_mnemonic (
_(
"_GTK+ Class..."));
1097 gtk_container_add (GTK_CONTAINER (menu_create_class1_menu), menu_create_gtk_class);
1099 menu_create_php_class = gtk_menu_item_new_with_mnemonic (
_(
"_PHP Class..."));
1100 gtk_container_add (GTK_CONTAINER (menu_create_class1_menu), menu_create_php_class);
1102 g_signal_connect(menu_create_cpp_class,
"activate",
1103 G_CALLBACK (on_menu_create_cpp_class_activate),
1105 g_signal_connect(menu_create_gtk_class,
"activate",
1106 G_CALLBACK (on_menu_create_gtk_class_activate),
1108 g_signal_connect(menu_create_php_class,
"activate",
1109 G_CALLBACK (on_menu_create_php_class_activate),
static const gchar templates_cpp_class_header[]
static GtkWidget * main_menu_item
static const gchar templates_gtk_class_header[]
static const gchar templates_cpp_class_source[]
struct _CreateClassDialog CreateClassDialog
static const gchar templates_gtk_class_source[]
GeanyDocument * document_new_file(const gchar *utf8_filename, GeanyFiletype *ft, const gchar *text)
Creates a new document.
void editor_insert_text_block(GeanyEditor *editor, const gchar *text, gint insert_pos, gint cursor_index, gint newline_indent_size, gboolean replace_newlines)
Inserts text, replacing \t tab chars (0x9) and \n newline chars (0xA) accordingly for the document.
Single include for plugins.
#define GEANY_API_VERSION
The Application Programming Interface (API) version, incremented whenever any plugin data types are m...
#define PLUGIN_SET_INFO(p_name, p_description, p_version, p_author)
Sets the plugin name and some other basic information about a plugin.
#define PLUGIN_VERSION_CHECK(api_required)
Defines a function to check the plugin is safe to load.
#define geany
Simple macro for geany_data that reduces typing.
void plugin_cleanup()
Called before unloading the plugin.
void plugin_init(GeanyData *data)
Called after loading the plugin.
void sci_set_current_position(ScintillaObject *sci, gint position, gboolean scroll_to_caret)
Sets the cursor position.
gtk_container_add(GTK_CONTAINER(dialog->vbox), check_button)
gtk_widget_show_all(dialog)
This contains pointers to global variables owned by Geany for plugins to use.
Structure for representing an open tab with all its properties.
GeanyEditor * editor
The editor associated with the document.
ScintillaObject * sci
The Scintilla editor GtkWidget.
gchar * gtk_destructor_registration
GtkWidget * create_issingleton_box
GtkWidget * create_isabstract_box
GtkWidget * class_name_entry
GtkWidget * base_header_entry
GtkWidget * class_implements_entry
GtkWidget * base_gtype_entry
GtkWidget * create_destructor_box
GtkWidget * gtk_constructor_type_entry
GtkWidget * class_namespace_entry
GtkWidget * create_constructor_box
GtkWidget * base_name_entry
GtkWidget * base_header_global_box
gchar * templates_get_template_fileheader(gint filetype_idx, const gchar *fname)
GtkWidget * ui_dialog_vbox_new(GtkDialog *dialog)
Makes a fixed border for dialogs without increasing the button box border.
GtkWidget * ui_image_menu_item_new(const gchar *stock_id, const gchar *label)
Creates a GtkImageMenuItem with a stock image and a custom label.
guint utils_string_replace_all(GString *haystack, const gchar *needle, const gchar *replace)
Replaces all occurrences of needle in haystack with replace.
gboolean utils_str_equal(const gchar *a, const gchar *b)
NULL-safe string comparison.
#define EMPTY(ptr)
Returns TRUE if ptr is NULL or *ptr is FALSE.