diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 70b36452a..be6951b4b 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -706,10 +706,13 @@ BufferID Notepad_plus::doOpen(const char *fileName, bool isReadOnly) } bool Notepad_plus::doReload(BufferID id, bool alert) { - if (!switchToFile(id)) //test if file present - { - return false; + + /* + //No activation when reloading, defer untill document is actually visible + if (alert) { + switchToFile(id); } + */ if (alert) { if (::MessageBox(_hSelf, "Do you want to reload the current file?", "Reload", MB_YESNO | MB_ICONQUESTION | MB_APPLMODAL) != IDYES) @@ -721,18 +724,27 @@ bool Notepad_plus::doReload(BufferID id, bool alert) bool mainVisisble = (_mainEditView.getCurrentBufferID() == id); bool subVisisble = (_subEditView.getCurrentBufferID() == id); if (mainVisisble) { + _mainEditView.saveCurrentPos(); _mainEditView.execute(SCI_SETDOCPOINTER, 0, 0); } if (subVisisble) { + _subEditView.saveCurrentPos(); _subEditView.execute(SCI_SETDOCPOINTER, 0, 0); } + + if (!mainVisisble && !subVisisble) { + return MainFileManager->reloadBufferDeferred(id); + } + bool res = MainFileManager->reloadBuffer(id); Buffer * pBuf = MainFileManager->getBufferByID(id); if (mainVisisble) { _mainEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + _mainEditView.restoreCurrentPos(); } if (subVisisble) { _subEditView.execute(SCI_SETDOCPOINTER, 0, pBuf->getDocument()); + _subEditView.restoreCurrentPos(); } return res; } @@ -1729,11 +1741,19 @@ BOOL Notepad_plus::notify(SCNotification *notification) buf = _subEditView.getCurrentBuffer(); } else { //Done by invisibleEditView? + BufferID id = BUFFER_INVALID; if (notification->nmhdr.hwndFrom == _invisibleEditView.getHSelf()) { - buf = _invisibleEditView.getCurrentBuffer(); + id = MainFileManager->getBufferFromDocument(_invisibleEditView.execute(SCI_GETDOCPOINTER)); + } else if (notification->nmhdr.hwndFrom == _fileEditView.getHSelf()) { + id = MainFileManager->getBufferFromDocument(_fileEditView.execute(SCI_GETDOCPOINTER)); } else { break; //wrong scintilla } + if (id != BUFFER_INVALID) { + buf = MainFileManager->getBufferByID(id); + } else { + break; + } } buf->setDirty(notification->nmhdr.code == SCN_SAVEPOINTLEFT); break; } @@ -4564,6 +4584,12 @@ void Notepad_plus::docGotoAnotherEditView(FileTransferMode mode) } bool Notepad_plus::activateBuffer(BufferID id, int whichOne) { + Buffer * pBuf = MainFileManager->getBufferByID(id); + bool reload = pBuf->getNeedReload(); + if (reload) { + MainFileManager->reloadBuffer(id); + pBuf->setNeedReload(false); + } if (whichOne == MAIN_VIEW) { if (_mainDocTab.activateBuffer(id)) //only activate if possible _mainEditView.activateBuffer(id); @@ -4575,10 +4601,28 @@ bool Notepad_plus::activateBuffer(BufferID id, int whichOne) { else return false; } + + if (reload) { + performPostReload(whichOne); + } + notifyBufferActivated(id, whichOne); return true; } +void Notepad_plus::performPostReload(int whichOne) { + NppParameters *pNppParam = NppParameters::getInstance(); + const NppGUI & nppGUI = pNppParam->getNppGUI(); + bool toEnd = (nppGUI._fileAutoDetection == cdAutoUpdateGo2end) || (nppGUI._fileAutoDetection == cdGo2end); + if (!toEnd) + return; + if (whichOne == MAIN_VIEW) { + _mainEditView.execute(SCI_GOTOLINE, _mainEditView.execute(SCI_GETLINECOUNT) -1); + } else { + _subEditView.execute(SCI_GOTOLINE, _subEditView.execute(SCI_GETLINECOUNT) -1); + } +} + void Notepad_plus::bookmarkNext(bool forwardScan) { int lineno = _pEditView->getCurrentLineNumber(); @@ -7913,19 +7957,10 @@ void Notepad_plus::notifyBufferChanged(Buffer * buffer, int mask) { if (doReloadOrNot(buffer->getFilePath()) != IDYES) break; //abort } - int index = _pDocTab->getIndexByBuffer(buffer->getID()); - int iView = currentView(); - if (index == -1) - iView = otherView(); - activateBuffer(buffer->getID(), iView); //activate the buffer in the first view possible + //activateBuffer(buffer->getID(), iView); //activate the buffer in the first view possible doReload(buffer->getID(), false); - if (nppGUI._fileAutoDetection == cdAutoUpdateGo2end || nppGUI._fileAutoDetection == cdGo2end) { - ScintillaEditView * pView = &_mainEditView; - if (iView==SUB_VIEW) { - pView = &_subEditView; - } - int line = pView->lastZeroBasedLineNumber(); - pView->gotoLine(line); + if (mainActive || subActive) { + performPostReload(mainActive?MAIN_VIEW:SUB_VIEW); } break; } case DOC_DELETED: { //ask for keep @@ -7933,7 +7968,7 @@ void Notepad_plus::notifyBufferChanged(Buffer * buffer, int mask) { int iView = currentView(); if (index == -1) iView = otherView(); - activateBuffer(buffer->getID(), iView); //activate the buffer in the first view possible + //activateBuffer(buffer->getID(), iView); //activate the buffer in the first view possible didDialog = true; if (doCloseOrNot(buffer->getFilePath()) == IDNO) { //close in both views, doing current view last since that has to remain opened diff --git a/PowerEditor/src/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h index f182c9482..428e6f44b 100644 --- a/PowerEditor/src/Notepad_plus.h +++ b/PowerEditor/src/Notepad_plus.h @@ -378,6 +378,7 @@ private: bool activateBuffer(BufferID id, int whichOne); //activate buffer in that view if found void notifyBufferActivated(BufferID bufid, int view); + void performPostReload(int whichOne); //END: Document management int doSaveOrNot(const char *fn) { diff --git a/PowerEditor/src/ScitillaComponent/Buffer.cpp b/PowerEditor/src/ScitillaComponent/Buffer.cpp index e9f03dab1..daff49e66 100644 --- a/PowerEditor/src/ScitillaComponent/Buffer.cpp +++ b/PowerEditor/src/ScitillaComponent/Buffer.cpp @@ -152,6 +152,7 @@ bool Buffer::checkFileState() { //returns true if the status has been changed (i { _currentStatus = DOC_DELETED; _isFileReadOnly = false; + _isDirty = true; //dirty sicne no match with filesystem _timeStamp = 0; doNotify(BufferChangeStatus | BufferChangeReadonly | BufferChangeTimestamp); return true; @@ -172,12 +173,24 @@ bool Buffer::checkFileState() { //returns true if the status has been changed (i if (!_stat(_fullPathName, &buf)) { - _isFileReadOnly = (bool)(!(buf.st_mode & _S_IWRITE)); + int mask = 0; //status always 'changes', even if from modified to modified + bool isFileReadOnly = (bool)(!(buf.st_mode & _S_IWRITE)); + if (isFileReadOnly != _isFileReadOnly) { + _isFileReadOnly = isFileReadOnly; + mask |= BufferChangeReadonly; + } + if (_timeStamp != buf.st_mtime) { - _currentStatus = DOC_MODIFIED; _timeStamp = buf.st_mtime; - doNotify(BufferChangeStatus | BufferChangeReadonly | BufferChangeTimestamp); + mask |= BufferChangeTimestamp; + } + + if (mask != 0) { + _currentStatus = DOC_MODIFIED; + mask |= BufferChangeStatus; //status always 'changes', even if from modified to modified + + doNotify(mask); return true; } @@ -298,6 +311,12 @@ void Buffer::setHideLineChanged(bool isHide, int location) { _referees.at(i)->notifyMarkers(this, isHide, location, (i == _references-1)); } } +void Buffer::setDeferredReload() { //triggers a reload on the next Document access + _isDirty = false; //when reloading, just set to false, since it sohuld be marked as clean + _needReloading = true; + doNotify(BufferChangeDirty); +} + //filemanager FileManager::FileManager() : _nextNewNumber(1), _nextBufferID(0), _pNotepadPlus(NULL), _nrBufs(0), _pscratchTilla(NULL) @@ -376,7 +395,8 @@ BufferID FileManager::loadFile(const char * filename, Document doc) { ::GetFullPathName(filename, MAX_PATH, fullpath, NULL); ::GetLongPathName(fullpath, fullpath, MAX_PATH); Utf8_16_Read UnicodeConvertor; //declare here so we can get information after loading is done - if (loadFileData(doc, fullpath, &UnicodeConvertor, L_TXT)) { + bool res = loadFileData(doc, fullpath, &UnicodeConvertor, L_TXT); + if (res) { Buffer * newBuf = new Buffer(this, _nextBufferID, doc, DOC_REGULAR, fullpath); BufferID id = (BufferID) newBuf; newBuf->_id = id; @@ -405,7 +425,9 @@ bool FileManager::reloadBuffer(BufferID id) { Buffer * buf = getBufferByID(id); Document doc = buf->getDocument(); Utf8_16_Read UnicodeConvertor; + buf->_canNotify = false; //disable notify during file load, we dont want dirty to be triggered bool res = loadFileData(doc, buf->getFilePath(), &UnicodeConvertor, buf->getLangType()); + buf->_canNotify = true; if (res) { if (UnicodeConvertor.getNewBuf()) { buf->determinateFormat(UnicodeConvertor.getNewBuf()); @@ -415,9 +437,16 @@ bool FileManager::reloadBuffer(BufferID id) { buf->setUnicodeMode(UnicodeConvertor.getEncoding()); // buf->setNeedsLexing(true); } + return res; } +bool FileManager::reloadBufferDeferred(BufferID id) { + Buffer * buf = getBufferByID(id); + buf->setDeferredReload(); + return true; +} + bool FileManager::saveBuffer(BufferID id, const char * filename, bool isCopy) { Buffer * buffer = getBufferByID(id); bool isHidden = false; @@ -568,6 +597,14 @@ BufferID FileManager::getBufferFromName(const char * name) { return BUFFER_INVALID; } +BufferID FileManager::getBufferFromDocument(Document doc) { + for(size_t i = 0; i < _nrBufs; i++) { + if (_buffers[i]->_doc == doc) + return _buffers[i]->_id; + } + return BUFFER_INVALID; +} + bool FileManager::createEmptyFile(const char * path) { FILE * file = fopen(path, "wb"); if (!file) diff --git a/PowerEditor/src/ScitillaComponent/Buffer.h b/PowerEditor/src/ScitillaComponent/Buffer.h index ca1397765..f6953badc 100644 --- a/PowerEditor/src/ScitillaComponent/Buffer.h +++ b/PowerEditor/src/ScitillaComponent/Buffer.h @@ -83,8 +83,10 @@ public: BufferID bufferFromDocument(Document doc, bool dontIncrease = false, bool dontRef = false); BufferID getBufferFromName(const char * name); + BufferID getBufferFromDocument(Document doc); bool reloadBuffer(BufferID id); + bool reloadBufferDeferred(BufferID id); bool saveBuffer(BufferID id, const char * filename, bool isCopy = false); bool createEmptyFile(const char * path); @@ -126,7 +128,7 @@ public : //Destructor makes sure its purged Buffer(FileManager * pManager, BufferID id, Document doc, DocFileStatus type, const char *fileName) //type must be either DOC_REGULAR or DOC_UNNAMED : _pManager(pManager), _id(id), _isDirty(false), _doc(doc), _isFileReadOnly(false), _isUserReadOnly(false), _recentTag(-1), _references(0), - _canNotify(false), _timeStamp(0) + _canNotify(false), _timeStamp(0), _needReloading(false) { NppParameters *pNppParamInst = NppParameters::getInstance(); const NewDocDefaultSettings & ndds = (pNppParamInst->getNppGUI()).getNewDocDefaultSettings(); @@ -255,7 +257,7 @@ public : return _timeStamp; }; - Document getDocument() const { + Document getDocument() { return _doc; }; @@ -316,6 +318,16 @@ public : int removeReference(ScintillaEditView * identifier); //reduces reference. If zero, Document is purged void setHideLineChanged(bool isHide, int location); + + void setDeferredReload(); + + bool getNeedReload() { + return _needReloading; + } + + void setNeedReload(bool reload) { + _needReloading = reload; + } private : FileManager * _pManager; bool _canNotify; @@ -343,6 +355,7 @@ private : bool _isFileReadOnly; char _fullPathName[MAX_PATH]; char * _fileName; //points to filename part in _fullPathName + bool _needReloading; //True if Buffer needs to be reloaded on activation long _recentTag; static long _recentTagCtr;