Don't allow restricted characters for tab file rename
Extend class StringDlg, so that characters which are not allowed in a file name such as |, :, >, < etc. will be restricted for tab's new name so that there will be no problem while saving backup file. Close #5324
This commit is contained in:
parent
c4f493a7c8
commit
ae980ce4d4
@ -1408,8 +1408,12 @@ 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
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file
|
||||
// Reserved characters: < > : " / \ | ? *
|
||||
std::wstring reservedChars = TEXT("<>:\"/\\|\?*");
|
||||
|
||||
StringDlg strDlg;
|
||||
strDlg.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), TEXT("Rename Current Tab"), TEXT("New Name : "), buf->getFileName(), 0, true);
|
||||
strDlg.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), TEXT("Rename Current Tab"), TEXT("New Name : "), buf->getFileName(), 0, reservedChars.c_str(), true);
|
||||
|
||||
TCHAR *tabNewName = reinterpret_cast<TCHAR *>(strDlg.doDialog());
|
||||
if (tabNewName)
|
||||
|
@ -1443,6 +1443,13 @@ INT_PTR CALLBACK StringDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM)
|
||||
{
|
||||
case WM_INITDIALOG :
|
||||
{
|
||||
// Re-route to Subclassed the edit control's proc if needed
|
||||
if (_restrictedChars.length())
|
||||
{
|
||||
::SetWindowLongPtr(GetDlgItem(_hSelf, IDC_STRING_EDIT), GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
|
||||
_oldEditProc = reinterpret_cast<WNDPROC>(SetWindowLongPtr(GetDlgItem(_hSelf, IDC_STRING_EDIT), GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(customEditProc)));
|
||||
}
|
||||
|
||||
::SetWindowText(_hSelf, _title.c_str());
|
||||
::SetDlgItemText(_hSelf, IDC_STRING_STATIC, _static.c_str());
|
||||
::SetDlgItemText(_hSelf, IDC_STRING_EDIT, _textValue.c_str());
|
||||
@ -1482,6 +1489,80 @@ INT_PTR CALLBACK StringDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM)
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT StringDlg::customEditProc(HWND hEdit, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
StringDlg *pSelf = reinterpret_cast<StringDlg *>(::GetWindowLongPtr(hEdit, GWLP_USERDATA));
|
||||
if (!pSelf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CHAR:
|
||||
if (0x80 & GetKeyState(VK_CONTROL))
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case 0x16: // ctrl - V
|
||||
pSelf->HandlePaste(hEdit);
|
||||
return 0;
|
||||
|
||||
case 0x03: // ctrl - C
|
||||
case 0x18: // ctrl - X
|
||||
default:
|
||||
// Let them go to default
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If Key pressed not permitted, then return 0
|
||||
if (!pSelf->isAllowed(reinterpret_cast<TCHAR*>(&wParam)))
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
// Reset the message handler to the original one
|
||||
SetWindowLongPtr(hEdit, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(pSelf->_oldEditProc));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Process the message using the default handler
|
||||
return CallWindowProc(pSelf->_oldEditProc, hEdit, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
bool StringDlg::isAllowed(const generic_string & txt)
|
||||
{
|
||||
for (auto ch : txt)
|
||||
{
|
||||
if (std::find(_restrictedChars.cbegin(), _restrictedChars.cend(), ch) != _restrictedChars.cend())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void StringDlg::HandlePaste(HWND hEdit)
|
||||
{
|
||||
if (OpenClipboard(hEdit))
|
||||
{
|
||||
HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT);
|
||||
if (NULL != hClipboardData)
|
||||
{
|
||||
LPTSTR pszText = reinterpret_cast<LPTSTR>(GlobalLock(hClipboardData));
|
||||
if (NULL != pszText && isAllowed(pszText))
|
||||
{
|
||||
SendMessage(hEdit, EM_REPLACESEL, TRUE, reinterpret_cast<LPARAM>(pszText));
|
||||
}
|
||||
|
||||
GlobalUnlock(hClipboardData);
|
||||
}
|
||||
|
||||
CloseClipboard();
|
||||
}
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK StylerDlg::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
StylerDlg * dlg = (StylerDlg *)::GetProp(hwnd, TEXT("Styler dialog prop"));
|
||||
|
@ -399,13 +399,17 @@ class StringDlg : public StaticDialog
|
||||
{
|
||||
public :
|
||||
StringDlg() : StaticDialog() {};
|
||||
void init(HINSTANCE hInst, HWND parent, const TCHAR *title, const TCHAR *staticName, const TCHAR *text2Set, int txtLen = 0, bool bGotoCenter = false) {
|
||||
void init(HINSTANCE hInst, HWND parent, const TCHAR *title, const TCHAR *staticName, const TCHAR *text2Set, int txtLen = 0, const TCHAR* restrictedChars = nullptr, bool bGotoCenter = false) {
|
||||
Window::init(hInst, parent);
|
||||
_title = title;
|
||||
_static = staticName;
|
||||
_textValue = text2Set;
|
||||
_txtLen = txtLen;
|
||||
_shouldGotoCenter = bGotoCenter;
|
||||
if (restrictedChars && _tcslen(restrictedChars))
|
||||
{
|
||||
_restrictedChars = restrictedChars;
|
||||
}
|
||||
};
|
||||
|
||||
INT_PTR doDialog() {
|
||||
@ -417,12 +421,20 @@ public :
|
||||
protected :
|
||||
INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM);
|
||||
|
||||
// Custom proc to subclass edit control
|
||||
LRESULT static CALLBACK customEditProc(HWND hEdit, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
bool isAllowed(const generic_string& txt);
|
||||
void HandlePaste(HWND hEdit);
|
||||
|
||||
private :
|
||||
generic_string _title;
|
||||
generic_string _textValue;
|
||||
generic_string _static;
|
||||
generic_string _restrictedChars;
|
||||
int _txtLen = 0;
|
||||
bool _shouldGotoCenter = false;
|
||||
WNDPROC _oldEditProc = nullptr;
|
||||
};
|
||||
|
||||
class StylerDlg
|
||||
|
Loading…
Reference in New Issue
Block a user