Add copy file names capacity from Windows dialog

Fix #10123, close #10194
This commit is contained in:
mere-human 2021-07-18 21:13:07 +03:00 committed by Don Ho
parent 81b21aae2a
commit 8e38b9daba
4 changed files with 123 additions and 33 deletions

View File

@ -1269,6 +1269,8 @@ You can re-activate this dialog in Preferences dialog later." /> <!-- HowToRepro
<ColumnType name="Type"/> <ColumnType name="Type"/>
<ColumnSize name="Size"/> <ColumnSize name="Size"/>
<NbDocsTotal name="total documents:"/> <NbDocsTotal name="total documents:"/>
<MenuCopyName name="Copy Name(s)"/>
<MenuCopyPath name="Copy Pathname(s)"/>
</WindowsDlg> </WindowsDlg>
<AsciiInsertion> <AsciiInsertion>
<PanelTitle name="ASCII Codes Insertion Panel"/> <PanelTitle name="ASCII Codes Insertion Panel"/>

View File

@ -39,6 +39,8 @@ using namespace std;
#define WD_CLMNTYPE "ColumnType" #define WD_CLMNTYPE "ColumnType"
#define WD_CLMNSIZE "ColumnSize" #define WD_CLMNSIZE "ColumnSize"
#define WD_NBDOCSTOTAL "NbDocsTotal" #define WD_NBDOCSTOTAL "NbDocsTotal"
#define WD_MENUCOPYNAME "MenuCopyName"
#define WD_MENUCOPYPATH "MenuCopyPath"
static const TCHAR *readonlyString = TEXT(" [Read Only]"); static const TCHAR *readonlyString = TEXT(" [Read Only]");
const UINT WDN_NOTIFY = RegisterWindowMessage(TEXT("WDN_NOTIFY")); const UINT WDN_NOTIFY = RegisterWindowMessage(TEXT("WDN_NOTIFY"));
@ -313,6 +315,22 @@ INT_PTR CALLBACK WindowsDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lPa
doColumnSort(); doColumnSort();
break; break;
} }
default:
if (HIWORD(wParam) == 0)
{
// Menu
switch (LOWORD(wParam))
{
case IDM_WINDOW_COPY_NAME:
putItemsToClipboard(false);
break;
case IDM_WINDOW_COPY_PATH:
putItemsToClipboard(true);
break;
}
}
break;
} }
break; break;
} }
@ -335,34 +353,20 @@ INT_PTR CALLBACK WindowsDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lPa
if (pLvdi->item.mask & LVIF_TEXT) if (pLvdi->item.mask & LVIF_TEXT)
{ {
pLvdi->item.pszText[0] = 0; pLvdi->item.pszText[0] = 0;
size_t index = pLvdi->item.iItem; Buffer* buf = getBuffer(pLvdi->item.iItem);
if (index >= _pTab->nbItem() || index >= _idxMap.size()) if (!buf)
return FALSE; return FALSE;
index = _idxMap[index]; generic_string text;
//const Buffer& buffer = _pView->getBufferAt(index);
BufferID bufID = _pTab->getBufferByIndex(index);
Buffer * buf = MainFileManager.getBufferByID(bufID);
if (pLvdi->item.iSubItem == 0) // file name if (pLvdi->item.iSubItem == 0) // file name
{ {
int len = pLvdi->item.cchTextMax; text = buf->getFileName();
const TCHAR *fileName = buf->getFileName();
generic_strncpy(pLvdi->item.pszText, fileName, len-1);
pLvdi->item.pszText[len-1] = 0;
len = lstrlen(pLvdi->item.pszText);
if (buf->isDirty()) if (buf->isDirty())
{ {
if (len < pLvdi->item.cchTextMax) text += '*';
{
pLvdi->item.pszText[len++] = '*';
pLvdi->item.pszText[len] = 0;
}
} }
else if (buf->isReadOnly()) else if (buf->isReadOnly())
{ {
len += lstrlen(readonlyString); text += readonlyString;
if (len <= pLvdi->item.cchTextMax)
wcscat_s(pLvdi->item.pszText, pLvdi->item.cchTextMax, readonlyString);
} }
} }
else if (pLvdi->item.iSubItem == 1) // directory else if (pLvdi->item.iSubItem == 1) // directory
@ -374,30 +378,27 @@ INT_PTR CALLBACK WindowsDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lPa
len = 1; len = 1;
fullName = TEXT(""); fullName = TEXT("");
} }
if (pLvdi->item.cchTextMax < len) text.assign(fullName, len);
len = pLvdi->item.cchTextMax;
generic_strncpy(pLvdi->item.pszText, fullName, len-1);
pLvdi->item.pszText[len-1] = 0;
} }
else if (pLvdi->item.iSubItem == 2) // Type else if (pLvdi->item.iSubItem == 2) // Type
{ {
int len = pLvdi->item.cchTextMax;
NppParameters& nppParameters = NppParameters::getInstance(); NppParameters& nppParameters = NppParameters::getInstance();
Lang *lang = nppParameters.getLangFromID(buf->getLangType()); Lang *lang = nppParameters.getLangFromID(buf->getLangType());
if (NULL != lang) if (NULL != lang)
{ {
generic_strncpy(pLvdi->item.pszText, lang->getLangName(), len-1); text = lang->getLangName();
} }
} }
else if (pLvdi->item.iSubItem == 3) // size else if (pLvdi->item.iSubItem == 3) // size
{ {
int docSize = buf->docLength(); int docSize = buf->docLength();
string docSizeText = to_string(docSize); string docSizeText = to_string(docSize);
wstring wstr = wstring(docSizeText.begin(), docSizeText.end()); text = wstring(docSizeText.begin(), docSizeText.end());
const wchar_t * wstrp = wstr.c_str(); }
int docSizeTextLen = lstrlen(wstrp); if (static_cast<int>(text.length()) < pLvdi->item.cchTextMax)
generic_strncpy(pLvdi->item.pszText, wstrp, docSizeTextLen); {
pLvdi->item.pszText[docSizeTextLen] = 0; // Copy the resulting text to destination with a null terminator.
_tcscpy_s(pLvdi->item.pszText, text.length() + 1, text.c_str());
} }
} }
return TRUE; return TRUE;
@ -438,20 +439,49 @@ INT_PTR CALLBACK WindowsDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lPa
else if (pNMHDR->code == LVN_KEYDOWN) else if (pNMHDR->code == LVN_KEYDOWN)
{ {
NMLVKEYDOWN *lvkd = (NMLVKEYDOWN *)pNMHDR; NMLVKEYDOWN *lvkd = (NMLVKEYDOWN *)pNMHDR;
// Ctrl+A
short ctrl = GetKeyState(VK_CONTROL); short ctrl = GetKeyState(VK_CONTROL);
short alt = GetKeyState(VK_MENU); short alt = GetKeyState(VK_MENU);
short shift = GetKeyState(VK_SHIFT); short shift = GetKeyState(VK_SHIFT);
if (lvkd->wVKey == 0x41/*a*/ && ctrl<0 && alt>=0 && shift>=0) if (lvkd->wVKey == 'A' && ctrl<0 && alt>=0 && shift>=0)
{ {
// Ctrl + A
for (int i=0, n=ListView_GetItemCount(_hList); i<n; ++i) for (int i=0, n=ListView_GetItemCount(_hList); i<n; ++i)
ListView_SetItemState(_hList, i, LVIS_SELECTED, LVIS_SELECTED); ListView_SetItemState(_hList, i, LVIS_SELECTED, LVIS_SELECTED);
} }
else if (lvkd->wVKey == 'C' && ctrl & 0x80)
{
// Ctrl + C
if (ListView_GetSelectedCount(_hList) != 0)
putItemsToClipboard(true);
}
return TRUE; return TRUE;
} }
} }
break; break;
} }
case WM_CONTEXTMENU:
{
if (!_listMenu.isCreated())
{
NativeLangSpeaker* pNativeSpeaker = (NppParameters::getInstance()).getNativeLangSpeaker();
const std::vector<MenuItemUnit> itemUnitArray
{
{IDM_WINDOW_COPY_NAME, pNativeSpeaker->getAttrNameStr(TEXT("Copy Name(s)"), WD_ROOTNODE, WD_MENUCOPYNAME)},
{IDM_WINDOW_COPY_PATH, pNativeSpeaker->getAttrNameStr(TEXT("Copy Pathname(s)"), WD_ROOTNODE, WD_MENUCOPYPATH)}
};
_listMenu.create(_hSelf, itemUnitArray);
}
const bool enableMenu = ListView_GetSelectedCount(_hList) != 0;
_listMenu.enableItem(IDM_WINDOW_COPY_NAME, enableMenu);
_listMenu.enableItem(IDM_WINDOW_COPY_PATH, enableMenu);
POINT p = {};
::GetCursorPos(&p);
_listMenu.display(p);
}
return TRUE;
} }
return MyBaseClass::run_dlgProc(message, wParam, lParam); return MyBaseClass::run_dlgProc(message, wParam, lParam);
} }
@ -907,6 +937,57 @@ void WindowsDlg::doSortToTabs()
delete[] nmdlg.Items; delete[] nmdlg.Items;
} }
void WindowsDlg::putItemsToClipboard(bool isFullPath)
{
constexpr int nameColumn = 0;
constexpr int pathColumn = 1;
TCHAR str[MAX_PATH] = {};
generic_string selection;
for (int i = -1, j = 0; ; ++j)
{
i = ListView_GetNextItem(_hList, i, LVNI_SELECTED);
if (i < 0)
break;
if (isFullPath)
{
// Get the directory path (2nd column).
ListView_GetItemText(_hList, i, pathColumn, str, sizeof(str));
if (str[0])
selection += str;
}
// Get the file name.
// Do not use ListView_GetItemText() because 1st column may contain "*" or "[Read Only]".
Buffer* buf = getBuffer(i);
if (buf)
{
const TCHAR* fileName = buf->getFileName();
if (fileName)
selection += fileName;
}
if (!selection.empty() && selection.back() != '\n')
selection += '\n';
}
if (!selection.empty())
str2Clipboard(selection, _hList);
}
Buffer* WindowsDlg::getBuffer(int index) const
{
if (index < 0 || index >= static_cast<int>(_idxMap.size()))
return nullptr;
index = _idxMap[index];
if (index < 0 || !_pTab || index >= static_cast<int>(_pTab->nbItem()))
return nullptr;
BufferID bufID = _pTab->getBufferByIndex(index);
return MainFileManager.getBufferByID(bufID);
}
WindowsMenu::WindowsMenu() WindowsMenu::WindowsMenu()
{} {}

View File

@ -19,8 +19,10 @@
#include "SizeableDlg.h" #include "SizeableDlg.h"
#include "Common.h" #include "Common.h"
#include "ContextMenu.h"
class DocTabView; class DocTabView;
class Buffer;
typedef enum { typedef enum {
WDT_ACTIVATE = 1, WDT_ACTIVATE = 1,
@ -73,6 +75,8 @@ protected :
void activateCurrent(); void activateCurrent();
void doColumnSort(); void doColumnSort();
void doCount(); void doCount();
void putItemsToClipboard(bool isFullPath);
Buffer* getBuffer(int index) const;
HWND _hList = nullptr; HWND _hList = nullptr;
static RECT _lastKnownLocation; static RECT _lastKnownLocation;
@ -83,6 +87,7 @@ protected :
int _currentColumn = -1; int _currentColumn = -1;
int _lastSort = -1; int _lastSort = -1;
bool _reverseSort = false; bool _reverseSort = false;
ContextMenu _listMenu;
private: private:
virtual void init(HINSTANCE hInst, HWND parent); virtual void init(HINSTANCE hInst, HWND parent);

View File

@ -38,4 +38,6 @@
#define IDM_WINDOW_WINDOWS (IDR_WINDOWS_MENU + 1) #define IDM_WINDOW_WINDOWS (IDR_WINDOWS_MENU + 1)
#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 + 29) #define IDM_WINDOW_MRU_LIMIT (IDR_WINDOWS_MENU + 29)
#define IDM_WINDOW_COPY_NAME (IDM_WINDOW_MRU_LIMIT + 1)
#define IDM_WINDOW_COPY_PATH (IDM_WINDOW_MRU_LIMIT + 2)