Add default sorting ability in Function list

* Add new preference setting to allow function list to be sorted lexicographically by default.
* Fix sorting for mixed mode function list parsers on new file open.
* Add new translations to english.xml and german.xml.

Fix #11446, close #11447
This commit is contained in:
Daniel Fuchs 2022-03-28 14:54:31 +02:00 committed by Don Ho
parent 658b626257
commit 64bfa72bd0
11 changed files with 101 additions and 18 deletions

View File

@ -3,7 +3,7 @@
The comments are here for explanation, it's not necessary to translate them. The comments are here for explanation, it's not necessary to translate them.
--> -->
<NotepadPlus> <NotepadPlus>
<Native-Langue name="English" filename="english.xml" version="8.3"> <Native-Langue name="English" filename="english.xml" version="8.3.3">
<Menu> <Menu>
<Main> <Main>
<!-- Main Menu Entries --> <!-- Main Menu Entries -->
@ -1349,6 +1349,8 @@ Continue?"/>
<PanelTitle name="Function List"/> <PanelTitle name="Function List"/>
<SortTip name="Sort"/> <SortTip name="Sort"/>
<ReloadTip name="Reload"/> <ReloadTip name="Reload"/>
<PreferencesTip name="Preferences"/>
<PreferencesInitialSort name="Sort functions (A to Z) by default"/>
</FunctionList> </FunctionList>
<FolderAsWorkspace> <FolderAsWorkspace>
<PanelTitle name="Folder as Workspace"/> <PanelTitle name="Folder as Workspace"/>

View File

@ -12,7 +12,7 @@
--> -->
<NotepadPlus> <NotepadPlus>
<Native-Langue name="Deutsch" filename="german.xml" version="8.3.2"> <Native-Langue name="Deutsch" filename="german.xml" version="8.3.3">
<Menu> <Menu>
<Main> <Main>
<!-- Main Menu Entries --> <!-- Main Menu Entries -->
@ -1357,6 +1357,8 @@ Fortsetzen?"/>
<PanelTitle name="Funktionsliste"/> <PanelTitle name="Funktionsliste"/>
<SortTip name="Sortieren"/> <SortTip name="Sortieren"/>
<ReloadTip name="Aktualisieren"/> <ReloadTip name="Aktualisieren"/>
<PreferencesTip name="Einstellungen"/>
<PreferencesInitialSort name="Funktionen standardmäßig nach Namen sortieren"/>
</FunctionList> </FunctionList>
<FolderAsWorkspace> <FolderAsWorkspace>
<PanelTitle name="Verzeichnis als Arbeitsbereich"/> <PanelTitle name="Verzeichnis als Arbeitsbereich"/>

View File

@ -369,8 +369,10 @@ IDI_FUNCLIST_LEAF BITMAP "icons/funcList_leaf.bmp"
IDI_FUNCLIST_SORTBUTTON BITMAP "icons/funclstSort.bmp" IDI_FUNCLIST_SORTBUTTON BITMAP "icons/funclstSort.bmp"
IDI_FUNCLIST_RELOADBUTTON BITMAP "icons/funclstReload.bmp" IDI_FUNCLIST_RELOADBUTTON BITMAP "icons/funclstReload.bmp"
IDI_FUNCLIST_PREFERENCEBUTTON BITMAP "icons/funclstPreferences.bmp"
IDI_FUNCLIST_SORTBUTTON_DM BITMAP "icons/darkMode/panels/funclstSort.bmp" IDI_FUNCLIST_SORTBUTTON_DM BITMAP "icons/darkMode/panels/funclstSort.bmp"
IDI_FUNCLIST_RELOADBUTTON_DM BITMAP "icons/darkMode/panels/funclstReload.bmp" IDI_FUNCLIST_RELOADBUTTON_DM BITMAP "icons/darkMode/panels/funclstReload.bmp"
IDI_FUNCLIST_PREFERENCEBUTTON_DM BITMAP "icons/darkMode/panels/funclstPreferences.bmp"
IDI_GET_INFO_FROM_TOOLTIP ICON "icons/MoreOnTooltip.ico" IDI_GET_INFO_FROM_TOOLTIP ICON "icons/MoreOnTooltip.ico"

