Index: classbuilder.c =================================================================== --- classbuilder.c (revision 4881) +++ classbuilder.c (working copy) @@ -27,8 +27,7 @@ #include "geanyplugin.h" - -GeanyData *geany_data; +GeanyData *geany_data; GeanyFunctions *geany_functions; @@ -44,7 +43,8 @@ enum { GEANY_CLASS_TYPE_CPP, - GEANY_CLASS_TYPE_GTK + GEANY_CLASS_TYPE_GTK, + GEANY_CLASS_TYPE_PHP }; typedef struct _ClassInfo ClassInfo; @@ -67,6 +67,11 @@ gchar *constructor_impl; gchar *destructor_impl; gchar *gtk_destructor_registration; + // These are needed only for PHP classes + gchar *namespace_decl; + gchar *implements_decl; + gchar *abstract_decl; + gchar *singleton_impl; }; typedef struct _CreateClassDialog @@ -83,6 +88,11 @@ GtkWidget *create_constructor_box; GtkWidget *create_destructor_box; GtkWidget *gtk_constructor_type_entry; + // These are needed only for PHP classes + GtkWidget *class_namespace_entry; + GtkWidget *class_implements_entry; + GtkWidget *create_isabstract_box; + GtkWidget *create_issingleton_box; } CreateClassDialog; @@ -184,7 +194,19 @@ {constructor_impl}\n\ "; +static const gchar templates_php_class_source[] = "gtk_destructor_registration); break; + + case GEANY_CLASS_TYPE_PHP: + fileheader = templates_get_template_fileheader(GEANY_FILETYPES_PHP, class_info->source); + template = g_string_new(templates_php_class_source); + utils_string_replace_all(template, "{fileheader}", fileheader); + utils_string_replace_all(template, "{namespace_decl}", class_info->namespace_decl); + utils_string_replace_all(template, "{base_include}", class_info->base_include); + utils_string_replace_all(template, "{abstract_decl}", class_info->abstract_decl); + utils_string_replace_all(template, "{class_name}", class_info->class_name); + utils_string_replace_all(template, "{base_decl}", class_info->base_decl); + utils_string_replace_all(template, "{implements_decl}", class_info->implements_decl); + utils_string_replace_all(template, "{constructor_impl}", class_info->constructor_impl); + utils_string_replace_all(template, "{destructor_impl}", class_info->destructor_impl); + utils_string_replace_all(template, "{singleton_impl}", class_info->singleton_impl); + break; } g_free(fileheader); @@ -331,7 +368,25 @@ g_signal_connect_swapped(cc_dlg->dialog, "destroy", G_CALLBACK(g_free), (gpointer)cc_dlg); main_box = ui_dialog_vbox_new(GTK_DIALOG(cc_dlg->dialog)); - + + if (type == GEANY_CLASS_TYPE_PHP) + { + frame = ui_frame_new_with_alignment(_("Namespace"), &align); + gtk_container_add(GTK_CONTAINER(main_box), frame); + + vbox = gtk_vbox_new(FALSE, 10); + gtk_container_add(GTK_CONTAINER(align), vbox); + + hbox = gtk_hbox_new(FALSE, 10); + gtk_container_add(GTK_CONTAINER(vbox), hbox); + + label = gtk_label_new(_("Namespace:")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + cc_dlg->class_namespace_entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(hbox), cc_dlg->class_namespace_entry, TRUE, TRUE, 0); + } + frame = ui_frame_new_with_alignment(_("Class"), &align); gtk_container_add(GTK_CONTAINER(main_box), frame); @@ -348,25 +403,28 @@ gtk_box_pack_start(GTK_BOX(hbox), cc_dlg->class_name_entry, TRUE, TRUE, 0); g_signal_connect(cc_dlg->class_name_entry, "changed", G_CALLBACK(cc_dlg_on_class_name_entry_changed), cc_dlg); - + + if (type != GEANY_CLASS_TYPE_PHP) + { + hbox = gtk_hbox_new(FALSE, 10); + gtk_container_add(GTK_CONTAINER(vbox), hbox); + + label = gtk_label_new(_("Header file:")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + cc_dlg->header_entry = gtk_entry_new(); + gtk_container_add(GTK_CONTAINER(hbox), cc_dlg->header_entry); + } + hbox = gtk_hbox_new(FALSE, 10); gtk_container_add(GTK_CONTAINER(vbox), hbox); - - label = gtk_label_new(_("Header file:")); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - - cc_dlg->header_entry = gtk_entry_new(); - gtk_container_add(GTK_CONTAINER(hbox), cc_dlg->header_entry); - - hbox = gtk_hbox_new(FALSE, 10); - gtk_container_add(GTK_CONTAINER(vbox), hbox); - + label = gtk_label_new(_("Source file:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - + cc_dlg->source_entry = gtk_entry_new(); gtk_container_add(GTK_CONTAINER(hbox), cc_dlg->source_entry); - + frame = ui_frame_new_with_alignment(_("Inheritance"), &align); gtk_container_add(GTK_CONTAINER(main_box), frame); @@ -387,20 +445,26 @@ G_CALLBACK(cc_dlg_on_base_name_entry_changed), (gpointer)cc_dlg); hbox = gtk_hbox_new(FALSE, 10); - gtk_container_add(GTK_CONTAINER(vbox), hbox); - - label = gtk_label_new(_("Base header:")); + gtk_container_add(GTK_CONTAINER(vbox), hbox); + + if (type == GEANY_CLASS_TYPE_PHP) + label = gtk_label_new(_("Base source:")); + else + label = gtk_label_new(_("Base header:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - + cc_dlg->base_header_entry = gtk_entry_new(); if (type == GEANY_CLASS_TYPE_GTK) gtk_entry_set_text(GTK_ENTRY(cc_dlg->base_header_entry), "glib-object.h"); gtk_container_add(GTK_CONTAINER(hbox), cc_dlg->base_header_entry); - - cc_dlg->base_header_global_box = gtk_check_button_new_with_label(_("Global")); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cc_dlg->base_header_global_box), TRUE); - gtk_box_pack_end(GTK_BOX(hbox), cc_dlg->base_header_global_box, FALSE, FALSE, 0); - + + if (type != GEANY_CLASS_TYPE_PHP) + { + cc_dlg->base_header_global_box = gtk_check_button_new_with_label(_("Global")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cc_dlg->base_header_global_box), TRUE); + gtk_box_pack_end(GTK_BOX(hbox), cc_dlg->base_header_global_box, FALSE, FALSE, 0); + } + if (type == GEANY_CLASS_TYPE_GTK) { hbox = gtk_hbox_new(FALSE, 10); @@ -413,7 +477,19 @@ gtk_entry_set_text(GTK_ENTRY(cc_dlg->base_gtype_entry), "G_TYPE_OBJECT"); gtk_container_add(GTK_CONTAINER(hbox), cc_dlg->base_gtype_entry); } - + + if (type == GEANY_CLASS_TYPE_PHP) + { + hbox = gtk_hbox_new(FALSE, 10); + gtk_container_add(GTK_CONTAINER(vbox), hbox); + + label = gtk_label_new(_("Implements:")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + cc_dlg->class_implements_entry = gtk_entry_new(); + gtk_container_add(GTK_CONTAINER(hbox), cc_dlg->class_implements_entry); + } + frame = ui_frame_new_with_alignment(_("Options"), &align); gtk_container_add(GTK_CONTAINER(main_box), frame); @@ -429,7 +505,19 @@ cc_dlg->create_destructor_box = gtk_check_button_new_with_label(_("Create destructor")); gtk_container_add(GTK_CONTAINER(hbox), cc_dlg->create_destructor_box); - + + if (type == GEANY_CLASS_TYPE_PHP) + { + hbox = gtk_hbox_new(FALSE, 10); + gtk_container_add(GTK_CONTAINER(vbox), hbox); + + cc_dlg->create_isabstract_box = gtk_check_button_new_with_label(_("Is abstract")); + gtk_container_add(GTK_CONTAINER(hbox), cc_dlg->create_isabstract_box); + + cc_dlg->create_issingleton_box = gtk_check_button_new_with_label(_("Is singleton")); + gtk_container_add(GTK_CONTAINER(hbox), cc_dlg->create_issingleton_box); + } + if (type == GEANY_CLASS_TYPE_GTK) { hbox = gtk_hbox_new(FALSE, 10); @@ -472,6 +560,7 @@ static void cc_dlg_on_class_name_entry_changed(GtkWidget *entry, CreateClassDialog *cc_dlg) { + gchar *class_name; gchar *class_name_down; gchar *class_header; gchar *class_source; @@ -480,16 +569,20 @@ g_return_if_fail(GTK_IS_ENTRY(entry)); g_return_if_fail(cc_dlg != NULL); - class_name_down = g_ascii_strdown(gtk_entry_get_text(GTK_ENTRY(entry)), -1); + class_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry))); + class_name_down = g_ascii_strdown(class_name, -1); class_header = g_strconcat(class_name_down, ".h", NULL); if (cc_dlg->class_type == GEANY_CLASS_TYPE_CPP) class_source = g_strconcat(class_name_down, ".cpp", NULL); + else if (cc_dlg->class_type == GEANY_CLASS_TYPE_PHP) + class_source = g_strconcat(class_name, ".php", NULL); else class_source = g_strconcat(class_name_down, ".c", NULL); gtk_entry_set_text(GTK_ENTRY(cc_dlg->header_entry), class_header); gtk_entry_set_text(GTK_ENTRY(cc_dlg->source_entry), class_source); - + + g_free(class_name); g_free(class_name_down); g_free(class_header); g_free(class_source); @@ -525,7 +618,7 @@ g_return_if_fail(entry != NULL); g_return_if_fail(GTK_IS_ENTRY(entry)); g_return_if_fail(cc_dlg != NULL); - + base_name_splitted = str_case_split(gtk_entry_get_text(GTK_ENTRY(entry)), '_'); if (! g_ascii_strncasecmp(gtk_entry_get_text(GTK_ENTRY(entry)), "gtk", 3)) /*tmp = g_strconcat("gtk/", gtk_entry_get_text(GTK_ENTRY(entry)), ".h", NULL);*/ @@ -533,9 +626,16 @@ tmp = g_strdup("gtk/gtk.h"); else if (utils_str_equal(gtk_entry_get_text(GTK_ENTRY(entry)), "GObject")) tmp = g_strdup("glib-object.h"); + else if (cc_dlg->class_type == GEANY_CLASS_TYPE_PHP) + tmp = g_strconcat(gtk_entry_get_text(GTK_ENTRY(entry)), ".php", NULL); else tmp = g_strconcat(gtk_entry_get_text(GTK_ENTRY(entry)), ".h", NULL); - base_header = g_ascii_strdown(tmp, -1); + + if (cc_dlg->class_type == GEANY_CLASS_TYPE_PHP) + base_header = g_strdup(tmp); + else + base_header = g_ascii_strdown(tmp, -1); + g_free(tmp); gtk_entry_set_text(GTK_ENTRY(cc_dlg->base_header_entry), base_header); @@ -584,12 +684,21 @@ if (! utils_str_equal(gtk_entry_get_text(GTK_ENTRY(cc_dlg->base_name_entry)), "")) { class_info->base_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(cc_dlg->base_name_entry))); - class_info->base_include = g_strdup_printf("\n#include %c%s%c\n", - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cc_dlg->base_header_global_box)) ? + if (class_info->type != GEANY_CLASS_TYPE_PHP) + { + class_info->base_include = g_strdup_printf("\n#include %c%s%c\n", + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cc_dlg->base_header_global_box)) ? '<' : '\"', - gtk_entry_get_text(GTK_ENTRY(cc_dlg->base_header_entry)), - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cc_dlg->base_header_global_box)) ? + gtk_entry_get_text(GTK_ENTRY(cc_dlg->base_header_entry)), + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cc_dlg->base_header_global_box)) ? '>' : '\"'); + } + else + { + class_info->base_include = g_strdup_printf("\nrequire_once \"%s\";\n", + gtk_entry_get_text(GTK_ENTRY(cc_dlg->base_header_entry))); + class_info->base_decl = g_strdup_printf(" extends %s", class_info->base_name); + } } else { @@ -697,8 +806,110 @@ } break; } + case GEANY_CLASS_TYPE_PHP: + { + gchar *tmp; + + class_info->source = g_strdup(gtk_entry_get_text(GTK_ENTRY(cc_dlg->source_entry))); + + tmp = g_strdup(gtk_entry_get_text(GTK_ENTRY(cc_dlg->class_namespace_entry))); + if (! utils_str_equal(tmp, "")) + class_info->namespace_decl = g_strdup_printf("namespace %s;", tmp); + else + class_info->namespace_decl = g_strdup(""); + + tmp = g_strdup(gtk_entry_get_text(GTK_ENTRY(cc_dlg->class_implements_entry))); + if (! utils_str_equal(tmp, "")) + class_info->implements_decl = g_strdup_printf(" implements %s", tmp); + else + class_info->implements_decl = g_strdup(""); + g_free(tmp); + + if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cc_dlg->create_constructor_box)) && + ! gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cc_dlg->create_isabstract_box))) + { + class_info->constructor_impl = g_strdup_printf("\n" + "\t/**\n" + "\t * Constructor of class %s.\n" + "\t *\n" + "\t * @return void\n" + "\t */\n" + "\tpublic function __construct()\n" + "\t{\n" + "\t\t// ...\n" + "\t}\n", + class_info->class_name); + } + else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cc_dlg->create_constructor_box)) && + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cc_dlg->create_isabstract_box))) + { + class_info->constructor_impl = g_strdup_printf("\n" + "\t/**\n" + "\t * Constructor of class %s.\n" + "\t *\n" + "\t * @return void\n" + "\t */\n" + "\tprotected function __construct()\n" + "\t{\n" + "\t\t// ...\n" + "\t}\n", + class_info->class_name); + } + else + class_info->constructor_impl = g_strdup(""); + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cc_dlg->create_destructor_box))) + { + class_info->destructor_impl = g_strdup_printf("\n" + "\t/**\n" + "\t * Destructor of class %s.\n" + "\t *\n" + "\t * @return void\n" + "\t */\n" + "\tpublic function __destruct()\n" + "\t{\n" + "\t\t// ...\n" + "\t}\n", + class_info->class_name); + } + else + class_info->destructor_impl = g_strdup(""); + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cc_dlg->create_isabstract_box))) + class_info->abstract_decl = g_strdup("abstract "); + else + class_info->abstract_decl = g_strdup(""); + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cc_dlg->create_issingleton_box))) + { + class_info->singleton_impl = g_strdup_printf("\n" + "\t/**\n" + "\t * Holds instance of self.\n" + "\t * \n" + "\t * @var %s\n" + "\t */\n" + "\tprotected static $kInstance = null;\n\n" + "\t/**\n" + "\t * Returns instance of self.\n" + "\t * \n" + "\t * @return %s\n" + "\t */\n" + "\tpublic static function getInstance() {\n" + "\t\tif(!(self::$kInstance instanceof %s)) {\n" + "\t\t\tself::$kInstance = new self();\n" + "\t\t}\n" + "\t\treturn self::$kInstance;\n" + "\t}\n", + class_info->class_name, + class_info->class_name, + class_info->class_name); + } + else + class_info->singleton_impl = g_strdup(""); + break; + } } - + /* only create the files if the filename is not empty */ if (! utils_str_equal(class_info->source, "")) { @@ -708,7 +919,8 @@ g_free(text); } - if (! utils_str_equal(class_info->header, "")) + if (! utils_str_equal(class_info->header, "") && + class_info->type != GEANY_CLASS_TYPE_PHP) { text = get_template_class_header(class_info); doc = document_new_file(class_info->header, NULL, NULL); @@ -721,7 +933,9 @@ class_info->header, class_info->header_guard, class_info->source, class_info->base_decl, class_info->constructor_decl, class_info->constructor_impl, class_info->gtk_destructor_registration, class_info->destructor_decl, - class_info->destructor_impl, class_info->base_gtype, class_info, NULL); + class_info->destructor_impl, class_info->base_gtype, + class_info->namespace_decl, class_info->implements_decl, + class_info->abstract_decl, class_info->singleton_impl, class_info, NULL); return TRUE; } @@ -742,12 +956,21 @@ } +static void +on_menu_create_php_class_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + show_dialog_create_class(GEANY_CLASS_TYPE_PHP); +} + + void plugin_init(GeanyData *data) { GtkWidget *menu_create_class1; GtkWidget *menu_create_class1_menu; GtkWidget *menu_create_cpp_class; GtkWidget *menu_create_gtk_class; + GtkWidget *menu_create_php_class; menu_create_class1 = ui_image_menu_item_new (GTK_STOCK_ADD, _("Create Cla_ss")); gtk_container_add (GTK_CONTAINER (geany->main_widgets->tools_menu), menu_create_class1); @@ -760,6 +983,9 @@ menu_create_gtk_class = gtk_menu_item_new_with_mnemonic (_("_GTK+ Class")); gtk_container_add (GTK_CONTAINER (menu_create_class1_menu), menu_create_gtk_class); + + menu_create_php_class = gtk_menu_item_new_with_mnemonic (_("_PHP Class")); + gtk_container_add (GTK_CONTAINER (menu_create_class1_menu), menu_create_php_class); g_signal_connect(menu_create_cpp_class, "activate", G_CALLBACK (on_menu_create_cpp_class_activate), @@ -767,6 +993,9 @@ g_signal_connect(menu_create_gtk_class, "activate", G_CALLBACK (on_menu_create_gtk_class_activate), NULL); + g_signal_connect(menu_create_php_class, "activate", + G_CALLBACK (on_menu_create_php_class_activate), + NULL); gtk_widget_show_all(menu_create_class1);