This repository has been archived on 2024-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
CodeBlocksPortable/share/CodeBlocks/templates/wizard/plugins/wizard.script

565 lines
21 KiB
Plaintext

// 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 <- 0; //0 - wx 2.8, 1 - wx 3.0, 2 - wx 3.1
// -----------------------------------------------------------------------------
// 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"));
local options = _T("wxWidgets 2.8.x;wxWidgets 3.0.x;wxWidgets 3.1.x");
if (PLATFORM != PLATFORM_MSW)
options += _T(";system default");
// Select wxwidgets version.
local wxVersionMsg = _T("Please select the wxWidgets version you want to use for the default configuration.");
Wizard.AddGenericSingleChoiceListPage(_T("wxVersionPage"), wxVersionMsg, options, WxVersion);
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 <file_index>
// 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
}
// Return the path to the devel folder based on the wx version we are targeting
function GetBaseDevelPath(version)
{
if (PLATFORM == PLATFORM_MSW)
{
if (version == 0)
return _T("$(#cb)\\devel");
else if (version == 1 || version == 2)
return _T("$(#cb)\\devel30");
}
else
{
if (version == 0)
return _T("$(#cb)/devel");
else if (version == 1 || version == 2 || version == 3)
return _T("$(#cb)/devel30");
};
}
// -----------------------------------------------------------------------------
// Setup the project options.
// We create three targets:
// * make_cbplugin:
// This target creates a .cbplugin archive that can be distributed and installed in codeblocks via the plugin
// manager. Uses the selected wx version.
// * to_codeblocks_wx28 and to_codeblocks_wx30:
// These targets copy the binary output and the resources directly to the "devel" and "devel30" sub folder of your
// codeblocks development folder provided by the $(#cb) global variable. This allows to debug the plugin easily.
// If the debugging process is started, codeblocks starts gdb with "$(#cb)/devel/codeblocks" as host application
// with the "debug" personality to create some kind of isolation from the working environment.
function SetupProject(project)
{
SetupProjectBuildOptions(project);
// Create the "default" target
local target = project.GetBuildTarget(_T("default"));
if (IsNull(target))
target = project.AddBuildTarget(_T("default"));
SetupTarget(target, true, WxVersion);
// Create plugin distribution file.
target.AddCommandsAfterBuild(_T("zip -j9 ") + PluginSettings.Name + _T(".cbplugin ") +
target.GetOutputFilename() + _T(" ") +
PluginSettings.Name + _T(".zip"));
// Create the "to_codeblocks_wx28" target
local target28 = project.GetBuildTarget(_T("to_codeblocks_wx28"));
if (IsNull(target28))
target28 = project.AddBuildTarget(_T("to_codeblocks_wx28"));
SetupTarget(target28, false, 0);
// Create the "to_codeblocks_wx30" target
local target30 = project.GetBuildTarget(_T("to_codeblocks_wx30"));
if (IsNull(target30))
target30 = project.AddBuildTarget(_T("to_codeblocks_wx30"));
SetupTarget(target30, false, 1);
// Add files to the wx28 and wx30 targets, they are not added for some reason.
for (local i = 0; i < project.GetFilesCount(); i++)
project.GetFile(i).AddBuildTarget(target28.GetTitle());
for (local i = 0; i < project.GetFilesCount(); i++)
project.GetFile(i).AddBuildTarget(target30.GetTitle());
// Merge all targets in a single virtual target, so the user can rebuild everything at once.
local virtualTargets = wxArrayString();
virtualTargets.Add(target.GetTitle(), 1);
virtualTargets.Add(target28.GetTitle(), 1);
virtualTargets.Add(target30.GetTitle(), 1);
project.DefineVirtualBuildTarget(_T("All"), virtualTargets);
return true;
}
function SetupProjectBuildOptions(project)
{
if (PLATFORM == PLATFORM_MSW)
{
project.AddCompilerOption(_T("-DBUILDING_PLUGIN"));
project.AddCompilerOption(_T("-DHAVE_W32API_H"));
project.AddCompilerOption(_T("-D__WXMSW__"));
project.AddCompilerOption(_T("-DWXUSINGDLL"));
project.AddCompilerOption(_T("-DcbDEBUG"));
project.AddCompilerOption(_T("-DCB_PRECOMP"));
project.AddCompilerOption(_T("-DWX_PRECOMP"));
project.AddCompilerOption(_T("-DwxUSE_UNICODE"));
project.AddCompilerOption(_T("-pipe"));
project.AddCompilerOption(_T("-mthreads"));
project.AddCompilerOption(_T("-fmessage-length=0"));
project.AddCompilerOption(_T("-fexceptions"));
project.AddCompilerOption(_T("-Winvalid-pch"));
project.AddCompilerOption(_T("-std=gnu++11"));
project.AddLinkerOption(_T("-mthreads"));
project.AddIncludeDir(_T("$(#cb)\\include"));
project.AddIncludeDir(_T("$(#cb)\\sdk\\wxscintilla\\include"));
project.AddIncludeDir(_T("$(#cb)\\include\\tinyxml"));
}
else
{
project.AddCompilerOption(_T("-std=c++11"));
project.AddCompilerOption(_T("-fPIC"));
project.AddLinkerOption(_T("-Wl,--no-undefined"));
}
}
// Setup all target common parameters for the targets
function SetupTarget(target, isSystemWide, targetWxVersion)
{
if (IsNull(target))
return false;
target.SetTargetType(ttDynamicLib);
target.SetOutputFilename(PluginSettings.Name);
target.SetCreateDefFile(false);
target.SetCreateStaticLib(false);
target.SetObjectOutput(_T(".objs/") + target.GetTitle());
if (PLATFORM == PLATFORM_MSW)
{
target.SetHostApplication(GetBaseDevelPath(targetWxVersion) + _T("\\codeblocks") + DOT_EXT_EXECUTABLE);
if (targetWxVersion == 0)
{
target.AddIncludeDir(_T("$(#wx.include)"));
target.AddIncludeDir(_T("$(#wx.lib)\\gcc_dll\\mswu"));
target.AddLinkLib(_T("wxmsw28u"));
target.AddLibDir(_T("$(#wx.lib)\\gcc_dll"));
}
else if (targetWxVersion == 1)
{
target.AddIncludeDir(_T("$(#wx30.include)"));
target.AddIncludeDir(_T("$(#wx30.lib)\\gcc_dll\\mswu"));
target.AddLinkLib(_T("wxmsw30u"));
target.AddLibDir(_T("$(#wx30.lib)\\gcc_dll"));
}
else if (targetWxVersion == 2)
{
target.AddIncludeDir(_T("$(#wx31.include)"));
target.AddIncludeDir(_T("$(#wx31.lib)\\gcc_dll\\mswu"));
target.AddLinkLib(_T("wxmsw31u"));
target.AddLibDir(_T("$(#wx31.lib)\\gcc_dll"));
}
target.AddLibDir(GetBaseDevelPath(targetWxVersion));
target.AddLinkLib(_T("codeblocks"));
}
else
{
if (isSystemWide)
{
target.AddCompilerOption(_T("`pkg-config --cflags codeblocks`"));
target.AddLinkerOption(_T("`pkg-config --libs codeblocks`"));
}
else
{
local develPath = GetBaseDevelPath(targetWxVersion);
target.SetHostApplication(develPath + _T("/codeblocks") + DOT_EXT_EXECUTABLE);
target.AddLibDir(develPath);
target.SetWorkingDir(develPath);
target.AddLinkLib(_T("codeblocks"));
target.AddIncludeDir(_T("$(#cb)/include"));
target.AddIncludeDir(_T("$(#cb)/sdk/wxscintilla/include"));
target.AddIncludeDir(_T("$(#cb)/include/tinyxml"));
}
local WxVersionFlag;
if (targetWxVersion == 0)
WxVersionFlag = _T(" --version=2.8");
else if (targetWxVersion == 1)
WxVersionFlag = _T(" --version=3.0");
else if (targetWxVersion == 2)
WxVersionFlag = _T(" --version=3.1");
else if (targetWxVersion == 3)
WxVersionFlag = _T("");
target.AddCompilerOption(_T("`wx-config --cflags ") + WxVersionFlag + _T("`"));
target.AddLinkerOption(_T("`wx-config --libs ") + WxVersionFlag + _T("`"));
}
local zipFilePath;
if (isSystemWide)
zipFilePath = PluginSettings.Name + _T(".zip");
else
{
// "to_codeblocks" has to copy multiple files to the $(#cb)\devel folder. This is a platform specific process
local basePath = GetBaseDevelPath(targetWxVersion) + _T("/share/codeblocks/");
zipFilePath = basePath + PluginSettings.Name + _T(".zip");
target.SetOutputFilename(basePath + _T("plugins/") + PluginSettings.Name);
local executionParameters = _T("--debug-log --multiple-instance --no-splash-screen --verbose -p debug");
if (PLATFORM == PLATFORM_MSW)
executionParameters += _T(" --no-dde --no-check-associations ");
else
executionParameters += _T(" --no-ipc ");
target.SetExecutionParameters(executionParameters);
}
target.AddCommandsAfterBuild(_T("zip -j9 ") + zipFilePath + _T(" manifest") + DOT_EXT_XML);
target.SetAlwaysRunPostBuildSteps (true)
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 <dot_ext> 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 <buffer>
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 <enabled> is true, removes the [IF <directive>] and [ENDIF <directive>]
// macros.
// if <enabled> is false, removes everything enclosed by the [IF <directive>]
// and [ENDIF <directive>] 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;
}