From 3f7956dc1bd16445f031a38bca8aa9e72806a408 Mon Sep 17 00:00:00 2001 From: Don HO Date: Wed, 3 Jul 2019 09:41:35 +0200 Subject: [PATCH] Add "No to All" and "Yes to All" options in Save dialog It allows users, while closing files, to reply Yes or No only for once in Save dialog for the all rest of modified files. Close #5835 , close #4385, close #4392 --- PowerEditor/installer/nativeLang/chinese.xml | 9 +- PowerEditor/installer/nativeLang/english.xml | 9 +- PowerEditor/installer/nativeLang/french.xml | 9 +- PowerEditor/src/Notepad_plus.cpp | 16 +- PowerEditor/src/Notepad_plus.h | 2 +- PowerEditor/src/Notepad_plus.rc | 14 +- PowerEditor/src/NppIO.cpp | 138 ++++++++++++++++-- .../src/WinControls/AboutDlg/AboutDlg.cpp | 93 ++++++++++++ .../src/WinControls/AboutDlg/AboutDlg.h | 32 ++++ .../src/WinControls/Grid/ShortcutMapper.rc | 1 - PowerEditor/src/resource.h | 3 + 11 files changed, 297 insertions(+), 29 deletions(-) diff --git a/PowerEditor/installer/nativeLang/chinese.xml b/PowerEditor/installer/nativeLang/chinese.xml index fc7bd82cb..2bd85b9bb 100644 --- a/PowerEditor/installer/nativeLang/chinese.xml +++ b/PowerEditor/installer/nativeLang/chinese.xml @@ -981,6 +981,14 @@ + + + + + + + + - diff --git a/PowerEditor/installer/nativeLang/english.xml b/PowerEditor/installer/nativeLang/english.xml index 81aeee296..4145679e9 100644 --- a/PowerEditor/installer/nativeLang/english.xml +++ b/PowerEditor/installer/nativeLang/english.xml @@ -981,6 +981,14 @@ + + + + + + + + - + + + + + + + + @@ -986,7 +994,6 @@ vous devez activer "Open all files of folder instead of launching Folder as Workspace on folder dropping" in "Default Directory" section of Preferences dialog to make this operation work."/> - getHSelf(), - TEXT("Save file \"$STR_REPLACE$\" ?"), - TEXT("Save"), - MB_YESNOCANCEL | MB_ICONQUESTION | MB_APPLMODAL, - 0, // not used - fn); + DoSaveOrNotBox doSaveOrNotBox; + doSaveOrNotBox.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), fn, isMulti); + doSaveOrNotBox.doDialog(_nativeLangSpeaker.isRTL()); + int buttonID = doSaveOrNotBox.getClickedButtonId(); + doSaveOrNotBox.destroy(); + + return buttonID; } int Notepad_plus::doReloadOrNot(const TCHAR *fn, bool dirty) diff --git a/PowerEditor/src/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h index 83e10d7b8..8d8a1459e 100644 --- a/PowerEditor/src/Notepad_plus.h +++ b/PowerEditor/src/Notepad_plus.h @@ -441,7 +441,7 @@ private: void performPostReload(int whichOne); //END: Document management - int doSaveOrNot(const TCHAR *fn); + int doSaveOrNot(const TCHAR *fn, bool isMulti = false); int doReloadOrNot(const TCHAR *fn, bool dirty); int doCloseOrNot(const TCHAR *fn); int doDeleteOrNot(const TCHAR *fn); diff --git a/PowerEditor/src/Notepad_plus.rc b/PowerEditor/src/Notepad_plus.rc index 5a1c79275..f2adca3aa 100644 --- a/PowerEditor/src/Notepad_plus.rc +++ b/PowerEditor/src/Notepad_plus.rc @@ -1029,10 +1029,22 @@ CAPTION "Debug Info" FONT 8, TEXT("MS Shell Dlg"), 0, 0, 0x1 BEGIN EDITTEXT IDC_DEBUGINFO_EDIT,31,20,220,96,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_BORDER | WS_VSCROLL - LTEXT "Copy debug info into clipboard",IDC_DEBUGINFO_COPYLINK,31,120,126,8 + LTEXT "Copy debug info into clipboard",IDC_DEBUGINFO_COPYLINK,31,120,126,8 DEFPUSHBUTTON "OK",IDOK,106,160,50,14,BS_FLAT END +IDD_DOSAVEORNOTBOX DIALOGEX 0, 0, 350, 115 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_THICKFRAME +CAPTION "Save" +FONT 8, TEXT("MS Shell Dlg"), 0, 0, 0x1 +BEGIN + LTEXT "",IDC_DOSAVEORNOTTEX,30,30,126,126 + DEFPUSHBUTTON "Yes",IDYES,50,85,50,14,BS_FLAT + PUSHBUTTON "No",IDNO,105,85,50,14,BS_FLAT + PUSHBUTTON "Cancel",IDCANCEL,160,85,50,14,BS_FLAT + PUSHBUTTON "Yes to all",IDRETRY,215,85,60,14,BS_FLAT + PUSHBUTTON "No to all",IDIGNORE,280,85,60,14,BS_FLAT +END IDD_GOLINE DIALOGEX 26, 41, 261, 88 STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU diff --git a/PowerEditor/src/NppIO.cpp b/PowerEditor/src/NppIO.cpp index c11f017cf..a91c8c5cb 100644 --- a/PowerEditor/src/NppIO.cpp +++ b/PowerEditor/src/NppIO.cpp @@ -871,7 +871,6 @@ bool Notepad_plus::fileClose(BufferID id, int curView) } else if (buf->isDirty()) { - res = doSaveOrNot(fileNamePath); if (res == IDYES) { @@ -899,10 +898,13 @@ bool Notepad_plus::fileClose(BufferID id, int curView) bool Notepad_plus::fileCloseAll(bool doDeleteBackup, bool isSnapshotMode) { + bool noSaveToAll = false; + bool saveToAll = false; + //closes all documents, makes the current view the only one visible //first check if we need to save any file - for (size_t i = 0; i < _mainDocTab.nbItem(); ++i) + for (size_t i = 0; i < _mainDocTab.nbItem() && !noSaveToAll; ++i) { BufferID id = _mainDocTab.getBufferByIndex(i); Buffer * buf = MainFileManager->getBufferByID(id); @@ -929,7 +931,6 @@ bool Notepad_plus::fileCloseAll(bool doDeleteBackup, bool isSnapshotMode) 0, // not used buf->getFullPathName()); - //int res = doSaveOrNot(buf->getFullPathName()); if (res == IDYES) { if (!fileSave(id)) @@ -947,7 +948,16 @@ bool Notepad_plus::fileCloseAll(bool doDeleteBackup, bool isSnapshotMode) if (!activateBuffer(id, SUB_VIEW)) switchEditViewTo(MAIN_VIEW); - int res = doSaveOrNot(buf->getFullPathName()); + int res = -1; + if (saveToAll) + { + res = IDYES; + } + else + { + res = doSaveOrNot(buf->getFullPathName(), true); + } + if (res == IDYES) { if (!fileSave(id)) @@ -957,10 +967,22 @@ bool Notepad_plus::fileCloseAll(bool doDeleteBackup, bool isSnapshotMode) { return false; } + else if (res == IDIGNORE) + { + noSaveToAll = true; + } + else if (res == IDRETRY) + { + if (!fileSave(id)) + return false; // Abort entire procedure. + + saveToAll = true; + } } } } - for (size_t i = 0; i < _subDocTab.nbItem(); ++i) + + for (size_t i = 0; i < _subDocTab.nbItem() && !noSaveToAll; ++i) { BufferID id = _subDocTab.getBufferByIndex(i); Buffer * buf = MainFileManager->getBufferByID(id); @@ -1002,7 +1024,16 @@ bool Notepad_plus::fileCloseAll(bool doDeleteBackup, bool isSnapshotMode) activateBuffer(id, SUB_VIEW); switchEditViewTo(SUB_VIEW); - int res = doSaveOrNot(buf->getFullPathName()); + int res = -1; + if (saveToAll) + { + res = IDYES; + } + else + { + res = doSaveOrNot(buf->getFullPathName(), true); + } + if (res == IDYES) { if (!fileSave(id)) @@ -1013,6 +1044,17 @@ bool Notepad_plus::fileCloseAll(bool doDeleteBackup, bool isSnapshotMode) return false; //otherwise continue (IDNO) } + else if (res == IDIGNORE) + { + noSaveToAll = true; + } + else if (res == IDRETRY) + { + if (!fileSave(id)) + return false; // Abort entire procedure. + + saveToAll = true; + } } } } @@ -1042,16 +1084,19 @@ bool Notepad_plus::fileCloseAllGiven(const std::vector &krvecBufferIndexes) // First check if we need to save any file. std::vector::const_iterator itIndexesEnd = krvecBufferIndexes.end(); + bool noSaveToAll = false; + bool saveToAll = false; for (std::vector::const_iterator itIndex = krvecBufferIndexes.begin(); itIndex != itIndexesEnd; ++itIndex) { BufferID id = _pDocTab->getBufferByIndex(*itIndex); Buffer * buf = MainFileManager->getBufferByID(id); + if (buf->isUntitled() && buf->docLength() == 0) { // Do nothing. } - else if (buf->isDirty()) + else if (buf->isDirty() && !noSaveToAll) { if (_activeView == MAIN_VIEW) { @@ -1065,7 +1110,16 @@ bool Notepad_plus::fileCloseAllGiven(const std::vector &krvecBufferIndexes) switchEditViewTo(SUB_VIEW); } - int res = doSaveOrNot(buf->getFullPathName()); + int res = -1; + if (saveToAll) + { + res = IDYES; + } + else + { + res = doSaveOrNot(buf->getFullPathName(), true); + } + if (res == IDYES) { if (!fileSave(id)) @@ -1073,7 +1127,18 @@ bool Notepad_plus::fileCloseAllGiven(const std::vector &krvecBufferIndexes) } else if (res == IDCANCEL) { - return false; + return false; + } + else if (res == IDIGNORE) + { + noSaveToAll = true; + } + else if (res == IDRETRY) + { + if (!fileSave(id)) + return false; // Abort entire procedure. + + saveToAll = true; } } } @@ -1135,10 +1200,13 @@ bool Notepad_plus::fileCloseAllButCurrent() BufferID current = _pEditView->getCurrentBufferID(); int active = _pDocTab->getCurrentTabIndex(); const int activeViewID = currentView(); + bool noSaveToAll = false; + bool saveToAll = false; + //closes all documents, makes the current view the only one visible //first check if we need to save any file - for (size_t i = 0; i < _mainDocTab.nbItem(); ++i) + for (size_t i = 0; i < _mainDocTab.nbItem() && !noSaveToAll; ++i) { BufferID id = _mainDocTab.getBufferByIndex(i); if (id == current) @@ -1154,7 +1222,16 @@ bool Notepad_plus::fileCloseAllButCurrent() if (!activateBuffer(id, SUB_VIEW)) switchEditViewTo(MAIN_VIEW); - int res = doSaveOrNot(buf->getFullPathName()); + int res = -1; + if (saveToAll) + { + res = IDYES; + } + else + { + res = doSaveOrNot(buf->getFullPathName(), true); + } + if (res == IDYES) { if (!fileSave(id)) @@ -1162,11 +1239,22 @@ bool Notepad_plus::fileCloseAllButCurrent() } else if (res == IDCANCEL) { - return false; + return false; + } + else if (res == IDIGNORE) + { + noSaveToAll = true; + } + else if (res == IDRETRY) + { + if (!fileSave(id)) + return false; // Abort entire procedure. + + saveToAll = true; } } } - for (size_t i = 0; i < _subDocTab.nbItem(); ++i) + for (size_t i = 0; i < _subDocTab.nbItem() && !noSaveToAll; ++i) { BufferID id = _subDocTab.getBufferByIndex(i); Buffer * buf = MainFileManager->getBufferByID(id); @@ -1181,7 +1269,16 @@ bool Notepad_plus::fileCloseAllButCurrent() activateBuffer(id, SUB_VIEW); switchEditViewTo(SUB_VIEW); - int res = doSaveOrNot(buf->getFullPathName()); + int res = -1; + if (saveToAll) + { + res = IDYES; + } + else + { + res = doSaveOrNot(buf->getFullPathName(), true); + } + if (res == IDYES) { if (!fileSave(id)) @@ -1189,7 +1286,18 @@ bool Notepad_plus::fileCloseAllButCurrent() } else if (res == IDCANCEL) { - return false; + return false; + } + else if (res == IDIGNORE) + { + noSaveToAll = true; + } + else if (res == IDRETRY) + { + if (!fileSave(id)) + return false; // Abort entire procedure. + + saveToAll = true; } } } diff --git a/PowerEditor/src/WinControls/AboutDlg/AboutDlg.cpp b/PowerEditor/src/WinControls/AboutDlg/AboutDlg.cpp index 59800eb49..6e3272cd0 100644 --- a/PowerEditor/src/WinControls/AboutDlg/AboutDlg.cpp +++ b/PowerEditor/src/WinControls/AboutDlg/AboutDlg.cpp @@ -32,6 +32,7 @@ #include "AboutDlg.h" #include "Parameters.h" +#include "localization.h" INT_PTR CALLBACK AboutDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) { @@ -225,3 +226,95 @@ void DebugInfoDlg::doDialog() goToCenter(); } +void DoSaveOrNotBox::doDialog(bool isRTL) +{ + + if (isRTL) + { + DLGTEMPLATE *pMyDlgTemplate = NULL; + HGLOBAL hMyDlgTemplate = makeRTLResource(IDD_DOSAVEORNOTBOX, &pMyDlgTemplate); + ::DialogBoxIndirectParam(_hInst, pMyDlgTemplate, _hParent, dlgProc, reinterpret_cast(this)); + ::GlobalFree(hMyDlgTemplate); + } + else + ::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_DOSAVEORNOTBOX), _hParent, dlgProc, reinterpret_cast(this)); +} + +void DoSaveOrNotBox::changeLang() +{ + generic_string msg; + generic_string defaultMessage = TEXT("Save file \"$STR_REPLACE$\" ?"); + NativeLangSpeaker* nativeLangSpeaker = NppParameters::getInstance()->getNativeLangSpeaker(); + + if (nativeLangSpeaker->changeDlgLang(_hSelf, "DoSaveOrNot")) + { + const unsigned char len = 255; + TCHAR text[len]; + ::GetDlgItemText(_hSelf, IDC_DOSAVEORNOTTEX, text, len); + msg = text; + } + + if (msg.empty()) + msg = defaultMessage; + + msg = stringReplace(msg, TEXT("$STR_REPLACE$"), _fn); + ::SetDlgItemText(_hSelf, IDC_DOSAVEORNOTTEX, msg.c_str()); +} + +INT_PTR CALLBACK DoSaveOrNotBox::run_dlgProc(UINT message, WPARAM wParam, LPARAM /*lParam*/) +{ + switch (message) + { + case WM_INITDIALOG : + { + changeLang(); + ::EnableWindow(::GetDlgItem(_hSelf, IDRETRY), _isMulti); + ::EnableWindow(::GetDlgItem(_hSelf, IDIGNORE), _isMulti); + goToCenter(); + return TRUE; + } + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDCANCEL: + { + ::EndDialog(_hSelf, -1); + clickedButtonId = IDCANCEL; + return TRUE; + } + + case IDYES: + { + ::EndDialog(_hSelf, 0); + clickedButtonId = IDYES; + return TRUE; + } + + case IDNO: + { + ::EndDialog(_hSelf, 0); + clickedButtonId = IDNO; + return TRUE; + } + + case IDIGNORE: + { + ::EndDialog(_hSelf, 0); + clickedButtonId = IDIGNORE; + return TRUE; + } + + case IDRETRY: + { + ::EndDialog(_hSelf, 0); + clickedButtonId = IDRETRY; + return TRUE; + } + } + } + default: + return FALSE; + } +} \ No newline at end of file diff --git a/PowerEditor/src/WinControls/AboutDlg/AboutDlg.h b/PowerEditor/src/WinControls/AboutDlg/AboutDlg.h index 72c5b54f5..cc5f1476b 100644 --- a/PowerEditor/src/WinControls/AboutDlg/AboutDlg.h +++ b/PowerEditor/src/WinControls/AboutDlg/AboutDlg.h @@ -96,3 +96,35 @@ private: URLCtrl _copyToClipboardLink; }; +class DoSaveOrNotBox : public StaticDialog +{ +public: + DoSaveOrNotBox() : StaticDialog() {}; + + void init(HINSTANCE hInst, HWND parent, const TCHAR* fn, bool isMulti) { + Window::init(hInst, parent); + if (fn) + _fn = fn; + + _isMulti = isMulti; + }; + + void doDialog(bool isRTL = false); + + virtual void destroy() { + }; + + int getClickedButtonId() const { + return clickedButtonId; + }; + + void changeLang(); + +protected: + virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + +private: + int clickedButtonId = -1; + generic_string _fn; + bool _isMulti = false; +}; diff --git a/PowerEditor/src/WinControls/Grid/ShortcutMapper.rc b/PowerEditor/src/WinControls/Grid/ShortcutMapper.rc index 23a1db537..8ddede0bf 100755 --- a/PowerEditor/src/WinControls/Grid/ShortcutMapper.rc +++ b/PowerEditor/src/WinControls/Grid/ShortcutMapper.rc @@ -36,7 +36,6 @@ IDD_SHORTCUTMAPPER_DLG DIALOGEX 0, 0, 450, 355 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_THICKFRAME -//EXSTYLE WS_EX_TOOLWINDOW CAPTION "Shortcut mapper" FONT 8, TEXT("MS Shell Dlg"), 400, 0, 0x1 BEGIN diff --git a/PowerEditor/src/resource.h b/PowerEditor/src/resource.h index dc9bdae70..a94f361d7 100644 --- a/PowerEditor/src/resource.h +++ b/PowerEditor/src/resource.h @@ -304,6 +304,9 @@ #define IDC_DEBUGINFO_EDIT 1751 #define IDC_DEBUGINFO_COPYLINK 1752 +#define IDD_DOSAVEORNOTBOX 1760 +#define IDC_DOSAVEORNOTTEX 1761 + //#define IDD_USER_DEFINE_BOX 1800 //#define IDD_RUN_DLG 1900 //#define IDD_MD5FROMFILES_DLG 1920