[NEW_FEATURE] Doc Switcher can be sorted now.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@797 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2011-08-20 22:13:22 +00:00
parent 1ce665e1e5
commit df3e1d4ef8
4 changed files with 243 additions and 64 deletions

View File

@ -19,6 +19,31 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "precompiledHeaders.h"
#include "VerticalFileSwitcher.h"
#include "menuCmdID.h"
int CALLBACK ListViewCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
int result;
LVCOLUMN lvc;
BOOL is_direction_up;
LPNMLISTVIEW pnm_list_view = (LPNMLISTVIEW)lParamSort;
TCHAR str1[2048];
TCHAR str2[2048];
ListView_GetItemText(pnm_list_view->hdr.hwndFrom, lParam1, pnm_list_view->iSubItem, str1, sizeof(str1));
ListView_GetItemText(pnm_list_view->hdr.hwndFrom, lParam2, pnm_list_view->iSubItem, str2, sizeof(str2));
lvc.mask = LVCF_FMT;
SendMessage(pnm_list_view->hdr.hwndFrom, LVM_GETCOLUMN, (WPARAM)pnm_list_view->iSubItem, (LPARAM)&lvc);
is_direction_up = (HDF_SORTUP & lvc.fmt);
result = lstrcmp(str1, str2);
if(is_direction_up)
result = 0 - result;
return(result);
};
BOOL CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
@ -27,6 +52,8 @@ BOOL CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, LPA
case WM_INITDIALOG :
{
_fileListView.init(_hInst, _hSelf, _hImaLst);
_fileListView.insertColumn(TEXT("Name"), 150, 0);
_fileListView.insertColumn(TEXT("Ext."), 50, 1);
_fileListView.initList();
_fileListView.display();
@ -37,6 +64,19 @@ BOOL CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, LPA
{
switch (((LPNMHDR)lParam)->code)
{
case NM_DBLCLK:
{
LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE) lParam;
int i = lpnmitem->iItem;
if (i == -1)
{
//::MessageBoxA(NULL, "oh yeh","",MB_OK);
::SendMessage(_hParent, WM_COMMAND, IDM_FILE_NEW, 0);
}
return TRUE;
}
case NM_CLICK:
{
LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE) lParam;
@ -45,7 +85,13 @@ BOOL CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, LPA
if (i == -1)
return TRUE;
activateDoc(i);
LVITEM item;
item.mask = LVIF_PARAM;
item.iItem = i;
ListView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam;
activateDoc(tlfs);
return TRUE;
}
@ -57,7 +103,13 @@ BOOL CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, LPA
if (i == -1)
return TRUE;
activateDoc(i);
LVITEM item;
item.mask = LVIF_PARAM;
item.iItem = i;
ListView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam;
activateDoc(tlfs);
// Redirect NM_RCLICK message to Notepad_plus handle
NMHDR nmhdr;
@ -74,11 +126,18 @@ BOOL CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, LPA
int i = pGetInfoTip->iItem;
if (i == -1)
return TRUE;
generic_string fn = this->getFullFilePath((size_t)i);
generic_string fn = getFullFilePath((size_t)i);
lstrcpyn(pGetInfoTip->pszText, fn.c_str(), pGetInfoTip->cchTextMax);
return TRUE;
}
case LVN_COLUMNCLICK:
{
LPNMLISTVIEW pnmLV = (LPNMLISTVIEW)lParam;
setHeaderOrder(pnmLV);
ListView_SortItemsEx(pnmLV->hdr.hwndFrom, ListViewCompareProc,(LPARAM)pnmLV);
return TRUE;
}
case LVN_KEYDOWN:
{
switch (((LPNMLVKEYDOWN)lParam)->wVKey)
@ -90,7 +149,12 @@ BOOL CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, LPA
if (i == -1)
return TRUE;
activateDoc(i);
LVITEM item;
item.mask = LVIF_PARAM;
item.iItem = i;
ListView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam;
activateDoc(tlfs);
return TRUE;
}
default:
@ -112,6 +176,12 @@ BOOL CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, LPA
::MoveWindow(_fileListView.getHSelf(), 0, 0, width, height, TRUE);
break;
}
case WM_DESTROY:
{
_fileListView.destroy();
break;
}
default :
return DockingDlgInterface::run_dlgProc(message, wParam, lParam);
@ -120,10 +190,11 @@ BOOL CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, LPA
}
void VerticalFileSwitcher::activateDoc(int i) const
void VerticalFileSwitcher::activateDoc(TaskLstFnStatus *tlfs) const
{
int view = MAIN_VIEW;
int bufferID = _fileListView.getBufferInfoFromIndex(i, view);
int view = tlfs->_iView;
//int bufferID = _fileListView.getBufferInfoFromIndex(i, view);
int bufferID = (int)tlfs->_bufID;
int docPosInfo = ::SendMessage(_hParent, NPPM_GETPOSFROMBUFFERID, bufferID, view);
int view2set = docPosInfo >> 30;
int index2Switch = (docPosInfo << 2) >> 2 ;
@ -131,3 +202,51 @@ void VerticalFileSwitcher::activateDoc(int i) const
::SendMessage(_hParent, NPPM_ACTIVATEDOC, view2set, index2Switch);
}
int VerticalFileSwitcher::setHeaderOrder(LPNMLISTVIEW pnm_list_view)
{
HWND hListView,colHeader;
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, (WPARAM)index, (LPARAM)&lvc);
if(HDF_SORTUP & lvc.fmt)
{
//set the opposite arrow
lvc.fmt = lvc.fmt & (~HDF_SORTUP) | HDF_SORTDOWN; //turns off sort-up, turns on sort-down
SendMessage(hListView, LVM_SETCOLUMN, (WPARAM) index, (LPARAM) &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, (WPARAM) index, (LPARAM) &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 = (HWND)SendMessage(hListView,LVM_GETHEADER,0,0);
cols = SendMessage(colHeader,HDM_GETITEMCOUNT,0,0);
for(q=0; q<cols; q++)
{
//Get current fmt
SendMessage(hListView,LVM_GETCOLUMN,(WPARAM) q, (LPARAM) &lvc);
//remove both sort-up and sort-down
lvc.fmt = lvc.fmt & (~HDF_SORTUP) & (~HDF_SORTDOWN);
SendMessage(hListView,LVM_SETCOLUMN,(WPARAM) q, (LPARAM) &lvc);
}
//read current fmt from clicked column
SendMessage(hListView,LVM_GETCOLUMN,(WPARAM) index, (LPARAM) &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, (WPARAM) index, (LPARAM) &lvc);
return SORT_DIRECTION_UP;
}

View File

@ -46,7 +46,7 @@ public:
};
//Activate document in scintilla by using the internal index
void activateDoc(int i) const;
void activateDoc(TaskLstFnStatus *tlfs) const;
int newItem(int bufferID, int iView){
return _fileListView.newItem(bufferID, iView);
@ -68,6 +68,8 @@ public:
return _fileListView.getFullFilePath(i);
};
int setHeaderOrder(LPNMLISTVIEW pnm_list_view);
protected:
virtual BOOL CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);

