[RESTORE_FEATURE] Restore remembering session folding feature with the optimized algorithm.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@1036 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2013-04-20 23:10:07 +00:00
parent 06756d2958
commit d7cce21309
9 changed files with 122 additions and 44 deletions

View File

@ -4217,6 +4217,16 @@ void Notepad_plus::getCurrentOpenedFiles(Session & session)
sfi.marks.push_back(j); sfi.marks.push_back(j);
} }
} }
if (i == int(session._activeMainIndex))
{
_mainEditView.getCurrentFoldStates(sfi._foldStates);
}
else
{
sfi._foldStates = buf->getHeaderLineState(&_mainEditView);
}
session._mainViewFiles.push_back(sfi); session._mainViewFiles.push_back(sfi);
} }
@ -4249,6 +4259,16 @@ void Notepad_plus::getCurrentOpenedFiles(Session & session)
sfi.marks.push_back(j); sfi.marks.push_back(j);
} }
} }
if (i == int(session._activeSubIndex))
{
_subEditView.getCurrentFoldStates(sfi._foldStates);
}
else
{
sfi._foldStates = buf->getHeaderLineState(&_subEditView);
}
session._subViewFiles.push_back(sfi); session._subViewFiles.push_back(sfi);
} }
} }

View File

@ -1002,6 +1002,9 @@ bool Notepad_plus::loadSession(Session & session)
size_t i = 0; size_t i = 0;
showView(MAIN_VIEW); showView(MAIN_VIEW);
switchEditViewTo(MAIN_VIEW); //open files in main switchEditViewTo(MAIN_VIEW); //open files in main
int mainIndex2Update = -1;
for ( ; i < session.nbMainFiles() ; ) for ( ; i < session.nbMainFiles() ; )
{ {
const TCHAR *pFn = session._mainViewFiles[i]._fileName.c_str(); const TCHAR *pFn = session._mainViewFiles[i]._fileName.c_str();
@ -1043,7 +1046,18 @@ bool Notepad_plus::loadSession(Session & session)
if (typeToSet == L_EXTERNAL ) if (typeToSet == L_EXTERNAL )
typeToSet = (LangType)(id - IDM_LANG_EXTERNAL + L_EXTERNAL); typeToSet = (LangType)(id - IDM_LANG_EXTERNAL + L_EXTERNAL);
Buffer * buf = MainFileManager->getBufferByID(lastOpened); Buffer *buf = MainFileManager->getBufferByID(lastOpened);
if (session._mainViewFiles[i]._foldStates.size() > 0)
{
if (buf == _mainEditView.getCurrentBuffer()) // current document
// Set floding state in the current doccument
mainIndex2Update = i;
else
// Set fold states in the buffer
buf->setHeaderLineState(session._mainViewFiles[i]._foldStates, &_mainEditView);
}
buf->setPosition(session._mainViewFiles[i], &_mainEditView); buf->setPosition(session._mainViewFiles[i], &_mainEditView);
buf->setLangType(typeToSet, pLn); buf->setLangType(typeToSet, pLn);
if (session._mainViewFiles[i]._encoding != -1) if (session._mainViewFiles[i]._encoding != -1)
@ -1067,10 +1081,14 @@ bool Notepad_plus::loadSession(Session & session)
allSessionFilesLoaded = false; allSessionFilesLoaded = false;
} }
} }
if (mainIndex2Update != -1)
_mainEditView.syncFoldStateWith(session._mainViewFiles[mainIndex2Update]._foldStates);
size_t k = 0; size_t k = 0;
showView(SUB_VIEW); showView(SUB_VIEW);
switchEditViewTo(SUB_VIEW); //open files in sub switchEditViewTo(SUB_VIEW); //open files in sub
int subIndex2Update = -1;
for ( ; k < session.nbSubFiles() ; ) for ( ; k < session.nbSubFiles() ; )
{ {
const TCHAR *pFn = session._subViewFiles[k]._fileName.c_str(); const TCHAR *pFn = session._subViewFiles[k]._fileName.c_str();
@ -1089,6 +1107,7 @@ bool Notepad_plus::loadSession(Session & session)
if (PathFileExists(pFn)) if (PathFileExists(pFn))
{ {
lastOpened = doOpen(pFn, false, session._subViewFiles[k]._encoding); lastOpened = doOpen(pFn, false, session._subViewFiles[k]._encoding);
//check if already open in main. If so, clone //check if already open in main. If so, clone
if (_mainDocTab.getIndexByBuffer(lastOpened) != -1) { if (_mainDocTab.getIndexByBuffer(lastOpened) != -1) {
loadBufferIntoView(lastOpened, SUB_VIEW); loadBufferIntoView(lastOpened, SUB_VIEW);
@ -1119,6 +1138,18 @@ bool Notepad_plus::loadSession(Session & session)
typeToSet = (LangType)(id - IDM_LANG_EXTERNAL + L_EXTERNAL); typeToSet = (LangType)(id - IDM_LANG_EXTERNAL + L_EXTERNAL);
Buffer * buf = MainFileManager->getBufferByID(lastOpened); Buffer * buf = MainFileManager->getBufferByID(lastOpened);
// Set fold states
if (session._subViewFiles[k]._foldStates.size() > 0)
{
if (buf == _subEditView.getCurrentBuffer()) // current document
// Set floding state in the current doccument
subIndex2Update = k;
else
// Set fold states in the buffer
buf->setHeaderLineState(session._subViewFiles[k]._foldStates, &_subEditView);
}
buf->setPosition(session._subViewFiles[k], &_subEditView); buf->setPosition(session._subViewFiles[k], &_subEditView);
if (typeToSet == L_USER) { if (typeToSet == L_USER) {
if (!lstrcmp(pLn, TEXT("User Defined"))) { if (!lstrcmp(pLn, TEXT("User Defined"))) {
@ -1147,6 +1178,9 @@ bool Notepad_plus::loadSession(Session & session)
allSessionFilesLoaded = false; allSessionFilesLoaded = false;
} }
} }
if (subIndex2Update != -1)
_subEditView.syncFoldStateWith(session._subViewFiles[subIndex2Update]._foldStates);
_mainEditView.restoreCurrentPos(); _mainEditView.restoreCurrentPos();
_subEditView.restoreCurrentPos(); _subEditView.restoreCurrentPos();

View File

@ -1654,6 +1654,18 @@ bool NppParameters::getSessionFromXmlTree(TiXmlDocument *pSessionDoc, Session *p
sfi.marks.push_back(lineNumber); sfi.marks.push_back(lineNumber);
} }
} }
for (TiXmlNode *foldNode = childNode->FirstChildElement(TEXT("Fold"));
foldNode ;
foldNode = foldNode->NextSibling(TEXT("Fold")))
{
int lineNumber;
const TCHAR *lineNumberStr = (foldNode->ToElement())->Attribute(TEXT("line"), &lineNumber);
if (lineNumberStr)
{
sfi._foldStates.push_back(lineNumber);
}
}
(*ptrSession)._mainViewFiles.push_back(sfi); (*ptrSession)._mainViewFiles.push_back(sfi);
} }
} }
@ -1702,6 +1714,18 @@ bool NppParameters::getSessionFromXmlTree(TiXmlDocument *pSessionDoc, Session *p
sfi.marks.push_back(lineNumber); sfi.marks.push_back(lineNumber);
} }
} }
for (TiXmlNode *foldNode = childNode->FirstChildElement(TEXT("Fold"));
foldNode ;
foldNode = foldNode->NextSibling(TEXT("Fold")))
{
int lineNumber;
const TCHAR *lineNumberStr = (foldNode->ToElement())->Attribute(TEXT("line"), &lineNumber);
if (lineNumberStr)
{
sfi._foldStates.push_back(lineNumber);
}
}
(*ptrSession)._subViewFiles.push_back(sfi); (*ptrSession)._subViewFiles.push_back(sfi);
} }
} }
@ -2416,6 +2440,13 @@ void NppParameters::writeSession(const Session & session, const TCHAR *fileName)
TiXmlNode *markNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Mark"))); TiXmlNode *markNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Mark")));
markNode->ToElement()->SetAttribute(TEXT("line"), markLine); markNode->ToElement()->SetAttribute(TEXT("line"), markLine);
} }
for (size_t j = 0 ; j < session._mainViewFiles[i]._foldStates.size() ; j++)
{
size_t foldLine = session._mainViewFiles[i]._foldStates[j];
TiXmlNode *foldNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Fold")));
foldNode->ToElement()->SetAttribute(TEXT("line"), foldLine);
}
} }
TiXmlNode *subViewNode = sessionNode->InsertEndChild(TiXmlElement(TEXT("subView"))); TiXmlNode *subViewNode = sessionNode->InsertEndChild(TiXmlElement(TEXT("subView")));
@ -2440,6 +2471,13 @@ void NppParameters::writeSession(const Session & session, const TCHAR *fileName)
TiXmlNode *markNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Mark"))); TiXmlNode *markNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Mark")));
markNode->ToElement()->SetAttribute(TEXT("line"), markLine); markNode->ToElement()->SetAttribute(TEXT("line"), markLine);
} }
for (size_t j = 0 ; j < session._subViewFiles[i]._foldStates.size() ; j++)
{
size_t foldLine = session._subViewFiles[i]._foldStates[j];
TiXmlNode *foldNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Fold")));
foldNode->ToElement()->SetAttribute(TEXT("line"), foldLine);
}
} }
} }
_pXmlSessionDoc->SaveFile(); _pXmlSessionDoc->SaveFile();

