[NEW_FEATURE] (Author: FLS) Remember folding states for each file in session.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@1024 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2013-02-18 23:13:18 +00:00
parent 283f7567a6
commit 0180d012cb
10 changed files with 625 additions and 14 deletions

View File

@ -4217,6 +4217,44 @@ void Notepad_plus::getCurrentOpenedFiles(Session & session)
sfi.marks.push_back(j);
}
}
//--FLS: xSaveFoldingStateSession:
// For all but the active document in the view, the folding states have to be retrieved from the buffer.
// For the active document, the folding state has to be retrieved directly from the view!
Buffer * viewCurrentBuf = _mainEditView.getCurrentBuffer();
if (buf != viewCurrentBuf) {
std::vector<HeaderLineState> lineStateVector;
lineStateVector = buf->getHeaderLineState(&_mainEditView);
int nbLineState = lineStateVector.size();
for (int i = 0 ; i < nbLineState ; i++)
{
const HeaderLineState & hls = lineStateVector.at(i);
//-- Store, if line is contracted
if (!hls._isExpanded)
sfi.foldedLines.push_back(hls._headerLineNumber);
}
} else {
//-- Development of saving Folding State to File Edit View History
//SCI_CONTRACTEDFOLDNEXT(int lineStart)
// Search efficiently for lines that are contracted fold headers.
// This is useful when saving the user's folding when switching documents or saving folding with a file.
// The search starts at line number lineStart and continues forwards to the end of the file.
// lineStart is returned if it is a contracted fold header otherwise the next contracted fold header is returned.
// If there are no more contracted fold headers then -1 is returned.
//-- Folding state is not copied to invisible view but only accessable in original view !!
int contractedFoldHeaderLine=0;
do {
contractedFoldHeaderLine = _mainEditView.execute(SCI_CONTRACTEDFOLDNEXT, contractedFoldHeaderLine);
if (contractedFoldHeaderLine != -1) {
//-- Store contracted line
sfi.foldedLines.push_back(contractedFoldHeaderLine);
//-- Start next search with next line
contractedFoldHeaderLine++;
}
} while (contractedFoldHeaderLine != -1);
} //-- else if (buf != viewCurrentBuf) --
//-- saving sfi in session --
session._mainViewFiles.push_back(sfi);
}
@ -4249,6 +4287,44 @@ void Notepad_plus::getCurrentOpenedFiles(Session & session)
sfi.marks.push_back(j);
}
}
//--FLS: xSaveFoldingStateSession:
// For all but the active document in the view, the folding states have to be retrieved from the buffer.
// For the active document, the folding state has to be retrieved directly from the view!
Buffer * viewCurrentBuf = _subEditView.getCurrentBuffer();
if (buf != viewCurrentBuf) {
std::vector<HeaderLineState> lineStateVector;
lineStateVector = buf->getHeaderLineState(&_subEditView);
int nbLineState = lineStateVector.size();
for (int i = 0 ; i < nbLineState ; i++)
{
const HeaderLineState & hls = lineStateVector.at(i);
//-- Store, if line is contracted
if (!hls._isExpanded)
sfi.foldedLines.push_back(hls._headerLineNumber);
}
} else {
//-- Development of saving Folding State to File Edit View History
//SCI_CONTRACTEDFOLDNEXT(int lineStart)
// Search efficiently for lines that are contracted fold headers.
// This is useful when saving the user's folding when switching documents or saving folding with a file.
// The search starts at line number lineStart and continues forwards to the end of the file.
// lineStart is returned if it is a contracted fold header otherwise the next contracted fold header is returned.
// If there are no more contracted fold headers then -1 is returned.
//-- Folding state is not copied to invisible view but only accessable in original view !!
int contractedFoldHeaderLine=0;
do {
contractedFoldHeaderLine = _subEditView.execute(SCI_CONTRACTEDFOLDNEXT, contractedFoldHeaderLine);
if (contractedFoldHeaderLine != -1) {
//-- Store contracted line
sfi.foldedLines.push_back(contractedFoldHeaderLine);
//-- Start next search with next line
contractedFoldHeaderLine++;
}
} while (contractedFoldHeaderLine != -1);
} //-- else if (buf != viewCurrentBuf) --
//-- saving sfi in session --
session._subViewFiles.push_back(sfi);
}
}
@ -5754,4 +5830,169 @@ bool Notepad_plus::undoStreamComment()
}
} while(1); //do as long as stream-comments are within selection
//return retVal;
} //----- undoStreamComment() -------------------------------
} //----- undoStreamComment() -------------------------------
//--FLS: xFileEditViewHistory: new function addFileToFileEditViewSession()
void Notepad_plus::addFileToFileEditViewSession(Session * pSession, const TCHAR *fileNamePath, BufferID id, int whichOne)
{
//--FLS: Adds the edit-view parameters of the current file, which is closed by fileClose()
// into the FileEditViewHistory-Session.
// (see also code from _lastRecentFileList.add(fileNamePath) and getCurrentOpenedFiles(currentSession) )
//--FLS: Use _mainViewFiles for ALL session files, even for the sub-view files, because FileEditViewHistory does not distinguish.
TCHAR strFileName[MAX_PATH];
vector<sessionFileInfo>::iterator posIt;
//-- Get Pointer to Buffer and to _EditView --
Buffer * buf = MainFileManager->getBufferByID(id);
ScintillaEditView *_pEditView= whichOne==MAIN_VIEW?(&_mainEditView):(&_subEditView);
if (!buf->isUntitled())
{
// 1.) Search throught the session list and if an entry with fileNamePath is available, delete the entry
for (size_t i = 0 ; i < pSession->_mainViewFiles.size() ; i++)
{
lstrcpy(strFileName, pSession->_mainViewFiles[i]._fileName.c_str());
if (generic_stricmp((TCHAR*)&strFileName, fileNamePath)==0) {
posIt = pSession->_mainViewFiles.begin() + i;
pSession->_mainViewFiles.erase(posIt);
}
}
// 2.) Insert the edit-view parameters at the end of the session list.
// Code stolen from getCurrentOpenedFiles(currentSession) and doClose()
_pEditView->saveCurrentPos();
pSession->_activeMainIndex = _mainDocTab.getCurrentTabIndex();
//Use _invisibleEditView to temporarily open documents to retrieve markers
Document oldDoc = _invisibleEditView.execute(SCI_GETDOCPOINTER);
generic_string languageName = getLangFromMenu(buf);
const TCHAR *langName = languageName.c_str();
sessionFileInfo sfi(buf->getFullPathName(), langName, buf->getEncoding(), buf->getPosition(_pEditView));
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument());
int maxLine = _invisibleEditView.execute(SCI_GETLINECOUNT);
for (int j = 0 ; j < maxLine ; j++)
{
if ((_invisibleEditView.execute(SCI_MARKERGET, j)&(1 << MARK_BOOKMARK)) != 0)
{
sfi.marks.push_back(j);
}
}
//--FLS: xSaveFoldingStateSession:
//-- Development of saving Folding State to File Edit View History
//SCI_CONTRACTEDFOLDNEXT(int lineStart)
// Search efficiently for lines that are contracted fold headers.
// This is useful when saving the user's folding when switching documents or saving folding with a file.
// The search starts at line number lineStart and continues forwards to the end of the file.
// lineStart is returned if it is a contracted fold header otherwise the next contracted fold header is returned.
// If there are no more contracted fold headers then -1 is returned.
//-- Folding state is not copied to invisible view but only accessable in original view !!
int contractedFoldHeaderLine=0;
do {
contractedFoldHeaderLine = _pEditView->execute(SCI_CONTRACTEDFOLDNEXT, contractedFoldHeaderLine);
if (contractedFoldHeaderLine != -1) {
//-- Store contracted line
sfi.foldedLines.push_back(contractedFoldHeaderLine);
//-- Start next search with next line
contractedFoldHeaderLine++;
}
} while (contractedFoldHeaderLine != -1);
//-- saving sfi in session --
pSession->_mainViewFiles.push_back(sfi);
//--FLS: Restore original saved document to invisibleEditView
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc);
} //-- if(!buf->isUntitled() )
} //-- addFileToFileEditViewSession() -----------------
//--FLS: xFileEditViewHistory: new function restoreFileEditView()
void Notepad_plus::restoreFileEditView(const TCHAR *longFileName, BufferID buffer)
{
//--FLS: FileEditViewHistory: restores edit-view settings (cursor position, marks, etc.) of files
// as they were when the file was closes the last time.
//--FLS: Use _mainViewFiles for ALL session files, even for the sub-view files, because FileEditViewHistory does not distinguish.
//-- Code partly stolen from loadSession() in NppIO.cpp
std::vector<HeaderLineState> lineStateVector;
//--Check, if FileEditViewHistoryRestore is Enabled
if ((NppParameters::getInstance())->getFileEditViewHistoryRestoreEnabled()) {
//--FLS: Save current view-Position and folding of current document into document buffer --
// Necessary to avoid drawback when doing SCI_SETDOCPOINTER below, because apparently SCI changes the SCI view-position
// and un-folds all foldings in some cases when applying SCI_SETDOCPOINTER!
// (see ScintillaEditView::activateBuffer()! )
_pEditView->saveCurrentPos();
//--FLS: get foldStateInfo of current doc and put the state into the buffer
_pEditView->getCurrentFoldStates(lineStateVector);
_pEditView->getCurrentBuffer()->setHeaderLineState(lineStateVector, _pEditView);
//--FLS: Restores the file edit-view (line position, window position, marks) of currently loaded file, if in FileEditViewSession list.
//--FLS: code stolen from init:..if (nppGUI._rememberLastSession)
Session lastSession = *(NppParameters::getInstance())->getPtrFileEditViewSession(); // _lastFileEditViewSession
for (size_t i = 0 ; i < lastSession._mainViewFiles.size() ; i++)
{
const TCHAR *pFn = lastSession._mainViewFiles[i]._fileName.c_str();
//-- searches through the list of FileEditViewSession for the recent FileName and restores the edit-view if found.
int res = generic_stricmp(longFileName,pFn);
if (res==0)
{
//--FLS: Compare restore actions with restore actions in loadSession() in NppIO.cpp - if (lastOpened)-case.!!
//showView(currentView()); //--- not needed, because view is not changed!
const TCHAR *pLn = lastSession._mainViewFiles[i]._langName.c_str();
int id = getLangFromMenuName(pLn);
LangType typeToSet = L_TEXT;
if (id != 0 && id != IDM_LANG_USER)
typeToSet = menuID2LangType(id);
if (typeToSet == L_EXTERNAL )
typeToSet = (LangType)(id - IDM_LANG_EXTERNAL + L_EXTERNAL);
Buffer * buf = MainFileManager->getBufferByID(buffer);
buf->setPosition(lastSession._mainViewFiles[i], _pEditView);
buf->setLangType(typeToSet, pLn);
if (lastSession._mainViewFiles[i]._encoding != -1)
buf->setEncoding(lastSession._mainViewFiles[i]._encoding);
//Force in the document so we can add the markers
//Dont use default methods because of performance
Document prevDoc = _pEditView->execute(SCI_GETDOCPOINTER);
_pEditView->execute(SCI_SETDOCPOINTER, 0, buf->getDocument());
for (size_t j = 0 ; j < lastSession._mainViewFiles[i].marks.size() ; j++)
{
_pEditView->execute(SCI_MARKERADD, lastSession._mainViewFiles[i].marks[j], MARK_BOOKMARK);
}
//--FLS: xSaveFoldingStateSession: restore fold levels
//- Bookmarks, selection marks and style marks are valid for a document in SCI (equal in all views of the same document in SCI)
//- But "folding" is a property of a view and not a document (different for the same document in two views)!
// So, if changing documents with SCI_SETDOCPOINTER, SCI un-folds all foldings!!
//- Therefore, the lexer needs first to do its work! But the lexer is not set at this stage (only for the first document replacing "new x" dummy document).
//- Set document language type and request lexter to style the document.
_pEditView->defineDocType(buf->getLangType());
_pEditView->execute(SCI_COLOURISE, 0, -1); // request the lexer to style the document.
for (size_t j = 0 ; j < lastSession._mainViewFiles[i].foldedLines.size() ; j++)
{
//-- Pre-Condition is that after file is opened NO lines are folded,
// but the Lexer has already styled the document so that the Folding-Header lines exist!!
_pEditView->execute(SCI_TOGGLEFOLD, lastSession._mainViewFiles[i].foldedLines[j]);
}
//-- Write folding state info also into current buffer for activation later in current view.
// get foldStateInfo of current doc
std::vector<HeaderLineState> lineStateVector;
_pEditView->getCurrentFoldStates(lineStateVector);
// put the state into the future ex buffer
buf->setHeaderLineState(lineStateVector, _pEditView);
//-- switch back the SCI-Buffer to the buffer of the current edit view.
_pEditView->execute(SCI_SETDOCPOINTER, 0, prevDoc);
} //-- if (res==0), when a File to restore EditView was found --
}
//--FLS: Restore saved view-Position and folding of original document from document buffer --
lineStateVector = _pEditView->getCurrentBuffer()->getHeaderLineState(_pEditView);
_pEditView->syncFoldStateWith(lineStateVector);
_pEditView->restoreCurrentPos();
}
return;
} //--restoreFileEditView()

