Code::Blocks
July 29, 2010, 06:01:51 pm *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Code::Blocks Logo Elections closed! And the winner is... otaco!
 
   Home   Help Search Login Register  :: WebsiteWiki  
Pages: [1]
  Send this topic  |  Print  
Author Topic: Feature Request: Code Folding by Level Shortcuts  (Read 3438 times)
javmss
Newcomer
*
Posts: 6


« on: November 17, 2009, 02:10:34 pm »

on
In November 06, 2009 I have previously posted this topic:
  Code::Blocks > User forums > Using Code::Blocks > Feature Request: Code Folding by Level Shortcuts

Since I got no answer, I thing it might be in the wrong place, so I am reposting it here.
I apologise if I'm being inconvenient.
--------------------------------------------------------------------------------

Notepad++ (http://notepad-plus.sourceforge.net/) has a very usefull feature that allows me to selectively fold all given levels by the respective keyboard shortcut.

If I want to fold all "level 3" blocks in a file (C, C++, XML, whatever), I just need to "ALT+3". To unfold, "SHIFT+ALT+3".
I can do this to anything between level 0 to level 9 (the number in my keyboard end on 9, unfortunately).

In Code::Blocks all I have (at least from what I know) is "fold/unfold current block" or "fold/unfold absolutely all existing blocks in my file".

Is there any chance to have a similar feature in Code::Blocks please???
Logged
ollydbg
Lives here!
****
Posts: 1484


Interests on OpenCV and Robotics


WWW
« Reply #1 on: November 17, 2009, 04:48:14 pm »

hi, javmss.

Currently, I don't have much time to help you, but I can give you the direction: the source code of cbeditor.cpp, which is located in:
svn\src\sdk\cbeditor.cpp
the related code was located from line 1924-2024. So, you can simply add some modification to these code, and do the folding function as you wanted.

Code:
void cbEditor::DoFoldAll(int fold)
{
    cbAssert(m_pControl);
    if (m_SplitType != stNoSplit)
        cbAssert(m_pControl2);
    cbStyledTextCtrl* ctrl = GetControl();
    ctrl->Colourise(0, -1); // the *most* important part!
    int count = ctrl->GetLineCount();
    for (int i = 0; i <= count; ++i)
        DoFoldLine(i, fold);
}

void cbEditor::DoFoldBlockFromLine(int line, int fold)
{
    cbAssert(m_pControl);
    if (m_SplitType != stNoSplit)
        cbAssert(m_pControl2);
    cbStyledTextCtrl* ctrl = GetControl();
    ctrl->Colourise(0, -1); // the *most* important part!
    int i, parent, maxLine, level, UnfoldUpto = line;
    bool FoldedInside = false;

    parent = ctrl->GetFoldParent(line);
    level = ctrl->GetFoldLevel(parent);
    /* The following code will check if the child is hidden
    *  under parent before unfolding it
    */
    if (fold == 0)
    {
        do
        {
            if (!ctrl->GetFoldExpanded(parent))
            {
                FoldedInside = true;
                UnfoldUpto = parent;
            }
            if (wxSCI_FOLDLEVELBASE == (level & wxSCI_FOLDLEVELNUMBERMASK))
                break;
            parent = ctrl->GetFoldParent(parent);
            level = ctrl->GetFoldLevel(parent);
        }
        while (parent != -1);
    }

    maxLine = ctrl->GetLastChild(line, -1);

    for (i = UnfoldUpto; i <= maxLine; ++i)
        DoFoldLine(i, fold);
}

bool cbEditor::DoFoldLine(int line, int fold)
{
    cbAssert(m_pControl);
    if (m_SplitType != stNoSplit)
        cbAssert(m_pControl2);
    cbStyledTextCtrl* ctrl = GetControl();
    int level = ctrl->GetFoldLevel(line);

    // The fold parameter is the type of folding action requested
    // 0 = Unfold; 1 = Fold; 2 = Toggle folding.

    // Check if the line is a header (fold point).
    if (level & wxSCI_FOLDLEVELHEADERFLAG)
    {
        bool IsExpanded = ctrl->GetFoldExpanded(line);

        // If a fold/unfold request is issued when the block is already
        // folded/unfolded, ignore the request.
        if (fold == 0 && IsExpanded) return true;
        if (fold == 1 && !IsExpanded) return true;

        // Apply the folding level limit only if the current block will be
        // folded (that means it's currently expanded), folding level limiter
        // must be enabled of course. Unfolding will not be affected.
        if (m_pData->mFoldingLimit && IsExpanded)
        {
            if ((level & wxSCI_FOLDLEVELNUMBERMASK) > (wxSCI_FOLDLEVELBASE + m_pData->mFoldingLimitLevel-1))
                return false;
        }

        ctrl->ToggleFold(line);
        return true;
    }
    return false;
}

void cbEditor::FoldAll()
{
    DoFoldAll(1);
}

void cbEditor::UnfoldAll()
{
    DoFoldAll(0);
}

void cbEditor::ToggleAllFolds()
{
    DoFoldAll(2);
}
Logged

If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.
javmss
Newcomer
*
Posts: 6


« Reply #2 on: December 16, 2009, 07:18:58 pm »

I don't have much knowledge about the C::B SDK, so I took a look to the code where you told me and realised I'd do something like this:

Code:
/** Fold/Unfold/Toggle all folds in the givel level.
\param level Level number of folding, starting from 0.
\param fold Type of folding action requested: \n
- 0 = Unfold.
- 1 = Fold.
- 2 = Toggle folding. */
void cbEditor::DoFoldAllAtLevel(int level, int fold)
{
    cbAssert(m_pControl);
    if (m_SplitType != stNoSplit)
        cbAssert(m_pControl2);

    cbStyledTextCtrl* ctrl = GetControl();
    ctrl->Colourise(0, -1); // the *most* important part!

// Scan all file lines searching for the specified folding level.
    int count = ctrl->GetLineCount();
    for (int line = 0; line <= count; ++line)
    {
int parent = ctrl->GetFoldParent(line);

if ( level == ctrl->GetFoldLevel(parent) ) // Found on fold in "level".
{
int maxLine = ctrl->GetLastChild(line, -1);

for (i = line; i <= maxLine; ++i)
DoFoldLine(i, fold);
}
    }
}

Now I wonder how can I bind this to different shortcuts.
I can suppose that I should create several "FoldAt#( )" methods, but I can't catch how to bind it to the "ALT+#" keys...

I will be looking for it, but I'd be very glad for a clue.

Tanks!
Logged
dmoore
Developer
Lives here!
*****
Posts: 790


« Reply #3 on: December 16, 2009, 07:40:28 pm »

maybe I can incorporate this into my editor tweaks plugin. http://forums.codeblocks.org/index.php/topic,11660.0.html

Quote
Now I wonder how can I bind this to different shortcuts.

once you have added menu entries, the keybinder plugin will let you set shortcuts for it
Logged

wxWidgets REGEX Library syntax: http://www.wxwidgets.org/manuals/stable/wx_wxresyn.html#wxresyn
Interpreted Languages Plugins for Code::Blocks: http://developer.berlios.de/projects/cbilplugin/
dmoore
Developer
Lives here!
*****
Posts: 790


« Reply #4 on: December 16, 2009, 10:15:26 pm »

btw, your code doesn't do what you think it does (GetFoldLevel returns a more complicated result). Also, I've no idea why you have the nested loop.

In addition I'm not even sure what you are trying to achieve. I assume you want options to fold all code above a certain fold level? If so, I propose:

Code:
//fold: 0 = unfold, 1 = fold
void EditorTweaks::DoFoldAboveLevel(int level, int fold)
{
    cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
    if(!ed || !ed->GetControl())
        return;

    level+=wxSCI_FOLDLEVELBASE;

    ed->GetControl()->Colourise(0, -1); // the *most* important part!

    int count = ed->GetControl()->GetLineCount();
    for (int line = 0; line <= count; ++line)
    {
        int line_level_data = ed->GetControl()->GetFoldLevel(line);
        if (!(line_level_data & wxSCI_FOLDLEVELHEADERFLAG))
            continue;
        int line_level = line_level_data & wxSCI_FOLDLEVELNUMBERMASK;

        bool IsExpanded = ed->GetControl()->GetFoldExpanded(line);

        // If a fold/unfold request is issued when the block is already
        // folded/unfolded, ignore the request.
        if(line_level<=level)
            if(IsExpanded)
                continue;
        else
            if(fold==0 && IsExpanded || fold ==1 && !IsExpanded)
                continue;
        ed->GetControl()->ToggleFold(line);
    }
}

this code is now part of editor tweaks:

Code:
svn checkout http://svn.berlios.de/svnroot/repos/cbilplugin/branches/EditorTweaks
« Last Edit: December 16, 2009, 10:43:16 pm by dmoore » Logged

wxWidgets REGEX Library syntax: http://www.wxwidgets.org/manuals/stable/wx_wxresyn.html#wxresyn
Interpreted Languages Plugins for Code::Blocks: http://developer.berlios.de/projects/cbilplugin/
MortenMacFly
Administrator
Lives here!
*****
Posts: 4593



WWW
« Reply #5 on: December 17, 2009, 07:57:12 am »

Just for the record: I think the idea behind the aligner plugin would fit very well into this plugin, too. How about that?

See here: http://forums.codeblocks.org/index.php/topic,11274.msg79225.html#msg79225
Logged

Logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
Compiling help
Debugging help
Portable C::B
Pages: [1]
  Send this topic  |  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!