Add Window dialog "File Modified Time" sorting capacity

Fix #16953, close #16954
This commit is contained in:
Get Lit Games 2025-08-30 00:01:22 -04:00 committed by Don Ho
parent 105a141a43
commit 5528fed4b0
6 changed files with 111 additions and 3 deletions

View File

@ -1619,6 +1619,7 @@ Please verify the search condition before performing the action."/> <!-- HowToRe
<ColumnPath name="Path"/> <ColumnPath name="Path"/>
<ColumnType name="Type"/> <ColumnType name="Type"/>
<ColumnSize name="Size"/> <ColumnSize name="Size"/>
<ColumnDateTime name="Date/Time"/>
<NbDocsTotal name="total documents:"/> <NbDocsTotal name="total documents:"/>
<MenuCopyName name="Copy Name(s)"/> <MenuCopyName name="Copy Name(s)"/>
<MenuCopyPath name="Copy Pathname(s)"/> <MenuCopyPath name="Copy Pathname(s)"/>
@ -1898,3 +1899,5 @@ If you select advanced mode but do not edit files in the aforementioned language
</MiscStrings> </MiscStrings>
</Native-Langue> </Native-Langue>
</NotepadPlus> </NotepadPlus>

View File

@ -1321,6 +1321,8 @@ BEGIN
MENUITEM "Type Z to A", IDM_WINDOW_SORT_FT_DSC MENUITEM "Type Z to A", IDM_WINDOW_SORT_FT_DSC
MENUITEM "Content Length Ascending", IDM_WINDOW_SORT_FS_ASC MENUITEM "Content Length Ascending", IDM_WINDOW_SORT_FS_ASC
MENUITEM "Content Length Descending", IDM_WINDOW_SORT_FS_DSC MENUITEM "Content Length Descending", IDM_WINDOW_SORT_FS_DSC
MENUITEM "Date/Time Ascending", IDM_WINDOW_SORT_FD_ASC
MENUITEM "Date/Time Descending", IDM_WINDOW_SORT_FD_DSC
END END
MENUITEM "&Windows...", IDM_WINDOW_WINDOWS MENUITEM "&Windows...", IDM_WINDOW_WINDOWS
MENUITEM SEPARATOR MENUITEM SEPARATOR

View File

@ -3947,6 +3947,24 @@ void Notepad_plus::command(int id)
} }
break; break;
case IDM_WINDOW_SORT_FD_ASC:
{
WindowsDlg windowsDlg;
windowsDlg.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), _pDocTab);
windowsDlg.sortDateTimeASC();
windowsDlg.doSort();
}
break;
case IDM_WINDOW_SORT_FD_DSC:
{
WindowsDlg windowsDlg;
windowsDlg.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), _pDocTab);
windowsDlg.sortDateTimeDSC();
windowsDlg.doSort();
}
break;
case IDM_SYSTRAYPOPUP_NEWDOC: case IDM_SYSTRAYPOPUP_NEWDOC:
{ {
NppGUI & nppGUI = (NppParameters::getInstance()).getNppGUI(); NppGUI & nppGUI = (NppParameters::getInstance()).getNppGUI();

View File

@ -38,6 +38,7 @@ using namespace std;
#define WD_CLMNPATH "ColumnPath" #define WD_CLMNPATH "ColumnPath"
#define WD_CLMNTYPE "ColumnType" #define WD_CLMNTYPE "ColumnType"
#define WD_CLMNSIZE "ColumnSize" #define WD_CLMNSIZE "ColumnSize"
#define WD_CLMNDT "ColumnDateTime"
#define WD_NBDOCSTOTAL "NbDocsTotal" #define WD_NBDOCSTOTAL "NbDocsTotal"
#define WD_MENUCOPYNAME "MenuCopyName" #define WD_MENUCOPYNAME "MenuCopyName"
#define WD_MENUCOPYPATH "MenuCopyPath" #define WD_MENUCOPYPATH "MenuCopyPath"
@ -151,9 +152,17 @@ struct BufferEquivalent
return compare(i1, i2); return compare(i1, i2);
} }
static inline unsigned long long to_u64(const FILETIME& ft)
{
ULARGE_INTEGER u;
u.LowPart = ft.dwLowDateTime;
u.HighPart = ft.dwHighDateTime;
return u.QuadPart; // 100-ns ticks since 1601 UTC
}
bool compare(int i1, int i2) const bool compare(int i1, int i2) const
{ {
if (_iColumn >= 0 && _iColumn <= 3) if (_iColumn >= 0 && _iColumn <= 4)
{ {
BufferID bid1 = _pTab->getBufferByIndex(i1); BufferID bid1 = _pTab->getBufferByIndex(i1);
BufferID bid2 = _pTab->getBufferByIndex(i2); BufferID bid2 = _pTab->getBufferByIndex(i2);
@ -206,6 +215,14 @@ struct BufferEquivalent
if (t1 != t2) // default to filepath sorting when equivalent if (t1 != t2) // default to filepath sorting when equivalent
return (t1 < t2); return (t1 < t2);
} }
else if (_iColumn == 4)
{
const auto v1 = to_u64(b1->getLastModifiedTimestamp());
const auto v2 = to_u64(b2->getLastModifiedTimestamp());
if (v1 != v2)
return (v1 < v2); //_isAscending ? (v1 < v2) : (v1 > v2);
}
// _iColumn == 1 // _iColumn == 1
const wchar_t *s1 = b1->getFullPathName(); const wchar_t *s1 = b1->getFullPathName();
@ -429,7 +446,8 @@ intptr_t CALLBACK WindowsDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP
const wchar_t *fullName = buf->getFullPathName(); const wchar_t *fullName = buf->getFullPathName();
const wchar_t *fileName = buf->getFileName(); const wchar_t *fileName = buf->getFileName();
int len = lstrlen(fullName)-lstrlen(fileName); int len = lstrlen(fullName)-lstrlen(fileName);
if (!len) { if (!len)
{
len = 1; len = 1;
fullName = L""; fullName = L"";
} }
@ -450,6 +468,33 @@ intptr_t CALLBACK WindowsDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP
string docSizeText = to_string(docSize); string docSizeText = to_string(docSize);
text = wstring(docSizeText.begin(), docSizeText.end()); text = wstring(docSizeText.begin(), docSizeText.end());
} }
else if (pLvdi->item.iSubItem == 4) // Date/Time
{
FILETIME ft = buf->getLastModifiedTimestamp();
// handle unsaved or unknown timestamp
if (ft.dwLowDateTime == 0 && ft.dwHighDateTime == 0)
{
text = L""; // or L"—"
}
else
{
FILETIME localFt{};
SYSTEMTIME st{};
if (FileTimeToLocalFileTime(&ft, &localFt) && FileTimeToSystemTime(&localFt, &st))
{
wchar_t bufW[20]; // "YYYY-MM-DD HH:MM:SS" = 19 + NUL
swprintf(bufW, 20, L"%04u-%02u-%02u %02u:%02u:%02u",
st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond);
text = bufW;
}
else
{
text = L"";
}
}
}
if (static_cast<int>(text.length()) < pLvdi->item.cchTextMax) if (static_cast<int>(text.length()) < pLvdi->item.cchTextMax)
{ {
@ -752,6 +797,11 @@ BOOL WindowsDlg::onInitDialog()
lvColumn.cx = 100; lvColumn.cx = 100;
SendMessage(_hList, LVM_INSERTCOLUMN, 3, LPARAM(&lvColumn)); SendMessage(_hList, LVM_INSERTCOLUMN, 3, LPARAM(&lvColumn));
columnText = L"" + pNativeSpeaker->getAttrNameStr(L"Date/Time", WD_ROOTNODE, WD_CLMNDT);
lvColumn.pszText = const_cast<wchar_t*>(columnText.c_str());
lvColumn.cx = 120;
SendMessage(_hList, LVM_INSERTCOLUMN, 4, LPARAM(&lvColumn));
fitColumnsToSize(); fitColumnsToSize();
if (_lastKnownLocation.bottom > 0 && _lastKnownLocation.right > 0) if (_lastKnownLocation.bottom > 0 && _lastKnownLocation.right > 0)
@ -845,6 +895,25 @@ void WindowsDlg::updateColumnNames()
lvColumn.pszText = const_cast<wchar_t *>(columnText.c_str()); lvColumn.pszText = const_cast<wchar_t *>(columnText.c_str());
lvColumn.cx = static_cast<int>(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 3, 0)); lvColumn.cx = static_cast<int>(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 3, 0));
SendMessage(_hList, LVM_SETCOLUMN, 3, LPARAM(&lvColumn)); SendMessage(_hList, LVM_SETCOLUMN, 3, LPARAM(&lvColumn));
// Date/Time
lvColumn.fmt = LVCFMT_LEFT;
columnText = pNativeSpeaker->getAttrNameStr(L"Date/Time", WD_ROOTNODE, WD_CLMNDT);
if (_currentColumn != 4)
{
columnText = L"" + columnText;
}
else if (_reverseSort)
{
columnText = L"" + columnText;
}
else
{
columnText = L"" + columnText;
}
lvColumn.pszText = const_cast<wchar_t*>(columnText.c_str());
lvColumn.cx = static_cast<int>(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 4, 0));
SendMessage(_hList, LVM_SETCOLUMN, 4, LPARAM(&lvColumn));
} }
void WindowsDlg::onSize(UINT nType, int cx, int cy) void WindowsDlg::onSize(UINT nType, int cx, int cy)
@ -861,7 +930,8 @@ void WindowsDlg::onGetMinMaxInfo(MINMAXINFO* lpMMI)
LRESULT WindowsDlg::onWinMgr(WPARAM wp, LPARAM lp) LRESULT WindowsDlg::onWinMgr(WPARAM wp, LPARAM lp)
{ {
NMWINMGR &nmw = *reinterpret_cast<NMWINMGR *>(lp); NMWINMGR &nmw = *reinterpret_cast<NMWINMGR *>(lp);
if (nmw.code==NMWINMGR::GET_SIZEINFO) { if (nmw.code==NMWINMGR::GET_SIZEINFO)
{
switch(wp) switch(wp)
{ {
case IDOK: case IDOK:
@ -923,6 +993,7 @@ void WindowsDlg::fitColumnsToSize()
len -= static_cast<int>(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 0, 0)); len -= static_cast<int>(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 0, 0));
len -= static_cast<int>(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 2, 0)); len -= static_cast<int>(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 2, 0));
len -= static_cast<int>(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 3, 0)); len -= static_cast<int>(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 3, 0));
len -= static_cast<int>(SendMessage(_hList, LVM_GETCOLUMNWIDTH, 4, 0));
len -= GetSystemMetrics(SM_CXVSCROLL); len -= GetSystemMetrics(SM_CXVSCROLL);
len -= 1; len -= 1;
SendMessage(_hList, LVM_SETCOLUMNWIDTH, 1, len); SendMessage(_hList, LVM_SETCOLUMNWIDTH, 1, len);
@ -1164,6 +1235,16 @@ void WindowsDlg::sortFileSizeDSC()
sort(3, true); sort(3, true);
} }
void WindowsDlg::sortDateTimeASC()
{
sort(4, false);
}
void WindowsDlg::sortDateTimeDSC()
{
sort(4, true);
}
void WindowsDlg::refreshMap() void WindowsDlg::refreshMap()
{ {
size_t count = (_pTab != NULL) ? _pTab->nbItem() : 0; size_t count = (_pTab != NULL) ? _pTab->nbItem() : 0;

View File

@ -65,6 +65,8 @@ public :
void sortFileTypeDSC(); void sortFileTypeDSC();
void sortFileSizeASC(); void sortFileSizeASC();
void sortFileSizeDSC(); void sortFileSizeDSC();
void sortDateTimeASC();
void sortDateTimeDSC();
void doRefresh(bool invalidate = false); void doRefresh(bool invalidate = false);
public: public:

View File

@ -643,6 +643,8 @@
#define IDM_WINDOW_SORT_FT_DSC (IDR_WINDOWS_MENU + 7) #define IDM_WINDOW_SORT_FT_DSC (IDR_WINDOWS_MENU + 7)
#define IDM_WINDOW_SORT_FS_ASC (IDR_WINDOWS_MENU + 8) #define IDM_WINDOW_SORT_FS_ASC (IDR_WINDOWS_MENU + 8)
#define IDM_WINDOW_SORT_FS_DSC (IDR_WINDOWS_MENU + 9) #define IDM_WINDOW_SORT_FS_DSC (IDR_WINDOWS_MENU + 9)
#define IDM_WINDOW_SORT_FD_ASC (IDR_WINDOWS_MENU + 10)
#define IDM_WINDOW_SORT_FD_DSC (IDR_WINDOWS_MENU + 11)
#define IDM_WINDOW_MRU_FIRST (IDR_WINDOWS_MENU + 20) #define IDM_WINDOW_MRU_FIRST (IDR_WINDOWS_MENU + 20)
#define IDM_WINDOW_MRU_LIMIT (IDR_WINDOWS_MENU + 59) #define IDM_WINDOW_MRU_LIMIT (IDR_WINDOWS_MENU + 59)
#define IDM_WINDOW_COPY_NAME (IDM_WINDOW_MRU_LIMIT + 1) #define IDM_WINDOW_COPY_NAME (IDM_WINDOW_MRU_LIMIT + 1)