View File

@ -219,7 +219,8 @@ public:
// fileOperations
//The doXXX functions apply to a single buffer and dont need to worry about views, with the excpetion of doClose, since closing one view doesnt have to mean the document is gone
BufferID doOpen(const TCHAR *fileName, bool isReadOnly = false, int encoding = -1);
//--FLS: xFileEditViewHistory: doOpen(fileName, isReadOnly, encoding) replaced by doOpen(fileName, isReadOnly, encoding, noRestoreFileEditView), due to reundancy of session-loading with RestoreFileEditView
BufferID doOpen(const TCHAR *fileName, bool isReadOnly = false, int encoding = -1, bool noRestoreFileEditView=false);
bool doReload(BufferID id, bool alert = true);
bool doSave(BufferID, const TCHAR * filename, bool isSaveCopy = false);
void doClose(BufferID, int whichOne);
@ -268,6 +269,11 @@ public:
};
void getCurrentOpenedFiles(Session & session);
//--FLS: xFileEditViewHistory: new function addFileToFileEditViewSession()
void addFileToFileEditViewSession(Session * pSession, const TCHAR *fileNamePath, BufferID id, int whichOne);
//--FLS: xFileEditViewHistory: new function declaration
void restoreFileEditView(const TCHAR *longFileName, BufferID buffer);
bool fileLoadSession(const TCHAR *fn = NULL);
const TCHAR * fileSaveSession(size_t nbFile, TCHAR ** fileNames, const TCHAR *sessionFile2save);

