* add interactive sort functionality to program search dialog
authorMartin Fuchs <fuchs.martin@gmail.com>
Sat, 18 Oct 2003 20:29:48 +0000 (20:29 +0000)
committerMartin Fuchs <fuchs.martin@gmail.com>
Sat, 18 Oct 2003 20:29:48 +0000 (20:29 +0000)
svn path=/trunk/; revision=6360

reactos/subsys/system/explorer/dialogs/searchprogram.cpp
reactos/subsys/system/explorer/dialogs/searchprogram.h
reactos/subsys/system/explorer/explorer_intres.rc
reactos/subsys/system/explorer/utility/utility.h
reactos/subsys/system/explorer/utility/window.cpp
reactos/subsys/system/explorer/utility/window.h

index ff43aec..ae089ea 100644 (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;
+}
index b1ca216..33c15ef 100644 (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);
 };
index eae407b..f40df13 100644 (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 | 
index be22968..a3e8afe 100644 (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
index 659309d..4c2ff12 100644 (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);
+       }
+}
index 89d82a3..e53d00b 100644 (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);
+};