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
|
// We are just going to rename the tab nothing else
|
||||||
// So just rename the tab and rename the backup file too if applicable
|
// 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;
|
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());
|
TCHAR *tabNewName = reinterpret_cast<TCHAR *>(strDlg.doDialog());
|
||||||
if (tabNewName)
|
if (tabNewName)
|
||||||
|
@ -1443,6 +1443,13 @@ INT_PTR CALLBACK StringDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM)
|
|||||||
{
|
{
|
||||||
case WM_INITDIALOG :
|
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());
|
::SetWindowText(_hSelf, _title.c_str());
|
||||||
::SetDlgItemText(_hSelf, IDC_STRING_STATIC, _static.c_str());
|
::SetDlgItemText(_hSelf, IDC_STRING_STATIC, _static.c_str());
|
||||||
::SetDlgItemText(_hSelf, IDC_STRING_EDIT, _textValue.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)
|
INT_PTR CALLBACK StylerDlg::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
StylerDlg * dlg = (StylerDlg *)::GetProp(hwnd, TEXT("Styler dialog prop"));
|
StylerDlg * dlg = (StylerDlg *)::GetProp(hwnd, TEXT("Styler dialog prop"));
|
||||||
|
@ -399,13 +399,17 @@ class StringDlg : public StaticDialog
|
|||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
StringDlg() : StaticDialog() {};
|
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);
|
Window::init(hInst, parent);
|
||||||
_title = title;
|
_title = title;
|
||||||
_static = staticName;
|
_static = staticName;
|
||||||
_textValue = text2Set;
|
_textValue = text2Set;
|
||||||
_txtLen = txtLen;
|
_txtLen = txtLen;
|
||||||
_shouldGotoCenter = bGotoCenter;
|
_shouldGotoCenter = bGotoCenter;
|
||||||
|
if (restrictedChars && _tcslen(restrictedChars))
|
||||||
|
{
|
||||||
|
_restrictedChars = restrictedChars;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
INT_PTR doDialog() {
|
INT_PTR doDialog() {
|
||||||
@ -417,12 +421,20 @@ public :
|
|||||||
protected :
|
protected :
|
||||||
INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM);
|
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 :
|
private :
|
||||||
generic_string _title;
|
generic_string _title;
|
||||||
generic_string _textValue;
|
generic_string _textValue;
|
||||||
generic_string _static;
|
generic_string _static;
|
||||||
|
generic_string _restrictedChars;
|
||||||
int _txtLen = 0;
|
int _txtLen = 0;
|
||||||
bool _shouldGotoCenter = false;
|
bool _shouldGotoCenter = false;
|
||||||
|
WNDPROC _oldEditProc = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StylerDlg
|
class StylerDlg
|
||||||
|
Loading…
Reference in New Issue
Block a user