View File

@ -1459,6 +1459,9 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa
saveScintillaParams(); //writeScintillaParams
saveGUIParams(); //writeGUIParams
saveProjectPanelsParams(); //writeProjectPanelsSettings
//--FLS: xFileEditViewHistory: write also FileEditViewHistory
Session lastSession = *(NppParameters::getInstance())->getPtrFileEditViewSession(); // _lastFileEditViewSession
(NppParameters::getInstance())->writeFileEditViewHistory(lastSession);
pNppParam->saveConfig_xml();

View File

@ -34,7 +34,8 @@
#include <TCHAR.h>
BufferID Notepad_plus::doOpen(const TCHAR *fileName, bool isReadOnly, int encoding)
//--FLS: xFileEditViewHistory: Additional parameter "noRestoreFileEditView" to avoid redundancy when a session is loaded!
BufferID Notepad_plus::doOpen(const TCHAR *fileName, bool isReadOnly, int encoding, bool noRestoreFileEditView)
{
NppParameters *pNppParam = NppParameters::getInstance();
TCHAR longFileName[MAX_PATH];
@ -166,6 +167,10 @@ BufferID Notepad_plus::doOpen(const TCHAR *fileName, bool isReadOnly, int encodi
::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0);
}
}
//--FLS: xFileEditViewHistory: File opened and now reset edit-view if file is in FileEditViewHistory and FileEditViewHistory is enabled!
if (!noRestoreFileEditView)
restoreFileEditView(longFileName, buffer);
PathRemoveFileSpec(longFileName);
_linkTriggered = true;
_isFileOpening = false;
@ -348,6 +353,10 @@ void Notepad_plus::doClose(BufferID id, int whichOne)
if (PathFileExists(buf->getFullPathName()))
_lastRecentFileList.add(buf->getFullPathName());
//--FLS: xFileEditViewHistory: save current edit-view into list of FileEditViewHistory
Session *lastSession = (NppParameters::getInstance())->getPtrFileEditViewSession(); // returns pointer to _lastFileEditViewSession
addFileToFileEditViewSession(lastSession, buf->getFullPathName(), id, whichOne);
// We enable Wow64 system, if it was disabled
if (isWow64Off)
{
@ -1019,7 +1028,8 @@ bool Notepad_plus::loadSession(Session & session)
}
if (PathFileExists(pFn))
{
lastOpened = doOpen(pFn, false, session._mainViewFiles[i]._encoding);
//--FLS: xFileEditViewHistory: Calling doOpen(..,noRestoreFileEditView=true), in order to suppress RestoreFileEditView() when a session is loading due to redundancy.
lastOpened = doOpen(pFn, false, session._mainViewFiles[i]._encoding, true);
}
else
{
@ -1048,15 +1058,51 @@ bool Notepad_plus::loadSession(Session & session)
if (session._mainViewFiles[i]._encoding != -1)
buf->setEncoding(session._mainViewFiles[i]._encoding);
//--FLS: xSaveFoldingStateSession: The CurrentPos from the session has to be also activated
// in Scintilla document before activateBuffer() is called, because activateBuffer() saves
// CurrentPos from Scintilla document into the buffer!
// This is especially necessary for the first session file loaded into "New xx" buffer and view.
_mainEditView.restoreCurrentPos();
//--FLS: xSaveFoldingStateSession: To switch and style the new document, activateBuffer() is better than
// to do the whole buffer/view treatment manually using the low level SCI_SETDOCPOINTER approach.
// Furthermore, for some reason, the folding below does not work properly without activateBuffer().
activateBuffer(lastOpened, MAIN_VIEW);
//--FLS: xSaveFoldingStateSession: SCI_SETDOCPOINTER approach not necessary, if document is switched with activateBuffer() !!
//-- To be deleted afterwards --
//Force in the document so we can add the markers
//Dont use default methods because of performance
Document prevDoc = _mainEditView.execute(SCI_GETDOCPOINTER);
_mainEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument());
//Document prevDoc = _mainEditView.execute(SCI_GETDOCPOINTER);
//_mainEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument());
//-- Add the bookmark markers.
for (size_t j = 0 ; j < session._mainViewFiles[i].marks.size() ; j++)
{
_mainEditView.execute(SCI_MARKERADD, session._mainViewFiles[i].marks[j], MARK_BOOKMARK);
}
_mainEditView.execute(SCI_SETDOCPOINTER, 0, prevDoc);
//--FLS: xSaveFoldingStateSession: Restore fold levels.
//- Bookmarks, selection marks and style marks are valid for a document in SCI (equal in all views of the same document in SCI)
//- But "folding" is a property of a view and not a document (different for the same document in two views)!
// So, if changing documents with SCI_SETDOCPOINTER, SCI un-folds all foldings!!
//- Therefore, the lexer needs first to do its work! But the lexer is not set at this stage
// (only for the first document replacing "new x" dummy document).
// So set document language type and request lexer to style the document.
//--FLS: xSaveFoldingStateSession: For some reason, the document has to be styled again here, whereas it should be already styled by activateBuffer().
// Otherwise, the folding below will not work !!??
_mainEditView.defineDocType(buf->getLangType());
//-- Following is equivalent to _mainEditView.restyleBuffer();
_mainEditView.execute(SCI_CLEARDOCUMENTSTYLE);
_mainEditView.execute(SCI_COLOURISE, 0, -1); // request the lexer to style the document.
for (size_t j = 0 ; j < session._mainViewFiles[i].foldedLines.size() ; j++)
{
//-- Pre-Condition is that after file is opened NO lines are folded,
// but the Lexer has already styled the document so that the Folding-Header lines exist!!
_mainEditView.execute(SCI_TOGGLEFOLD, session._mainViewFiles[i].foldedLines[j]);
}
//--FLS: xSaveFoldingStateSession: SCI_SETDOCPOINTER approach not necessary, if document is switched with activateBuffer() !!
//-- To be deleted afterwards --
//_mainEditView.execute(SCI_SETDOCPOINTER, 0, prevDoc);
i++;
}
else
@ -1087,7 +1133,8 @@ bool Notepad_plus::loadSession(Session & session)
}
if (PathFileExists(pFn))
{
lastOpened = doOpen(pFn, false, session._subViewFiles[k]._encoding);
//--FLS: xFileEditViewHistory: Calling doOpen(..,noRestoreFileEditView=true), in order to suppress RestoreFileEditView() when a session is loading due to redundancy.
lastOpened = doOpen(pFn, false, session._subViewFiles[k]._encoding, true);
//check if already open in main. If so, clone
if (_mainDocTab.getIndexByBuffer(lastOpened) != -1) {
loadBufferIntoView(lastOpened, SUB_VIEW);
@ -1111,6 +1158,7 @@ bool Notepad_plus::loadSession(Session & session)
const TCHAR *pLn = session._subViewFiles[k]._langName.c_str();
int id = getLangFromMenuName(pLn);
LangType typeToSet = L_TEXT;
//-- FLS: Attention, handling of language-setting is different to the MAIN_VIEW code above !!??
if (id != 0)
typeToSet = menuID2LangType(id);
if (typeToSet == L_EXTERNAL )
@ -1126,15 +1174,41 @@ bool Notepad_plus::loadSession(Session & session)
buf->setLangType(typeToSet, pLn);
buf->setEncoding(session._subViewFiles[k]._encoding);
//--FLS: xSaveFoldingStateSession: Activate CurrentPos in Scintilla document.
// (for more detailed comments see at mainEditView part above)
_subEditView.restoreCurrentPos();
//--FLS: xSaveFoldingStateSession: Switch and style the new document using activateBuffer()
// (for more detailed comments see at mainEditView part above)
activateBuffer(lastOpened, SUB_VIEW);
//--FLS: xSaveFoldingStateSession: SCI_SETDOCPOINTER approach not necessary, if document is switched with activateBuffer() !!
//-- To be deleted afterwards --
//Force in the document so we can add the markers
//Dont use default methods because of performance
Document prevDoc = _subEditView.execute(SCI_GETDOCPOINTER);
_subEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument());
//Document prevDoc = _subEditView.execute(SCI_GETDOCPOINTER);
//_subEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument());
//-- Add the bookmark markers.
for (size_t j = 0 ; j < session._subViewFiles[k].marks.size() ; j++)
{
_subEditView.execute(SCI_MARKERADD, session._subViewFiles[k].marks[j], MARK_BOOKMARK);
}
_subEditView.execute(SCI_SETDOCPOINTER, 0, prevDoc);
//--FLS: xSaveFoldingStateSession: Restore fold levels
// (for more detailed comments see at mainEditView part above)
_subEditView.defineDocType(buf->getLangType());
//-- Following is equivalent to _subEditView.restyleBuffer();
_subEditView.execute(SCI_CLEARDOCUMENTSTYLE);
_subEditView.execute(SCI_COLOURISE, 0, -1); // request the lexer to style the document.
for (size_t j = 0 ; j < session._subViewFiles[k].foldedLines.size() ; j++)
{
//-- Pre-Condition is that after file is opened NO lines are folded,
// but the Lexer has already styled the document so that the Folding-Header lines exist!!
_subEditView.execute(SCI_TOGGLEFOLD, session._subViewFiles[k].foldedLines[j]);
}
//--FLS: xSaveFoldingStateSession: SCI_SETDOCPOINTER approach not necessary, if document is switched with activateBuffer() !!
//-- To be deleted afterwards --
//_subEditView.execute(SCI_SETDOCPOINTER, 0, prevDoc);
k++;
}
@ -1146,8 +1220,11 @@ bool Notepad_plus::loadSession(Session & session)
}
}
_mainEditView.restoreCurrentPos();
_subEditView.restoreCurrentPos();
//--FLS: xSaveFoldingStateSession: SCI_SETDOCPOINTER approach not necessary, if document is switched with activateBuffer() !!
//-- To be deleted afterwards --
//_mainEditView.restoreCurrentPos();
//_subEditView.restoreCurrentPos();
if (session._activeMainIndex < (size_t)_mainDocTab.nbItem())//session.nbMainFiles())
activateBuffer(_mainDocTab.getBufferByIndex(session._activeMainIndex), MAIN_VIEW);