View File

@ -31,8 +31,7 @@ void VerticalFileSwitcherListView::init(HINSTANCE hInst, HWND parent, HIMAGELIST
InitCommonControlsEx(&icex);
// Create the list-view window in report view with label editing enabled.
int listViewStyles = LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER\
| LVS_SINGLESEL | LVS_AUTOARRANGE\
int listViewStyles = LVS_REPORT | LVS_SINGLESEL | LVS_AUTOARRANGE\
| LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS;
_hSelf = ::CreateWindow(WC_LISTVIEW,
@ -53,29 +52,25 @@ void VerticalFileSwitcherListView::init(HINSTANCE hInst, HWND parent, HIMAGELIST
::SetWindowLongPtr(_hSelf, GWLP_USERDATA, (LONG_PTR)this);
_defaultProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(_hSelf, GWLP_WNDPROC, (LONG_PTR)staticProc));
/*
DWORD exStyle = ListView_GetExtendedListViewStyle(_hSelf);
exStyle |= LVS_EX_FULLROWSELECT | LVS_EX_BORDERSELECT ;
ListView_SetExtendedListViewStyle(_hSelf, exStyle);
*/
ListView_SetExtendedListViewStyle(_hSelf, LVS_EX_FULLROWSELECT | LVS_EX_BORDERSELECT | LVS_EX_INFOTIP);
LVCOLUMN lvColumn;
lvColumn.mask = LVCF_WIDTH;
lvColumn.cx = 200;
ListView_InsertColumn(_hSelf, 0, &lvColumn);
ListView_SetItemCountEx(_hSelf, 50, LVSICF_NOSCROLL);
ListView_SetImageList(_hSelf, _hImaLst, LVSIL_SMALL);
ListView_SetItemState(_hSelf, 0, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
//ListView_SetBkColor(_hSelf, lightYellow);
}
void VerticalFileSwitcherListView::destroy()
{
LVITEM item;
item.mask = LVIF_PARAM;
int nbItem = ListView_GetItemCount(_hSelf);
for (int i = 0 ; i < nbItem ; i++)
{
item.iItem = i;
ListView_GetItem(_hSelf, &item);
TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam;
delete tlfs;
}
::DestroyWindow(_hSelf);
_hSelf = NULL;
}
@ -87,27 +82,44 @@ LRESULT VerticalFileSwitcherListView::runProc(HWND hwnd, UINT Message, WPARAM wP
void VerticalFileSwitcherListView::initList()
{
::SendMessage(::GetParent(_hParent), WM_GETTASKLISTINFO, (WPARAM)&_taskListInfo, TRUE);
for (size_t i = 0 ; i < _taskListInfo._tlfsLst.size() ; i++)
TaskListInfo taskListInfo;
::SendMessage(::GetParent(_hParent), WM_GETTASKLISTINFO, (WPARAM)&taskListInfo, TRUE);
for (size_t i = 0 ; i < taskListInfo._tlfsLst.size() ; i++)
{
TaskLstFnStatus & fileNameStatus = _taskListInfo._tlfsLst[i];
TaskLstFnStatus & fileNameStatus = taskListInfo._tlfsLst[i];
TaskLstFnStatus *tl = new TaskLstFnStatus(fileNameStatus._iView, fileNameStatus._docIndex, fileNameStatus._fn, fileNameStatus._status, (void *)fileNameStatus._bufID);
TCHAR fn[MAX_PATH];
lstrcpy(fn, ::PathFindFileName(fileNameStatus._fn.c_str()));
::PathRemoveExtension(fn);
LVITEM item;
item.mask = LVIF_TEXT | LVIF_IMAGE;
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
item.pszText = (TCHAR *)::PathFindFileName(fileNameStatus._fn.c_str());
item.pszText = fn;
item.iItem = i;
item.iSubItem = 0;
item.iImage = fileNameStatus._status;
item.lParam = (LPARAM)tl;
ListView_InsertItem(_hSelf, &item);
ListView_SetItemText(_hSelf, i, 1, (LPTSTR)::PathFindExtension(fileNameStatus._fn.c_str()));
}
}
int VerticalFileSwitcherListView::getBufferInfoFromIndex(int index, int & view) const {
if (index < 0 || index >= int(_taskListInfo._tlfsLst.size()))
int nbItem = ListView_GetItemCount(_hSelf);
if (index < 0 || index >= nbItem)
return -1;
view = _taskListInfo._tlfsLst[index]._iView;
return int(_taskListInfo._tlfsLst[index]._bufID);
LVITEM item;
item.mask = LVIF_PARAM;
item.iItem = index;
ListView_GetItem(_hSelf, &item);
TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam;
view = tlfs->_iView;
return int(tlfs->_bufID);
}
int VerticalFileSwitcherListView::newItem(int bufferID, int iView)
@ -122,29 +134,48 @@ int VerticalFileSwitcherListView::newItem(int bufferID, int iView)
void VerticalFileSwitcherListView::setItemIconStatus(int bufferID)
{
Buffer *buf = (Buffer *)bufferID;
LVITEM item;
Buffer *buf = (Buffer *)bufferID;
TCHAR fn[MAX_PATH];
lstrcpy(fn, ::PathFindFileName(buf->getFileName()));
::PathRemoveExtension(fn);
item.mask = LVIF_TEXT | LVIF_IMAGE;
item.pszText = (TCHAR *)::PathFindFileName(buf->getFileName());
LVITEM item;
item.pszText = fn;
item.iSubItem = 0;
item.iImage = buf->getUserReadOnly()||buf->getFileReadOnly()?2:(buf->isDirty()?1:0);
int i = find(bufferID, MAIN_VIEW);
if (i != -1)
{
item.iItem = i;
ListView_SetItem(_hSelf, &item);
}
int nbItem = ListView_GetItemCount(_hSelf);
int j = find(bufferID, SUB_VIEW);
if (j != -1 && j != i)
for (int i = 0 ; i < nbItem ; i++)
{
item.iItem = j;
ListView_SetItem(_hSelf, &item);
item.mask = LVIF_PARAM;
item.iItem = i;
ListView_GetItem(_hSelf, &item);
TaskLstFnStatus *tlfs = (TaskLstFnStatus *)(item.lParam);
if (int(tlfs->_bufID) == bufferID)
{
item.mask = LVIF_TEXT | LVIF_IMAGE;
ListView_SetItem(_hSelf, &item);
ListView_SetItemText(_hSelf, i, 1, (LPTSTR)::PathFindExtension(buf->getFileName()));
}
}
}
generic_string VerticalFileSwitcherListView::getFullFilePath(size_t i) const
{
size_t nbItem = ListView_GetItemCount(_hSelf);
if (i < 0 || i > nbItem)
return TEXT("");
LVITEM item;
item.mask = LVIF_PARAM;
item.iItem = i;
ListView_GetItem(_hSelf, &item);
TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam;
return tlfs->_fn;
}
int VerticalFileSwitcherListView::closeItem(int bufferID, int iView)
{
@ -166,20 +197,27 @@ void VerticalFileSwitcherListView::activateItem(int bufferID, int iView)
int VerticalFileSwitcherListView::add(int bufferID, int iView)
{
int index = int(_taskListInfo._tlfsLst.size());
int index = ListView_GetItemCount(_hSelf);
Buffer *buf = (Buffer *)bufferID;
const TCHAR *fn = buf->getFileName();
const TCHAR *fileName = buf->getFileName();
_taskListInfo._tlfsLst.push_back(TaskLstFnStatus(iView, 0, fn, 0, (void *)bufferID));
TaskLstFnStatus *tl = new TaskLstFnStatus(iView, 0, fileName, 0, (void *)bufferID);
TCHAR fn[MAX_PATH];
lstrcpy(fn, ::PathFindFileName(fileName));
::PathRemoveExtension(fn);
LVITEM item;
item.mask = LVIF_TEXT | LVIF_IMAGE;
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
item.pszText = (TCHAR *)::PathFindFileName(fn);
item.pszText = fn;
item.iItem = index;
item.iSubItem = 0;
item.iImage = buf->getUserReadOnly()||buf->getFileReadOnly()?2:(buf->isDirty()?1:0);
item.lParam = (LPARAM)tl;
ListView_InsertItem(_hSelf, &item);
ListView_SetItemText(_hSelf, index, 1, ::PathFindExtension(fileName));
ListView_SetItemState(_hSelf, index, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
return index;
@ -187,23 +225,42 @@ int VerticalFileSwitcherListView::add(int bufferID, int iView)
void VerticalFileSwitcherListView::remove(int index)
{
_taskListInfo._tlfsLst.erase(_taskListInfo._tlfsLst.begin() + index);
LVITEM item;
item.mask = LVIF_PARAM;
item.iItem = index;
ListView_GetItem(_hSelf, &item);
TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam;
delete tlfs;
ListView_DeleteItem(_hSelf, index);
}
int VerticalFileSwitcherListView::find(int bufferID, int iView) const
{
LVITEM item;
bool found = false;
size_t i = 0;
for (; i < _taskListInfo._tlfsLst.size() ; i++)
int nbItem = ListView_GetItemCount(_hSelf);
int i = 0;
for (; i < nbItem ; i++)
{
if (_taskListInfo._tlfsLst[i]._bufID == (void *)bufferID &&
_taskListInfo._tlfsLst[i]._iView == iView)
item.mask = LVIF_PARAM;
item.iItem = i;
ListView_GetItem(_hSelf, &item);
TaskLstFnStatus *tlfs = (TaskLstFnStatus *)item.lParam;
if (int(tlfs->_bufID) == bufferID && tlfs->_iView == iView)
{
found = true;
found = true;
break;
}
}
return (found?i:-1);
}
void VerticalFileSwitcherListView::insertColumn(TCHAR *name, int width, int index)
{
LVCOLUMN lvColumn;
lvColumn.mask = LVCF_TEXT | LVCF_WIDTH;
lvColumn.cx = width;
lvColumn.pszText = name;
ListView_InsertColumn(_hSelf, index, &lvColumn);
}

View File

@ -21,6 +21,9 @@
#include "window.h"
#include "TaskListDlg.h"
#define SORT_DIRECTION_UP 0
#define SORT_DIRECTION_DOWN 1
class VerticalFileSwitcherListView : public Window
{
public:
@ -38,14 +41,12 @@ public:
int closeItem(int bufferID, int iView);
void activateItem(int bufferID, int iView);
void setItemIconStatus(int bufferID);
generic_string getFullFilePath(size_t i) const {
if (i < 0 || i > _taskListInfo._tlfsLst.size())
return TEXT("");
return _taskListInfo._tlfsLst[i]._fn;
};
generic_string getFullFilePath(size_t i) const;
void insertColumn(TCHAR *name, int width, int index);
protected:
TaskListInfo _taskListInfo;
HIMAGELIST _hImaLst;
WNDPROC _defaultProc;
LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);