Browse Source

Add tab created time tooltip for new opened untitled tab

Note: while create the new tab (empty & clean), there will be a created time displayed. When the document is modified and period backup feature is enabled, a new created time will be assigned and displayed. However, the time of the first modification which makes empty document dirty will be remained as the tab creation time, even with several modification afterward.

Fix #15563, close #15651
pull/15670/head
Don Ho 2 months ago
parent
commit
fc051a1231
  1. 2
      PowerEditor/src/Notepad_plus.h
  2. 2
      PowerEditor/src/NppBigSwitch.cpp
  3. 88
      PowerEditor/src/NppIO.cpp
  4. 15
      PowerEditor/src/NppNotification.cpp
  5. 77
      PowerEditor/src/ScintillaComponent/Buffer.cpp
  6. 17
      PowerEditor/src/ScintillaComponent/Buffer.h

2
PowerEditor/src/Notepad_plus.h

@ -190,7 +190,7 @@ public:
bool fileSaveAs(BufferID id = BUFFER_INVALID, bool isSaveCopy = false);
bool fileDelete(BufferID id = BUFFER_INVALID);
bool fileRename(BufferID id = BUFFER_INVALID);
bool fileRenameUntitled(BufferID id, const wchar_t* tabNewName);
bool fileRenameUntitledPluginAPI(BufferID id, const wchar_t* tabNewName);
bool switchToFile(BufferID buffer); //find buffer in active view then in other view.
//@}

2
PowerEditor/src/NppBigSwitch.cpp

@ -3150,7 +3150,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
case NPPM_SETUNTITLEDNAME:
{
if (!wParam || !lParam) return FALSE;
return fileRenameUntitled(reinterpret_cast<BufferID>(wParam), reinterpret_cast<const wchar_t*>(lParam));
return fileRenameUntitledPluginAPI(reinterpret_cast<BufferID>(wParam), reinterpret_cast<const wchar_t*>(lParam));
}
case NPPM_GETBOOKMARKID:

88
PowerEditor/src/NppIO.cpp