View File

@ -5503,6 +5503,10 @@ void NppParameters::feedGUIParameters(TiXmlNode *node)
if (optDocPeekOnMap) if (optDocPeekOnMap)
_nppGUI._isDocPeekOnMap = (lstrcmp(optDocPeekOnMap, TEXT("yes")) == 0); _nppGUI._isDocPeekOnMap = (lstrcmp(optDocPeekOnMap, TEXT("yes")) == 0);
const TCHAR* optSortFunctionList = element->Attribute(TEXT("sortFunctionList"));
if (optSortFunctionList)
_nppGUI._shouldSortFunctionList = (lstrcmp(optSortFunctionList, TEXT("yes")) == 0);
const TCHAR* saveDlgExtFilterToAllTypes = element->Attribute(TEXT("saveDlgExtFilterToAllTypes")); const TCHAR* saveDlgExtFilterToAllTypes = element->Attribute(TEXT("saveDlgExtFilterToAllTypes"));
if (saveDlgExtFilterToAllTypes) if (saveDlgExtFilterToAllTypes)
_nppGUI._setSaveDlgExtFiltToAllTypes = (lstrcmp(saveDlgExtFilterToAllTypes, TEXT("yes")) == 0); _nppGUI._setSaveDlgExtFiltToAllTypes = (lstrcmp(saveDlgExtFilterToAllTypes, TEXT("yes")) == 0);
@ -6564,6 +6568,7 @@ void NppParameters::createXmlTreeFromGUIParams()
GUIConfigElement->SetAttribute(TEXT("isFolderDroppedOpenFiles"), _nppGUI._isFolderDroppedOpenFiles ? TEXT("yes") : TEXT("no")); GUIConfigElement->SetAttribute(TEXT("isFolderDroppedOpenFiles"), _nppGUI._isFolderDroppedOpenFiles ? TEXT("yes") : TEXT("no"));
GUIConfigElement->SetAttribute(TEXT("docPeekOnTab"), _nppGUI._isDocPeekOnTab ? TEXT("yes") : TEXT("no")); GUIConfigElement->SetAttribute(TEXT("docPeekOnTab"), _nppGUI._isDocPeekOnTab ? TEXT("yes") : TEXT("no"));
GUIConfigElement->SetAttribute(TEXT("docPeekOnMap"), _nppGUI._isDocPeekOnMap ? TEXT("yes") : TEXT("no")); GUIConfigElement->SetAttribute(TEXT("docPeekOnMap"), _nppGUI._isDocPeekOnMap ? TEXT("yes") : TEXT("no"));
GUIConfigElement->SetAttribute(TEXT("sortFunctionList"), _nppGUI._shouldSortFunctionList ? TEXT("yes") : TEXT("no"));
GUIConfigElement->SetAttribute(TEXT("saveDlgExtFilterToAllTypes"), _nppGUI._setSaveDlgExtFiltToAllTypes ? TEXT("yes") : TEXT("no")); GUIConfigElement->SetAttribute(TEXT("saveDlgExtFilterToAllTypes"), _nppGUI._setSaveDlgExtFiltToAllTypes ? TEXT("yes") : TEXT("no"));
GUIConfigElement->SetAttribute(TEXT("muteSounds"), _nppGUI._muteSounds ? TEXT("yes") : TEXT("no")); GUIConfigElement->SetAttribute(TEXT("muteSounds"), _nppGUI._muteSounds ? TEXT("yes") : TEXT("no"));
} }

View File

