mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
* add interactive sort functionality to program search dialog
svn path=/trunk/; revision=6360
This commit is contained in:
parent
87921d1868
commit
e8822d364b
6 changed files with 165 additions and 10 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue