Add copy file names capacity from Windows dialog
Fix #10123, close #10194
This commit is contained in:
parent
81b21aae2a
commit
8e38b9daba
|
@ -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"/>
|
||||||
|
|
|
@ -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()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue