diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 62d00e6c..17c2ae46 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -4952,7 +4952,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()), buf->getMapPosition()); + sessionFileInfo sfi(buf->getFullPathName(), langName, buf->getEncoding(), buf->getPosition(editView), buf->getBackupFileName().c_str(), 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/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h index 11a6286d..9a8160f8 100644 --- a/PowerEditor/src/Notepad_plus.h +++ b/PowerEditor/src/Notepad_plus.h @@ -174,7 +174,7 @@ public: //! \name File Operations //@{ //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 generic_string& fileName, bool isRecursive = false, bool isReadOnly = false, int encoding = -1, const TCHAR *backupFileName = NULL, time_t fileNameTimestamp = 0); + BufferID doOpen(const generic_string& fileName, bool isRecursive = false, bool isReadOnly = false, int encoding = -1, const TCHAR *backupFileName = NULL, FILETIME fileNameTimestamp = {}); bool doReload(BufferID id, bool alert = true); bool doSave(BufferID, const TCHAR * filename, bool isSaveCopy = false); void doClose(BufferID, int whichOne, bool doDeleteBackup = false); diff --git a/PowerEditor/src/NppIO.cpp b/PowerEditor/src/NppIO.cpp index 01aedcf4..c8db820f 100644 --- a/PowerEditor/src/NppIO.cpp +++ b/PowerEditor/src/NppIO.cpp @@ -121,7 +121,7 @@ DWORD WINAPI Notepad_plus::monitorFileOnChange(void * params) return EXIT_SUCCESS; } -BufferID Notepad_plus::doOpen(const generic_string& fileName, bool isRecursive, bool isReadOnly, int encoding, const TCHAR *backupFileName, time_t fileNameTimestamp) +BufferID Notepad_plus::doOpen(const generic_string& fileName, bool isRecursive, bool isReadOnly, int encoding, const TCHAR *backupFileName, FILETIME fileNameTimestamp) { const rsize_t longFileNameBufferSize = MAX_PATH; // TODO stop using fixed-size buffer if (fileName.size() >= longFileNameBufferSize - 1) // issue with all other sub-routines diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 7d257650..a02e83c1 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -2050,8 +2050,9 @@ bool NppParameters::getSessionFromXmlTree(TiXmlDocument *pSessionDoc, Session *p const TCHAR *encStr = (childNode->ToElement())->Attribute(TEXT("encoding"), &encoding); const TCHAR *backupFilePath = (childNode->ToElement())->Attribute(TEXT("backupFilePath")); - int fileModifiedTimestamp = 0; - (childNode->ToElement())->Attribute(TEXT("originalFileLastModifTimestamp"), &fileModifiedTimestamp); + FILETIME fileModifiedTimestamp; + (childNode->ToElement())->Attribute(TEXT("originalFileLastModifTimestamp"), reinterpret_cast(&fileModifiedTimestamp.dwLowDateTime)); + (childNode->ToElement())->Attribute(TEXT("originalFileLastModifTimestampHigh"), reinterpret_cast(&fileModifiedTimestamp.dwHighDateTime)); sessionFileInfo sfi(fileName, langName, encStr?encoding:-1, position, backupFilePath, fileModifiedTimestamp, mapPosition); @@ -2985,7 +2986,8 @@ void NppParameters::writeSession(const Session & session, const TCHAR *fileName) (fileNameNode->ToElement())->SetAttribute(TEXT("encoding"), viewSessionFiles[i]._encoding); (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)); + (fileNameNode->ToElement())->SetAttribute(TEXT("originalFileLastModifTimestamp"), static_cast(viewSessionFiles[i]._originalFileLastModifTimestamp.dwLowDateTime)); + (fileNameNode->ToElement())->SetAttribute(TEXT("originalFileLastModifTimestampHigh"), static_cast(viewSessionFiles[i]._originalFileLastModifTimestamp.dwHighDateTime)); // docMap (fileNameNode->ToElement())->SetAttribute(TEXT("mapFirstVisibleDisplayLine"), viewSessionFiles[i]._mapPos._firstVisibleDisplayLine); diff --git a/PowerEditor/src/Parameters.h b/PowerEditor/src/Parameters.h index b343acd3..e4c61921 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -162,7 +162,7 @@ private: struct sessionFileInfo : public Position { - sessionFileInfo(const TCHAR *fn, const TCHAR *ln, int encoding, Position pos, const TCHAR *backupFilePath, int originalFileLastModifTimestamp, const MapPosition & mapPos) : + sessionFileInfo(const TCHAR *fn, const TCHAR *ln, int encoding, Position pos, const TCHAR *backupFilePath, FILETIME originalFileLastModifTimestamp, const MapPosition & mapPos) : _encoding(encoding), Position(pos), _originalFileLastModifTimestamp(originalFileLastModifTimestamp), _mapPos(mapPos) { if (fn) _fileName = fn; @@ -179,7 +179,7 @@ struct sessionFileInfo : public Position int _encoding = -1; generic_string _backupFilePath; - time_t _originalFileLastModifTimestamp = 0; + FILETIME _originalFileLastModifTimestamp = {}; MapPosition _mapPos; }; diff --git a/PowerEditor/src/ScitillaComponent/Buffer.cpp b/PowerEditor/src/ScitillaComponent/Buffer.cpp index 1126c4ac..36aa3179 100644 --- a/PowerEditor/src/ScitillaComponent/Buffer.cpp +++ b/PowerEditor/src/ScitillaComponent/Buffer.cpp @@ -144,10 +144,14 @@ void Buffer::setLangType(LangType lang, const TCHAR* userLangName) void Buffer::updateTimeStamp() { - struct _stat buf; - time_t timeStamp = (generic_stat(_fullPathName.c_str(), &buf)==0)?buf.st_mtime:0; + FILETIME timeStamp = {}; + WIN32_FILE_ATTRIBUTE_DATA attributes; + if (GetFileAttributesEx(_fullPathName.c_str(), GetFileExInfoStandard, &attributes) != 0) + { + timeStamp = attributes.ftLastWriteTime; + } - if (timeStamp != _timeStamp) + if (CompareFileTime(&_timeStamp, &timeStamp) != 0) { _timeStamp = timeStamp; doNotify(BufferChangeTimestamp); @@ -222,7 +226,7 @@ bool Buffer::checkFileState() //eturns true if the status has been changed (it c if (_currentStatus == DOC_UNNAMED) //unsaved document cannot change by environment return false; - struct _stat buf; + WIN32_FILE_ATTRIBUTE_DATA attributes; bool isWow64Off = false; NppParameters *pNppParam = NppParameters::getInstance(); @@ -238,18 +242,18 @@ bool Buffer::checkFileState() //eturns true if the status has been changed (it c _currentStatus = DOC_DELETED; _isFileReadOnly = false; _isDirty = true; //dirty sicne no match with filesystem - _timeStamp = 0; + _timeStamp = {}; doNotify(BufferChangeStatus | BufferChangeReadonly | BufferChangeTimestamp); isOK = true; } else if (_currentStatus == DOC_DELETED && PathFileExists(_fullPathName.c_str())) { //document has returned from its grave - if (not generic_stat(_fullPathName.c_str(), &buf)) + if (GetFileAttributesEx(_fullPathName.c_str(), GetFileExInfoStandard, &attributes) != 0) { - _isFileReadOnly = (bool)(!(buf.st_mode & _S_IWRITE)); + _isFileReadOnly = attributes.dwFileAttributes & FILE_ATTRIBUTE_READONLY; _currentStatus = DOC_MODIFIED; - _timeStamp = buf.st_mtime; + _timeStamp = attributes.ftLastWriteTime; if (_reloadFromDiskRequestGuard.try_lock()) { @@ -259,18 +263,18 @@ bool Buffer::checkFileState() //eturns true if the status has been changed (it c isOK = true; } } - else if (not generic_stat(_fullPathName.c_str(), &buf)) + else if (GetFileAttributesEx(_fullPathName.c_str(), GetFileExInfoStandard, &attributes) != 0) { int mask = 0; //status always 'changes', even if from modified to modified - bool isFileReadOnly = (bool)(not(buf.st_mode & _S_IWRITE)); + bool isFileReadOnly = attributes.dwFileAttributes & FILE_ATTRIBUTE_READONLY; if (isFileReadOnly != _isFileReadOnly) { _isFileReadOnly = isFileReadOnly; mask |= BufferChangeReadonly; } - if (_timeStamp != buf.st_mtime) + if (CompareFileTime(&_timeStamp, &attributes.ftLastWriteTime) != 0) { - _timeStamp = buf.st_mtime; + _timeStamp = attributes.ftLastWriteTime; mask |= BufferChangeTimestamp; _currentStatus = DOC_MODIFIED; mask |= BufferChangeStatus; //status always 'changes', even if from modified to modified @@ -300,10 +304,10 @@ bool Buffer::checkFileState() //eturns true if the status has been changed (it c void Buffer::reload() { - struct _stat buf; - if (PathFileExists(_fullPathName.c_str()) && not generic_stat(_fullPathName.c_str(), &buf)) + WIN32_FILE_ATTRIBUTE_DATA attributes; + if (GetFileAttributesEx(_fullPathName.c_str(), GetFileExInfoStandard, &attributes) != 0) { - _timeStamp = buf.st_mtime; + _timeStamp = attributes.ftLastWriteTime; _currentStatus = DOC_NEEDRELOAD; doNotify(BufferChangeTimestamp | BufferChangeStatus); } @@ -552,7 +556,7 @@ void FileManager::closeBuffer(BufferID id, ScintillaEditView * identifier) // backupFileName is sentinel of backup mode: if it's not NULL, then we use it (load it). Otherwise we use filename -BufferID FileManager::loadFile(const TCHAR * filename, Document doc, int encoding, const TCHAR *backupFileName, time_t fileNameTimestamp) +BufferID FileManager::loadFile(const TCHAR * filename, Document doc, int encoding, const TCHAR *backupFileName, FILETIME fileNameTimestamp) { bool ownDoc = false; if (doc == NULL) @@ -593,7 +597,8 @@ BufferID FileManager::loadFile(const TCHAR * filename, Document doc, int encodin newBuf->_currentStatus = DOC_UNNAMED; } - if (fileNameTimestamp != 0) + const FILETIME zeroTime = {}; + if (CompareFileTime(&fileNameTimestamp, &zeroTime) != 0) newBuf->_timeStamp = fileNameTimestamp; _buffers.push_back(newBuf); diff --git a/PowerEditor/src/ScitillaComponent/Buffer.h b/PowerEditor/src/ScitillaComponent/Buffer.h index 544ba7ed..71519599 100644 --- a/PowerEditor/src/ScitillaComponent/Buffer.h +++ b/PowerEditor/src/ScitillaComponent/Buffer.h @@ -87,7 +87,7 @@ public: void addBufferReference(BufferID id, ScintillaEditView * identifer); //called by Scintilla etc indirectly - BufferID loadFile(const TCHAR * filename, Document doc = NULL, int encoding = -1, const TCHAR *backupFileName = NULL, time_t fileNameTimestamp = 0); //ID == BUFFER_INVALID on failure. If Doc == NULL, a new file is created, otherwise data is loaded in given document + BufferID loadFile(const TCHAR * filename, Document doc = NULL, int encoding = -1, const TCHAR *backupFileName = NULL, FILETIME fileNameTimestamp = {}); //ID == BUFFER_INVALID on failure. If Doc == NULL, a new file is created, otherwise data is loaded in given document BufferID newEmptyDocument(); //create Buffer from existing Scintilla, used from new Scintillas. If dontIncrease = true, then the new document number isnt increased afterwards. //usefull for temporary but neccesary docs @@ -321,7 +321,7 @@ public: void setModifiedStatus(bool isModified) { _isModified = isModified; } generic_string getBackupFileName() const { return _backupFileName; } void setBackupFileName(generic_string fileName) { _backupFileName = fileName; } - time_t getLastModifiedTimestamp() const { return _timeStamp; } + FILETIME getLastModifiedTimestamp() const { return _timeStamp; } bool isLoadedDirty() const { @@ -394,7 +394,7 @@ private: //Environment properties DocFileStatus _currentStatus; - time_t _timeStamp = 0; // 0 if it's a new doc + FILETIME _timeStamp = {}; // 0 if it's a new doc bool _isFileReadOnly = false; generic_string _fullPathName;