[NEW] FunctionList: restore the previous state.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@1020 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2013-02-10 20:11:18 +00:00
parent ce1b17b79a
commit 7c05c2f208
5 changed files with 174 additions and 61 deletions

View File

@ -451,7 +451,7 @@ BEGIN
MENUITEM "Document Map", IDM_VIEW_DOC_MAP
//MENUITEM "Function List", IDM_VIEW_FUNC_LIST
MENUITEM "Function List", IDM_VIEW_FUNC_LIST
MENUITEM SEPARATOR
MENUITEM "Synchronize Vertical Scrolling", IDM_VIEW_SYNSCROLLV
MENUITEM "Synchronize Horizontal Scrolling", IDM_VIEW_SYNSCROLLH

View File

@ -46,7 +46,9 @@ void FunctionListPanel::addEntry(const TCHAR *nodeName, const TCHAR *displayText
{
itemParent = _treeView.searchSubItemByName(nodeName, root);
if (!itemParent)
itemParent = _treeView.addItem(nodeName, root, NULL, posStr);
{
itemParent = _treeView.addItem(nodeName, root, NULL, TEXT("-1"));
}
}
else
itemParent = root;
@ -268,57 +270,44 @@ generic_string FunctionListPanel::parseSubLevel(size_t begin, size_t end, std::v
}
}
void FunctionListPanel::addInTreeStateArray(TreeStateNode tree2Update)
{
bool found = false;
for (size_t i = 0; i < _treeStates.size(); i++)
{
if (_treeStates[i]._extraData == tree2Update._extraData)
{
_treeStates[i] = tree2Update;
found = true;
}
}
if (!found)
_treeStates.push_back(tree2Update);
}
TreeStateNode* FunctionListPanel::getFromTreeStateArray(generic_string fullFilePath)
{
for (size_t i = 0; i < _treeStates.size(); i++)
{
if (_treeStates[i]._extraData == fullFilePath)
return &_treeStates[i];
}
return NULL;
}
void FunctionListPanel::reload()
{
// clean up
TreeStateNode currentTree;
bool isOK = _treeView.retrieveFoldingStateTo(currentTree, _treeView.getRoot());
if (isOK)
addInTreeStateArray(currentTree);
removeAllEntries();
/*
generic_string funcBegin = TEXT("^[\\t ]*");
generic_string qualifier_maybe = TEXT("((static|const)[\\s]+)?");
generic_string returnType = TEXT("[\\w]+");
generic_string space_starMaybe = TEXT("([\\s]+|\\*[\\s]+|[\\s]+\\*|[\\s]+\\*[\\s]+)");
generic_string classQualifier_maybe = TEXT("([\\w_]+[\\s]*::)?");
generic_string funcName = TEXT("(?!(if|whil|for))[\\w_]+");
generic_string const_maybe = TEXT("([\\s]*const[\\s]*)?");
generic_string space_maybe = TEXT("[\\s]*");
generic_string params = TEXT("\\([\\n\\w_,*&\\s]*\\)");
generic_string funcBody = TEXT("\\{");
generic_string space_eol_maybe = TEXT("[\\n\\s]*");
generic_string function = funcBegin + qualifier_maybe + returnType + space_starMaybe + classQualifier_maybe + funcName + space_maybe + params + const_maybe + space_eol_maybe + funcBody;
generic_string secondSearch = funcName + space_maybe;
secondSearch += TEXT("\\(");
vector<generic_string> regExpr1;
vector<generic_string> regExpr2;
regExpr1.push_back(secondSearch);
regExpr1.push_back(funcName);
generic_string secondSearch_className = TEXT("[\\w_]+(?=[\\s]*::)");
regExpr2.push_back(secondSearch_className);
generic_string classRegExpr = TEXT("^[\\t ]*(class|struct)[\\t ]+[\\w]+[\\s]*(:[\\s]*(public|protected|private)[\\s]+[\\w]+[\\s]*)?\\{");
vector<generic_string> classRegExprArray;
generic_string str1 = TEXT("(class|struct)[\\t ]+[\\w]+");
generic_string str2 = TEXT("[\\t ]+[\\w]+");
generic_string str3 = TEXT("[\\w]+");
classRegExprArray.push_back(str1.c_str());
classRegExprArray.push_back(str2.c_str());
//classRegExprArray.push_back(str3.c_str());
//parse(fi, 0, docLen, function.c_str(), regExpr1, regExpr2);
const TCHAR bodyOpenSymbol[] = TEXT("\\{");
const TCHAR bodyCloseSymbol[] = TEXT("\\}");
parse2(fi, 0, docLen, classRegExpr.c_str(), classRegExprArray, bodyOpenSymbol, bodyCloseSymbol, function.c_str(), regExpr1);
*/
vector<foundInfo> fi;
generic_string fullFilePath = ((*_ppEditView)->getCurrentBuffer())->getFileName();
TCHAR *fn = ::PathFindFileName(fullFilePath.c_str());
const TCHAR *fn = ((*_ppEditView)->getCurrentBuffer())->getFileName();
TCHAR *ext = ::PathFindExtension(fn);
if (_funcParserMgr.parse(fi, ext))
@ -345,8 +334,20 @@ void FunctionListPanel::reload()
}
}
HTREEITEM root = _treeView.getRoot();
const TCHAR *fullFilePath = ((*_ppEditView)->getCurrentBuffer())->getFullPathName();
if (root)
_treeView.expand(root);
{
_treeView.setItemParam(root, fullFilePath);
TreeStateNode *previousTree = getFromTreeStateArray(fullFilePath);
if (!previousTree)
{
_treeView.expand(root);
}
else
{
_treeView.restoreFoldingStateFrom(*previousTree, root);
}
}
}
void FunctionListPanel::init(HINSTANCE hInst, HWND hPere, ScintillaEditView **ppEditView)
{
@ -354,20 +355,13 @@ void FunctionListPanel::init(HINSTANCE hInst, HWND hPere, ScintillaEditView **pp
_ppEditView = ppEditView;
generic_string funcListXmlPath = (NppParameters::getInstance())->getUserPath();
PathAppend(funcListXmlPath, TEXT("functionList.xml"));
/*_isValidated = */_funcParserMgr.init(funcListXmlPath, ppEditView);
_funcParserMgr.init(funcListXmlPath, ppEditView);
}
void FunctionListPanel::notified(LPNMHDR notification)
{
if((notification->hwndFrom == _treeView.getHSelf()))
{
/*
TCHAR textBuffer[MAX_PATH];
TVITEM tvItem;
tvItem.mask = TVIF_TEXT | TVIF_PARAM;
tvItem.pszText = textBuffer;
tvItem.cchTextMax = MAX_PATH;
*/
switch (notification->code)
{
case NM_DBLCLK:
@ -382,9 +376,12 @@ void FunctionListPanel::notified(LPNMHDR notification)
if (posStr)
{
int pos = generic_atoi(posStr->c_str());
int sci_line = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, pos);
(*_ppEditView)->execute(SCI_ENSUREVISIBLE, sci_line);
(*_ppEditView)->execute(SCI_GOTOPOS, pos);
if (pos != -1)
{
int sci_line = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, pos);
(*_ppEditView)->execute(SCI_ENSUREVISIBLE, sci_line);
(*_ppEditView)->execute(SCI_GOTOPOS, pos);
}
}
}
break;

View File

@ -105,8 +105,11 @@ private:
FunctionParsersManager _funcParserMgr;
std::vector<FuncInfo> _funcInfos;
std::vector< std::pair<int, int> > _skipZones;
std::vector<TreeStateNode> _treeStates;
generic_string parseSubLevel(size_t begin, size_t end, std::vector< generic_string > dataToSearch, int & foundPos);
size_t getBodyClosePos(size_t begin, const TCHAR *bodyOpenSymbol, const TCHAR *bodyCloseSymbol);
void notified(LPNMHDR notification);
void addInTreeStateArray(TreeStateNode tree2Update);
TreeStateNode* getFromTreeStateArray(generic_string fullFilePath);
};
#endif // FUNCLISTPANEL_H

