Fix Copy/Cut/Paste shortcut modification conflict problem

The bug is introduced by:
f7c44b4413

Fix #14585, close #14586
pull/14593/head
Don Ho 2024-01-13 19:53:53 +01:00
parent f7c44b4413
commit 75ae73c173
5 changed files with 79 additions and 8 deletions

View File

@ -364,7 +364,7 @@ void Notepad_plus::command(int id)
{
_pEditView->execute(WM_CUT);
}
else // Cul the entire line
else // Cut the entire line
{
_pEditView->execute(SCI_COPYALLOWLINE);
_pEditView->execute(SCI_LINEDELETE);

View File

@ -2082,11 +2082,13 @@ void NppParameters::initMenuKeys()
{
int nbCommands = sizeof(winKeyDefs)/sizeof(WinMenuKeyDefinition);
WinMenuKeyDefinition wkd;
int previousFuncID = 0;
for (int i = 0; i < nbCommands; ++i)
{
wkd = winKeyDefs[i];
Shortcut sc((wkd.specialName ? wstring2string(wkd.specialName, CP_UTF8).c_str() : ""), wkd.isCtrl, wkd.isAlt, wkd.isShift, static_cast<unsigned char>(wkd.vKey));
_shortcuts.push_back( CommandShortcut(sc, wkd.functionId) );
_shortcuts.push_back( CommandShortcut(sc, wkd.functionId, previousFuncID == wkd.functionId) );
previousFuncID = wkd.functionId;
}
}
@ -2839,12 +2841,15 @@ void NppParameters::feedShortcut(TiXmlNodeA *node)
{
//find the commandid that matches this Shortcut sc and alter it, push back its index in the modified list, if not present
size_t len = _shortcuts.size();
for (size_t i = 0; i < len; ++i)
bool isFound = false;
for (size_t i = 0; i < len, !isFound; ++i)
{
if (_shortcuts[i].getID() == (unsigned long)id)
{ //found our match
getShortcuts(childNode, _shortcuts[i]);
addUserModifiedIndex(i);
isFound = getInternalCommandShortcuts(childNode, _shortcuts[i]);
if (isFound)
addUserModifiedIndex(i);
}
}
}
@ -3031,6 +3036,52 @@ void NppParameters::feedScintKeys(TiXmlNodeA *node)
}
}
bool NppParameters::getInternalCommandShortcuts(TiXmlNodeA *node, CommandShortcut & cs, string* folderName)
{
if (!node) return false;
const char* name = (node->ToElement())->Attribute("name");
if (!name)
name = "";
bool isCtrl = false;
const char* isCtrlStr = (node->ToElement())->Attribute("Ctrl");
if (isCtrlStr)
isCtrl = (strcmp("yes", isCtrlStr) == 0);
bool isAlt = false;
const char* isAltStr = (node->ToElement())->Attribute("Alt");
if (isAltStr)
isAlt = (strcmp("yes", isAltStr) == 0);
bool isShift = false;
const char* isShiftStr = (node->ToElement())->Attribute("Shift");
if (isShiftStr)
isShift = (strcmp("yes", isShiftStr) == 0);
int key;
const char* keyStr = (node->ToElement())->Attribute("Key", &key);
if (!keyStr)
return false;
int nth = -1; // 0 based
const char* nthStr = (node->ToElement())->Attribute("nth", &nth);
if (nthStr && nth == 1)
{
if (cs.getNth() != nth)
return false;
}
if (folderName)
{
const char* fn = (node->ToElement())->Attribute("FolderName");
*folderName = fn ? fn : "";
}
cs = Shortcut(name, isCtrl, isAlt, isShift, static_cast<unsigned char>(key));
return true;
}
bool NppParameters::getShortcuts(TiXmlNodeA *node, Shortcut & sc, string* folderName)
{
if (!node) return false;
@ -3059,6 +3110,7 @@ bool NppParameters::getShortcuts(TiXmlNodeA *node, Shortcut & sc, string* folder
if (!keyStr)
return false;
if (folderName)
{
const char* fn = (node->ToElement())->Attribute("FolderName");
@ -3458,6 +3510,8 @@ void NppParameters::insertCmd(TiXmlNodeA *shortcutsRoot, const CommandShortcut &
sc->ToElement()->SetAttribute("Alt", key._isAlt?"yes":"no");
sc->ToElement()->SetAttribute("Shift", key._isShift?"yes":"no");
sc->ToElement()->SetAttribute("Key", key._key);
if (cmd.getNth() != 0)
sc->ToElement()->SetAttribute("nth", cmd.getNth());
}

View File

@ -1603,7 +1603,6 @@ public:
bool isRemappingShortcut() const {return _shortcuts.size() != 0;};
std::vector<CommandShortcut> & getUserShortcuts() { return _shortcuts; };
std::vector<size_t> & getUserModifiedShortcuts() { return _customizedShortcuts; };
void addUserModifiedIndex(size_t index);
std::vector<MacroShortcut> & getMacroList() { return _macros; };
@ -2017,6 +2016,7 @@ private:
void getActions(TiXmlNodeA *node, Macro & macro);
bool getShortcuts(TiXmlNodeA *node, Shortcut & sc, std::string* folderName = nullptr);
bool getInternalCommandShortcuts(TiXmlNodeA* node, CommandShortcut& cs, std::string* folderName = nullptr);
void writeStyle2Element(const Style & style2Write, Style & style2Sync, TiXmlElement *element);
void insertUserLang2Tree(TiXmlNode *node, UserLangContainer *userLang);

View File

@ -1264,3 +1264,13 @@ void CommandShortcut::setCategoryFromMenu(HMENU hMenu)
else
pNativeSpeaker->getMainMenuEntryName(_category, hMenu, "run", L"Run");
}
CommandShortcut& CommandShortcut::operator = (const Shortcut& sct)
{
if (this != &sct)
{
strcpy(this->_name, sct.getName());
this->_keyCombo = sct.getKeyCombo();
}
return *this;
}

View File

@ -184,19 +184,26 @@ protected :
class CommandShortcut : public Shortcut {
public:
CommandShortcut(const Shortcut& sc, long id) : Shortcut(sc), _id(id){
CommandShortcut(const Shortcut& sc, long id, bool isDuplicated = false) : Shortcut(sc), _id(id) {
_shortcutName = string2wstring(getName(), CP_UTF8);
if (isDuplicated) _nth = 1;
};
CommandShortcut& operator = (const Shortcut& sct);
void setCategoryFromMenu(HMENU hMenu);
unsigned long getID() const {return _id;};
void setID(unsigned long id) { _id = id;};
int getNth() const { return _nth; };
const TCHAR * getCategory() const { return _category.c_str(); };
const TCHAR * getShortcutName() const { return _shortcutName.c_str(); };
private :
unsigned long _id;
unsigned long _id = 0;
generic_string _category;
generic_string _shortcutName;
int _nth = 0; // Allow several shortcuts for the same command (_id).
// If there is the 2nd identical command in winKeyDefs array, the value of _nth will be 1.
// This variable member allows the application to distinguish the different shortcuts assigned to the same command.
};