Skip to content

Commit b76bf9e

Browse files
committed
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 notepad-plus-plus#7762
1 parent 703a49b commit b76bf9e

File tree

6 files changed

+100
-7
lines changed

6 files changed

+100
-7
lines changed

PowerEditor/src/Notepad_plus.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1884,6 +1884,21 @@ int Notepad_plus::doSaveOrNot(const TCHAR* fn, bool isMulti)
18841884
::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0);
18851885
}
18861886

1887+
if (!isMulti)
1888+
{
1889+
generic_string title, msg;
1890+
1891+
if (!_nativeLangSpeaker.getDoSaveOrNotStrings(title, msg))
1892+
{
1893+
title = TEXT("Save");
1894+
msg = TEXT("Save file \"$STR_REPLACE$\" ?");
1895+
}
1896+
1897+
msg = stringReplace(msg, TEXT("$STR_REPLACE$"), fn);
1898+
1899+
return ::MessageBox(_pPublicInterface->getHSelf(), msg.c_str(), title.c_str(), MB_YESNOCANCEL | MB_ICONQUESTION | MB_APPLMODAL);
1900+
}
1901+
18871902
DoSaveOrNotBox doSaveOrNotBox;
18881903
doSaveOrNotBox.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), fn, isMulti);
18891904
doSaveOrNotBox.doDialog(_nativeLangSpeaker.isRTL());

PowerEditor/src/NppIO.cpp

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,8 @@ bool Notepad_plus::fileCloseAll(bool doDeleteBackup, bool isSnapshotMode)
959959
}
960960
else
961961
{
962-
res = doSaveOrNot(buf->getFullPathName(), true);
962+
size_t nbDirtyFiles = MainFileManager.getNbDirtyBuffers();
963+
res = doSaveOrNot(buf->getFullPathName(), nbDirtyFiles > 1);
963964
}
964965

965966
if (res == IDYES)
@@ -1040,7 +1041,8 @@ bool Notepad_plus::fileCloseAll(bool doDeleteBackup, bool isSnapshotMode)
10401041
}
10411042
else
10421043
{
1043-
res = doSaveOrNot(buf->getFullPathName(), true);
1044+
size_t nbDirtyFiles = MainFileManager.getNbDirtyBuffers();
1045+
res = doSaveOrNot(buf->getFullPathName(), nbDirtyFiles > 1);
10441046
}
10451047

10461048
if (res == IDYES)
@@ -1096,6 +1098,17 @@ bool Notepad_plus::fileCloseAllGiven(const std::vector<int>& krvecBufferIndexes)
10961098
bool saveToAll = false;
10971099
std::vector<int> bufferIndexesToClose;
10981100

1101+
// Count the number of dirty file
1102+
size_t nbDirtyFiles = 0;
1103+
for (const auto& index : krvecBufferIndexes)
1104+
{
1105+
BufferID id = _pDocTab->getBufferByIndex(index);
1106+
Buffer* buf = MainFileManager.getBufferByID(id);
1107+
1108+
if (buf->isDirty())
1109+
++nbDirtyFiles;
1110+
}
1111+
10991112
for (const auto& index : krvecBufferIndexes)
11001113
{
11011114
BufferID id = _pDocTab->getBufferByIndex(index);
@@ -1126,8 +1139,9 @@ bool Notepad_plus::fileCloseAllGiven(const std::vector<int>& krvecBufferIndexes)
11261139
* IDNO : No
11271140
* IDIGNORE : No To All
11281141
* IDCANCEL : Cancel Opration
1129-
*/
1130-
int res = saveToAll ? IDYES : doSaveOrNot(buf->getFullPathName(), true);
1142+
*/
1143+
1144+
int res = saveToAll ? IDYES : doSaveOrNot(buf->getFullPathName(), nbDirtyFiles > 1);
11311145

11321146
if (res == IDYES || res == IDRETRY)
11331147
{
@@ -1245,7 +1259,13 @@ bool Notepad_plus::fileCloseAllButCurrent()
12451259
}
12461260
else
12471261
{
1248-
res = doSaveOrNot(buf->getFullPathName(), true);
1262+
size_t nbDirtyFiles = MainFileManager.getNbDirtyBuffers();
1263+
1264+
// if current file is dirty, if should be removed from dirty files to make nbDirtyFiles accurate
1265+
Buffer* currentBuf = MainFileManager.getBufferByID(current);
1266+
nbDirtyFiles -= currentBuf->isDirty() ? 1 : 0;
1267+
1268+
res = doSaveOrNot(buf->getFullPathName(), nbDirtyFiles > 1);
12491269
}
12501270

12511271
if (res == IDYES)
@@ -1309,7 +1329,13 @@ bool Notepad_plus::fileCloseAllButCurrent()
13091329
}
13101330
else
13111331
{
1312-
res = doSaveOrNot(buf->getFullPathName(), true);
1332+
size_t nbDirtyFiles = MainFileManager.getNbDirtyBuffers();
1333+
1334+
// if current file is dirty, if should be removed from dirty files to make nbDirtyFiles accurate
1335+
Buffer* currentBuf = MainFileManager.getBufferByID(current);
1336+
nbDirtyFiles -= currentBuf->isDirty() ? 1 : 0;
1337+
1338+
res = doSaveOrNot(buf->getFullPathName(), nbDirtyFiles > 1);
13131339
}
13141340