View File

@ -67,6 +67,28 @@ LRESULT TreeView::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
return ::CallWindowProc(_defaultProc, hwnd, Message, wParam, lParam);
}
bool TreeView::setItemParam(HTREEITEM Item2Set, const TCHAR *paramStr)
{
if (!Item2Set)
return false;
TVITEM tvItem;
tvItem.hItem = Item2Set;
tvItem.mask = TVIF_PARAM;
SendMessage(_hSelf, TVM_GETITEM, 0,(LPARAM)&tvItem);
if (!tvItem.lParam)
tvItem.lParam = (LPARAM)(new generic_string(paramStr));
else
{
*((generic_string *)tvItem.lParam) = paramStr;
}
SendMessage(_hSelf, TVM_SETITEM, 0,(LPARAM)&tvItem);
return true;
}
HTREEITEM TreeView::addItem(const TCHAR *itemName, HTREEITEM hParentItem, int iImage, const TCHAR *filePath)
{
TVITEM tvi;
@ -464,3 +486,77 @@ bool TreeView::canDragOut(HTREEITEM targetItem)
}
return true;
}
bool TreeView::retrieveFoldingStateTo(TreeStateNode & treeState2Construct, HTREEITEM treeviewNode)
{
if (!treeviewNode)
return false;
TCHAR textBuffer[MAX_PATH];
TVITEM tvItem;
tvItem.hItem = treeviewNode;
tvItem.pszText = textBuffer;
tvItem.cchTextMax = MAX_PATH;
tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_STATE;
SendMessage(_hSelf, TVM_GETITEM, 0,(LPARAM)&tvItem);
treeState2Construct._label = textBuffer;
treeState2Construct._isExpanded = (tvItem.state & TVIS_EXPANDED) != 0;
treeState2Construct._isSelected = (tvItem.state & TVIS_SELECTED) != 0;
if (tvItem.lParam)
{
treeState2Construct._extraData = *((generic_string *)tvItem.lParam);
}
int i = 0;
for (HTREEITEM hItem = getChildFrom(treeviewNode); hItem != NULL; hItem = getNextSibling(hItem))
{
treeState2Construct._children.push_back(TreeStateNode());
retrieveFoldingStateTo(treeState2Construct._children.at(i), hItem);
i++;
}
return true;
}
bool TreeView::restoreFoldingStateFrom(const TreeStateNode & treeState2Compare, HTREEITEM treeviewNode)
{
if (!treeviewNode)
return false;
TCHAR textBuffer[MAX_PATH];
TVITEM tvItem;
tvItem.hItem = treeviewNode;
tvItem.pszText = textBuffer;
tvItem.cchTextMax = MAX_PATH;
tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_STATE;
SendMessage(_hSelf, TVM_GETITEM, 0,(LPARAM)&tvItem);
if (treeState2Compare._label != textBuffer)
return false;
if (tvItem.lParam)
{
if (treeState2Compare._extraData != *((generic_string *)tvItem.lParam))
return false;
}
if (treeState2Compare._isExpanded) //= (tvItem.state & TVIS_EXPANDED) != 0;
expand(treeviewNode);
else
fold(treeviewNode);
if (treeState2Compare._isSelected) //= (tvItem.state & TVIS_SELECTED) != 0;
selectItem(treeviewNode);
int i = 0;
bool isOk = true;
for (HTREEITEM hItem = getChildFrom(treeviewNode); hItem != NULL; hItem = getNextSibling(hItem))
{
isOk = restoreFoldingStateFrom(treeState2Compare._children.at(i), hItem);
if (!isOk)
break;
i++;
}
return isOk;
}