View File

@ -125,14 +125,8 @@ const TCHAR allowAppDataPluginsFile[] = TEXT("allowAppDataPlugins.xml");
const TCHAR notepadStyleFile[] = TEXT("asNotepad.xml"); const TCHAR notepadStyleFile[] = TEXT("asNotepad.xml");
void cutString(const TCHAR *str2cut, vector<generic_string> & patternVect); void cutString(const TCHAR *str2cut, vector<generic_string> & patternVect);
/*
struct HeaderLineState {
HeaderLineState() : _headerLineNumber(0), _isCollapsed(false){};
HeaderLineState(int lineNumber, bool isFoldUp) : _headerLineNumber(lineNumber), _isCollapsed(isFoldUp){};
int _headerLineNumber;
bool _isCollapsed;
};
*/
struct Position struct Position
{ {
int _firstVisibleLine; int _firstVisibleLine;
@ -155,6 +149,7 @@ struct sessionFileInfo : public Position {
generic_string _fileName; generic_string _fileName;
generic_string _langName; generic_string _langName;
vector<size_t> marks; vector<size_t> marks;
vector<size_t> _foldStates;
int _encoding; int _encoding;
}; };

View File

@ -274,12 +274,12 @@ Position & Buffer::getPosition(ScintillaEditView * identifier) {
return _positions.at(index); return _positions.at(index);
} }
void Buffer::setHeaderLineState(const std::vector<HeaderLineState> & folds, ScintillaEditView * identifier) { void Buffer::setHeaderLineState(const std::vector<size_t> & folds, ScintillaEditView * identifier) {
int index = indexOfReference(identifier); int index = indexOfReference(identifier);
if (index == -1) if (index == -1)
return; return;
//deep copy //deep copy
std::vector<HeaderLineState> & local = _foldStates[index]; std::vector<size_t> & local = _foldStates[index];
local.clear(); local.clear();
size_t size = folds.size(); size_t size = folds.size();
for(size_t i = 0; i < size; i++) { for(size_t i = 0; i < size; i++) {
@ -287,7 +287,7 @@ void Buffer::setHeaderLineState(const std::vector<HeaderLineState> & folds, Scin
} }
} }
const std::vector<HeaderLineState> & Buffer::getHeaderLineState(const ScintillaEditView * identifier) const { const std::vector<size_t> & Buffer::getHeaderLineState(const ScintillaEditView * identifier) const {
int index = indexOfReference(identifier); int index = indexOfReference(identifier);
return _foldStates.at(index); return _foldStates.at(index);
} }
@ -320,7 +320,7 @@ int Buffer::addReference(ScintillaEditView * identifier) {
return _references; return _references;
_referees.push_back(identifier); _referees.push_back(identifier);
_positions.push_back(Position()); _positions.push_back(Position());
_foldStates.push_back(std::vector<HeaderLineState>()); _foldStates.push_back(std::vector<size_t>());
_references++; _references++;
return _references; return _references;
} }