View File

@ -629,7 +629,9 @@ NppParameters::NppParameters() : _pXmlDoc(NULL),_pXmlUserDoc(NULL), _pXmlUserSty
_pXmlShortcutDoc(NULL), _pXmlContextMenuDocA(NULL), _pXmlSessionDoc(NULL), _pXmlBlacklistDoc(NULL),\
_nbUserLang(0), _nbExternalLang(0), _hUser32(NULL), _hUXTheme(NULL),\
_transparentFuncAddr(NULL), _enableThemeDialogTextureFuncAddr(NULL), _pNativeLangSpeaker(NULL),\
_isTaskListRBUTTONUP_Active(false), _fileSaveDlgFilterIndex(-1), _asNotepadStyle(false), _isFindReplacing(false)
_isTaskListRBUTTONUP_Active(false), _fileSaveDlgFilterIndex(-1), _asNotepadStyle(false), _isFindReplacing(false),\
//--FLS: xFileEditViewHistory: Initialize parameter setting variables:
_nbMaxFileEditView(20), _blnFileEditViewHistoryRestoreEnabled(false)
{
// init import UDL array
_nbImportedULD = 0;
@ -1248,6 +1250,9 @@ bool NppParameters::getUserParametersFromXmlTree()
//Get Find history parameters
feedFindHistoryParameters(root);
//--FLS: xFileEditViewHistory: new function feedFileEditViewHistoryParameters() to feed the parameters from config.xml
feedFileEditViewHistoryParameters(root);
//Get Project Panel parameters
feedProjectPanelsParameters(root);
@ -1654,6 +1659,18 @@ bool NppParameters::getSessionFromXmlTree(TiXmlDocument *pSessionDoc, Session *p
sfi.marks.push_back(lineNumber);
}
}
//--FLS: xSaveFoldingStateSession:
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.foldedLines.push_back(lineNumber);
}
}
(*ptrSession)._mainViewFiles.push_back(sfi);
}
}
@ -1702,6 +1719,18 @@ bool NppParameters::getSessionFromXmlTree(TiXmlDocument *pSessionDoc, Session *p
sfi.marks.push_back(lineNumber);
}
}
//--FLS: xSaveFoldingStateSession:
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.foldedLines.push_back(lineNumber);
}
}
(*ptrSession)._subViewFiles.push_back(sfi);
}
}
@ -2416,6 +2445,13 @@ void NppParameters::writeSession(const Session & session, const TCHAR *fileName)
TiXmlNode *markNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Mark")));
markNode->ToElement()->SetAttribute(TEXT("line"), markLine);
}
//--FLS: xSaveFoldingStateSession:
for (size_t j = 0 ; j < session._mainViewFiles[i].foldedLines.size() ; j++)
{
size_t foldedLine = session._mainViewFiles[i].foldedLines[j];
TiXmlNode *markNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Fold")));
markNode->ToElement()->SetAttribute(TEXT("line"), foldedLine);
}
}
TiXmlNode *subViewNode = sessionNode->InsertEndChild(TiXmlElement(TEXT("subView")));
@ -2440,6 +2476,13 @@ void NppParameters::writeSession(const Session & session, const TCHAR *fileName)
TiXmlNode *markNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Mark")));
markNode->ToElement()->SetAttribute(TEXT("line"), markLine);
}
//--FLS: xSaveFoldingStateSession:
for (size_t j = 0 ; j < session._subViewFiles[i].foldedLines.size() ; j++)
{
size_t foldedLine = session._subViewFiles[i].foldedLines[j];
TiXmlNode *markNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Fold")));
markNode->ToElement()->SetAttribute(TEXT("line"), foldedLine);
}
}
}
_pXmlSessionDoc->SaveFile();
@ -5487,3 +5530,154 @@ void NppParameters::safeWow64EnableWow64FsRedirection(BOOL Wow64FsEnableRedirect
}
}
}
//--FLS: xFileEditViewHistory: new function writeFileEditViewHistory()
void NppParameters::writeFileEditViewHistory(const Session & session)
{
//--FLS: Opens the XML-node of config.xml file and dumps the session. File is saved when notepad++ is exited.
//-- Code stolen from writeSession()
//--FLS: Use _mainViewFiles for ALL session files, even for the sub-view files, because FileEditViewHistory does not distinguish.
if (!_pXmlUserDoc) return; //otherwise, this will cause a system error!
TiXmlNode *nppRoot = _pXmlUserDoc->FirstChild(TEXT("NotepadPlus"));
if (!nppRoot) return;
TiXmlNode *sessionNode;
sessionNode = nppRoot->FirstChildElement(TEXT("FileEditViewHistory"));
//--FLS: Erase always FileEditViewHistory node and re-insert it at the end.
if (sessionNode)
nppRoot->RemoveChild(sessionNode);
sessionNode = new TiXmlElement(TEXT("FileEditViewHistory"));
if (!sessionNode) return;
//--FLS: Write FileEditViewHistory to config.xml Document. Note: Document is only written to config.xml-file with _pXmlUserDoc->SaveFile()!
(sessionNode->ToElement())->SetAttribute(TEXT("FileEditViewHistoryRestoreEnabled"), _blnFileEditViewHistoryRestoreEnabled?TEXT("True"):TEXT("False"));
//--FLS: Write Attribute "nbMaxFile" and activeIndex
(sessionNode->ToElement())->SetAttribute(TEXT("nbMaxFile"), (int)_nbMaxFileEditView);
int actIndex = 0; // set default, if no file is present!!
if (session._mainViewFiles.size() != 0) actIndex = session._activeMainIndex;
(sessionNode->ToElement())->SetAttribute(TEXT("activeMainIndex"), actIndex);
//-- Only write last _nbMaxFileEditView elements from session.
int nAll = session._mainViewFiles.size();
size_t nStart = (nAll - _nbMaxFileEditView)>0?(nAll - _nbMaxFileEditView):0;
for (size_t i = nStart ; i < session._mainViewFiles.size() ; i++)
{
TiXmlNode *fileNameNode = sessionNode->InsertEndChild(TiXmlElement(TEXT("File")));
////--FLS: Don't save editViewIndex, because for file edit view history user wants to load the document allways into the current view.
(fileNameNode->ToElement())->SetAttribute(TEXT("firstVisibleLine"), session._mainViewFiles[i]._firstVisibleLine);
(fileNameNode->ToElement())->SetAttribute(TEXT("xOffset"), session._mainViewFiles[i]._xOffset);
(fileNameNode->ToElement())->SetAttribute(TEXT("scrollWidth"), session._mainViewFiles[i]._scrollWidth);
(fileNameNode->ToElement())->SetAttribute(TEXT("startPos"), session._mainViewFiles[i]._startPos);
(fileNameNode->ToElement())->SetAttribute(TEXT("endPos"), session._mainViewFiles[i]._endPos);
(fileNameNode->ToElement())->SetAttribute(TEXT("selMode"), session._mainViewFiles[i]._selMode);
(fileNameNode->ToElement())->SetAttribute(TEXT("lang"), session._mainViewFiles[i]._langName.c_str());
(fileNameNode->ToElement())->SetAttribute(TEXT("encoding"), session._mainViewFiles[i]._encoding);
(fileNameNode->ToElement())->SetAttribute(TEXT("filename"), session._mainViewFiles[i]._fileName.c_str());
for (size_t j = 0 ; j < session._mainViewFiles[i].marks.size() ; j++)
{
size_t markLine = session._mainViewFiles[i].marks[j];
TiXmlNode *markNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Mark")));
markNode->ToElement()->SetAttribute(TEXT("line"), markLine);
}
//--FLS: xSaveFoldingStateSession:
for (size_t j = 0 ; j < session._mainViewFiles[i].foldedLines.size() ; j++)
{
size_t foldedLine = session._mainViewFiles[i].foldedLines[j];
TiXmlNode *markNode = fileNameNode->InsertEndChild(TiXmlElement(TEXT("Fold")));
markNode->ToElement()->SetAttribute(TEXT("line"), foldedLine);
}
}
//-- (Re)Insert the XML-node
(nppRoot->ToElement())->InsertEndChild(*sessionNode);
} //--- writeFileEditViewHistory() ----
//--FLS: xFileEditViewHistory: new function feedFileEditViewHistoryParameters()
// Reads the parameters from the config.xml file Node, after config.xml file is loaded.
void NppParameters::feedFileEditViewHistoryParameters(TiXmlNode *node)
{
const TCHAR *str;
//--FLS: Reads the FileEditViewHistory parameters out of according section in config.xml and stores them
// in a Session _lastFileEditViewSession.
//--FLS: Use _mainViewFiles for ALL session files, even for the sub-view files, because FileEditViewHistory does not distinguish.
//--FLS: Note: Don't use _nbMaxFile, which is directly assigned to the history _LRFileList,
// which is not really an independent class but a somehow directly linked class to _nbMaxFile variable!!
//--FLS: Code stolen from getSessionFromXmlTree().
//-- Set default values for variables, if there would be a reading error.
_nbMaxFileEditView = 20;
_blnFileEditViewHistoryRestoreEnabled = true;
//--FLS: Read FileEditViewHistory list into _lastFileEditViewSession. Same approach as used in getSessionFromXmlTree().
Session *ptrSession = &_lastFileEditViewSession;
TiXmlNode *sessionRoot = node->FirstChildElement(TEXT("FileEditViewHistory"));
if (!sessionRoot)
return;
TiXmlElement *actIndex = sessionRoot->ToElement();
size_t index;
str = actIndex->Attribute(TEXT("FileEditViewHistoryRestoreEnabled"), (int *)&index);
if (str) {
_blnFileEditViewHistoryRestoreEnabled = !generic_stricmp(TEXT("TRUE"), str);
}
//--FLS: Only one of the flags _fileEditViewHistoryRestoreEnabled or _rememberLastSession should be enabled!
// The GUI parameters have to be initialized before!!!
if (_nppGUI._rememberLastSession && _blnFileEditViewHistoryRestoreEnabled) _blnFileEditViewHistoryRestoreEnabled = false;
//--FLS: ->Attribute(const char *name, int *i) returns i=0, if a reading error occurs.
// Therefore, the code using "if (str)..." is not needed and is not the best, because it lets the ptrSession parameter uninitialized.
// read also activeYyIndex, which is not needed but just handled to set it in the session structure.
str = actIndex->Attribute(TEXT("activeView"), (int *)&(ptrSession->_activeView));
str = actIndex->Attribute(TEXT("activeMainIndex"), (int *)&(ptrSession->_activeMainIndex));
str = actIndex->Attribute(TEXT("activeSubIndex"), (int *)&(ptrSession->_activeSubIndex));
// read maximum list size
str = actIndex->Attribute(TEXT("nbMaxFile"), &_nbMaxFileEditView);
for (TiXmlNode *childNode = sessionRoot->FirstChildElement(TEXT("File"));
childNode ;
childNode = childNode->NextSibling(TEXT("File")) )
{
const TCHAR *fileName = (childNode->ToElement())->Attribute(TEXT("filename"));
if (fileName)
{
Position position;
(childNode->ToElement())->Attribute(TEXT("firstVisibleLine"), &position._firstVisibleLine);
(childNode->ToElement())->Attribute(TEXT("xOffset"), &position._xOffset);
(childNode->ToElement())->Attribute(TEXT("startPos"), &position._startPos);
(childNode->ToElement())->Attribute(TEXT("endPos"), &position._endPos);
(childNode->ToElement())->Attribute(TEXT("selMode"), &position._selMode);
(childNode->ToElement())->Attribute(TEXT("scrollWidth"), &position._scrollWidth);
const TCHAR *langName;
langName = (childNode->ToElement())->Attribute(TEXT("lang"));
int encoding = -1;
const TCHAR *encStr = (childNode->ToElement())->Attribute(TEXT("encoding"), &encoding);
sessionFileInfo sfi(fileName, langName, encStr?encoding:-1, position);
for (TiXmlNode *markNode = childNode->FirstChildElement(TEXT("Mark"));
markNode ;
markNode = markNode->NextSibling(TEXT("Mark")))
{
int lineNumber;
const TCHAR *lineNumberStr = (markNode->ToElement())->Attribute(TEXT("line"), &lineNumber);
if (lineNumberStr)
{
sfi.marks.push_back(lineNumber);
}
}
//--FLS: xSaveFoldingStateSession:
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.foldedLines.push_back(lineNumber);
}
}
(*ptrSession)._mainViewFiles.push_back(sfi);
}
}
return;
} //---feedFileEditViewHistoryParameters()-----