@ -1949,7 +1949,8 @@ bool Notepad_plus::fileRename(BufferID id)
scnN.nmhdr.idFrom = (uptr_t)bufferID;
bool success = false;
bool isFileExisting = doesFileExist(buf->getFullPathName());
wstring oldFileNamePath = buf->getFullPathName();
bool isFileExisting = doesFileExist(oldFileNamePath.c_str());
if (isFileExisting)
{
CustomFileDialog fDlg(_pPublicInterface->getHSelf());
@ -1977,16 +1978,16 @@ bool Notepad_plus::fileRename(BufferID id)
// We are just going to rename the tab nothing else
// So just rename the tab and rename the backup file too if applicable
std::wstring staticName = _nativeLangSpeaker.getLocalizedStrFromID("tabrename-newname", L"New name");
wstring staticName = _nativeLangSpeaker.getLocalizedStrFromID("tabrename-newname", L"New name");
StringDlg strDlg;
std::wstring title = _nativeLangSpeaker.getLocalizedStrFromID("tabrename-title", L"Rename Current Tab");
wstring title = _nativeLangSpeaker.getLocalizedStrFromID("tabrename-title", L"Rename Current Tab");
strDlg.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), title.c_str(), staticName.c_str(), buf->getFileName(), langNameLenMax - 1, filenameReservedChars.c_str(), true);
wchar_t *tabNewName = reinterpret_cast<wchar_t *>(strDlg.doDialog());
if (tabNewName)
{
std::wstring tabNewNameStr = tabNewName;
wstring tabNewNameStr = tabNewName;
trim(tabNewNameStr); // No leading and tailing space allowed
BufferID sameNamedBufferId = _pDocTab->findBufferByName(tabNewNameStr.c_str());
@ -2023,18 +2024,21 @@ bool Notepad_plus::fileRename(BufferID id)
bool isSnapshotMode = NppParameters::getInstance().getNppGUI().isSnapshotMode();
if (isSnapshotMode)
{
std::wstring oldBackUpFile = buf->getBackupFileName();
wstring oldBackUpFileName = buf->getBackupFileName();
if (oldBackUpFileName.empty())
return success;
// Change the backup file name and let MainFileManager decide the new filename
buf->setBackupFileName(L"");
wstring newBackUpFileName = oldBackUpFileName;
// Create new backup
buf->setModifiedStatus(true);
bool bRes = MainFileManager.backupCurrentBuffer();
size_t index = newBackUpFileName.find_last_of(oldFileNamePath) - oldFileNamePath.length() + 1;
newBackUpFileName.replace(index, oldFileNamePath.length(), tabNewNameStr);
// Delete old backup
if (bRes)
::DeleteFile(oldBackUpFile.c_str());
if (doesFileExist(newBackUpFileName.c_str()))
::ReplaceFile(newBackUpFileName.c_str(), oldBackUpFileName.c_str(), nullptr, REPLACEFILE_IGNORE_MERGE_ERRORS | REPLACEFILE_IGNORE_ACL_ERRORS, 0, 0);
else
::MoveFileEx(oldBackUpFileName.c_str(), newBackUpFileName.c_str(), MOVEFILE_REPLACE_EXISTING);
buf->setBackupFileName(newBackUpFileName);
}
}
}
@ -2043,17 +2047,17 @@ bool Notepad_plus::fileRename(BufferID id)
return success;
}
bool Notepad_plus::fileRenameUntitled(BufferID id, const wchar_t* tabNewName)
bool Notepad_plus::fileRenameUntitledPluginAPI(BufferID id, const wchar_t* tabNewName)
{
BufferID bufferID = id;
if (id == BUFFER_INVALID)
{
bufferID = _pEditView->getCurrentBufferID();
}
Buffer* buf = MainFileManager.getBufferByID(bufferID);
bool isFileExisting = doesFileExist(buf->getFullPathName());
if (isFileExisting) return false;
if (!buf->isUntitled()) return false;
// We are just going to rename the tab nothing else
// So just rename the tab and rename the backup file too if applicable
@ -2076,37 +2080,39 @@ bool Notepad_plus::fileRenameUntitled(BufferID id, const wchar_t* tabNewName)
sameNamedBufferId = _pNonDocTab->findBufferByName(tabNewNameStr.c_str());
}
if (sameNamedBufferId == BUFFER_INVALID)
{
SCNotification scnN{};
scnN.nmhdr.code = NPPN_FILEBEFORERENAME;
scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf();
scnN.nmhdr.idFrom = (uptr_t)bufferID;
_pluginsManager.notify(&scnN);
if (sameNamedBufferId != BUFFER_INVALID) return false;
buf->setFileName(tabNewNameStr.c_str());
scnN.nmhdr.code = NPPN_FILERENAMED;
_pluginsManager.notify(&scnN);
SCNotification scnN{};
scnN.nmhdr.code = NPPN_FILEBEFORERENAME;
scnN.nmhdr.hwndFrom = _pPublicInterface->getHSelf();
scnN.nmhdr.idFrom = (uptr_t)bufferID;
_pluginsManager.notify(&scnN);
bool isSnapshotMode = NppParameters::getInstance().getNppGUI().isSnapshotMode();
if (isSnapshotMode)
{
std::wstring oldBackUpFile = buf->getBackupFileName();
buf->setFileName(tabNewNameStr.c_str());
scnN.nmhdr.code = NPPN_FILERENAMED;
_pluginsManager.notify(&scnN);
bool isSnapshotMode = NppParameters::getInstance().getNppGUI().isSnapshotMode();
if (isSnapshotMode)
{
wstring oldName = buf->getFullPathName();
wstring oldBackUpFileName = buf->getBackupFileName();
if (oldBackUpFileName.empty())
return false;
// Change the backup file name and let MainFileManager decide the new filename
buf->setBackupFileName(L"");
wstring newBackUpFileName = oldBackUpFileName;
// Create new backup
buf->setModifiedStatus(true);
bool bRes = MainFileManager.backupCurrentBuffer();
size_t index = newBackUpFileName.find_last_of(oldName) - oldName.length() + 1;
newBackUpFileName.replace(index, oldName.length(), tabNewNameStr);
// Delete old backup
if (bRes)
{
::DeleteFile(oldBackUpFile.c_str());
}
}
if (doesFileExist(newBackUpFileName.c_str()))
::ReplaceFile(newBackUpFileName.c_str(), oldBackUpFileName.c_str(), nullptr, REPLACEFILE_IGNORE_MERGE_ERRORS | REPLACEFILE_IGNORE_ACL_ERRORS, 0, 0);
else
::MoveFileEx(oldBackUpFileName.c_str(), newBackUpFileName.c_str(), MOVEFILE_REPLACE_EXISTING);
buf->setBackupFileName(newBackUpFileName);
}
return true;

15
PowerEditor/src/NppNotification.cpp

@ -995,14 +995,27 @@ BOOL Notepad_plus::notify(SCNotification *notification)
else
return FALSE;
Buffer * buf = MainFileManager.getBufferByID(idd);
Buffer* buf = MainFileManager.getBufferByID(idd);
if (buf == nullptr)
return FALSE;
tipTmp = buf->getFullPathName();
wstring tabCreatedTime = buf->tabCreatedTimeString();
if (!tabCreatedTime.empty())
{
tipTmp += L"\r";
tipTmp += tabCreatedTime;
SendMessage(lpttt->hdr.hwndFrom, TTM_SETMAXTIPWIDTH, 0, 200);
}
else
{
SendMessage(lpttt->hdr.hwndFrom, TTM_SETMAXTIPWIDTH, 0, -1);
}
if (tipTmp.length() >= tipMaxLen)
return FALSE;
wcscpy_s(docTip, tipTmp.c_str());
lpttt->lpszText = docTip;
return TRUE;

77
PowerEditor/src/ScintillaComponent/Buffer.cpp

@ -398,46 +398,51 @@ int64_t Buffer::getFileLength() const
return -1;
}
wstring Buffer::getFileTime(fileTimeType ftt) const
wstring Buffer::getTimeString(FILETIME rawtime) const
{
wstring result;
SYSTEMTIME utcSystemTime, localSystemTime;
FileTimeToSystemTime(&rawtime, &utcSystemTime);
SystemTimeToTzSpecificLocalTime(nullptr, &utcSystemTime, &localSystemTime);
if (_currentStatus != DOC_UNNAMED)
{
WIN32_FILE_ATTRIBUTE_DATA attributes{};
if (GetFileAttributesEx(_fullPathName.c_str(), GetFileExInfoStandard, &attributes) != 0)
{
FILETIME rawtime;
switch (ftt)
{
case ft_created:
rawtime = attributes.ftCreationTime;
break;
case ft_modified:
rawtime = attributes.ftLastWriteTime;
break;
default:
rawtime = attributes.ftLastAccessTime;
break;
}
const size_t dateTimeStrLen = 256;
wchar_t bufDate[dateTimeStrLen] = { '\0' };
GetDateFormat(LOCALE_USER_DEFAULT, 0, &localSystemTime, nullptr, bufDate, dateTimeStrLen);
result += bufDate;
result += ' ';
SYSTEMTIME utcSystemTime, localSystemTime;
FileTimeToSystemTime(&rawtime, &utcSystemTime);
SystemTimeToTzSpecificLocalTime(nullptr, &utcSystemTime, &localSystemTime);
wchar_t bufTime[dateTimeStrLen] = { '\0' };
GetTimeFormat(LOCALE_USER_DEFAULT, 0, &localSystemTime, nullptr, bufTime, dateTimeStrLen);
result += bufTime;
const size_t dateTimeStrLen = 256;
wchar_t bufDate[dateTimeStrLen] = {'\0'};
GetDateFormat(LOCALE_USER_DEFAULT, 0, &localSystemTime, nullptr, bufDate, dateTimeStrLen);
result += bufDate;
result += ' ';
return result;
}
wstring Buffer::getFileTime(fileTimeType ftt) const
{
wstring filePath;
wchar_t bufTime[dateTimeStrLen] = {'\0'};
GetTimeFormat(LOCALE_USER_DEFAULT, 0, &localSystemTime, nullptr, bufTime, dateTimeStrLen);
result += bufTime;
WIN32_FILE_ATTRIBUTE_DATA attributes{};
if (GetFileAttributesEx(_currentStatus == DOC_UNNAMED ? _backupFileName.c_str() : _fullPathName.c_str(), GetFileExInfoStandard, &attributes) != 0)
{
FILETIME rawtime;
switch (ftt)
{
case ft_created:
rawtime = attributes.ftCreationTime;
break;
case ft_modified:
rawtime = attributes.ftLastWriteTime;
break;
default:
rawtime = attributes.ftLastAccessTime;
break;
}
return getTimeString(rawtime);
}
return result;
return L"";
}
@ -779,7 +784,10 @@ BufferID FileManager::loadFile(const wchar_t* filename, Document doc, int encodi
{
newBuf->_backupFileName = backupFileName;
if (!doesFileExist(fullpath))
{
newBuf->_currentStatus = DOC_UNNAMED;
newBuf->setTabCreatedTimeStringFromBakFile();
}
}
const FILETIME zeroTimeStamp = {};
@ -1085,7 +1093,8 @@ bool FileManager::backupCurrentBuffer()
::MoveFileEx(fullpathTemp.c_str(), fullpath, MOVEFILE_REPLACE_EXISTING);
}
buffer->setModifiedStatus(false);
buffer->setTabCreatedTimeStringFromBakFile();
result = true; //all done
}
}
@ -1365,6 +1374,7 @@ BufferID FileManager::newEmptyDocument()
BufferID id = newBuf;
newBuf->_id = id;
newBuf->setTabCreatedTimeStringWithCurrentTime();
_buffers.push_back(newBuf);
++_nbBufs;
++_nextBufferID;
@ -1432,6 +1442,7 @@ BufferID FileManager::bufferFromDocument(Document doc, bool isMainEditZone)
newBuf->_id = id;
const NewDocDefaultSettings& ndds = (nppParamInst.getNppGUI()).getNewDocDefaultSettings();
newBuf->_lang = ndds._lang;
newBuf->setTabCreatedTimeStringWithCurrentTime();
_buffers.push_back(newBuf);
++_nbBufs;

