Author Topic: ScriptedWizard Plugin Add function such as Wiz::AppendComboListboxWithChoice()  (Read 10709 times)

Offline gocad

  • Multiple posting newcomer
  • *
  • Posts: 15
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

Code
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

Code
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()));
        }
    }
}

Code
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

Code
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()
Code
            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:
Code
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.
« Last Edit: May 31, 2014, 03:54:56 pm by gocad »

Offline gocad

  • Multiple posting newcomer
  • *
  • Posts: 15
Another useful function is
Code
// get the path of the running wizard.scrip
wxString Wiz::GetWizardDir(void)
{
    return m_WizardDir;
}

wxString m_WizardDir;
Code
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.
Code
// 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
Code
// 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.
« Last Edit: June 01, 2014, 02:52:20 am by gocad »

Offline gocad

  • Multiple posting newcomer
  • *
  • Posts: 15
This a simple sample to Demo the new function.

wizard.script
Code
////////////////////////////////////////////////////////////////////////////////
//
// 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]
« Last Edit: May 31, 2014, 03:52:21 pm by gocad »

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
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!]

Offline gocad

  • Multiple posting newcomer
  • *
  • Posts: 15
That make program on new ScriptedWizard Project easier.

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

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3352
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

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
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!]

Offline gocad

  • Multiple posting newcomer
  • *
  • Posts: 15
I find that Wiz::GetWizardDir() is not what I want.

I just want to get that
Code
// get the folder of the running wizard.scrip
wxString Wiz::GetWizardScriptFolder(void)
{
    return m_WizardScriptFolder;
}

wxString m_WizardScriptFolder;  // in wiz.h

Code
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.
Code
// 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().
Code
// 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;
}

Offline gocad

  • Multiple posting newcomer
  • *
  • Posts: 15
Put A Extended Scripted Wizard Plugin source code on https://github.com/ywx/cbScriptedWizardPlugin

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
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!]

Offline gocad

  • Multiple posting newcomer
  • *
  • Posts: 15
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

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
What?
(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!]