View File

@ -155,6 +155,8 @@ struct sessionFileInfo : public Position {
generic_string _fileName;
generic_string _langName;
vector<size_t> marks;
//--FLS: xSaveFoldingStateSession: additional vector for saving folding state.
vector<size_t> foldedLines;
int _encoding;
};
@ -1305,6 +1307,8 @@ public:
void writeShortcuts();
void writeSession(const Session & session, const TCHAR *fileName = NULL);
bool writeFindHistory();
//--FLS: xFileEditViewHistory: new function writeFileEditViewHistory()
void writeFileEditViewHistory(const Session & session);
bool isExistingUserLangName(const TCHAR *newName) const {
@ -1401,6 +1405,14 @@ public:
vector<MenuItemUnit> & getContextMenuItems() {return _contextMenuItems;};
const Session & getSession() const {return _session;};
//--FLS: xFileEditViewHistory: new functions for EditViewPerFileHistory
Session * getPtrFileEditViewSession() {return &_lastFileEditViewSession;};
bool getFileEditViewHistoryRestoreEnabled() const {return _blnFileEditViewHistoryRestoreEnabled;};
void setFileEditViewHistoryRestoreEnabled(bool en) { _blnFileEditViewHistoryRestoreEnabled=en;};
int getNbMaxFileEditView() const {return _nbMaxFileEditView;};
void setNbMaxFileEditView(int nb) { _nbMaxFileEditView = nb;};
bool hasCustomContextMenu() const {return !_contextMenuItems.empty();};
void setAccelerator(Accelerator *pAccel) {_pAccelerator = pAccel;};
@ -1568,6 +1580,12 @@ private:
vector<MenuItemUnit> _contextMenuItems;
Session _session;
//--FLS: xFileEditViewHistory: _lastFileEditViewList for (FileEditViewHistory)
Session _lastFileEditViewSession;
int _nbMaxFileEditView;
//--FLS: xFileEditViewHistory: Parameter setting control for FileEditViewHistory (restores last EditView of files, if true)
bool _blnFileEditViewHistoryRestoreEnabled;
generic_string _shortcutsPath;
generic_string _contextMenuPath;
generic_string _sessionPath;
@ -1625,6 +1643,8 @@ private:
void feedGUIParameters(TiXmlNode *node);
void feedKeyWordsParameters(TiXmlNode *node);
void feedFileListParameters(TiXmlNode *node);
//--FLS: xFileEditViewHistory: new function feedFileEditViewHistoryParameters()
void feedFileEditViewHistoryParameters(TiXmlNode *node);
void feedScintillaParam(TiXmlNode *node);
void feedDockingManager(TiXmlNode *node);
void feedFindHistoryParameters(TiXmlNode *node);

View File

@ -269,6 +269,11 @@ void Buffer::setPosition(const Position & pos, ScintillaEditView * identifier) {
Position & Buffer::getPosition(ScintillaEditView * identifier) {
int index = indexOfReference(identifier);
//--FLS: xFileEditViewHistory: Crashes if index is -1 when buffer is not within given EditView! Therefore, check and return default Position.
if (index == -1) {
static Position pos; // 'static' because of warning returning local value!
return pos;
}
return _positions.at(index);
}

View File

@ -716,6 +716,23 @@ BOOL CALLBACK SettingsDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM)
::SendDlgItemMessage(_hSelf, IDC_CHECK_MIN2SYSTRAY, BM_SETCHECK, nppGUI._isMinimizedToTray, 0);
::SendDlgItemMessage(_hSelf, IDC_CHECK_REMEMBERSESSION, BM_SETCHECK, nppGUI._rememberLastSession, 0);
::SendDlgItemMessage(_hSelf, IDC_CHECK_AUTOUPDATE, BM_SETCHECK, nppGUI._autoUpdateOpt._doAutoUpdate, 0);
//--FLS: xFileEditViewHistoryParameterGUI: Initialize Checkbox for enabling the history for restoring the edit view per file.
bool boolItem = (pNppParam->getFileEditViewHistoryRestoreEnabled());
//--FLS: Only one of the flags _fileEditViewHistoryRestoreEnabled or _rememberLastSession should be enabled!
if (boolItem && nppGUI._rememberLastSession)
{
boolItem = false;
(pNppParam->setFileEditViewHistoryRestoreEnabled(boolItem));
}
::SendDlgItemMessage(_hSelf, IDC_CHECK_REMEMBEREDITVIEWPERFILE, BM_SETCHECK, boolItem, 0);
//--FLS: xFileEditViewHistoryParameterGUI: Initializing number of files for edit view history per file
::SetDlgItemInt(_hSelf, IDC_EDIT_REMEMBEREDITVIEWPERFILE, pNppParam->getNbMaxFileEditView(), FALSE);
_nbFileEditViewHistoryVal.init(_hInst, _hSelf);
_nbFileEditViewHistoryVal.create(::GetDlgItem(_hSelf, IDC_EDIT_REMEMBEREDITVIEWPERFILE), IDC_EDIT_REMEMBEREDITVIEWPERFILE);
::ShowWindow(::GetDlgItem(_hSelf, IDC_CHECK_AUTOUPDATE), nppGUI._doesExistUpdater?SW_SHOW:SW_HIDE);
BOOL linkEnable = FALSE;
@ -846,8 +863,45 @@ BOOL CALLBACK SettingsDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM)
case IDC_CHECK_REMEMBERSESSION:
//::SendMessage(_hParent, WM_COMMAND, IDM_SETTING_REMEMBER_LAST_SESSION, 0);
nppGUI._rememberLastSession = isCheckedOrNot(wParam);
//--FLS: xFileEditViewHistoryParameterGUI: Only one of the flags _fileEditViewHistoryRestoreEnabled or _rememberLastSession should be enabled!
if (nppGUI._rememberLastSession) {
//-- disable IDC_CHECK_REMEMBEREDITVIEWPERFILE
(pNppParam->setFileEditViewHistoryRestoreEnabled(false));
::SendDlgItemMessage(_hSelf, IDC_CHECK_REMEMBEREDITVIEWPERFILE, BM_SETCHECK, false, 0);
}
return TRUE;
//--FLS: xFileEditViewHistoryParameterGUI: Checkbox for enabling the history for restoring the edit view per file.
case IDC_CHECK_REMEMBEREDITVIEWPERFILE:
{
bool isChecked = isCheckedOrNot(wParam);
(pNppParam->setFileEditViewHistoryRestoreEnabled(isChecked));
//--FLS: Only one of the flags _fileEditViewHistoryRestoreEnabled or _rememberLastSession should be enabled!
if (isChecked) {
//-- disable IDM_SETTING_REMEMBER_LAST_SESSION
nppGUI._rememberLastSession = false;
::SendDlgItemMessage(_hSelf, IDC_CHECK_REMEMBERSESSION, BM_SETCHECK, false, 0);
}
return TRUE;
}
//--FLS: xFileEditViewHistoryParameterGUI: Handle number of files for edit view history per file
case IDC_EDIT_REMEMBEREDITVIEWPERFILE:
{
ValueDlg nbFileMaxDlg;
nbFileMaxDlg.init(NULL, _hSelf, pNppParam->getNbMaxFileEditView(), TEXT("Max File: "));
POINT p;
::GetCursorPos(&p);
int nbMaxFile = nbFileMaxDlg.doDialog(p);
if (nbMaxFile != -1)
{
pNppParam->setNbMaxFileEditView(nbMaxFile);
::SetDlgItemInt(_hSelf, IDC_EDIT_REMEMBEREDITVIEWPERFILE, nbMaxFile, FALSE);
}
return TRUE;
}
case IDC_CHECK_ENABLEDOCSWITCHER :
{
nppGUI._doTaskList = !nppGUI._doTaskList;

View File

@ -57,7 +57,13 @@ class SettingsDlg : public StaticDialog
{
public :
SettingsDlg() {};
//--FLS: xFileEditViewHistoryParameterGUI: Number of files in file edit view history list.
virtual void destroy() {
_nbFileEditViewHistoryVal.destroy();
}
private :
//--FLS: xFileEditViewHistoryParameterGUI: Number of files in file edit view history list.
URLCtrl _nbFileEditViewHistoryVal;
BOOL CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam);
};

