diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index e575b45f..861b184b 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -4876,7 +4876,7 @@ void Notepad_plus::getCurrentOpenedFiles(Session & session, bool includUntitledD generic_string languageName = getLangFromMenu(buf); const TCHAR *langName = languageName.c_str(); - sessionFileInfo sfi(buf->getFullPathName(), langName, buf->getEncoding(), buf->getPosition(editView), buf->getBackupFileName().c_str(), int(buf->getLastModifiedTimestamp())); + sessionFileInfo sfi(buf->getFullPathName(), langName, buf->getEncoding(), buf->getPosition(editView), buf->getBackupFileName().c_str(), int(buf->getLastModifiedTimestamp()), buf->getMapPosition()); _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument()); size_t maxLine = static_cast(_invisibleEditView.execute(SCI_GETLINECOUNT)); diff --git a/PowerEditor/src/NppIO.cpp b/PowerEditor/src/NppIO.cpp index 441a88f7..6233a8d9 100644 --- a/PowerEditor/src/NppIO.cpp +++ b/PowerEditor/src/NppIO.cpp @@ -1601,6 +1601,7 @@ bool Notepad_plus::loadSession(Session & session, bool isSnapshotMode) } buf->setPosition(session._mainViewFiles[i], &_mainEditView); + buf->setMapPosition(session._mainViewFiles[i]._mapPos._firstVisibleDocLine, session._mainViewFiles[i]._mapPos._lastVisibleDocLine, session._mainViewFiles[i]._mapPos._nbLine, session._mainViewFiles[i]._mapPos._higherPos); buf->setLangType(typeToSet, pLn); if (session._mainViewFiles[i]._encoding != -1) buf->setEncoding(session._mainViewFiles[i]._encoding); @@ -1704,6 +1705,7 @@ bool Notepad_plus::loadSession(Session & session, bool isSnapshotMode) } buf->setPosition(session._subViewFiles[k], &_subEditView); + buf->setMapPosition(session._subViewFiles[k]._mapPos._firstVisibleDocLine, session._subViewFiles[k]._mapPos._lastVisibleDocLine, session._subViewFiles[k]._mapPos._nbLine, session._subViewFiles[k]._mapPos._higherPos); if (typeToSet == L_USER) { if (!lstrcmp(pLn, TEXT("User Defined"))) { pLn = TEXT(""); //default user defined diff --git a/PowerEditor/src/NppNotification.cpp b/PowerEditor/src/NppNotification.cpp index 928fad4a..26492de7 100644 --- a/PowerEditor/src/NppNotification.cpp +++ b/PowerEditor/src/NppNotification.cpp @@ -162,6 +162,8 @@ BOOL Notepad_plus::notify(SCNotification *notification) Buffer * pBuf = MainFileManager->getBufferByID(id); _pDocMap->showInMapTemporarily(pBuf, notifyView); _pDocMap->setSyntaxHiliting(); + + _pDocMap->setTemporarilyShowing(true); } } */ @@ -175,6 +177,8 @@ BOOL Notepad_plus::notify(SCNotification *notification) { _pDocMap->reloadMap(); _pDocMap->setSyntaxHiliting(); + + _pDocMap->setTemporarilyShowing(false); } */ break; @@ -906,7 +910,7 @@ BOOL Notepad_plus::notify(SCNotification *notification) _linkTriggered = false; } - if (_pDocMap) + if (_pDocMap && (not _pDocMap->isClosed()) && _pDocMap->isVisible() && not _pDocMap->isTemporarilyShowing()) { _pDocMap->wrapMap(); _pDocMap->scrollMap(); diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index f97d2891..cd8384b2 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -2002,6 +2002,12 @@ bool NppParameters::getSessionFromXmlTree(TiXmlDocument *pSessionDoc, Session *p (childNode->ToElement())->Attribute(TEXT("selMode"), &position._selMode); (childNode->ToElement())->Attribute(TEXT("scrollWidth"), &position._scrollWidth); + MapPosition mapPosition; + (childNode->ToElement())->Attribute(TEXT("mapFirstVisibleDocLine"), &mapPosition._firstVisibleDocLine); + (childNode->ToElement())->Attribute(TEXT("mapLastVisibleDocLine"), &mapPosition._lastVisibleDocLine); + (childNode->ToElement())->Attribute(TEXT("mapNbLine"), &mapPosition._nbLine); + (childNode->ToElement())->Attribute(TEXT("mapHigherPos"), &mapPosition._higherPos); + const TCHAR *langName; langName = (childNode->ToElement())->Attribute(TEXT("lang")); int encoding = -1; @@ -2011,7 +2017,7 @@ bool NppParameters::getSessionFromXmlTree(TiXmlDocument *pSessionDoc, Session *p int fileModifiedTimestamp = 0; (childNode->ToElement())->Attribute(TEXT("originalFileLastModifTimestamp"), &fileModifiedTimestamp); - sessionFileInfo sfi(fileName, langName, encStr?encoding:-1, position, backupFilePath, fileModifiedTimestamp); + sessionFileInfo sfi(fileName, langName, encStr?encoding:-1, position, backupFilePath, fileModifiedTimestamp, mapPosition); for (TiXmlNode *markNode = childNode->FirstChildElement(TEXT("Mark")); markNode ; @@ -2940,6 +2946,12 @@ void NppParameters::writeSession(const Session & session, const TCHAR *fileName) (fileNameNode->ToElement())->SetAttribute(TEXT("filename"), viewSessionFiles[i]._fileName.c_str()); (fileNameNode->ToElement())->SetAttribute(TEXT("backupFilePath"), viewSessionFiles[i]._backupFilePath.c_str()); (fileNameNode->ToElement())->SetAttribute(TEXT("originalFileLastModifTimestamp"), static_cast(viewSessionFiles[i]._originalFileLastModifTimestamp)); + + // docMap + (fileNameNode->ToElement())->SetAttribute(TEXT("mapFirstVisibleDocLine"), viewSessionFiles[i]._mapPos._lastVisibleDocLine); + (fileNameNode->ToElement())->SetAttribute(TEXT("mapLastVisibleDocLine"), viewSessionFiles[i]._mapPos._lastVisibleDocLine); + (fileNameNode->ToElement())->SetAttribute(TEXT("mapNbLine"), viewSessionFiles[i]._mapPos._nbLine); + (fileNameNode->ToElement())->SetAttribute(TEXT("mapHigherPos"), viewSessionFiles[i]._mapPos._higherPos); for (size_t j = 0, len = viewSessionFiles[i]._marks.size() ; j < len ; ++j) { diff --git a/PowerEditor/src/Parameters.h b/PowerEditor/src/Parameters.h index 058af75e..8af61a7a 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -24,6 +24,7 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + #pragma once #include "tinyxmlA.h" @@ -137,10 +138,20 @@ struct Position }; +struct MapPosition +{ + int32_t _firstVisibleDocLine = -1; + int32_t _lastVisibleDocLine = -1; + int32_t _nbLine = -1; + int32_t _higherPos = -1; + bool isValid() { return _firstVisibleDocLine != -1; }; +}; + + struct sessionFileInfo : public Position { - sessionFileInfo(const TCHAR *fn, const TCHAR *ln, int encoding, Position pos, const TCHAR *backupFilePath, int originalFileLastModifTimestamp) : - _encoding(encoding), Position(pos), _originalFileLastModifTimestamp(originalFileLastModifTimestamp) + sessionFileInfo(const TCHAR *fn, const TCHAR *ln, int encoding, Position pos, const TCHAR *backupFilePath, int originalFileLastModifTimestamp, const MapPosition & mapPos) : + _encoding(encoding), Position(pos), _originalFileLastModifTimestamp(originalFileLastModifTimestamp), _mapPos(mapPos) { if (fn) _fileName = fn; if (ln) _langName = ln; @@ -157,6 +168,8 @@ struct sessionFileInfo : public Position generic_string _backupFilePath; time_t _originalFileLastModifTimestamp = 0; + + MapPosition _mapPos; }; diff --git a/PowerEditor/src/ScitillaComponent/Buffer.cpp b/PowerEditor/src/ScitillaComponent/Buffer.cpp index ea997d9b..7cd61d33 100644 --- a/PowerEditor/src/ScitillaComponent/Buffer.cpp +++ b/PowerEditor/src/ScitillaComponent/Buffer.cpp @@ -468,35 +468,14 @@ void Buffer::setDeferredReload() // triggers a reload on the next Document acces } -/* -pair Buffer::getLineUndoState(size_t currentLine) const +void Buffer::setMapPosition(int32_t firstVisibleDocLine, int32_t lastVisibleDocLine, int32_t nbLine, int32_t higherPos) { - for (size_t i = 0 ; i < _linesUndoState.size() ; i++) - { - if (_linesUndoState[i].first == currentLine) - return _linesUndoState[i].second; - } - return pair(0, false); + _mapPosition._firstVisibleDocLine = firstVisibleDocLine; + _mapPosition._lastVisibleDocLine = lastVisibleDocLine; + _mapPosition._nbLine = nbLine; + _mapPosition._higherPos = higherPos; } -void Buffer::setLineUndoState(size_t currentLine, size_t undoLevel, bool isSaved) -{ - bool found = false; - for (size_t i = 0 ; i < _linesUndoState.size() ; i++) - { - if (_linesUndoState[i].first == currentLine) - { - _linesUndoState[i].second.first = undoLevel; - _linesUndoState[i].second.second = isSaved; - } - } - if (!found) - { - _linesUndoState.push_back(pair >(currentLine, pair(undoLevel, false))); - } -} -*/ - //filemanager FileManager::~FileManager() diff --git a/PowerEditor/src/ScitillaComponent/Buffer.h b/PowerEditor/src/ScitillaComponent/Buffer.h index e0b4f0d2..b5268ade 100644 --- a/PowerEditor/src/ScitillaComponent/Buffer.h +++ b/PowerEditor/src/ScitillaComponent/Buffer.h @@ -130,9 +130,6 @@ private: #define MainFileManager FileManager::getInstance() - - - class Buffer final { friend class FileManager; @@ -304,11 +301,6 @@ public: _needReloading = reload; } - /* - pair getLineUndoState(size_t currentLine) const; - void setLineUndoState(size_t currentLine, size_t undoLevel, bool isSaved = false); - */ - int docLength() const { assert(_pManager != nullptr); @@ -357,6 +349,9 @@ public: void updateTimeStamp(); void reload(); + void setMapPosition(int32_t firstVisibleDocLine, int32_t lastVisibleDocLine, int32_t nbLine, int32_t higherPos); + MapPosition getMapPosition() { return _mapPosition; }; + private: int indexOfReference(const ScintillaEditView * identifier) const; @@ -394,8 +389,6 @@ private: std::vector _positions; std::vector> _foldStates; - //vector< pair > > _linesUndoState; - //Environment properties DocFileStatus _currentStatus; time_t _timeStamp = 0; // 0 if it's a new doc @@ -416,4 +409,6 @@ private: // For the monitoring HANDLE _eventHandle = nullptr; bool _isMonitoringOn = false; + + MapPosition _mapPosition; }; \ No newline at end of file diff --git a/PowerEditor/src/ScitillaComponent/DocTabView.h b/PowerEditor/src/ScitillaComponent/DocTabView.h index a9295141..08172762 100644 --- a/PowerEditor/src/ScitillaComponent/DocTabView.h +++ b/PowerEditor/src/ScitillaComponent/DocTabView.h @@ -25,17 +25,10 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#pragma once -#ifndef DOCTABVIEW_H -#define DOCTABVIEW_H - -#ifndef TAB_BAR_H #include "TabBar.h" -#endif //TAB_BAR_H - -#ifndef BUFFER_H #include "Buffer.h" -#endif //BUFFER_H const int SAVED_IMG_INDEX = 0; const int UNSAVED_IMG_INDEX = 1; @@ -91,5 +84,3 @@ private : ScintillaEditView *_pView; static bool _hideTabBarStatus; }; - -#endif //DOCTABVIEW_H diff --git a/PowerEditor/src/WinControls/DocumentMap/documentMap.cpp b/PowerEditor/src/WinControls/DocumentMap/documentMap.cpp index e430a5a2..e9597e10 100644 --- a/PowerEditor/src/WinControls/DocumentMap/documentMap.cpp +++ b/PowerEditor/src/WinControls/DocumentMap/documentMap.cpp @@ -59,7 +59,7 @@ void DocumentMap::reloadMap() } } -void DocumentMap::showInMapTemporarily(Buffer *buf2show, const ScintillaEditView *fromEditView) +void DocumentMap::showInMapTemporarily(Buffer *buf2show, ScintillaEditView *fromEditView) { if (_pScintillaEditView && fromEditView) { @@ -75,29 +75,11 @@ void DocumentMap::showInMapTemporarily(Buffer *buf2show, const ScintillaEditView { wrapMap(fromEditView); } - //_pScintillaEditView->restoreCurrentPos(); - scrollMap(fromEditView); - - /* - Buffer * buf = buf2show; - Position & pos = buf->getPosition(const_cast(fromEditView)); - - _pScintillaEditView->execute(SCI_GOTOPOS, 0); //make sure first line visible by setting caret there, will scroll to top of document - - _pScintillaEditView->execute(SCI_SETSELECTIONMODE, pos._selMode); //enable - _pScintillaEditView->execute(SCI_SETANCHOR, pos._startPos); - _pScintillaEditView->execute(SCI_SETCURRENTPOS, pos._endPos); - _pScintillaEditView->execute(SCI_CANCEL); //disable - if (not _pScintillaEditView->isWrap()) //only offset if not wrapping, otherwise the offset isnt needed at all - { - _pScintillaEditView->execute(SCI_SETSCROLLWIDTH, pos._scrollWidth); - _pScintillaEditView->execute(SCI_SETXOFFSET, pos._xOffset); - } - _pScintillaEditView->execute(SCI_CHOOSECARETX); // choose current x position - - int lineToShow = static_cast(_pScintillaEditView->execute(SCI_VISIBLEFROMDOCLINE, pos._firstVisibleLine)); - _pScintillaEditView->scroll(0, lineToShow); - */ + MapPosition mp = buf2show->getMapPosition(); + if (mp.isValid()) + scrollMapWith(mp, *fromEditView); + else + scrollMap(fromEditView); } } @@ -226,24 +208,18 @@ int DocumentMap::getEditorTextZoneWidth(const ScintillaEditView *editView) } return editorRect.right - editorRect.left - marginWidths; } -/* -struct mapPosition { - int32_t _firstVisibleDocLine; - int32_t _nbLine; - int32_t _lastVisibleDocLine; -}; -*/ -void DocumentMap::scrollMap(const ScintillaEditView *editView) + +void DocumentMap::scrollMap(ScintillaEditView *editView) { - const ScintillaEditView *pEditView = editView ? editView : *_ppEditView; + ScintillaEditView *pEditView = editView ? editView : *_ppEditView; if (_pScintillaEditView && pEditView) { // Visible document line for the code view (but not displayed line) auto firstVisibleDisplayLine = pEditView->execute(SCI_GETFIRSTVISIBLELINE); - auto firstVisibleDocLine = pEditView->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLine); - auto nbLine = pEditView->execute(SCI_LINESONSCREEN, firstVisibleDisplayLine); - auto lastVisibleDocLine = pEditView->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLine + nbLine); + const auto firstVisibleDocLine = pEditView->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLine); + const auto nbLine = pEditView->execute(SCI_LINESONSCREEN, firstVisibleDisplayLine); + const auto lastVisibleDocLine = pEditView->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLine + nbLine); // Visible document line for the map view auto firstVisibleDisplayLineMap = _pScintillaEditView->execute(SCI_GETFIRSTVISIBLELINE); @@ -260,6 +236,7 @@ void DocumentMap::scrollMap(const ScintillaEditView *editView) // Get the editor's higher/lower Y, then compute the map's higher/lower Y LRESULT higherY = 0; LRESULT lowerY = 0; + auto higherPos = -1 ; // -1 => not pEditView->isWrap() if (not pEditView->isWrap()) { auto higherPos = _pScintillaEditView->execute(SCI_POSITIONFROMLINE, firstVisibleDocLine); @@ -274,12 +251,59 @@ void DocumentMap::scrollMap(const ScintillaEditView *editView) } else { - auto higherPos = pEditView->execute(SCI_POSITIONFROMPOINT, 0, 0); + higherPos = pEditView->execute(SCI_POSITIONFROMPOINT, 0, 0); higherY = _pScintillaEditView->execute(SCI_POINTYFROMPOSITION, 0, higherPos); auto lineHeight = _pScintillaEditView->execute(SCI_TEXTHEIGHT, firstVisibleDocLine); lowerY = nbLine * lineHeight + higherY; } + // set current map position in buffer + Buffer *buffer = pEditView->getCurrentBuffer(); + buffer->setMapPosition(firstVisibleDocLine, lastVisibleDocLine, nbLine, higherPos); + + // Update view zone in map + _vzDlg.drawZone(static_cast(higherY), static_cast(lowerY)); + } +} + +void DocumentMap::scrollMapWith(const MapPosition & mapPos, ScintillaEditView & editView) +{ + if (_pScintillaEditView) + { + // Visible document line for the map view + auto firstVisibleDisplayLineMap = _pScintillaEditView->execute(SCI_GETFIRSTVISIBLELINE); + auto firstVisibleDocLineMap = _pScintillaEditView->execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLineMap); + auto nbLineMap = _pScintillaEditView->execute(SCI_LINESONSCREEN, firstVisibleDocLineMap); + auto lastVisibleDocLineMap = editView.execute(SCI_DOCLINEFROMVISIBLE, firstVisibleDisplayLineMap + nbLineMap); + + // If part of editor view is out of map, then scroll map + if (lastVisibleDocLineMap < mapPos._lastVisibleDocLine) + _pScintillaEditView->execute(SCI_GOTOLINE, mapPos._lastVisibleDocLine); + else + _pScintillaEditView->execute(SCI_GOTOLINE, mapPos._firstVisibleDocLine); + + // Get the editor's higher/lower Y, then compute the map's higher/lower Y + LRESULT higherY = 0; + LRESULT lowerY = 0; + if (mapPos._higherPos == -1) // mapPos._higherPos == -1 => not pEditView->isWrap() + { + auto higherPos = _pScintillaEditView->execute(SCI_POSITIONFROMLINE, mapPos._firstVisibleDocLine); + auto lowerPos = _pScintillaEditView->execute(SCI_POSITIONFROMLINE, mapPos._lastVisibleDocLine); + higherY = _pScintillaEditView->execute(SCI_POINTYFROMPOSITION, 0, higherPos); + lowerY = _pScintillaEditView->execute(SCI_POINTYFROMPOSITION, 0, lowerPos); + if (lowerY == 0) + { + auto lineHeight = _pScintillaEditView->execute(SCI_TEXTHEIGHT, mapPos._firstVisibleDocLine); + lowerY = mapPos._nbLine * lineHeight + mapPos._firstVisibleDocLine; + } + } + else + { + higherY = _pScintillaEditView->execute(SCI_POINTYFROMPOSITION, 0, mapPos._higherPos); + auto lineHeight = _pScintillaEditView->execute(SCI_TEXTHEIGHT, mapPos._firstVisibleDocLine); + lowerY = mapPos._nbLine * lineHeight + higherY; + } + // Update view zone in map _vzDlg.drawZone(static_cast(higherY), static_cast(lowerY)); } diff --git a/PowerEditor/src/WinControls/DocumentMap/documentMap.h b/PowerEditor/src/WinControls/DocumentMap/documentMap.h index 4449da03..ec53ea79 100644 --- a/PowerEditor/src/WinControls/DocumentMap/documentMap.h +++ b/PowerEditor/src/WinControls/DocumentMap/documentMap.h @@ -39,10 +39,12 @@ class ScintillaEditView; class Buffer; +struct MapPosition; const bool moveDown = true; const bool moveUp = false; + enum moveMode { perLine, perPage @@ -82,8 +84,8 @@ protected : void drawPreviewZone(DRAWITEMSTRUCT *pdis); private : - HWND _viewZoneCanvas; - WNDPROC _canvasDefaultProc; + HWND _viewZoneCanvas = nullptr; + WNDPROC _canvasDefaultProc = nullptr; long _higherY; long _lowerY; @@ -120,16 +122,19 @@ public: } void reloadMap(); - void showInMapTemporarily(Buffer *buf2show, const ScintillaEditView *fromEditView); + void showInMapTemporarily(Buffer *buf2show, ScintillaEditView *fromEditView); void wrapMap(const ScintillaEditView *editView = nullptr); void initWrapMap(); - void scrollMap(const ScintillaEditView *editView = nullptr); + void scrollMap(ScintillaEditView *editView = nullptr); void scrollMap(bool direction, moveMode whichMode); + void scrollMapWith(const MapPosition & mapPos, ScintillaEditView & editView); void doMove(); void fold(int line, bool foldOrNot); void foldAll(bool mode); void setSyntaxHiliting(); void changeTextDirection(bool isRTL); + bool isTemporarilyShowing() const { return _isTemporarilyShowing; }; + void setTemporarilyShowing(bool tempShowing) { _isTemporarilyShowing = tempShowing; } protected: virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); @@ -141,6 +146,8 @@ private: ScintillaEditView *_pScintillaEditView = nullptr; ViewZoneDlg _vzDlg; + bool _isTemporarilyShowing = false; + // for needToRecomputeWith function int _displayZoom = -1; int _displayWidth = 0;