13151341

PowerEditor/src/ScitillaComponent/Buffer.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,16 @@ void FileManager::checkFilesystemChanges(bool bCheckOnlyCurrentBuffer)
533533
}
534534
}
535535

536+
size_t FileManager::getNbDirtyBuffers() const
537+
{
538+
size_t nb_dirtyBufs = 0;
539+
for (size_t i = 0; i < _nbBufs; ++i)
540+
{
541+
if (_buffers[i]->_isDirty)
542+
++nb_dirtyBufs;
543+
}
544+
return nb_dirtyBufs;
545+
}
536546

537547
int FileManager::getBufferIndexByID(BufferID id)
538548
{

PowerEditor/src/ScitillaComponent/Buffer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ class FileManager final
7676
//void activateBuffer(int index);
7777
void checkFilesystemChanges(bool bCheckOnlyCurrentBuffer);
7878

79-
size_t getNbBuffers() { return _nbBufs; };
79+
size_t getNbBuffers() const { return _nbBufs; };
80+
size_t getNbDirtyBuffers() const;
8081
int getBufferIndexByID(BufferID id);
8182
Buffer * getBufferByIndex(size_t index);
8283
Buffer * getBufferByID(BufferID id) {return static_cast<Buffer*>(id);}

PowerEditor/src/localization.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,45 @@ TiXmlNodeA * NativeLangSpeaker::searchDlgNode(TiXmlNodeA *node, const char *dlgT
10481048
return NULL;
10491049
}
10501050

1051+
bool NativeLangSpeaker::getDoSaveOrNotStrings(generic_string& title, generic_string& msg)
1052+
{
1053+
if (!_nativeLangA) return false;
1054+
1055+
TiXmlNodeA *dlgNode = _nativeLangA->FirstChild("Dialog");
1056+
if (!dlgNode) return false;
1057+
1058+
dlgNode = searchDlgNode(dlgNode, "DoSaveOrNot");
1059+
if (!dlgNode) return false;
1060+
1061+
const char *title2set = (dlgNode->ToElement())->Attribute("title");
1062+
if (!title2set || !title2set[0]) return false;
1063+
1064+
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
1065+
const wchar_t *titleW = wmc.char2wchar(title2set, _nativeLangEncoding);
1066+
title = titleW;
1067+
1068+
for (TiXmlNodeA *childNode = dlgNode->FirstChildElement("Item");
1069+
childNode;
1070+
childNode = childNode->NextSibling("Item"))
1071+
{
1072+
TiXmlElementA *element = childNode->ToElement();
1073+
int id;
1074+
const char *sentinel = element->Attribute("id", &id);
1075+
const char *name = element->Attribute("name");
1076+
if (sentinel && (name && name[0]))
1077+
{
1078+
if (id == 1761)
1079+
{
1080+
const wchar_t *msgW = wmc.char2wchar(name, _nativeLangEncoding);
1081+
msg = msgW;
1082+
1083+
return true;
1084+
}
1085+
}
1086+
}
1087+
return false;
1088+
}
1089+
10511090
bool NativeLangSpeaker::changeDlgLang(HWND hDlg, const char *dlgTagName, char *title, size_t titleMaxSize)
10521091
{
10531092
if (title)

PowerEditor/src/localization.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class NativeLangSpeaker {
6767
void changePrefereceDlgLang(PreferenceDlg & preference);
6868
void changePluginsAdminDlgLang(PluginsAdminDlg & pluginsAdminDlg);
6969

70+
bool getDoSaveOrNotStrings(generic_string& title, generic_string& msg);
71+
7072
bool isRTL() const {
7173
return _isRTL;
7274
};

0 commit comments

Comments
 (0)