[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);
}
}
if (i == int(session._activeMainIndex))
{
_mainEditView.getCurrentFoldStates(sfi._foldStates);
}
else
{
sfi._foldStates = buf->getHeaderLineState(&_mainEditView);
}
session._mainViewFiles.push_back(sfi);
}
@ -4249,6 +4259,16 @@ void Notepad_plus::getCurrentOpenedFiles(Session & session)
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);
}
}

View File

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

View File

@ -1654,6 +1654,18 @@ bool NppParameters::getSessionFromXmlTree(TiXmlDocument *pSessionDoc, Session *p
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);
}
}
@ -1702,6 +1714,18 @@ bool NppParameters::getSessionFromXmlTree(TiXmlDocument *pSessionDoc, Session *p
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);
}
}
@ -2416,6 +2440,13 @@ void NppParameters::writeSession(const Session & session, const TCHAR *fileName)
TiXmlNode *markNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Mark")));
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")));
@ -2440,6 +2471,13 @@ void NppParameters::writeSession(const Session & session, const TCHAR *fileName)
TiXmlNode *markNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Mark")));
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();

View File

@ -125,14 +125,8 @@ const TCHAR allowAppDataPluginsFile[] = TEXT("allowAppDataPlugins.xml");
const TCHAR notepadStyleFile[] = TEXT("asNotepad.xml");
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
{
int _firstVisibleLine;
@ -155,6 +149,7 @@ struct sessionFileInfo : public Position {
generic_string _fileName;
generic_string _langName;
vector<size_t> marks;
vector<size_t> _foldStates;
int _encoding;
};

View File

@ -274,12 +274,12 @@ Position & Buffer::getPosition(ScintillaEditView * identifier) {
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);
if (index == -1)
return;
//deep copy
std::vector<HeaderLineState> & local = _foldStates[index];
std::vector<size_t> & local = _foldStates[index];
local.clear();
size_t size = folds.size();
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);
return _foldStates.at(index);
}
@ -320,7 +320,7 @@ int Buffer::addReference(ScintillaEditView * identifier) {
return _references;
_referees.push_back(identifier);
_positions.push_back(Position());
_foldStates.push_back(std::vector<HeaderLineState>());
_foldStates.push_back(std::vector<size_t>());
_references++;
return _references;
}

View File

