From 883045d96fca53197e0d164a802db4b0171cedb7 Mon Sep 17 00:00:00 2001 From: AngryGamer Date: Sun, 11 Feb 2018 17:13:34 -0800 Subject: [PATCH] Keep Doc Switcher's ordering in sync with Tab bar Close #946, close #1684, close #2342, close #4015 --- PowerEditor/src/NppBigSwitch.cpp | 5 + .../VerticalFileSwitcher.cpp | 140 +++++++++++------- .../VerticalFileSwitcher.h | 26 +++- .../VerticalFileSwitcherListView.cpp | 55 +++++-- .../VerticalFileSwitcherListView.h | 1 + 5 files changed, 155 insertions(+), 72 deletions(-) diff --git a/PowerEditor/src/NppBigSwitch.cpp b/PowerEditor/src/NppBigSwitch.cpp index 81ff9c2a..ee685d76 100644 --- a/PowerEditor/src/NppBigSwitch.cpp +++ b/PowerEditor/src/NppBigSwitch.cpp @@ -458,6 +458,11 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa case NPPM_INTERNAL_DOCORDERCHANGED : { + if (_pFileSwitcherPanel) + { + _pFileSwitcherPanel->updateTabOrder(); + } + BufferID id = _pEditView->getCurrentBufferID(); // Notify plugins that current file is about to be closed diff --git a/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.cpp b/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.cpp index cfdb0a41..d8876e42 100644 --- a/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.cpp +++ b/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.cpp @@ -34,26 +34,41 @@ int CALLBACK ListViewCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { - LPNMLISTVIEW pnmListView = (LPNMLISTVIEW)lParamSort; + sortCompareData* sortData = (sortCompareData*)lParamSort; TCHAR str1[MAX_PATH]; TCHAR str2[MAX_PATH]; - ListView_GetItemText(pnmListView->hdr.hwndFrom, lParam1, pnmListView->iSubItem, str1, sizeof(str1)); - ListView_GetItemText(pnmListView->hdr.hwndFrom, lParam2, pnmListView->iSubItem, str2, sizeof(str2)); - - LVCOLUMN lvc; - lvc.mask = LVCF_FMT; - ::SendMessage(pnmListView->hdr.hwndFrom, LVM_GETCOLUMN, pnmListView->iSubItem, reinterpret_cast(&lvc)); - bool isDirectionUp = (HDF_SORTUP & lvc.fmt) != 0; + ListView_GetItemText(sortData->hListView, lParam1, sortData->columnIndex, str1, sizeof(str1)); + ListView_GetItemText(sortData->hListView, lParam2, sortData->columnIndex, str2, sizeof(str2)); int result = lstrcmp(str1, str2); - if (isDirectionUp) + if (sortData->sortDirection == SORT_DIRECTION_UP) return result; return (0 - result); }; +void VerticalFileSwitcher::startColumnSort() +{ + // reset sorting if exts column was just disabled + HWND colHeader = reinterpret_cast(SendMessage(_fileListView.getHSelf(), LVM_GETHEADER, 0, 0)); + int columnCount = static_cast(SendMessage(colHeader, HDM_GETITEMCOUNT, 0, 0)); + if (_lastSortingColumn >= columnCount) + { + _lastSortingColumn = 0; + _lastSortingDirection = SORT_DIRECTION_NONE; + } + + if (_lastSortingDirection != SORT_DIRECTION_NONE) + { + sortCompareData sortData = {_fileListView.getHSelf(), _lastSortingColumn, _lastSortingDirection}; + ListView_SortItemsEx(_fileListView.getHSelf(), ListViewCompareProc, reinterpret_cast(&sortData)); + } + + updateHeaderArrow(); +} + INT_PTR CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) @@ -146,8 +161,17 @@ INT_PTR CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, case LVN_COLUMNCLICK: { LPNMLISTVIEW pnmLV = (LPNMLISTVIEW)lParam; - setHeaderOrder(pnmLV); - ListView_SortItemsEx(pnmLV->hdr.hwndFrom, ListViewCompareProc, reinterpret_cast(pnmLV)); + _lastSortingDirection = setHeaderOrder(pnmLV->iSubItem); + _lastSortingColumn = pnmLV->iSubItem; + if (_lastSortingDirection != SORT_DIRECTION_NONE) + { + startColumnSort(); + } + else + { + _fileListView.reload(); + updateHeaderArrow(); + } return TRUE; } case LVN_KEYDOWN: @@ -220,51 +244,65 @@ void VerticalFileSwitcher::activateDoc(TaskLstFnStatus *tlfs) const ::SendMessage(_hParent, NPPM_ACTIVATEDOC, view2set, index2Switch); } -int VerticalFileSwitcher::setHeaderOrder(LPNMLISTVIEW pnm_list_view) +int VerticalFileSwitcher::setHeaderOrder(int columnIndex) { - HWND hListView, colHeader; + HWND hListView = _fileListView.getHSelf(); LVCOLUMN lvc; - int q, cols; - int index = pnm_list_view->iSubItem; - lvc.mask = LVCF_FMT; - hListView = pnm_list_view->hdr.hwndFrom; - SendMessage(hListView, LVM_GETCOLUMN, index, reinterpret_cast(&lvc)); - if(HDF_SORTUP & lvc.fmt) + + //strip HDF_SORTUP and HDF_SORTDOWN from old sort column + if (_lastSortingColumn != columnIndex && _lastSortingDirection != SORT_DIRECTION_NONE) + { + HWND colHeader = reinterpret_cast(SendMessage(hListView, LVM_GETHEADER, 0, 0)); + int columnCount = static_cast(SendMessage(colHeader, HDM_GETITEMCOUNT, 0, 0)); + if (_lastSortingColumn < columnCount) + { + // Get current fmt + SendMessage(hListView, LVM_GETCOLUMN, _lastSortingColumn, reinterpret_cast(&lvc)); + + // remove both sort-up and sort-down + lvc.fmt = lvc.fmt & (~HDF_SORTUP) & (~HDF_SORTDOWN); + SendMessage(hListView, LVM_SETCOLUMN, _lastSortingColumn, reinterpret_cast(&lvc)); + } + + _lastSortingDirection = SORT_DIRECTION_NONE; + } + + if (_lastSortingDirection == SORT_DIRECTION_NONE) + { + return SORT_DIRECTION_UP; + } + + if (_lastSortingDirection == SORT_DIRECTION_UP) { - //set the opposite arrow - lvc.fmt = lvc.fmt & (~HDF_SORTUP) | HDF_SORTDOWN; //turns off sort-up, turns on sort-down - SendMessage(hListView, LVM_SETCOLUMN, index, reinterpret_cast(&lvc)); - //use any sorting you would use, e.g. the LVM_SORTITEMS message return SORT_DIRECTION_DOWN; } - if(HDF_SORTDOWN & lvc.fmt) - { - //the opposite - lvc.fmt = lvc.fmt & (~HDF_SORTDOWN) | HDF_SORTUP; - SendMessage(hListView, LVM_SETCOLUMN, index, reinterpret_cast(&lvc)); - return SORT_DIRECTION_UP; - } - - // this is the case our clicked column wasn't the one being sorted up until now - // so first we need to iterate through all columns and send LVM_SETCOLUMN to them with fmt set to NOT include these HDFs - colHeader = reinterpret_cast(SendMessage(hListView, LVM_GETHEADER, 0, 0)); - cols = static_cast(SendMessage(colHeader, HDM_GETITEMCOUNT, 0, 0)); - for (q = 0; q < cols; ++q) - { - //Get current fmt - SendMessage(hListView, LVM_GETCOLUMN, q, reinterpret_cast(&lvc)); - //remove both sort-up and sort-down - lvc.fmt = lvc.fmt & (~HDF_SORTUP) & (~HDF_SORTDOWN); - SendMessage(hListView, LVM_SETCOLUMN, q, reinterpret_cast(&lvc)); - } - - //read current fmt from clicked column - SendMessage(hListView, LVM_GETCOLUMN, index, reinterpret_cast(&lvc)); - // then set whichever arrow you feel like and send LVM_SETCOLUMN to this particular column - lvc.fmt = lvc.fmt | HDF_SORTUP; - SendMessage(hListView, LVM_SETCOLUMN, index, reinterpret_cast(&lvc)); - - return SORT_DIRECTION_UP; + //if (_lastSortingDirection == SORT_DIRECTION_DOWN) + return SORT_DIRECTION_NONE; +} + +void VerticalFileSwitcher::updateHeaderArrow() +{ + HWND hListView = _fileListView.getHSelf(); + LVCOLUMN lvc; + lvc.mask = LVCF_FMT; + + SendMessage(hListView, LVM_GETCOLUMN, _lastSortingColumn, reinterpret_cast(&lvc)); + + if (_lastSortingDirection == SORT_DIRECTION_UP) + { + lvc.fmt = lvc.fmt | HDF_SORTUP & ~HDF_SORTDOWN; + SendMessage(hListView, LVM_SETCOLUMN, _lastSortingColumn, reinterpret_cast(&lvc)); + } + else if (_lastSortingDirection == SORT_DIRECTION_DOWN) + { + lvc.fmt = lvc.fmt & ~HDF_SORTUP | HDF_SORTDOWN; + SendMessage(hListView, LVM_SETCOLUMN, _lastSortingColumn, reinterpret_cast(&lvc)); + } + else if (_lastSortingDirection == SORT_DIRECTION_NONE) + { + lvc.fmt = lvc.fmt & (~HDF_SORTUP) & (~HDF_SORTDOWN); + SendMessage(hListView, LVM_SETCOLUMN, _lastSortingColumn, reinterpret_cast(&lvc)); + } } diff --git a/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.h b/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.h index 6d58181f..a24af027 100644 --- a/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.h +++ b/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcher.h @@ -35,6 +35,12 @@ #define FS_PROJECTPANELTITLE TEXT("Doc Switcher") +struct sortCompareData { + HWND hListView; + int columnIndex; + int sortDirection; +}; + class VerticalFileSwitcher : public DockingDlgInterface { public: VerticalFileSwitcher(): DockingDlgInterface(IDD_FILESWITCHER_PANEL) {}; @@ -75,7 +81,8 @@ public: return _fileListView.getFullFilePath(i); }; - int setHeaderOrder(LPNMLISTVIEW pnm_list_view); + int setHeaderOrder(int columnIndex); + void updateHeaderArrow(); int nbSelectedFiles() const { return _fileListView.nbSelectedFiles(); @@ -84,11 +91,18 @@ public: std::vector getSelectedFiles(bool reverse = false) const { return _fileListView.getSelectedFiles(reverse); }; - + + void startColumnSort(); + void reload(){ - _fileListView.deleteColumn(1); - _fileListView.deleteColumn(0); _fileListView.reload(); + startColumnSort(); + }; + + void updateTabOrder(){ + if (_lastSortingDirection == SORT_DIRECTION_NONE) { + _fileListView.reload(); + } }; virtual void setBackgroundColor(COLORREF bgColour) { @@ -98,11 +112,11 @@ public: virtual void setForegroundColor(COLORREF fgColour) { _fileListView.setForegroundColor(fgColour); }; - protected: virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); - private: + int _lastSortingColumn = 0; + int _lastSortingDirection = SORT_DIRECTION_NONE; VerticalFileSwitcherListView _fileListView; HIMAGELIST _hImaLst = nullptr; }; diff --git a/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.cpp b/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.cpp index 9d089f4a..3d728846 100644 --- a/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.cpp +++ b/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.cpp @@ -97,28 +97,53 @@ LRESULT VerticalFileSwitcherListView::runProc(HWND hwnd, UINT Message, WPARAM wP void VerticalFileSwitcherListView::initList() { - TaskListInfo taskListInfo; - static HWND nppHwnd = ::GetParent(_hParent); - ::SendMessage(nppHwnd, WM_GETTASKLISTINFO, reinterpret_cast(&taskListInfo), TRUE); - + HWND colHeader = reinterpret_cast(SendMessage(_hSelf, LVM_GETHEADER, 0, 0)); + int columnCount = static_cast(SendMessage(colHeader, HDM_GETITEMCOUNT, 0, 0)); + NppParameters *nppParams = NppParameters::getInstance(); NativeLangSpeaker *pNativeSpeaker = nppParams->getNativeLangSpeaker(); bool isExtColumn = !nppParams->getNppGUI()._fileSwitcherWithoutExtColumn; - RECT rc; - ::GetClientRect(_hParent, &rc); - int totalWidth = rc.right - rc.left; - - generic_string nameStr = pNativeSpeaker->getAttrNameStr(TEXT("Name"), FS_ROOTNODE, FS_CLMNNAME); - - insertColumn(nameStr.c_str(), (isExtColumn ? totalWidth - 50 : totalWidth), 0); - - if (isExtColumn) + // check if columns need to be added + if (columnCount <= 1) { - generic_string extStr = pNativeSpeaker->getAttrNameStr(TEXT("Ext."), FS_ROOTNODE, FS_CLMNEXT); - insertColumn(extStr.c_str(), 50, 1); + RECT rc; + ::GetClientRect(_hParent, &rc); + int totalWidth = rc.right - rc.left; + + if (columnCount == 0) + { + generic_string nameStr = pNativeSpeaker->getAttrNameStr(TEXT("Name"), FS_ROOTNODE, FS_CLMNNAME); + insertColumn(nameStr.c_str(), (isExtColumn ? totalWidth - 50 : totalWidth), 0); + } + + if (isExtColumn) + { + // resize "Name" column when "exts" won't fit + LVCOLUMN lvc; + SendMessage(_hSelf, LVM_GETCOLUMN, 0, reinterpret_cast(&lvc)); + + if (lvc.cx + 50 > totalWidth) + { + lvc.cx = totalWidth - 50; + SendMessage(_hSelf, LVM_SETCOLUMN, 0, reinterpret_cast(&lvc)); + } + + generic_string extStr = pNativeSpeaker->getAttrNameStr(TEXT("Ext."), FS_ROOTNODE, FS_CLMNEXT); + insertColumn(extStr.c_str(), 50, 1); + } } + + // "exts" was disabled + if (columnCount >= 2 && !isExtColumn) + { + ListView_DeleteColumn(_hSelf, 1); + } + + TaskListInfo taskListInfo; + static HWND nppHwnd = ::GetParent(_hParent); + ::SendMessage(nppHwnd, WM_GETTASKLISTINFO, reinterpret_cast(&taskListInfo), TRUE); for (size_t i = 0, len = taskListInfo._tlfsLst.size(); i < len ; ++i) { diff --git a/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.h b/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.h index 9ee78342..916e51e1 100644 --- a/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.h +++ b/PowerEditor/src/WinControls/VerticalFileSwitcher/VerticalFileSwitcherListView.h @@ -35,6 +35,7 @@ class Buffer; typedef Buffer * BufferID; //each buffer has unique ID by which it can be retrieved +#define SORT_DIRECTION_NONE -1 #define SORT_DIRECTION_UP 0 #define SORT_DIRECTION_DOWN 1