* add interactive sort functionality to program search dialog

svn path=/trunk/; revision=6360
This commit is contained in:
Martin Fuchs 2003-10-18 20:29:48 +00:00
parent 87921d1868
commit e8822d364b
6 changed files with 165 additions and 10 deletions

View file

@ -95,7 +95,8 @@ FindProgramDlg::FindProgramDlg(HWND hwnd)
: super(hwnd),
_list_ctrl(GetDlgItem(hwnd, IDC_MAILS_FOUND)),
_himl(ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32, 0, 0)),
_thread(collect_programs_callback, hwnd, this)
_thread(collect_programs_callback, hwnd, this),
_sort(_list_ctrl, CompareFunc/*, (LPARAM)this*/)
{
SetWindowIcon(hwnd, IDI_REACTOS/*IDI_SEARCH*/);
@ -156,6 +157,8 @@ void FindProgramDlg::Refresh(bool delete_cache)
#endif
_lwr_filter = buffer;
HiddenWindow hide_listctrl(_list_ctrl);
ListView_DeleteAllItems(_list_ctrl);
if (delete_cache || !_thread._cache_valid) {
@ -243,8 +246,7 @@ void FindProgramDlg::add_entry(const FPDEntry& cache_entry)
item.pszText = cache_entry._shell_entry->_display_name;
item.iImage = cache_entry._idxIcon;
item.lParam = (LPARAM) &cache_entry;
item.iItem = ListView_InsertItem(_list_ctrl, &item);
item.iItem = ListView_InsertItem(_list_ctrl, &item); // We could use the information in _sort to enable manual sorting while populating the list.
item.mask = LVIF_TEXT;
item.iSubItem = 1;
@ -274,6 +276,10 @@ int FindProgramDlg::Command(int id, int code)
Refresh(true);
break;
case IDOK:
LaunchSelected();
break;
default:
return super::Command(id, code);
}
@ -286,6 +292,23 @@ int FindProgramDlg::Command(int id, int code)
return TRUE;
}
void FindProgramDlg::LaunchSelected()
{
Lock lock(_thread._crit_sect);
int count = ListView_GetSelectedCount(_list_ctrl);
//TODO: ask user if there are many selected items
for(int idx=-1; (idx=ListView_GetNextItem(_list_ctrl, idx, LVNI_SELECTED))!=-1; ) {
LPARAM lparam = ListView_GetItemData(_list_ctrl, idx);
if (lparam) {
FPDEntry& cache_entry = *(FPDEntry*)lparam;
cache_entry._shell_entry->launch_entry(_hwnd);
}
}
}
int FindProgramDlg::Notify(int id, NMHDR* pnmh)
{
switch(pnmh->code) {
@ -307,16 +330,59 @@ int FindProgramDlg::Notify(int id, NMHDR* pnmh)
}*/}
break;
case NM_DBLCLK: {
LPNMLISTVIEW pnmv = (LPNMLISTVIEW) pnmh;
LPARAM lparam = ListView_GetItemData(pnmh->hwndFrom, pnmv->iItem);
case NM_DBLCLK:
if (pnmh->hwndFrom == _list_ctrl)
LaunchSelected();
/*{
Lock lock(_thread._crit_sect);
if (lparam) {
FPDEntry& cache_entry = *(FPDEntry*)lparam;
cache_entry._shell_entry->launch_entry(_hwnd);
LPNMLISTVIEW pnmv = (LPNMLISTVIEW) pnmh;
LPARAM lparam = ListView_GetItemData(pnmh->hwndFrom, pnmv->iItem);
if (lparam) {
FPDEntry& cache_entry = *(FPDEntry*)lparam;
cache_entry._shell_entry->launch_entry(_hwnd);
}
}*/
break;
case HDN_ITEMCLICK: {
WaitCursor wait;
NMHEADER* phdr = (NMHEADER*)pnmh;
if (GetParent(pnmh->hwndFrom) == _list_ctrl) {
if (_thread._cache_valid) { // disable manual sorting while populating the list
_sort.toggle_sort(phdr->iItem);
_sort.sort();
}
}
break;}
}
return 0;
}
int CALLBACK FindProgramDlg::CompareFunc(LPARAM lparam1, LPARAM lparam2, LPARAM lparamSort)
{
ListSort* sort = (ListSort*)lparamSort;
FPDEntry& a = *(FPDEntry*)lparam1;
FPDEntry& b = *(FPDEntry*)lparam2;
int cmp = 0;
switch(sort->_sort_crit) {
case 0:
cmp = _tcsicoll(a._shell_entry->_display_name, b._shell_entry->_display_name);
break;
case 1:
cmp = _tcsicoll(a._path, b._path);
break;
case 2:
cmp = _tcsicoll(a._menu_path, b._menu_path);
}
return sort->_direction? -cmp: cmp;
}