@ -60,13 +60,6 @@ enum BufferStatusInfo {
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 TCHAR UNTITLED_STR[] = TEXT("new ");
@ -256,8 +249,8 @@ public :
void setPosition(const Position & pos, ScintillaEditView * identifier);
Position & getPosition(ScintillaEditView * identifier);
void setHeaderLineState(const std::vector<HeaderLineState> & folds, ScintillaEditView * identifier);
const std::vector<HeaderLineState> & getHeaderLineState(const ScintillaEditView * identifier) const;
void setHeaderLineState(const std::vector<size_t> & folds, ScintillaEditView * identifier);
const std::vector<size_t> & getHeaderLineState(const ScintillaEditView * identifier) const;
bool isUserDefineLangExt() const {
return (_userLangExt[0] != '\0');
@ -349,7 +342,7 @@ private :
//All the vectors must have the same size at all times
vector< ScintillaEditView * > _referees;
vector< Position > _positions;
vector< vector<HeaderLineState> > _foldStates;
vector< vector<size_t> > _foldStates;
//vector< pair<size_t, pair<size_t, bool> > > _linesUndoState;

View File

@ -1556,7 +1556,7 @@ void ScintillaEditView::activateBuffer(BufferID buffer)
saveCurrentPos();
// get foldStateInfo of current doc
std::vector<HeaderLineState> lineStateVector;
std::vector<size_t> lineStateVector;
getCurrentFoldStates(lineStateVector);
// put the state into the future ex buffer
@ -1579,7 +1579,7 @@ void ScintillaEditView::activateBuffer(BufferID buffer)
}
// restore the collapsed info
const std::vector<HeaderLineState> & lineStateVectorNew = newBuf->getHeaderLineState(this);
const std::vector<size_t> & lineStateVectorNew = newBuf->getHeaderLineState(this);
syncFoldStateWith(lineStateVectorNew);
restoreCurrentPos();
@ -1596,7 +1596,7 @@ void ScintillaEditView::activateBuffer(BufferID buffer)
return; //all done
}
void ScintillaEditView::getCurrentFoldStates(std::vector<HeaderLineState> & lineStateVector)
void ScintillaEditView::getCurrentFoldStates(std::vector<size_t> & lineStateVector)
{
int maxLine = execute(SCI_GETLINECOUNT);
@ -1605,22 +1605,20 @@ void ScintillaEditView::getCurrentFoldStates(std::vector<HeaderLineState> & line
int level = execute(SCI_GETFOLDLEVEL, line);
if (level & SC_FOLDLEVELHEADERFLAG)
{
bool expanded = (execute(SCI_GETFOLDEXPANDED, line) != 0);
lineStateVector.push_back(HeaderLineState(line, expanded));
bool expanded = isFolded(line);
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();
for (int i = 0 ; i < nbLineState ; i++)
{
const HeaderLineState & hls = lineStateVectorNew.at(i);
bool expanded = isFolded(hls._headerLineNumber);
// set line to state folded
if (hls._isExpanded != expanded)
execute(SCI_TOGGLEFOLD, hls._headerLineNumber);
int line = lineStateVectorNew.at(i);
fold(line, false);
}
}
@ -1746,7 +1744,7 @@ void ScintillaEditView::foldAll(bool mode)
{
int level = execute(SCI_GETFOLDLEVEL, line);
if (level & SC_FOLDLEVELHEADERFLAG)
if ((execute(SCI_GETFOLDEXPANDED, line) != 0) != mode)
if (isFolded(line) != mode)
execute(SCI_TOGGLEFOLD, line);
}
}
@ -2043,7 +2041,7 @@ void ScintillaEditView::addText(int length, const char *buf)
{
execute(SCI_ADDTEXT, length, (LPARAM)buf);
}
void ScintillaEditView::marginClick(int position, int modifiers)
{
int lineClick = int(execute(SCI_LINEFROMPOSITION, position, 0));
@ -2058,7 +2056,7 @@ void ScintillaEditView::marginClick(int position, int modifiers)
}
else if (modifiers & SCMOD_CTRL)
{
if (execute(SCI_GETFOLDEXPANDED, lineClick, 0))
if (isFolded(lineClick))
{
// Contract this line and all children
execute(SCI_SETFOLDEXPANDED, lineClick, 0);
@ -2116,7 +2114,7 @@ void ScintillaEditView::expand(int &line, bool doExpand, bool force, int visLeve
{
if (doExpand)
{
if (!execute(SCI_GETFOLDEXPANDED, line, 0))
if (!isFolded(line))
execute(SCI_SETFOLDEXPANDED, line, 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)
{
if (!execute(SCI_GETFOLDEXPANDED, line))
if (isFolded(line))
{
// Removing the fold from one that has been contracted so should expand
// 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
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);
}
}
@ -2955,7 +2953,7 @@ void ScintillaEditView::runMarkers(bool doHide, int searchStart, bool endOfDoc,
int levelLine = execute(SCI_GETFOLDLEVEL, i, 0);
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);
startShowing = execute(SCI_GETLASTCHILD, i, (levelLine & SC_FOLDLEVELNUMBERMASK));
}

View File

@ -241,8 +241,8 @@ public:
void activateBuffer(BufferID buffer);
void getCurrentFoldStates(std::vector<HeaderLineState> & lineStateVector);
void syncFoldStateWith(const std::vector<HeaderLineState> & lineStateVectorNew);
void getCurrentFoldStates(std::vector<size_t> & lineStateVector);
void syncFoldStateWith(const std::vector<size_t> & lineStateVectorNew);
void getText(char *dest, 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);
// folding
std::vector<HeaderLineState> lineStateVector;
std::vector<size_t> lineStateVector;
(*_ppEditView)->getCurrentFoldStates(lineStateVector);
_pScintillaEditView->syncFoldStateWith(lineStateVector);