Developer forums (C::B DEVELOPMENT STRICTLY!) > Contributions to C::B
Feature Request: Code Folding by Level Shortcuts
			javmss:
			
			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???
		
			ollydbg:
			
			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);
}
--- End code ---
		
			javmss:
			
			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);
		}
    }
}
--- End code ---
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!
		
			dmoore:
			
			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.
--- End quote ---
once you have added menu entries, the keybinder plugin will let you set shortcuts for it
		
			dmoore:
			
			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);
    }
}
--- End code ---
this code is now part of editor tweaks:
--- Code:  ---svn checkout http://svn.berlios.de/svnroot/repos/cbilplugin/branches/EditorTweaks
--- End code ---
		
Navigation
[0] Message Index
[#] Next page
Go to full version