View File

@ -30,8 +30,16 @@
#include "window.h"
class TreeView : public Window
{
struct TreeStateNode {
generic_string _label;
generic_string _extraData;
bool _isExpanded;
bool _isSelected;
std::vector<TreeStateNode> _children;
};
class TreeView : public Window {
public:
TreeView() : Window(), _isItemDragged(false) {};
@ -39,6 +47,7 @@ public:
virtual void init(HINSTANCE hInst, HWND parent, int treeViewID);
virtual void destroy();
HTREEITEM addItem(const TCHAR *itemName, HTREEITEM hParentItem, int iImage, const TCHAR *filePath = NULL);
bool setItemParam(HTREEITEM Item2Set, const TCHAR *paramStr);
HTREEITEM searchSubItemByName(const TCHAR *itemName, HTREEITEM hParentItem);
void removeItem(HTREEITEM hTreeItem);
void removeAllItems();
@ -64,9 +73,15 @@ public:
HTREEITEM getPrevSibling(HTREEITEM hItem) const {
return TreeView_GetPrevSibling(_hSelf, hItem);
};
void expand(HTREEITEM hItem) const {
TreeView_Expand(_hSelf, hItem, TVE_EXPAND);
};
void fold(HTREEITEM hItem) const {
TreeView_Expand(_hSelf, hItem, TVE_COLLAPSE);
};
void toggleExpandCollapse(HTREEITEM hItem) const {
TreeView_Expand(_hSelf, hItem, TVE_TOGGLE);
};
@ -90,6 +105,8 @@ public:
bool moveDown(HTREEITEM itemToMove);
bool moveUp(HTREEITEM itemToMove);
bool swapTreeViewItem(HTREEITEM itemGoDown, HTREEITEM itemGoUp);
bool restoreFoldingStateFrom(const TreeStateNode & treeState2Compare, HTREEITEM treeviewNode);
bool retrieveFoldingStateTo(TreeStateNode & treeState2Construct, HTREEITEM treeviewNode);
protected:
WNDPROC _defaultProc;