@ -859,6 +859,9 @@ struct NppGUI final
bool _isDocPeekOnTab = false; bool _isDocPeekOnTab = false;
bool _isDocPeekOnMap = false; bool _isDocPeekOnMap = false;
// function list should be sorted by default on new file open
bool _shouldSortFunctionList = false;
DarkModeConf _darkmode; DarkModeConf _darkmode;
}; };

View File

@ -27,8 +27,7 @@ using namespace std;
#define INDEX_NODE 1 #define INDEX_NODE 1
#define INDEX_LEAF 2 #define INDEX_LEAF 2
#define FL_SORTLOCALNODENAME "SortTip" #define FL_PREFERENCES_INITIALSORT_ID 1
#define FL_RELOADLOCALNODENAME "ReloadTip"
FunctionListPanel::~FunctionListPanel() FunctionListPanel::~FunctionListPanel()
{ {
@ -394,7 +393,8 @@ void FunctionListPanel::reload()
if (!previousParams) if (!previousParams)
{ {
::SendMessage(_hSearchEdit, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(TEXT(""))); ::SendMessage(_hSearchEdit, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(TEXT("")));
setSort(false); setSort(NppParameters::getInstance().getNppGUI()._shouldSortFunctionList);
sortOrUnsort();
_treeView.expand(root); _treeView.expand(root);
} }
else else
@ -420,6 +420,32 @@ void FunctionListPanel::reload()
} }
} }
void FunctionListPanel::initPreferencesMenu()
{
NativeLangSpeaker* pNativeSpeaker = NppParameters::getInstance().getNativeLangSpeaker();
NppGUI& nppGUI = NppParameters::getInstance().getNppGUI();
generic_string shouldSortFunctionListStr = pNativeSpeaker->getAttrNameStr(TEXT("Sort functions (A to Z) by default"), FL_FUCTIONLISTROOTNODE, FL_PREFERENCE_INITIALSORT);
_hPreferencesMenu = ::CreatePopupMenu();
::InsertMenu(_hPreferencesMenu, 0, MF_BYCOMMAND, FL_PREFERENCES_INITIALSORT_ID, shouldSortFunctionListStr.c_str());
::CheckMenuItem(_hPreferencesMenu, FL_PREFERENCES_INITIALSORT_ID, MF_BYCOMMAND | (nppGUI._shouldSortFunctionList ? MF_CHECKED : MF_UNCHECKED));
}
void FunctionListPanel::showPreferencesMenu()
{
RECT rectToolbar;
RECT rectPreferencesButton;
::GetWindowRect(_hToolbarMenu, &rectToolbar);
::SendMessage(_hToolbarMenu, TB_GETRECT, IDC_PREFERENCEBUTTON_FUNCLIST, (LPARAM)&rectPreferencesButton);
::TrackPopupMenu(_hPreferencesMenu,
NppParameters::getInstance().getNativeLangSpeaker()->isRTL() ? TPM_RIGHTALIGN | TPM_LAYOUTRTL : TPM_LEFTALIGN,
rectToolbar.left + rectPreferencesButton.left,
rectToolbar.top + rectPreferencesButton.bottom,
0, _hSelf, NULL);
}
void FunctionListPanel::markEntry() void FunctionListPanel::markEntry()
{ {
LONG lineNr = static_cast<LONG>((*_ppEditView)->getCurrentLineNumber()); LONG lineNr = static_cast<LONG>((*_ppEditView)->getCurrentLineNumber());
@ -570,6 +596,10 @@ void FunctionListPanel::notified(LPNMHDR notification)
{ {
wcscpy_s(lpttt->szText, _reloadTipStr.c_str()); wcscpy_s(lpttt->szText, _reloadTipStr.c_str());
} }
else if (notification->idFrom == IDC_PREFERENCEBUTTON_FUNCLIST)
{
wcscpy_s(lpttt->szText, _preferenceTipStr.c_str());
}
} }
else if (notification->hwndFrom == _treeView.getHSelf() || notification->hwndFrom == this->_treeViewSearchResult.getHSelf()) else if (notification->hwndFrom == _treeView.getHSelf() || notification->hwndFrom == this->_treeViewSearchResult.getHSelf())
{ {
@ -638,7 +668,6 @@ void FunctionListPanel::searchFuncAndSwitchView()
{ {
TCHAR text2search[MAX_PATH] ; TCHAR text2search[MAX_PATH] ;
::SendMessage(_hSearchEdit, WM_GETTEXT, MAX_PATH, reinterpret_cast<LPARAM>(text2search)); ::SendMessage(_hSearchEdit, WM_GETTEXT, MAX_PATH, reinterpret_cast<LPARAM>(text2search));
bool doSort = shouldSort();
if (text2search[0] == '\0') if (text2search[0] == '\0')
{ {
@ -669,8 +698,11 @@ void FunctionListPanel::searchFuncAndSwitchView()
::InvalidateRect(_hSearchEdit, NULL, TRUE); ::InvalidateRect(_hSearchEdit, NULL, TRUE);
} }
if (doSort) // restore selected sorting
if (shouldSort())
_pTreeView->sort(_pTreeView->getRoot(), true); _pTreeView->sort(_pTreeView->getRoot(), true);
else
_pTreeView->customSorting(_pTreeView->getRoot(), categorySortFunc, 0, true);
} }
static WNDPROC oldFunclstToolbarProc = NULL; static WNDPROC oldFunclstToolbarProc = NULL;
@ -788,6 +820,8 @@ intptr_t CALLBACK FunctionListPanel::run_dlgProc(UINT message, WPARAM wParam, LP
case WM_INITDIALOG : case WM_INITDIALOG :
{ {
FunctionListPanel::initPreferencesMenu();
NppParameters& nppParams = NppParameters::getInstance(); NppParameters& nppParams = NppParameters::getInstance();
int editWidth = nppParams._dpiManager.scaleX(100); int editWidth = nppParams._dpiManager.scaleX(100);
@ -809,9 +843,9 @@ intptr_t CALLBACK FunctionListPanel::run_dlgProc(UINT message, WPARAM wParam, LP
::SendMessage(_hToolbarMenu, TB_SETBITMAPSIZE, 0, MAKELPARAM(iconSizeDyn, iconSizeDyn)); ::SendMessage(_hToolbarMenu, TB_SETBITMAPSIZE, 0, MAKELPARAM(iconSizeDyn, iconSizeDyn));
TBADDBITMAP addbmp = { 0, 0 }; TBADDBITMAP addbmp = { 0, 0 };
const int nbIcons = 2; const int nbIcons = 3;
int iconIDs[nbIcons] = { IDI_FUNCLIST_SORTBUTTON, IDI_FUNCLIST_RELOADBUTTON }; int iconIDs[nbIcons] = { IDI_FUNCLIST_SORTBUTTON, IDI_FUNCLIST_RELOADBUTTON, IDI_FUNCLIST_PREFERENCEBUTTON };
int iconDarkModeIDs[nbIcons] = { IDI_FUNCLIST_SORTBUTTON_DM, IDI_FUNCLIST_RELOADBUTTON_DM }; int iconDarkModeIDs[nbIcons] = { IDI_FUNCLIST_SORTBUTTON_DM, IDI_FUNCLIST_RELOADBUTTON_DM, IDI_FUNCLIST_PREFERENCEBUTTON_DM };
for (size_t i = 0; i < nbIcons; ++i) for (size_t i = 0; i < nbIcons; ++i)
{ {
int icoID = NppDarkMode::isEnabled() ? iconDarkModeIDs[i] : iconIDs[i]; int icoID = NppDarkMode::isEnabled() ? iconDarkModeIDs[i] : iconIDs[i];
@ -841,6 +875,12 @@ intptr_t CALLBACK FunctionListPanel::run_dlgProc(UINT message, WPARAM wParam, LP
tbButtons[2].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; tbButtons[2].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE;
tbButtons[2].iString = reinterpret_cast<intptr_t>(TEXT("")); tbButtons[2].iString = reinterpret_cast<intptr_t>(TEXT(""));
tbButtons[3].idCommand = IDC_PREFERENCEBUTTON_FUNCLIST;
tbButtons[3].iBitmap = 2;
tbButtons[3].fsState = TBSTATE_ENABLED;
tbButtons[3].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE;
tbButtons[3].iString = reinterpret_cast<intptr_t>(TEXT(""));
::SendMessage(_hToolbarMenu, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); ::SendMessage(_hToolbarMenu, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
::SendMessage(_hToolbarMenu, TB_SETBUTTONSIZE, 0, MAKELONG(nppParams._dpiManager.scaleX(16), nppParams._dpiManager.scaleY(16))); ::SendMessage(_hToolbarMenu, TB_SETBUTTONSIZE, 0, MAKELONG(nppParams._dpiManager.scaleX(16), nppParams._dpiManager.scaleY(16)));
::SendMessage(_hToolbarMenu, TB_ADDBUTTONS, sizeof(tbButtons) / sizeof(TBBUTTON), reinterpret_cast<LPARAM>(&tbButtons)); ::SendMessage(_hToolbarMenu, TB_ADDBUTTONS, sizeof(tbButtons) / sizeof(TBBUTTON), reinterpret_cast<LPARAM>(&tbButtons));
@ -852,6 +892,7 @@ intptr_t CALLBACK FunctionListPanel::run_dlgProc(UINT message, WPARAM wParam, LP
NativeLangSpeaker *pNativeSpeaker = nppParams.getNativeLangSpeaker(); NativeLangSpeaker *pNativeSpeaker = nppParams.getNativeLangSpeaker();
_sortTipStr = pNativeSpeaker->getAttrNameStr(_sortTipStr.c_str(), FL_FUCTIONLISTROOTNODE, FL_SORTLOCALNODENAME); _sortTipStr = pNativeSpeaker->getAttrNameStr(_sortTipStr.c_str(), FL_FUCTIONLISTROOTNODE, FL_SORTLOCALNODENAME);
_reloadTipStr = pNativeSpeaker->getAttrNameStr(_reloadTipStr.c_str(), FL_FUCTIONLISTROOTNODE, FL_RELOADLOCALNODENAME); _reloadTipStr = pNativeSpeaker->getAttrNameStr(_reloadTipStr.c_str(), FL_FUCTIONLISTROOTNODE, FL_RELOADLOCALNODENAME);
_preferenceTipStr = pNativeSpeaker->getAttrNameStr(_preferenceTipStr.c_str(), FL_FUCTIONLISTROOTNODE, FL_PREFERENCESLOCALNODENAME);
_hSearchEdit = CreateWindowEx(0, L"Edit", NULL, _hSearchEdit = CreateWindowEx(0, L"Edit", NULL,
WS_CHILD | WS_BORDER | WS_VISIBLE | ES_AUTOVSCROLL, WS_CHILD | WS_BORDER | WS_VISIBLE | ES_AUTOVSCROLL,
@ -892,6 +933,7 @@ intptr_t CALLBACK FunctionListPanel::run_dlgProc(UINT message, WPARAM wParam, LP
case WM_DESTROY: case WM_DESTROY:
_treeView.destroy(); _treeView.destroy();
_treeViewSearchResult.destroy(); _treeViewSearchResult.destroy();
::DestroyMenu(_hPreferencesMenu);
::DestroyWindow(_hToolbarMenu); ::DestroyWindow(_hToolbarMenu);
break; break;
@ -930,6 +972,20 @@ intptr_t CALLBACK FunctionListPanel::run_dlgProc(UINT message, WPARAM wParam, LP
reload(); reload();
} }
return TRUE; return TRUE;
case IDC_PREFERENCEBUTTON_FUNCLIST:
{
showPreferencesMenu();
}
return TRUE;
case FL_PREFERENCES_INITIALSORT_ID:
{
bool& shouldSortFunctionList = NppParameters::getInstance().getNppGUI()._shouldSortFunctionList;
shouldSortFunctionList = !shouldSortFunctionList;
::CheckMenuItem(_hPreferencesMenu, FL_PREFERENCES_INITIALSORT_ID, MF_BYCOMMAND | (shouldSortFunctionList ? MF_CHECKED : MF_UNCHECKED));
}
return TRUE;
} }
} }
break; break;

View File

@ -24,6 +24,12 @@
#define FL_PANELTITLE TEXT("Function List") #define FL_PANELTITLE TEXT("Function List")
#define FL_FUCTIONLISTROOTNODE "FunctionList" #define FL_FUCTIONLISTROOTNODE "FunctionList"
#define FL_SORTLOCALNODENAME "SortTip"
#define FL_RELOADLOCALNODENAME "ReloadTip"
#define FL_PREFERENCESLOCALNODENAME "PreferencesTip"
#define FL_PREFERENCE_INITIALSORT "PreferencesInitialSort"
class ScintillaEditView; class ScintillaEditView;
/* /*
@ -98,6 +104,7 @@ public:
protected: protected:
virtual intptr_t CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); virtual intptr_t CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);
HMENU _hPreferencesMenu = NULL;
private: private:
HWND _hToolbarMenu = nullptr; HWND _hToolbarMenu = nullptr;
@ -114,6 +121,7 @@ private:
generic_string _sortTipStr = TEXT("Sort"); generic_string _sortTipStr = TEXT("Sort");
generic_string _reloadTipStr = TEXT("Reload"); generic_string _reloadTipStr = TEXT("Reload");
generic_string _preferenceTipStr = TEXT("Preferences");
std::vector<foundInfo> _foundFuncInfos; std::vector<foundInfo> _foundFuncInfos;
@ -134,5 +142,7 @@ private:
bool shouldSort(); bool shouldSort();
void setSort(bool isEnabled); void setSort(bool isEnabled);
void findMarkEntry(HTREEITEM htItem, LONG line); void findMarkEntry(HTREEITEM htItem, LONG line);
void initPreferencesMenu();
void showPreferencesMenu();
}; };

View File

@ -23,4 +23,5 @@
#define IDC_SEARCHFIELD_FUNCLIST (IDD_FUNCLIST_PANEL + 3) #define IDC_SEARCHFIELD_FUNCLIST (IDD_FUNCLIST_PANEL + 3)
#define IDC_RELOADBUTTON_FUNCLIST (IDD_FUNCLIST_PANEL + 4) #define IDC_RELOADBUTTON_FUNCLIST (IDD_FUNCLIST_PANEL + 4)
#define IDC_SORTBUTTON_FUNCLIST (IDD_FUNCLIST_PANEL + 5) #define IDC_SORTBUTTON_FUNCLIST (IDD_FUNCLIST_PANEL + 5)
#define IDC_PREFERENCEBUTTON_FUNCLIST (IDD_FUNCLIST_PANEL + 6)

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

View File

@ -282,8 +282,10 @@
#define IDI_FUNCLIST_SORTBUTTON 631 #define IDI_FUNCLIST_SORTBUTTON 631
#define IDI_FUNCLIST_RELOADBUTTON 632 #define IDI_FUNCLIST_RELOADBUTTON 632
#define IDI_FUNCLIST_SORTBUTTON_DM 633 #define IDI_FUNCLIST_PREFERENCEBUTTON 633
#define IDI_FUNCLIST_RELOADBUTTON_DM 634 #define IDI_FUNCLIST_SORTBUTTON_DM 634
#define IDI_FUNCLIST_RELOADBUTTON_DM 635
#define IDI_FUNCLIST_PREFERENCEBUTTON_DM 636