View file

@ -94,12 +94,16 @@ protected:
String _common_programs, _user_programs;
ListSort _sort;
virtual LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam);
virtual int Command(int id, int code);
virtual int Notify(int id, NMHDR* pnmh);
void Refresh(bool delete_cache=false);
void add_entry(const FPDEntry& cache_entry);
void LaunchSelected();
static void collect_programs_callback(ShellFolder& folder, ShellEntry* entry, void* param);
static int CALLBACK CompareFunc(LPARAM lparam1, LPARAM lparam2, LPARAM lparamSort);
};

View file

@ -569,7 +569,7 @@ EXSTYLE WS_EX_APPWINDOW
CAPTION "Search Program in Startmenu"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Filter:",IDC_STATIC,7,9,18,8
LTEXT "&Filter:",IDC_STATIC,7,9,18,8
EDITTEXT IDC_TOPIC,34,7,103,14,ES_AUTOHSCROLL
CONTROL "List1",IDC_MAILS_FOUND,"SysListView32",LVS_REPORT |
LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER |

View file

@ -128,6 +128,21 @@ protected:
};
struct HiddenWindow : public WindowHandle
{
HiddenWindow(HWND hwnd)
: WindowHandle(hwnd)
{
SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW|SWP_NOREDRAW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
}
~HiddenWindow()
{
SetWindowPos(_hwnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
}
};
/// critical section wrapper
struct CritSect : public CRITICAL_SECTION

View file

@ -897,3 +897,35 @@ ToolTip::ToolTip(HWND owner)
{
activate();
}
ListSort::ListSort(HWND hwndListview, PFNLVCOMPARE compare_fct)
: WindowHandle(hwndListview),
_compare_fct(compare_fct)
{
_sort_crit = 0;
_direction = false;
}
void ListSort::toggle_sort(int idx)
{
if (_sort_crit == idx)
_direction = !_direction;
else {
_sort_crit = idx;
_direction = false;
}
}
void ListSort::sort()
{
int idx = ListView_GetSelectionMark(_hwnd);
LPARAM param = ListView_GetItemData(_hwnd, idx);
ListView_SortItems(_hwnd, _compare_fct, (LPARAM)this);
if (idx >= 0) {
idx = ListView_FindItemPara(_hwnd, param);
ListView_EnsureVisible(_hwnd, idx, FALSE);
}
}

View file

@ -641,3 +641,41 @@ inline int ListView_GetItemData(HWND list_ctrl, int idx)
return item.lParam;
}
inline int ListView_FindItemPara(HWND list_ctrl, LPARAM param)
{
LVFINDINFO fi;
fi.flags = LVFI_PARAM;
fi.lParam = param;
return ListView_FindItem(list_ctrl, -1, &fi);
}
inline int ListView_GetFocusedItem(HWND list_ctrl)
{
int idx = ListView_GetItemCount(list_ctrl);
while(--idx >= 0)
if (ListView_GetItemState(list_ctrl, idx, LVIS_FOCUSED))
break;
return idx;
}
struct ListSort : public WindowHandle
{
ListSort(HWND hwndListview, PFNLVCOMPARE compare_fct);
void toggle_sort(int idx);
void sort();
int _sort_crit;
bool _direction;
protected:
PFNLVCOMPARE _compare_fct;
static int CALLBACK CompareFunc(LPARAM lparam1, LPARAM lparam2, LPARAM lparamSort);
};