View File

@ -137,6 +137,11 @@
#define IDC_CHECK_SHORTTITLE (IDD_PREFERENCE_SETTING_BOX + 31)
#define IDC_CHECK_SMARTHILITECASESENSITIVE (IDD_PREFERENCE_SETTING_BOX + 32)
#define IDC_SMARTHILITING_STATIC (IDD_PREFERENCE_SETTING_BOX + 33)
//-- FLS: xFileEditViewHistoryParameterGUI: Additional Checkbox for enabling the history for restoring the edit view per file.
#define IDC_PREFERENCE_OFFSET_FLS 40
#define IDC_CHECK_REMEMBEREDITVIEWPERFILE (IDD_PREFERENCE_SETTING_BOX + IDC_PREFERENCE_OFFSET_FLS + 1)
#define IDC_REMEMBEREDITVIEWPERFILE_STATIC (IDD_PREFERENCE_SETTING_BOX + IDC_PREFERENCE_OFFSET_FLS + 2)
#define IDC_EDIT_REMEMBEREDITVIEWPERFILE (IDD_PREFERENCE_SETTING_BOX + IDC_PREFERENCE_OFFSET_FLS + 3)
#define IDD_PREFERENCE_NEWDOCSETTING_BOX 6400 //(IDD_PREFERENCE_BOX + 400)
#define IDC_FORMAT_GB_STATIC (IDD_PREFERENCE_NEWDOCSETTING_BOX + 1)