Make doSaveOrNot dialog simpler when there's a single file to save

When there are several files to save, the same doSaveOrNot dialog which cotains 5 buttons (Yes, No, Cancel, Yes to All and No to All) is shown. But if there is only one file to save, then it's better to not show Yes to All and No to All buttons to make a consistent user interface.

Fix #7762
This commit is contained in:
Don HO 2019-12-20 00:38:57 +01:00
parent 703a49b323
commit b76bf9e4df
No known key found for this signature in database
GPG Key ID: 6C429F1D8D84F46E
6 changed files with 100 additions and 7 deletions

View File

@ -1884,6 +1884,21 @@ int Notepad_plus::doSaveOrNot(const TCHAR* fn, bool isMulti)
::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0);
}
if (!isMulti)
{
generic_string title, msg;
if (!_nativeLangSpeaker.getDoSaveOrNotStrings(title, msg))
{
title = TEXT("Save");
msg = TEXT("Save file \"$STR_REPLACE$\" ?");
}
msg = stringReplace(msg, TEXT("$STR_REPLACE$"), fn);
return ::MessageBox(_pPublicInterface->getHSelf(), msg.c_str(), title.c_str(), MB_YESNOCANCEL | MB_ICONQUESTION | MB_APPLMODAL);
}
DoSaveOrNotBox doSaveOrNotBox;
doSaveOrNotBox.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), fn, isMulti);
doSaveOrNotBox.doDialog(_nativeLangSpeaker.isRTL());

View File

@ -959,7 +959,8 @@ bool Notepad_plus::fileCloseAll(bool doDeleteBackup, bool isSnapshotMode)
}
else
{
res = doSaveOrNot(buf->getFullPathName(), true);
size_t nbDirtyFiles = MainFileManager.getNbDirtyBuffers();
res = doSaveOrNot(buf->getFullPathName(), nbDirtyFiles > 1);
}
if (res == IDYES)
@ -1040,7 +1041,8 @@ bool Notepad_plus::fileCloseAll(bool doDeleteBackup, bool isSnapshotMode)
}
else
{
res = doSaveOrNot(buf->getFullPathName(), true);
size_t nbDirtyFiles = MainFileManager.getNbDirtyBuffers();
res = doSaveOrNot(buf->getFullPathName(), nbDirtyFiles > 1);
}
if (res == IDYES)
@ -1096,6 +1098,17 @@ bool Notepad_plus::fileCloseAllGiven(const std::vector<int>& krvecBufferIndexes)
bool saveToAll = false;
std::vector<int> bufferIndexesToClose;
// Count the number of dirty file
size_t nbDirtyFiles = 0;
for (const auto& index : krvecBufferIndexes)
{
BufferID id = _pDocTab->getBufferByIndex(index);
Buffer* buf = MainFileManager.getBufferByID(id);
if (buf->isDirty())
++nbDirtyFiles;
}
for (const auto& index : krvecBufferIndexes)
{
BufferID id = _pDocTab->getBufferByIndex(index);
@ -1127,7 +1140,8 @@ bool Notepad_plus::fileCloseAllGiven(const std::vector<int>& krvecBufferIndexes)
* IDIGNORE : No To All
* IDCANCEL : Cancel Opration
*/
int res = saveToAll ? IDYES : doSaveOrNot(buf->getFullPathName(), true);
int res = saveToAll ? IDYES : doSaveOrNot(buf->getFullPathName(), nbDirtyFiles > 1);
if (res == IDYES || res == IDRETRY)
{
@ -1245,7 +1259,13 @@ bool Notepad_plus::fileCloseAllButCurrent()
}
else
{
res = doSaveOrNot(buf->getFullPathName(), true);
size_t nbDirtyFiles = MainFileManager.getNbDirtyBuffers();
// if current file is dirty, if should be removed from dirty files to make nbDirtyFiles accurate
Buffer* currentBuf = MainFileManager.getBufferByID(current);
nbDirtyFiles -= currentBuf->isDirty() ? 1 : 0;
res = doSaveOrNot(buf->getFullPathName(), nbDirtyFiles > 1);
}
if (res == IDYES)
@ -1309,7 +1329,13 @@ bool Notepad_plus::fileCloseAllButCurrent()
}
else
{
res = doSaveOrNot(buf->getFullPathName(), true);
size_t nbDirtyFiles = MainFileManager.getNbDirtyBuffers();
// if current file is dirty, if should be removed from dirty files to make nbDirtyFiles accurate
Buffer* currentBuf = MainFileManager.getBufferByID(current);
nbDirtyFiles -= currentBuf->isDirty() ? 1 : 0;
res = doSaveOrNot(buf->getFullPathName(), nbDirtyFiles > 1);
}

View File

@ -533,6 +533,16 @@ void FileManager::checkFilesystemChanges(bool bCheckOnlyCurrentBuffer)
}
}
size_t FileManager::getNbDirtyBuffers() const
{
size_t nb_dirtyBufs = 0;
for (size_t i = 0; i < _nbBufs; ++i)
{
if (_buffers[i]->_isDirty)
++nb_dirtyBufs;
}
return nb_dirtyBufs;
}
int FileManager::getBufferIndexByID(BufferID id)
{

View File

@ -76,7 +76,8 @@ public:
//void activateBuffer(int index);
void checkFilesystemChanges(bool bCheckOnlyCurrentBuffer);
size_t getNbBuffers() { return _nbBufs; };
size_t getNbBuffers() const { return _nbBufs; };
size_t getNbDirtyBuffers() const;
int getBufferIndexByID(BufferID id);
Buffer * getBufferByIndex(size_t index);
Buffer * getBufferByID(BufferID id) {return static_cast<Buffer*>(id);}

View File

@ -1048,6 +1048,45 @@ TiXmlNodeA * NativeLangSpeaker::searchDlgNode(TiXmlNodeA *node, const char *dlgT
return NULL;
}
bool NativeLangSpeaker::getDoSaveOrNotStrings(generic_string& title, generic_string& msg)
{
if (!_nativeLangA) return false;
TiXmlNodeA *dlgNode = _nativeLangA->FirstChild("Dialog");
if (!dlgNode) return false;
dlgNode = searchDlgNode(dlgNode, "DoSaveOrNot");
if (!dlgNode) return false;
const char *title2set = (dlgNode->ToElement())->Attribute("title");
if (!title2set || !title2set[0]) return false;
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
const wchar_t *titleW = wmc.char2wchar(title2set, _nativeLangEncoding);
title = titleW;
for (TiXmlNodeA *childNode = dlgNode->FirstChildElement("Item");
childNode;
childNode = childNode->NextSibling("Item"))
{
TiXmlElementA *element = childNode->ToElement();
int id;
const char *sentinel = element->Attribute("id", &id);
const char *name = element->Attribute("name");
if (sentinel && (name && name[0]))
{
if (id == 1761)
{
const wchar_t *msgW = wmc.char2wchar(name, _nativeLangEncoding);
msg = msgW;
return true;
}
}
}
return false;
}
bool NativeLangSpeaker::changeDlgLang(HWND hDlg, const char *dlgTagName, char *title, size_t titleMaxSize)
{
if (title)

View File

@ -67,6 +67,8 @@ public:
void changePrefereceDlgLang(PreferenceDlg & preference);
void changePluginsAdminDlgLang(PluginsAdminDlg & pluginsAdminDlg);
bool getDoSaveOrNotStrings(generic_string& title, generic_string& msg);
bool isRTL() const {
return _isRTL;
};