Add the ability to hide selected toolbar buttons via a XML conf file

Usage:
Move & rename toolbarButtonsConf_example.xml to %APPDATA%\Notepad++\toolbarButtonsConf.xml, modify the XML file content & save it in your favorite editor (Notepad++, whatelse? ;) ), then relaunch Notepad++.

This PR simplies largely the logic of PR #15999 to make the code maintainable.

Fix #15106, fix #15440, fix #16000
This commit is contained in:
Don Ho 2025-02-21 17:11:57 +01:00
parent fd2157729a
commit 87b4276b3e
6 changed files with 185 additions and 15 deletions

View File

@ -150,11 +150,17 @@ Notepad_plus::Notepad_plus()
nppParam.setNativeLangSpeaker(&_nativeLangSpeaker);
TiXmlDocument *toolIconsDocRoot = nppParam.getCustomizedToolIcons();
TiXmlDocument *toolButtonsDocRoot = nppParam.getCustomizedToolButtons();
if (toolIconsDocRoot)
{
_toolBar.initTheme(toolIconsDocRoot);
}
_toolBar.initTheme(toolIconsDocRoot);
}
if (toolButtonsDocRoot)
{
_toolBar.initHideButtonsConf(toolButtonsDocRoot, toolBarIcons, sizeof(toolBarIcons) / sizeof(ToolBarButtonUnit));
}
// Determine if user is administrator.
BOOL is_admin;

View File

@ -1498,6 +1498,21 @@ bool NppParameters::load()
isAllLoaded = false;
}
//---------------------------------------//
// toolbarButtonsConf.xml : for per user //
//---------------------------------------//
std::wstring toolbarButtonsConfXmlPath(_userPath);
pathAppend(toolbarButtonsConfXmlPath, L"toolbarButtonsConf.xml");
_pXmlToolButtonsConfDoc = new TiXmlDocument(toolbarButtonsConfXmlPath);
loadOkay = _pXmlToolButtonsConfDoc->LoadFile();
if (!loadOkay)
{
delete _pXmlToolButtonsConfDoc;
_pXmlToolButtonsConfDoc = nullptr;
isAllLoaded = false;
}
//------------------------------//
// shortcuts.xml : for per user //
//------------------------------//
@ -1724,6 +1739,7 @@ void NppParameters::destroyInstance()
delete _pXmlNativeLangDocA;
delete _pXmlToolIconsDoc;
delete _pXmlToolButtonsConfDoc;
delete _pXmlShortcutDocA;
delete _pXmlContextMenuDocA;
delete _pXmlTabContextMenuDocA;

View File

@ -1630,7 +1630,8 @@ public:
TiXmlDocumentA * getNativeLangA() const {return _pXmlNativeLangDocA;};
TiXmlDocument * getCustomizedToolIcons() const {return _pXmlToolIconsDoc;};
TiXmlDocument* getCustomizedToolIcons() const {return _pXmlToolIconsDoc;};
TiXmlDocument* getCustomizedToolButtons() const {return _pXmlToolButtonsConfDoc;};
bool isTransparentAvailable() const {
return (_winVersion >= WV_VISTA);
@ -1875,6 +1876,7 @@ private:
TiXmlDocument *_pXmlUserLangDoc = nullptr; // userDefineLang.xml
std::vector<UdlXmlFileState> _pXmlUserLangsDoc; // userDefineLang customized XMLs
TiXmlDocument *_pXmlToolIconsDoc = nullptr; // toolbarIcons.xml
TiXmlDocument * _pXmlToolButtonsConfDoc = nullptr; // toolbarButtonsConf.xml
TiXmlDocumentA *_pXmlShortcutDocA = nullptr; // shortcuts.xml

View File

@ -67,6 +67,81 @@ ToolbarIconIdUnit toolbarIconIDs[] = {
{ L"save-macro", true }
};
void ToolBar::initHideButtonsConf(TiXmlDocument* toolButtonsDocRoot, ToolBarButtonUnit* buttonUnitArray, int arraySize)
{
TiXmlNode* toolButtons = toolButtonsDocRoot->FirstChild(L"NotepadPlus");
if (toolButtons)
{
toolButtons = toolButtons->FirstChild(L"ToolbarButtons");
if (toolButtons)
{
// Standard toolbar button
TiXmlNode* standardToolButtons = toolButtons->FirstChild(L"Standard");
if (standardToolButtons)
{
_toolbarStdButtonsConfArray = new bool[arraySize];
TiXmlElement* stdBtnElement = standardToolButtons->ToElement();
const wchar_t* isHideAll = stdBtnElement->Attribute(L"hideAll");
if (isHideAll && (lstrcmp(isHideAll, L"yes") == 0))
{
for (size_t i = 0; i < arraySize; ++i)
_toolbarStdButtonsConfArray[i] = false;
return;
}
for (size_t i = 0; i < arraySize; ++i)
_toolbarStdButtonsConfArray[i] = true;
for (TiXmlNode* childNode = standardToolButtons->FirstChildElement(L"Button");
childNode;
childNode = childNode->NextSibling(L"Button"))
{
TiXmlElement* element = childNode->ToElement();
int cmdID =0;
const wchar_t* cmdIDStr = element->Attribute(L"id", &cmdID);
int index = 0;
const wchar_t* orderStr = element->Attribute(L"index", &index);
const wchar_t* isHide = element->Attribute(L"hide");
if (cmdIDStr && orderStr && isHide && (lstrcmp(isHide, L"yes") == 0))
{
if (index < arraySize && buttonUnitArray[index]._cmdID == cmdID)
_toolbarStdButtonsConfArray[index] = false;
}
}
}
// Plugin toolbar button
TiXmlNode* pluginToolButtons = toolButtons->FirstChild(L"Plugin");
if (pluginToolButtons)
{
TiXmlElement* pluginBtnElement = pluginToolButtons->ToElement();
const wchar_t* isHideAll = pluginBtnElement->Attribute(L"hideAll");
if (isHideAll && (lstrcmp(isHideAll, L"yes") == 0))
{
_toolbarPluginButtonsConf._isHideAll = true;
return;
}
for (TiXmlNode* childNode = pluginToolButtons->FirstChildElement(L"Button");
childNode;
childNode = childNode->NextSibling(L"Button"))
{
bool doShow = true;
TiXmlElement* element = childNode->ToElement();
const wchar_t* isHide = element->Attribute(L"hide");
doShow = !(isHide && (lstrcmp(isHide, L"yes") == 0));
_toolbarPluginButtonsConf._showPluginButtonsArray.push_back(doShow);
}
}
}
}
}
void ToolBar::initTheme(TiXmlDocument *toolIconsDocRoot)
{
_toolIcons = toolIconsDocRoot->FirstChild(L"NotepadPlus");
@ -122,7 +197,7 @@ void ToolBar::initTheme(TiXmlDocument *toolIconsDocRoot)
}
}
bool ToolBar::init( HINSTANCE hInst, HWND hPere, toolBarStatusType type, ToolBarButtonUnit *buttonUnitArray, int arraySize)
bool ToolBar::init( HINSTANCE hInst, HWND hPere, toolBarStatusType type, ToolBarButtonUnit* buttonUnitArray, int arraySize)
{
Window::init(hInst, hPere);
@ -141,7 +216,7 @@ bool ToolBar::init( HINSTANCE hInst, HWND hPere, toolBarStatusType type, ToolBar
InitCommonControlsEx(&icex);
//Create the list of buttons
_nbButtons = arraySize;
_nbButtons = arraySize;
_nbDynButtons = _vDynBtnReg.size();
_nbTotalButtons = _nbButtons + (_nbDynButtons ? _nbDynButtons + 1 : 0);
_pTBB = new TBBUTTON[_nbTotalButtons]; //add one for the extra separator
@ -150,6 +225,7 @@ bool ToolBar::init( HINSTANCE hInst, HWND hPere, toolBarStatusType type, ToolBar
int bmpIndex = -1;
BYTE style = 0;
size_t i = 0;
for (; i < _nbButtons && i < _nbTotalButtons; ++i)
{
cmd = buttonUnitArray[i]._cmdID;
@ -158,38 +234,42 @@ bool ToolBar::init( HINSTANCE hInst, HWND hPere, toolBarStatusType type, ToolBar
case 0:
{
style = BTNS_SEP;
break;
}
break;
case IDM_VIEW_ALL_CHARACTERS:
{
++bmpIndex;
style = BTNS_DROPDOWN;
break;
}
break;
default:
{
++bmpIndex;
style = BTNS_BUTTON;
break;
}
}
_pTBB[i].iBitmap = (cmd != 0 ? bmpIndex : 0);
_pTBB[i].idCommand = cmd;
_pTBB[i].fsState = TBSTATE_ENABLED;
_pTBB[i].fsState = TBSTATE_ENABLED | (_toolbarStdButtonsConfArray ? (_toolbarStdButtonsConfArray[i] ? 0 : TBSTATE_HIDDEN) : 0);
_pTBB[i].fsStyle = style;
_pTBB[i].dwData = 0;
_pTBB[i].iString = 0;
}
bool doHideAllPluginButtons = _toolbarPluginButtonsConf._isHideAll;
size_t nbPluginButtonsConf = _toolbarPluginButtonsConf._showPluginButtonsArray.size();
if (_nbDynButtons > 0 && i < _nbTotalButtons)
{
unsigned char addedStateFlag = doHideAllPluginButtons ? TBSTATE_HIDDEN : (nbPluginButtonsConf > 0 ? (_toolbarPluginButtonsConf._showPluginButtonsArray[0] ? 0 : TBSTATE_HIDDEN) : 0);
//add separator
_pTBB[i].iBitmap = 0;
_pTBB[i].idCommand = 0;
_pTBB[i].fsState = TBSTATE_ENABLED;
_pTBB[i].fsState = TBSTATE_ENABLED | addedStateFlag;
_pTBB[i].fsStyle = BTNS_SEP;
_pTBB[i].dwData = 0;
_pTBB[i].iString = 0;
@ -201,9 +281,11 @@ bool ToolBar::init( HINSTANCE hInst, HWND hPere, toolBarStatusType type, ToolBar
cmd = _vDynBtnReg[j]._message;
++bmpIndex;
addedStateFlag = doHideAllPluginButtons ? TBSTATE_HIDDEN : (nbPluginButtonsConf > j + 1 ? (_toolbarPluginButtonsConf._showPluginButtonsArray[j + 1] ? 0 : TBSTATE_HIDDEN) : 0);
_pTBB[i].iBitmap = bmpIndex;
_pTBB[i].idCommand = cmd;
_pTBB[i].fsState = TBSTATE_ENABLED;
_pTBB[i].fsState = TBSTATE_ENABLED | addedStateFlag;
_pTBB[i].fsStyle = BTNS_BUTTON;
_pTBB[i].dwData = 0;
_pTBB[i].iString = 0;

View File

@ -43,6 +43,12 @@ struct iconLocator {
: _listIndex(iList), _iconIndex(iIcon), _iconLocation(iconLoc){};
};
struct ToolbarPluginButtonsConf
{
bool _isHideAll = false;
std::vector<bool> _showPluginButtonsArray;
};
class ReBar;
class TiXmlDocument;
class TiXmlNode;
@ -53,9 +59,10 @@ public :
ToolBar() = default;
~ToolBar() = default;
void initTheme(TiXmlDocument *toolIconsDocRoot);
virtual bool init(HINSTANCE hInst, HWND hPere, toolBarStatusType type,
ToolBarButtonUnit *buttonUnitArray, int arraySize);
void initTheme(TiXmlDocument* toolIconsDocRoot);
void initHideButtonsConf(TiXmlDocument* toolButtonsDocRoot, ToolBarButtonUnit* buttonUnitArray, int arraySize);
virtual bool init(HINSTANCE hInst, HWND hPere, toolBarStatusType type, ToolBarButtonUnit* buttonUnitArray, int arraySize);
virtual void destroy();
void enable(int cmdID, bool doEnable) const {
@ -116,8 +123,10 @@ private :
ReBar * _pRebar = nullptr;
REBARBANDINFO _rbBand = {};
std::vector<iconLocator> _customIconVect;
bool* _toolbarStdButtonsConfArray = nullptr;
ToolbarPluginButtonsConf _toolbarPluginButtonsConf;
TiXmlNode *_toolIcons = nullptr;
TiXmlNode* _toolIcons = nullptr;
DPIManagerV2 _dpiManager;

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" ?>
<NotepadPlus>
<ToolbarButtons>
<Standard hideAll="no">
<Button hide="no" index="0" id="41001" name="New" />
<Button hide="no" index="1" id="41002" name="Open..." />
<Button hide="no" index="2" id="41006" name="Save" />
<Button hide="no" index="3" id="41007" name="Save All" />
<Button hide="no" index="4" id="41003" name="Close" />
<Button hide="no" index="5" id="41004" name="Close All" />
<Button hide="no" index="6" id="41010" name="Print..." />
<Button hide="no" index="7" id="0" name="SEPARATOR" />
<Button hide="no" index="8" id="42001" name="Cut" />
<Button hide="no" index="9" id="42002" name="Copy" />
<Button hide="no" index="10" id="42005" name="Paste" />
<Button hide="no" index="11" id="0" name="SEPARATOR" />
<Button hide="no" index="12" id="42003" name="Undo" />
<Button hide="no" index="13" id="42004" name="Redo" />
<Button hide="no" index="14" id="0" name="SEPARATOR" />
<Button hide="no" index="15" id="43001" name="Find..." />
<Button hide="no" index="16" id="43003" name="Replace..." />
<Button hide="no" index="17" id="0" name="SEPARATOR" />
<Button hide="no" index="18" id="44023" name="Zoom In (Ctrl+Mouse Wheel Up)" />
<Button hide="no" index="19" id="44024" name="Zoom Out (Ctrl+Mouse Wheel Down)" />
<Button hide="no" index="20" id="0" name="SEPARATOR" />
<Button hide="no" index="21" id="44035" name="Synchronize Vertical Scrolling" />
<Button hide="no" index="22" id="44036" name="Synchronize Horizontal Scrolling" />
<Button hide="no" index="23" id="0" name="SEPARATOR" />
<Button hide="no" index="24" id="44022" name="Word wrap" />
<Button hide="no" index="25" id="44019" name="Show All Characters" />
<Button hide="no" index="26" id="44020" name="Show Indent Guide" />
<Button hide="no" index="27" id="0" name="SEPARATOR" />
<Button hide="no" index="28" id="46250" name="Define your language..." />
<Button hide="no" index="29" id="44080" name="Document Map" />
<Button hide="no" index="30" id="44070" name="Document List" />
<Button hide="no" index="31" id="44084" name="Function List" />
<Button hide="no" index="32" id="44085" name="Folder as Workspace" />
<Button hide="no" index="33" id="0" name="SEPARATOR" />
<Button hide="no" index="34" id="44097" name="Monitoring (tail -f)" />
<Button hide="no" index="35" id="0" name="SEPARATOR" />
<Button hide="no" index="36" id="42018" name="Start Recording" />
<Button hide="no" index="37" id="42019" name="Stop Recording" />
<Button hide="no" index="38" id="42021" name="Playback" />
<Button hide="no" index="39" id="42032" name="Run a Macro Multiple Times..." />
<Button hide="no" index="40" id="42025" name="Save Current Recorded Macro..." />
</Standard>
<Plugin hideAll="no">
<Button hide="no" name="SEPARATOR" /> <!-- order="1" -->
<Button hide="no" name="Plugin button 1" /> <!-- order="2" -->
<Button hide="no" name="Plugin button 2" /> <!-- order="3" -->
<Button hide="no" name="Plugin button 3" /> <!-- order="4" -->
</Plugin>
</ToolbarButtons>
</NotepadPlus>