News:

The new Release 25.03 is out! You can download binaries for Windows and many major Linux distros here .

Main Menu

ScriptedWizard Plugin Add function such as Wiz::AppendComboListboxWithChoice()

Started by gocad, May 31, 2014, 06:45:02 AM

Previous topic - Next topic

gocad

Maybe ScriptedWizard Plugin can add some functions such as ....

I found some useful funtions in scriptedwizard plugin after I readed the source code of emIDE ( http://www.emide.org/ ) last week.

In codeblocks\src\plugins\scriptedwizard\wiz.cpp and wiz.h


int Wiz::AddListboxChoices(const wxString& choices)
{
   wxWizardPage* page = m_pWizard->GetCurrentPage();
   if (page)
   {
       wxListBox* win = dynamic_cast<wxListBox*>(page->FindWindowByName(_("GenericChoiceList"), page));
       if (win)
{
         win->Clear();
         win->InsertItems(GetArrayFromString(choices, _T(";")), 0);
         return 0;
       }
   }
   return -1;
}



It is similar to


void Wiz::FillComboboxWithCompilers(const wxString& name)
{
   wxWizardPage* page = m_pWizard->GetCurrentPage();
   if (page)
   {
       wxComboBox* win = dynamic_cast<wxComboBox*>(page->FindWindowByName(name, page));
       if (win && win->GetCount() == 0)
       {
           for (size_t i = 0; i < CompilerFactory::GetCompilersCount(); ++i)
           {
               Compiler* compiler = CompilerFactory::GetCompiler(i);
               if (compiler)
                   win->Append(compiler->GetName());
           }
           Compiler* compiler = CompilerFactory::GetDefaultCompiler();
           if (compiler)
               win->SetSelection(win->FindString(compiler->GetName()));
       }
   }
}



void Wiz::AddGenericSingleChoiceListPage(const wxString& pageName, const wxString& descr, const wxString& choices, int defChoice)
{
   // we don't track this; can add more than one
   WizPageBase* page = new WizGenericSingleChoiceList(pageName, descr, GetArrayFromString(choices, _T(";")), defChoice, m_pWizard, m_Wizards[m_LaunchIndex].wizardPNG);
   if (!page->SkipPage())
       m_Pages.Add(page);
   else
       delete page;
}


I try to add some new functions as follow


void Wiz::FillComboListboxWithSelCompilers( const wxString& name, const wxString& validCompilerIDs )
{
   wxWizardPage* page = m_pWizard->GetCurrentPage();
   if (page)
   {
       wxControlWithItems* win = dynamic_cast<wxControlWithItems*>( page->FindWindowByName( name.IsEmpty() ? _T("GenericChoiceList") : name , page ) );
       if (win)
       {
           wxArrayString valids = GetArrayFromString(validCompilerIDs, _T(";"), true);
           win->Clear();
           for (size_t i = 0; i < CompilerFactory::GetCompilersCount(); ++i)
           {
               Compiler* compiler = CompilerFactory::GetCompiler(i);
               if (compiler)
               {
                   for (size_t n = 0; n < valids.GetCount(); ++n)
                   {
                       // match not only if IDs match, but if ID inherits from it too
                       if (CompilerFactory::CompilerInheritsFrom(compiler, valids[n]))
                       {
                           win->Append(compiler->GetName());
                           break;
                       }
                   }
               }
           }
           Compiler* compiler = CompilerFactory::GetDefaultCompiler();
           if (compiler)
               win->SetSelection(win->FindString(compiler->GetName()));
       }
   }
}

void Wiz::AppendComboListboxWithSelCompilers( const wxString& name, const wxString& validCompilerIDs )
{
   wxWizardPage* page = m_pWizard->GetCurrentPage();
   if (page)
   {
       wxControlWithItems* win = dynamic_cast<wxControlWithItems*>( page->FindWindowByName( name.IsEmpty() ? _T("GenericChoiceList") : name , page ) );
       if (win)
       {
           wxArrayString valids = GetArrayFromString(validCompilerIDs, _T(";"), true);
           size_t iItemsCount = win->GetCount();
           wxString nameInItems = _T(";");
           for( size_t i = 0; i < iItemsCount; ++i )
           {
               nameInItems += win->GetString(i) + _T(";");
           }
           for (size_t i = 0; i < CompilerFactory::GetCompilersCount(); ++i)
           {
               Compiler* compiler = CompilerFactory::GetCompiler(i);
               if (compiler)
               {
                   wxString compilerName = compiler->GetName();
                   if( wxNOT_FOUND != nameInItems.Find( _T(";") + compilerName + _T(";") ) )
                       continue;
                   for (size_t n = 0; n < valids.GetCount(); ++n)
                   {
                       // match not only if IDs match, but if ID inherits from it too
                       if (CompilerFactory::CompilerInheritsFrom(compiler, valids[n]))
                       {
                           win->Append( compilerName );
                           nameInItems += compilerName + _T(";");
                           break;
                       }
                   }
               }
           }
       }
   }
}

int Wiz::FillComboListboxWithChoices( const wxString& name, const wxString& choices )
{
   wxWizardPage* page = m_pWizard->GetCurrentPage();
   if (page)
   {
       wxControlWithItems* win = dynamic_cast<wxControlWithItems*>( page->FindWindowByName( name.IsEmpty() ? _T("GenericChoiceList") : name , page ) );
       if (win)
       {
           win->Clear();
           wxArrayString items = GetArrayFromString( choices, _T(";") );
           unsigned int nItems = items.GetCount();
           for ( unsigned int i = 0; i < nItems; i++ )
           {
               win->Append( items[i] );
           }

           return 0;
       }
   }
   return -1;
}

int Wiz::AppendComboListboxWithChoices( const wxString& name, const wxString& choices )
{
   wxWizardPage* page = m_pWizard->GetCurrentPage();
   if (page)
   {
       wxControlWithItems* win = dynamic_cast<wxControlWithItems*>( page->FindWindowByName( name.IsEmpty() ? _T("GenericChoiceList") : name , page ) );
       if (win)
       {
           wxArrayString items = GetArrayFromString( choices, _T(";") );
           size_t iItemsCount = win->GetCount();
           wxString nameInItems = _T(";");
           for( size_t i = 0; i < iItemsCount; ++i )
           {
               nameInItems += win->GetString(i) + _T(";");
           }
           unsigned int nItems = items.GetCount();
           for ( unsigned int i = 0; i < nItems; i++ )
           {
               wxString tItemsName = items[i];
               if( wxNOT_FOUND != nameInItems.Find( _T(";") + tItemsName + _T(";") ) )
                   continue;
               win->Append( tItemsName );
               nameInItems += tItemsName + _T(";");
           }

           return 0;
       }
   }
   return -1;
}


Then Add those to Wiz::RegisterWizard()

           func(&Wiz::FillComboListboxWithSelCompilers, "FillComboListboxWithSelCompilers").
           func(&Wiz::AppendComboListboxWithSelCompilers, "AppendComboListboxWithSelCompilers").
           func(&Wiz::FillComboListboxWithChoices, "FillComboListboxWithChoices").
           func(&Wiz::AppendComboListboxWithChoices, "AppendComboListboxWithChoices").


Now you can use that in your wizard.script.
Such as:

function BeginWizard()
{
          .
          .
       // Generic device selection
       Wizard.AddGenericSingleChoiceListPage(_T("DeviceSelection"), _T("Please select your device."), _T(""), deviceId);
          .
          .
}

function OnEnter_DeviceSelection(fwd)
{
   Wizard.FillComboListboxWithChoices( _T(""), deviceNames );
}


You don't put all data or resource into xrc file. You can select another data source such as xml file.
You can change the data in running ScriptedWizard to new Project as you needing.
That let you have a bigger space to customize you Project wizard.

gocad

Another useful function is

// get the path of the running wizard.scrip
wxString Wiz::GetWizardDir(void)
{
   return m_WizardDir;
}


wxString m_WizardDir;

CompileTargetBase* Wiz::Launch(int index, wxString* pFilename)
{
   .
   .

   // locate the script
   wxString script = ConfigManager::GetFolder(sdDataUser) + _T("/templates/wizard/") + m_Wizards[index].script;
   if (!wxFileExists(script))
       script = ConfigManager::GetFolder(sdDataGlobal) + _T("/templates/wizard/") + m_Wizards[index].script;

   if (!Manager::Get()->GetScriptingManager()->LoadScript(script)) // build and run script
   {
       // any errors have been displayed by ScriptingManager
       Clear();
       InfoWindow::Display(_("Error"), _("Failed to load the wizard's script.\nPlease check the debug log for details..."));
       return 0;
   }
   m_WizardDir = script.BeforeLast(_T('/'));
   m_WizardDir << _T("/");

   // call BeginWizard()
   try
   {
       SqPlus::SquirrelFunction<void> f("BeginWizard");
       f();
   }
   catch (SquirrelError& e)
   {
       Manager::Get()->GetScriptingManager()->DisplayErrors(&e);
       Clear();
       return 0;
   }
   catch (cbException& e)
   {
       e.ShowErrorMessage(false);
       Clear();
       return 0;
   }

   .
   .
   Clear();
   return base;
}

void Wiz::RegisterWizard()
{
   .
   .

           func(&Wiz::GetWizardDir, "GetWizardDir").

   .
   .
   SqPlus::BindVariable(this, "Wizard", SqPlus::VAR_ACCESS_READ_ONLY);
}


When you change the CodeBlocks\share\CodeBlocks\templates\wizard\wxwidgets to CodeBlocks\share\CodeBlocks\templates\wizard\My_wxwidgets
You can use that in your wizard.script.

// return the files this project contains
function GetFilesDir()
{
   local result = _T("");
   local wizdir = Wizard.GetWizardDir();
   if (!IsEmpty) // Checks whether user wants Empty Project or not
   {
       if (PLATFORM == PLATFORM_MSW)
           result = wizdir + _T("rc;");
       if (GuiBuilder == 2)
       {
           if (GuiAppType == 0)
               result = result + wizdir + _T("wxfb/dialog;");
           else if (GuiAppType == 1)
               result = result + wizdir + _T("wxfb/frame;");
       }
   }
   return result;
}


Instead of follow

// return the files this project contains
function GetFilesDir()
{
   local result = _T("");
   if (!IsEmpty) // Checks whether user wants Empty Project or not
   {
       if (PLATFORM == PLATFORM_MSW)
           result = _T("My_wxwidgets/rc;");
       if (GuiBuilder == 2)
       {
           if (GuiAppType == 0)
               result = result + _T("My_wxwidgets/wxfb/dialog;");
           else if (GuiAppType == 1)
               result = result + _T("My_wxwidgets/wxfb/frame;");
       }
   }
   return result;
}


wizard.script don't know which floder he will local in.

gocad

This a simple sample to Demo the new function.

wizard.script

////////////////////////////////////////////////////////////////////////////////
//
// New ScriptWizard Function Demo project wizard
//
////////////////////////////////////////////////////////////////////////////////

//
// GLOBALS
//
CompilerSetId        <- 1;
strValidCompilerID   <- _T("");
CompilerId           <- 1;

// Page setup
// Startup function
function BeginWizard()
{
   local wiz_type = Wizard.GetWizardType();

   if (wiz_type == wizProject)
   {
       local intro_msg = _T( "Welcome to the new ScriptWizard Function Demo wizard!\n" + "This wizard will help you use the follow new functions:\n\n" + "Wizard.FillComboListboxWithChoices()\n" + "Wizard.FillComboListboxWithSelCompilers()\n" + "Please click \"Next\" to proceed." );
       // Welcome Page
       Wizard.AddInfoPage( _T("ScriptWizard Function Demo"), intro_msg );
       // select project name and path
       Wizard.AddProjectPathPage();
       // Compiler Set selection
       Wizard.AddGenericSingleChoiceListPage( _T("CompilerSetSelection"), _T("Please select your Compiler Set."), _T(""), CompilerSetId );
       // Compiler selection
       Wizard.AddGenericSingleChoiceListPage( _T("CompilerSelection"), _T("Please select your Compiler."), _T(""), CompilerId );
   }
   else
   {
       print(wiz_type);
   }
}

// Page processing
function GetValidCompilerFromSetName( strSetName )
{
   if( strSetName.Matches( _T("Gcc;") ) )
   {
return _T("gcc*");
   }
else if( strSetName.Matches( _T("Microsoft VC;") ) )
{
return _T("msvc*");
   }
else if( strSetName.Matches( _T("Fortran;") ) )
{
return _T("g95;*fortran");
   }
else if( strSetName.Matches( _T("Arm;") ) )
{
return _T("*arm*");
   }
else if( strSetName.Matches( _T("8051;") ) )
{
return _T("*51*");
   }
return _T("");
}

function OnEnter_CompilerSetSelection( fwd )
{
   Wizard.FillComboListboxWithChoices( _T(""), _T("Gcc;Microsoft VC;Fortran;Arm;8051") );
}

// Generic Compiler Set Selection page
function OnLeave_CompilerSetSelection( fwd )
{
   local strCompilerSet = _("");
   if( fwd )
   {
       strCompilerSet = Wizard.GetListboxStringSelections( _T("GenericChoiceList") );
       if( strCompilerSet.IsEmpty() )
       {
           ShowWarning( _T("Please select a Compiler Set...") );
           return false;
       }
       strValidCompilerID = GetValidCompilerFromSetName( strCompilerSet );
   }
   return true;
}

// Generic Compiler Selection page
function OnEnter_CompilerSelection( fwd )
{
   Wizard.FillComboListboxWithSelCompilers( _T(""), strValidCompilerID );
}

function OnLeave_CompilerSelection( fwd )
{
   local strCompilerName = _T("");
   if( fwd )
   {
       strCompilerName = Wizard.GetListboxStringSelections( _T("GenericChoiceList") ).RemoveLast( 1 );
       if( strCompilerName.IsEmpty() )
       {
           ShowWarning(_T("Please select a Compiler..."));
           return false;
       }
       ShowInfo( _T("You have select ") + strCompilerName );
   }
   return true;
}

function SetupProject( project )
{
   return true;
}





[attachment deleted by admin]

oBFusCATed

BlueHazzard: What do you think about this proposals? Are the going to clash with your changes to the scripting? Can you adopt them?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

gocad

That make program on new ScriptedWizard Project easier.

Something on emIDE is good idea.
Touch screen is cool but it is not everthing.

BlueHazzard

I see no big problems with this. Should i implement it in my branch?

@gocad: can you make a git patch against one of this repos:
https://github.com/obfuscated/codeblocks_sf
or
https://github.com/bluehazzard/codeblocks_sf

greetings

oBFusCATed

The question is will this change cause you problems in your branch?
Will it work out-of-the-box there or you'll have to make some changes?
And so on...
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

gocad

I find that Wiz::GetWizardDir() is not what I want.

I just want to get that

// get the folder of the running wizard.scrip
wxString Wiz::GetWizardScriptFolder(void)
{
    return m_WizardScriptFolder;
}


wxString m_WizardScriptFolder;  // in wiz.h


CompileTargetBase* Wiz::Launch(int index, wxString* pFilename)
{
    .
    .

    // locate the script
    wxString script = ConfigManager::GetFolder(sdDataUser) + _T("/templates/wizard/") + m_Wizards[index].script;
    if (!wxFileExists(script))
        script = ConfigManager::GetFolder(sdDataGlobal) + _T("/templates/wizard/") + m_Wizards[index].script;

    if (!Manager::Get()->GetScriptingManager()->LoadScript(script)) // build and run script
    {
        // any errors have been displayed by ScriptingManager
        Clear();
        InfoWindow::Display(_("Error"), _("Failed to load the wizard's script.\nPlease check the debug log for details..."));
        return 0;
    }
    m_WizardScriptFolder = script.BeforeLast( _T('/') );
    m_WizardScriptFolder = m_WizardScriptFolder.AfterLast( _T('/') );

    // call BeginWizard()
    try
    {
        SqPlus::SquirrelFunction<void> f("BeginWizard");
        f();
    }
    catch (SquirrelError& e)
    {
        Manager::Get()->GetScriptingManager()->DisplayErrors(&e);
        Clear();
        return 0;
    }
    catch (cbException& e)
    {
        e.ShowErrorMessage(false);
        Clear();
        return 0;
    }

    .
    .
    Clear();
    return base;
}

void Wiz::RegisterWizard()
{
    .
    .

            func(&Wiz::GetWizardScriptFolder, "GetWizardScriptFolder").

    .
    .
    SqPlus::BindVariable(this, "Wizard", SqPlus::VAR_ACCESS_READ_ONLY);
}



The code use Wiz::GetWizardDir() in function GetFilesDir() ( wizard.script ) will go wrong.

// return the files this project contains
function GetFilesDir()
{
    local result = _T("");
    local wizdir = Wizard.GetWizardDir();
    if (!IsEmpty) // Checks whether user wants Empty Project or not
    {
        if (PLATFORM == PLATFORM_MSW)
            result = wizdir + _T("rc;"); // go wrong, it doesn't copy any file
        if (GuiBuilder == 2)
        {
            if (GuiAppType == 0)
                result = result + wizdir + _T("wxfb/dialog;"); // go wrong, it doesn't copy any file
            else if (GuiAppType == 1)
                result = result + wizdir + _T("wxfb/frame;"); // go wrong, it doesn't copy any file
        }
    }
    return result;
}

You will use Wiz::GetWizardScriptFolder().

// return the files this project contains
function GetFilesDir()
{
    local result = _T("");
    local wizScriptFolder = Wizard.GetWizardScriptFolder();
    if (!IsEmpty) // Checks whether user wants Empty Project or not
    {
        if (PLATFORM == PLATFORM_MSW)
            result = wizScriptFolder + _T("/rc;");
        if (GuiBuilder == 2)
        {
            if (GuiAppType == 0)
                result = result + wizScriptFolder + _T("/wxfb/dialog;");
            else if (GuiAppType == 1)
                result = result + wizScriptFolder + _T("/wxfb/frame;");
        }
    }
    return result;
}


oBFusCATed

What is the purpose of this plugin?
It won't be reintegrated in the main repo.
Why don't you post patches against the main source tree as BlueHazzard have suggested?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

gocad

I just share it with us.

Code::Blocks is a free C, C++ and Fortran IDE built to meet the most demanding needs of its users. It is designed to be very extensible and fully configurable.

Finally, an IDE with all the features you need, having a consistent look, feel and operation across platforms.

Built around a plugin framework, Code::Blocks can be extended with plugins. Any kind of functionality can be added by installing/coding a plugin. For instance, compiling and debugging functionality is already provided by plugins!

Special credits go to darmar for his great work on the FortranProject plugin, bundled since release 13.12.

We hope you enjoy using Code::Blocks!

The Code::Blocks Team

oBFusCATed

(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]