View File

@ -60,13 +60,6 @@ enum BufferStatusInfo {
BufferChangeMask = 0x3FF //Mask: covers all changes BufferChangeMask = 0x3FF //Mask: covers all changes
}; };
struct HeaderLineState {
HeaderLineState() : _headerLineNumber(0), _isExpanded(true){};
HeaderLineState(int lineNumber, bool isExpanded) : _headerLineNumber(lineNumber), _isExpanded(isExpanded){};
int _headerLineNumber;
bool _isExpanded;
};
//const int userLangNameMax = 16; //const int userLangNameMax = 16;
const TCHAR UNTITLED_STR[] = TEXT("new "); const TCHAR UNTITLED_STR[] = TEXT("new ");
@ -256,8 +249,8 @@ public :
void setPosition(const Position & pos, ScintillaEditView * identifier); void setPosition(const Position & pos, ScintillaEditView * identifier);
Position & getPosition(ScintillaEditView * identifier); Position & getPosition(ScintillaEditView * identifier);
void setHeaderLineState(const std::vector<HeaderLineState> & folds, ScintillaEditView * identifier); void setHeaderLineState(const std::vector<size_t> & folds, ScintillaEditView * identifier);
const std::vector<HeaderLineState> & getHeaderLineState(const ScintillaEditView * identifier) const; const std::vector<size_t> & getHeaderLineState(const ScintillaEditView * identifier) const;
bool isUserDefineLangExt() const { bool isUserDefineLangExt() const {
return (_userLangExt[0] != '\0'); return (_userLangExt[0] != '\0');
@ -349,7 +342,7 @@ private :
//All the vectors must have the same size at all times //All the vectors must have the same size at all times
vector< ScintillaEditView * > _referees; vector< ScintillaEditView * > _referees;
vector< Position > _positions; vector< Position > _positions;
vector< vector<HeaderLineState> > _foldStates; vector< vector<size_t> > _foldStates;
//vector< pair<size_t, pair<size_t, bool> > > _linesUndoState; //vector< pair<size_t, pair<size_t, bool> > > _linesUndoState;

View File

@ -1556,7 +1556,7 @@ void ScintillaEditView::activateBuffer(BufferID buffer)
saveCurrentPos(); saveCurrentPos();
// get foldStateInfo of current doc // get foldStateInfo of current doc
std::vector<HeaderLineState> lineStateVector; std::vector<size_t> lineStateVector;
getCurrentFoldStates(lineStateVector); getCurrentFoldStates(lineStateVector);
// put the state into the future ex buffer // put the state into the future ex buffer
@ -1579,7 +1579,7 @@ void ScintillaEditView::activateBuffer(BufferID buffer)
} }
// restore the collapsed info // restore the collapsed info
const std::vector<HeaderLineState> & lineStateVectorNew = newBuf->getHeaderLineState(this); const std::vector<size_t> & lineStateVectorNew = newBuf->getHeaderLineState(this);
syncFoldStateWith(lineStateVectorNew); syncFoldStateWith(lineStateVectorNew);
restoreCurrentPos(); restoreCurrentPos();
@ -1596,7 +1596,7 @@ void ScintillaEditView::activateBuffer(BufferID buffer)
return; //all done return; //all done
} }
void ScintillaEditView::getCurrentFoldStates(std::vector<HeaderLineState> & lineStateVector) void ScintillaEditView::getCurrentFoldStates(std::vector<size_t> & lineStateVector)
{ {
int maxLine = execute(SCI_GETLINECOUNT); int maxLine = execute(SCI_GETLINECOUNT);
@ -1605,22 +1605,20 @@ void ScintillaEditView::getCurrentFoldStates(std::vector<HeaderLineState> & line
int level = execute(SCI_GETFOLDLEVEL, line); int level = execute(SCI_GETFOLDLEVEL, line);
if (level & SC_FOLDLEVELHEADERFLAG) if (level & SC_FOLDLEVELHEADERFLAG)
{ {
bool expanded = (execute(SCI_GETFOLDEXPANDED, line) != 0); bool expanded = isFolded(line);
lineStateVector.push_back(HeaderLineState(line, expanded)); if (!expanded)
lineStateVector.push_back(line);
} }
} }
} }
void ScintillaEditView::syncFoldStateWith(const std::vector<HeaderLineState> & lineStateVectorNew) void ScintillaEditView::syncFoldStateWith(const std::vector<size_t> & lineStateVectorNew)
{ {
int nbLineState = lineStateVectorNew.size(); int nbLineState = lineStateVectorNew.size();
for (int i = 0 ; i < nbLineState ; i++) for (int i = 0 ; i < nbLineState ; i++)
{ {
const HeaderLineState & hls = lineStateVectorNew.at(i); int line = lineStateVectorNew.at(i);
bool expanded = isFolded(hls._headerLineNumber); fold(line, false);
// set line to state folded
if (hls._isExpanded != expanded)
execute(SCI_TOGGLEFOLD, hls._headerLineNumber);
} }
} }
@ -1746,7 +1744,7 @@ void ScintillaEditView::foldAll(bool mode)
{ {
int level = execute(SCI_GETFOLDLEVEL, line); int level = execute(SCI_GETFOLDLEVEL, line);
if (level & SC_FOLDLEVELHEADERFLAG) if (level & SC_FOLDLEVELHEADERFLAG)
if ((execute(SCI_GETFOLDEXPANDED, line) != 0) != mode) if (isFolded(line) != mode)
execute(SCI_TOGGLEFOLD, line); execute(SCI_TOGGLEFOLD, line);
} }
} }
@ -2043,7 +2041,7 @@ void ScintillaEditView::addText(int length, const char *buf)
{ {
execute(SCI_ADDTEXT, length, (LPARAM)buf); execute(SCI_ADDTEXT, length, (LPARAM)buf);
} }
void ScintillaEditView::marginClick(int position, int modifiers) void ScintillaEditView::marginClick(int position, int modifiers)
{ {
int lineClick = int(execute(SCI_LINEFROMPOSITION, position, 0)); int lineClick = int(execute(SCI_LINEFROMPOSITION, position, 0));
@ -2058,7 +2056,7 @@ void ScintillaEditView::marginClick(int position, int modifiers)
} }
else if (modifiers & SCMOD_CTRL) else if (modifiers & SCMOD_CTRL)
{ {
if (execute(SCI_GETFOLDEXPANDED, lineClick, 0)) if (isFolded(lineClick))
{ {
// Contract this line and all children // Contract this line and all children
execute(SCI_SETFOLDEXPANDED, lineClick, 0); execute(SCI_SETFOLDEXPANDED, lineClick, 0);
@ -2116,7 +2114,7 @@ void ScintillaEditView::expand(int &line, bool doExpand, bool force, int visLeve
{ {
if (doExpand) if (doExpand)
{ {
if (!execute(SCI_GETFOLDEXPANDED, line, 0)) if (!isFolded(line))
execute(SCI_SETFOLDEXPANDED, line, 1); execute(SCI_SETFOLDEXPANDED, line, 1);
expand(line, true, force, visLevels - 1); expand(line, true, force, visLevels - 1);
@ -2741,7 +2739,7 @@ void ScintillaEditView::foldChanged(int line, int levelNow, int levelPrev)
} }
else if (levelPrev & SC_FOLDLEVELHEADERFLAG) else if (levelPrev & SC_FOLDLEVELHEADERFLAG)
{ {
if (!execute(SCI_GETFOLDEXPANDED, line)) if (isFolded(line))
{ {
// Removing the fold from one that has been contracted so should expand // Removing the fold from one that has been contracted so should expand
// otherwise lines are left invisible with no way to make them visible // otherwise lines are left invisible with no way to make them visible
@ -2754,7 +2752,7 @@ void ScintillaEditView::foldChanged(int line, int levelNow, int levelPrev)
{ {
// See if should still be hidden // See if should still be hidden
int parentLine = execute(SCI_GETFOLDPARENT, line); int parentLine = execute(SCI_GETFOLDPARENT, line);
if ((parentLine < 0) || (execute(SCI_GETFOLDEXPANDED, parentLine) && execute(SCI_GETLINEVISIBLE, parentLine))) if ((parentLine < 0) || !isFolded(parentLine && execute(SCI_GETLINEVISIBLE, parentLine)))
execute(SCI_SHOWLINES, line, line); execute(SCI_SHOWLINES, line, line);
} }
} }
@ -2955,7 +2953,7 @@ void ScintillaEditView::runMarkers(bool doHide, int searchStart, bool endOfDoc,
int levelLine = execute(SCI_GETFOLDLEVEL, i, 0); int levelLine = execute(SCI_GETFOLDLEVEL, i, 0);
if (levelLine & SC_FOLDLEVELHEADERFLAG) { //fold section. Dont show lines if fold is closed if (levelLine & SC_FOLDLEVELHEADERFLAG) { //fold section. Dont show lines if fold is closed
if (isInSection && execute(SCI_GETFOLDEXPANDED, i) == 0) { if (isInSection && !isFolded(i)) {
execute(SCI_SHOWLINES, startShowing, i); execute(SCI_SHOWLINES, startShowing, i);
startShowing = execute(SCI_GETLASTCHILD, i, (levelLine & SC_FOLDLEVELNUMBERMASK)); startShowing = execute(SCI_GETLASTCHILD, i, (levelLine & SC_FOLDLEVELNUMBERMASK));
} }

View File

@ -241,8 +241,8 @@ public:
void activateBuffer(BufferID buffer); void activateBuffer(BufferID buffer);
void getCurrentFoldStates(std::vector<HeaderLineState> & lineStateVector); void getCurrentFoldStates(std::vector<size_t> & lineStateVector);
void syncFoldStateWith(const std::vector<HeaderLineState> & lineStateVectorNew); void syncFoldStateWith(const std::vector<size_t> & lineStateVectorNew);
void getText(char *dest, int start, int end) const; void getText(char *dest, int start, int end) const;
void getGenericText(TCHAR *dest, size_t destlen, int start, int end) const; void getGenericText(TCHAR *dest, size_t destlen, int start, int end) const;

View File

@ -47,7 +47,7 @@ void DocumentMap::reloadMap()
_pScintillaEditView->setCurrentBuffer(editBuf); _pScintillaEditView->setCurrentBuffer(editBuf);
// folding // folding
std::vector<HeaderLineState> lineStateVector; std::vector<size_t> lineStateVector;
(*_ppEditView)->getCurrentFoldStates(lineStateVector); (*_ppEditView)->getCurrentFoldStates(lineStateVector);
_pScintillaEditView->syncFoldStateWith(lineStateVector); _pScintillaEditView->syncFoldStateWith(lineStateVector);