// table to hold all settings for this wizard PluginSettings <- { Type = 0 // cbToolPlugin Name = _T("") Title = _T("") Version = _T("") Description = _T("") Author = _T("") Email = _T("") Website = _T("") ThanksTo = _T("") HasConfig = false HasMenu = false HasModuleMenu = false HasToolbar = false } WxVersion <- 1; // 0 - wx 2.6, 1 - wx 2.8 // ----------------------------------------------------------------------------- // init wizard function BeginWizard() { local wiz_type = Wizard.GetWizardType(); local intro_msg = _T("Welcome to the new Code::Blocks plugin wizard!\n" + "This wizard will guide you to create a new Code::Blocks plugin.\n\n"); if (PLATFORM == PLATFORM_MSW) { intro_msg += _T("\nVERY IMPORTANT NOTE:\n\n" + "Code::Blocks is built with the GNU GCC compiler and links to\n" + "the monolithic unicode wxWidgets DLL.\n" + "This means that you must have exactly this setup to be able to\n" + "build the generated plugin.\n" + "You must also have defined two global variables:\n" + " 1. $(#cb) pointing to Code::Blocks base dir (where CodeBlocks.cbp is)\n" + " 2. $(#wx) pointing to wxWidgets base directory\n\n\n"); } intro_msg += _T("When you 're ready to proceed, please click \"Next\"..."); Wizard.AddInfoPage(_T("PluginIntro"), intro_msg); Wizard.AddProjectPathPage(); Wizard.AddPage(_T("PluginOptions")); Wizard.AddPage(_T("PluginInfo")); Wizard.AddGenericSingleChoiceListPage(_T("wxVersionPage"), _T("Please select the wxWidgets version you want to use."), _T("wxWidgets 2.6.x;wxWidgets 2.8.x"), WxVersion); // select wxwidgets version Wizard.AddCompilerPage(_T(""), _T("gcc*"), true, false); } // ----------------------------------------------------------------------------- // entering plugin options page function OnEnter_PluginOptions(fwd) { // update options state OnClick_cmbPluginType(); } // ----------------------------------------------------------------------------- // enable/disable available options based on selected plugin type function OnClick_cmbPluginType() { PluginSettings.Type = Wizard.GetComboboxSelection(_T("cmbPluginType")); local isTool = PluginSettings.Type == 1; local isMime = PluginSettings.Type == 2; local isWizard = PluginSettings.Type == 3; Wizard.EnableWindow(_T("chkHasConfig"), !isWizard); Wizard.EnableWindow(_T("chkHasMenu"), !isTool && !isMime && !isWizard); Wizard.EnableWindow(_T("chkHasModuleMenu"), !isTool && !isMime && !isWizard); Wizard.EnableWindow(_T("chkHasToolbar"), !isTool && !isMime && !isWizard); } // ----------------------------------------------------------------------------- // leaving plugin options page, validate entered values function OnLeave_PluginOptions(fwd) { if (fwd) { // read text values entered PluginSettings.Name = Wizard.GetTextControlValue(_T("txtPluginName")); PluginSettings.Type = Wizard.GetComboboxSelection(_T("cmbPluginType")); PluginSettings.HasConfig = Wizard.IsCheckboxChecked(_T("chkHasConfig")); PluginSettings.HasMenu = Wizard.IsCheckboxChecked(_T("chkHasMenu")); PluginSettings.HasModuleMenu = Wizard.IsCheckboxChecked(_T("chkHasModuleMenu")); PluginSettings.HasToolbar = Wizard.IsCheckboxChecked(_T("chkHasToolbar")); // check that essentials were filled in if (PluginSettings.Name.IsEmpty()) { ShowWarning(_T("You have to enter the plugin's name before you can proceed...")); return false; } } return true; } // ----------------------------------------------------------------------------- // entering plugin info page, set some default values function OnEnter_PluginInfo(fwd) { if (fwd) { // set the title same as the project title if (Wizard.GetTextControlValue(_T("txtTitle")).IsEmpty()) Wizard.SetTextControlValue(_T("txtTitle"), Wizard.GetProjectTitle()); if (Wizard.GetTextControlValue(_T("txtVersion")).IsEmpty()) Wizard.SetTextControlValue(_T("txtVersion"), _T("0.1")); // load config Wizard.SetTextControlValue(_T("txtAuthor"), GetConfigManager().Read(_T("/cb_plugin_wizard/author"), _T(""))); Wizard.SetTextControlValue(_T("txtEmail"), GetConfigManager().Read(_T("/cb_plugin_wizard/email"), _T(""))); Wizard.SetTextControlValue(_T("txtWebsite"), GetConfigManager().Read(_T("/cb_plugin_wizard/website"), _T(""))); } } // ----------------------------------------------------------------------------- // leaving plugin info page, validate entered values function OnLeave_PluginInfo(fwd) { if (fwd) { // read text values entered PluginSettings.Title = Wizard.GetTextControlValue(_T("txtTitle")); PluginSettings.Version = Wizard.GetTextControlValue(_T("txtVersion")); PluginSettings.Description = Wizard.GetTextControlValue(_T("txtDescription")); PluginSettings.Author = Wizard.GetTextControlValue(_T("txtAuthor")); PluginSettings.Email = Wizard.GetTextControlValue(_T("txtEmail")); PluginSettings.Website = Wizard.GetTextControlValue(_T("txtWebsite")); PluginSettings.ThanksTo = Wizard.GetTextControlValue(_T("txtThanksTo")); // check that essentials were filled in if (PluginSettings.Name.IsEmpty() || PluginSettings.Version.IsEmpty()) { ShowWarning(_T("You have to fill the Title and Version fields before you can proceed...")); return false; } PluginSettings.Name = GetFixedProjectName(PluginSettings.Name); } // save config GetConfigManager().Write(_T("/cb_plugin_wizard/author"), PluginSettings.Author); GetConfigManager().Write(_T("/cb_plugin_wizard/email"), PluginSettings.Email); GetConfigManager().Write(_T("/cb_plugin_wizard/website"), PluginSettings.Website); return true; } //////////////////////////////////////////////////////////////////////////////// // wxWidgets' version page //////////////////////////////////////////////////////////////////////////////// function OnEnter_wxVersionPage(fwd) { if (fwd) { WxVersion = Wizard.GetListboxSelection(_T("GenericChoiceList")); } return true; } function OnLeave_wxVersionPage(fwd) { if (fwd) { WxVersion = Wizard.GetListboxSelection(_T("GenericChoiceList")); } return true; } // ----------------------------------------------------------------------------- // each time, return a string of the form "filename.ext;contents" // you can change the return string based on // return an empty string to denote that no more files are to be generated function GetGeneratedFile(file_index) { switch (file_index) { // header file case 0: return PluginSettings.Name + DOT_EXT_H + _T(";") + GenerateHeader(); // source file case 1: return PluginSettings.Name + DOT_EXT_CPP + _T(";") + GenerateSource(); // manifest case 2: return _T("manifest") + DOT_EXT_XML + _T(";") + GenerateManifest(); } return _T(""); // no more generated files } // ----------------------------------------------------------------------------- // setup the project options function SetupProject(project) { local target = project.GetBuildTarget(_T("default")); if (IsNull(target)) target = project.AddBuildTarget(_T("default")); SetupTarget(target, true); return true; } function SetupTarget(target,is_debug) { if (IsNull(target)) return false; target.SetTargetType(ttDynamicLib); target.SetOutputFilename(PluginSettings.Name); target.SetCreateDefFile(false); target.SetCreateStaticLib(false); if (PLATFORM == PLATFORM_MSW) { target.AddCompilerOption(_T("-DBUILDING_PLUGIN")); target.AddCompilerOption(_T("-DHAVE_W32API_H")); target.AddCompilerOption(_T("-D__WXMSW__")); target.AddCompilerOption(_T("-DWXUSINGDLL")); target.AddCompilerOption(_T("-DcbDEBUG")); target.AddCompilerOption(_T("-DCB_PRECOMP")); target.AddCompilerOption(_T("-DWX_PRECOMP")); target.AddCompilerOption(_T("-DwxUSE_UNICODE")); target.AddCompilerOption(_T("-pipe")); target.AddCompilerOption(_T("-mthreads")); target.AddCompilerOption(_T("-fmessage-length=0")); target.AddCompilerOption(_T("-fexceptions")); target.AddCompilerOption(_T("-Winvalid-pch")); target.AddLinkerOption(_T("-mthreads")); target.AddIncludeDir(_T("$(#cb)\\include")); target.AddIncludeDir(_T("$(#cb)\\sdk\\wxscintilla\\include")); target.AddIncludeDir(_T("$(#wx.include)")); target.AddIncludeDir(_T("$(#wx.lib)\\gcc_dll\\mswu")); target.AddLinkLib(_T("codeblocks")); if (WxVersion == 0) target.AddLinkLib(_T("wxmsw26u")); else target.AddLinkLib(_T("wxmsw28u")); target.AddLibDir(_T("$(#cb)\\devel")); target.AddLibDir(_T("$(#wx.lib)\\gcc_dll")); target.SetHostApplication(_T("$(#cb)\\devel\\codeblocks") + DOT_EXT_EXECUTABLE); } else { target.AddCompilerOption(_T("`pkg-config --cflags codeblocks`")); target.AddCompilerOption(_T("`wx-config --cflags`")); target.AddCompilerOption(_T("-ansi")); target.AddCompilerOption(_T("-fPIC")); target.AddLinkerOption(_T("`pkg-config --libs codeblocks`")); target.AddLinkerOption(_T("`wx-config --libs`")); target.SetHostApplication(_T("codeblocks") + DOT_EXT_EXECUTABLE); } // create plugin resources target.AddCommandsAfterBuild(_T("zip -j9 ") + PluginSettings.Name + _T(".zip manifest") + DOT_EXT_XML); // create plugin distribution file target.AddCommandsAfterBuild(_T("zip -j9 ") + PluginSettings.Name + _T(".cbplugin ") + target.GetOutputFilename() + _T(" ") + PluginSettings.Name + _T(".zip")); if (is_debug) DebugSymbolsOn(target, Wizard.GetCompilerID()); return true; } //////////////////////////////////////////////////////////////////////////////// // // locally defined functions below // //////////////////////////////////////////////////////////////////////////////// // ----------------------------------------------------------------------------- // return the header contents string function GenerateHeader() { local path = Wizard.FindTemplateFile(GetTemplateFile(DOT_EXT_H)); local buffer = IO.ReadFileContents(path); // create header guard word local guard = PluginSettings.Name + DOT_EXT_H + _T("_INCLUDED"); guard.MakeUpper(); guard.Replace(_T(" "), _T("_")); guard.Replace(_T("."), _T("_")); buffer.Replace(_T("[GUARD_WORD]"), guard); return SubstituteMacros(buffer); } // ----------------------------------------------------------------------------- // return the implementation contents string function GenerateSource() { local path = Wizard.FindTemplateFile(GetTemplateFile(DOT_EXT_CPP)); local buffer = IO.ReadFileContents(path); return SubstituteMacros(buffer); } // ----------------------------------------------------------------------------- // return the manifest contents string function GenerateManifest() { local path = Wizard.FindTemplateFile(_T("plugins/templates/manifest_template.xml")); local buffer = IO.ReadFileContents(path); return SubstituteMacros(buffer); } // ----------------------------------------------------------------------------- // return the template's filename, appending as an extension (must include the dot) function GetTemplateFile(dot_ext) { local template_file = _T(""); switch (PluginSettings.Type) { // generic plugin case 0: template_file = _T("plugins/templates/generic_template") + dot_ext; break; // tool plugin case 1: template_file = _T("plugins/templates/tool_template") + dot_ext; break; // mime plugin case 2: template_file = _T("plugins/templates/mime_template") + dot_ext; break; // wizard plugin case 3: template_file = _T("plugins/templates/wizard_template") + dot_ext; break; default: break; // error } return template_file; } // ----------------------------------------------------------------------------- // substitute all plugin macros in function SubstituteMacros(buffer) { // handle [IF] / [ENDIF] pairs buffer = HandleDirective(buffer, _T("HAS_CONFIGURE"), PluginSettings.HasConfig); buffer = HandleDirective(buffer, _T("HAS_MENU"), PluginSettings.HasMenu); buffer = HandleDirective(buffer, _T("HAS_MODULE_MENU"), PluginSettings.HasModuleMenu); buffer = HandleDirective(buffer, _T("HAS_TOOLBAR"), PluginSettings.HasToolbar); buffer = HandleDirective(buffer, _T("NEED_EVENTS"), PluginSettings.HasMenu || PluginSettings.HasModuleMenu || PluginSettings.HasToolbar); // macros substitution buffer.Replace(_T("[PLUGIN_SDK_VERSION_MAJOR]"), _T("") + PLUGIN_SDK_VERSION_MAJOR); buffer.Replace(_T("[PLUGIN_SDK_VERSION_MINOR]"), _T("") + PLUGIN_SDK_VERSION_MINOR); buffer.Replace(_T("[PLUGIN_SDK_VERSION_RELEASE]"), _T("") + PLUGIN_SDK_VERSION_RELEASE); buffer.Replace(_T("[PLUGIN_NAME]"), PluginSettings.Name); buffer.Replace(_T("[PLUGIN_TITLE]"), PluginSettings.Title); buffer.Replace(_T("[PLUGIN_VERSION]"), PluginSettings.Version); buffer.Replace(_T("[PLUGIN_DESCRIPTION]"), PluginSettings.Description); buffer.Replace(_T("[PROJECT_NAME]"), Wizard.GetProjectName()); buffer.Replace(_T("[AUTHOR_NAME]"), PluginSettings.Author); buffer.Replace(_T("[AUTHOR_EMAIL]"), PluginSettings.Email); buffer.Replace(_T("[AUTHOR_WWW]"), PluginSettings.Website); buffer.Replace(_T("[THANKS_TO]"), PluginSettings.ThanksTo); buffer.Replace(_T("[HEADER_FILENAME]"), PluginSettings.Name + DOT_EXT_H); buffer.Replace(_T("[NOW]"), ReplaceMacros(_T("$(TODAY)"), false)); return buffer; } // ----------------------------------------------------------------------------- // if is true, removes the [IF ] and [ENDIF ] // macros. // if is false, removes everything enclosed by the [IF ] // and [ENDIF ] macros (including them). function HandleDirective(buffer, directive, enabled) { local dir_if = _T("[IF ") + directive + _T("]"); local dir_endif = _T("[ENDIF ") + directive + _T("]"); local findStart = buffer.Find(dir_if); if (findStart == -1) return buffer; local findEnd = buffer.Find(dir_endif); if (findEnd == -1 || findEnd <= findStart) return buffer; // look for [ELSE] local block = buffer.Mid(findStart, findEnd - findStart); local findElse = block.Find(_T("[ELSE]")); // findElse is in "local scope", i.e. offset from findStart if (!enabled) { if (findElse == -1) { // remove whole section buffer.Remove(findStart, (findEnd - findStart) + dir_endif.Length()); } else { // remove [ENDIF] buffer.Remove(findEnd, dir_endif.Length()); // remove from [IF] to [ELSE] (including) buffer.Remove(findStart, findElse + 6); // 6 is the [ELSE] size } } else { if (findElse == -1) { // just remove the directives // we must remove the [ENDIF] first because if we removed the [IF] it would // render the findEnd index invalid! buffer.Remove(findEnd, dir_endif.Length()); buffer.Remove(findStart, dir_if.Length()); } else { // remove from [ELSE] to [ENDIF] local start = findStart + findElse; buffer.Remove(start, (findEnd - start) + dir_endif.Length()); // remove from [IF] buffer.Remove(findStart, dir_if.Length()); } } return buffer; }