17
PowerEditor/src/ScintillaComponent/Buffer.h

@ -277,6 +277,20 @@ public:
bool getNeedReload() const { return _needReloading; }
void setNeedReload(bool reload) { _needReloading = reload; }
std::wstring tabCreatedTimeString() const { return _tabCreatedTimeString; }
void setTabCreatedTimeStringFromBakFile() {
if (_currentStatus == DOC_UNNAMED)
_tabCreatedTimeString = getFileTime(Buffer::ft_created); // while DOC_UNNAMED, getFileTime will retrieve time from backup file
}
void setTabCreatedTimeStringWithCurrentTime() {
if (_currentStatus == DOC_UNNAMED)
{
FILETIME now{};
GetSystemTimeAsFileTime(&now);
_tabCreatedTimeString = getTimeString(now);
}
}
size_t docLength() const {
assert(_pManager != nullptr);
return _pManager->docLength(_id);
@ -286,6 +300,7 @@ public:
enum fileTimeType { ft_created, ft_modified, ft_accessed };
std::wstring getFileTime(fileTimeType ftt) const;
std::wstring getTimeString(FILETIME rawtime) const;
Lang * getCurrentLang() const;
@ -391,6 +406,8 @@ private:
wchar_t * _fileName = nullptr; // points to filename part in _fullPathName
bool _needReloading = false; // True if Buffer needs to be reloaded on activation
std::wstring _tabCreatedTimeString;
long _recentTag = -1;
static long _recentTagCtr;

Loading…
Cancel
Save