source: trunk/src/HaliteSortListViewCtrl.hpp @ 654

Revision 654, 18.1 KB checked in by Eoin, 11 years ago (diff)

Sorting on the main listview now working with groups.

Line 
1
2//         Copyright Eóin O'Callaghan 2006 - 2008.
3// Distributed under the Boost Software License, Version 1.0.
4//    (See accompanying file LICENSE_1_0.txt or copy at
5//          http://www.boost.org/LICENSE_1_0.txt)
6
7#pragma once
8
9#include "stdAfx.hpp"
10
11#include <functional>
12
13#include <boost/array.hpp>
14#include <boost/signals.hpp>
15#include <boost/algorithm/string/split.hpp>
16#include <boost/ptr_container/ptr_map.hpp>
17
18#include <winstl/controls/listview_sequence.hpp>
19
20#include "Halite.hpp"
21#include "halTorrent.hpp"
22#include "halEvent.hpp"
23#include "WinAPIWaitableTimer.hpp"
24
25#include "UxthemeWrapper.hpp"
26
27#define LVS_EX_DOUBLEBUFFER     0x00010000
28
29#include "WTLx/SelectionManager.hpp"
30#include "WTLx/ListViewIterators.hpp"
31#include "HaliteUpdateLock.hpp"
32
33namespace hal
34{
35
36template<typename T>
37int compare(const T& l, const T& r)
38{
39        if (l == r) 
40                return 0;
41        else if (l > r) 
42                return 1;
43        else 
44                return -1;
45}
46
47}
48
49template <class TBase, typename AdapterType=void*>
50class CHaliteSortListViewCtrl : 
51        public ATL::CWindowImpl<TBase, WTL::CListViewCtrl>,
52        public WTLx::ListViewIterators<CHaliteSortListViewCtrl<TBase, AdapterType> >
53{
54public:
55        typedef CHaliteSortListViewCtrl<TBase, AdapterType> thisClass;
56        typedef ATL::CWindowImpl<TBase, WTL::CListViewCtrl> parentClass;
57       
58        class CHaliteHeaderCtrl : public CWindowImpl<CHaliteHeaderCtrl, WTL::CHeaderCtrl>
59        {
60        public:
61                enum { COL_MENU_NAMES = 123, COL_MAX_NAMES = 256 };
62
63                CHaliteHeaderCtrl(thisClass& listView) :
64                        listView_(listView)
65                {}
66
67                BEGIN_MSG_MAP(CHaliteHeaderCtrl)
68                        REFLECTED_NOTIFY_CODE_HANDLER(NM_RCLICK, OnRClick)
69                        COMMAND_RANGE_HANDLER(COL_MENU_NAMES, COL_MENU_NAMES+COL_MAX_NAMES, OnMenuNames)
70
71                        DEFAULT_REFLECTION_HANDLER()
72                END_MSG_MAP()
73               
74                void Attach(HWND hWndNew)
75                {
76                        ATLASSERT(::IsWindow(hWndNew));
77                        CWindowImpl<CHaliteHeaderCtrl, WTL::CHeaderCtrl>::SubclassWindow(hWndNew);
78                }
79               
80                LRESULT OnRClick(int i, LPNMHDR pnmh, BOOL&)
81                {
82                        POINT ptPoint;
83                        GetCursorPos(&ptPoint);
84                        menu_.TrackPopupMenu(0, ptPoint.x, ptPoint.y, m_hWnd);
85
86                        return 0;
87                }
88
89                LRESULT OnMenuNames(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
90                {               
91                        ATLASSERT(wID-COL_MENU_NAMES <= GetItemCount());
92
93                        bool visible = listView_.OnNameChecked(wID-COL_MENU_NAMES);
94
95                /*      MENUITEMINFO minfo = {sizeof(MENUITEMINFO)};
96               
97                        minfo.fMask = MIIM_STATE;
98                        minfo.fState = visible ? MFS_CHECKED : MFS_UNCHECKED;
99               
100                        menu_.SetMenuItemInfo(wID, false, &minfo);
101                */
102                        return 0;
103                }
104
105                WTL::CMenu& Menu()
106                {
107                        return menu_;
108                }
109               
110        private:
111                WTL::CMenu menu_;
112                thisClass& listView_;
113        };
114       
115        struct ColumnAdapter
116        {
117                virtual int compare(AdapterType& l, AdapterType& r) = 0;
118                virtual std::wstring print(AdapterType& t) = 0;
119        };
120
121public:
122        typedef WTLx::selection_manager<thisClass, std::wstring> SelectionManager;
123        typedef SelectionManager selection_manage_class;
124       
125        thisClass() :
126                manager_(*this),
127                header_(*this),
128                update_lock_(0),
129                autoSort_(false),
130                descending_(false),
131                sortCol_(-1)
132        {               
133                if (TBase::LISTVIEW_ID_MENU)
134                {
135                        WTL::CMenuHandle menu;
136                        BOOL menu_created = menu.LoadMenu(TBase::LISTVIEW_ID_MENU);
137                        assert(menu_created);   
138                       
139                        menu_.Attach(menu.GetSubMenu(0));
140                }
141        }
142
143        BEGIN_MSG_MAP_EX(thisClass)
144                COMMAND_ID_HANDLER(ID_LVM_AUTOSORT, OnAutoSort)
145               
146                REFLECTED_NOTIFY_CODE_HANDLER(NM_RCLICK, OnRClick)
147                REFLECTED_NOTIFY_CODE_HANDLER(LVN_ITEMCHANGED, OnItemChanged)
148
149                DEFAULT_REFLECTION_HANDLER()
150//              CHAIN_MSG_MAP(parentClass)
151        END_MSG_MAP()
152
153        void Attach(HWND hWndNew)
154        {
155                ATLASSERT(::IsWindow(hWndNew));
156        parentClass::SubclassWindow(hWndNew);
157
158                TBase* pT = static_cast<TBase*>(this);
159                pT->OnAttach();
160        }
161       
162        HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
163                        DWORD dwStyle = 0, DWORD dwExStyle = 0,
164                        ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
165        {
166                HWND hwnd = parentClass::Create(hWndParent, 
167                        (RECT &)rect.m_lpRect, szWindowName, dwStyle, dwExStyle, (UINT)MenuOrID.m_hMenu, lpCreateParam);
168                       
169                SetExtendedListViewStyle(WS_EX_CLIENTEDGE|LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_DOUBLEBUFFER|LVS_EX_SUBITEMIMAGES);
170//              SetSortListViewExtendedStyle(SORTLV_USESHELLBITMAPS, SORTLV_USESHELLBITMAPS);
171               
172                return hwnd;
173        }
174       
175        bool SubclassWindow(HWND hwnd)
176        {
177                if(!parentClass::SubclassWindow(hwnd))
178                        return false;
179                       
180                SetExtendedListViewStyle(WS_EX_CLIENTEDGE|LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_DOUBLEBUFFER);
181//              SetSortListViewExtendedStyle(SORTLV_USESHELLBITMAPS, SORTLV_USESHELLBITMAPS);
182               
183                return true;
184        }               
185       
186/*      template<typename N, typename W, typename O, typename P>
187        void SetDefaults(N nameList, W widthList, O orderList, P visibleList, bool autoSort=false)
188        {
189                listNames_.assign(nameList.begin(), nameList.end());
190                listWidths_.assign(widthList.begin(), widthList.end());
191                listOrder_.assign(orderList.begin(), orderList.end());
192                listVisible_.assign(visibleList.begin(), visibleList.end());
193               
194                autoSort_ = autoSort;
195        }
196*/
197        void SafeLoadFromIni()
198        {
199                std::vector<wstring> listNames;
200                std::vector<int> listWidths;
201                std::vector<int> listOrder;
202                std::vector<bool> listVisible;
203
204                listNames.assign(listNames_.begin(), listNames_.end());
205                listWidths.assign(listWidths_.begin(), listWidths_.end());
206                listOrder.assign(listOrder_.begin(), listOrder_.end());
207                listVisible.assign(listVisible_.begin(), listVisible_.end());
208
209                TBase* pT = static_cast<TBase*>(this);
210                if (!pT->load_from_ini() || !vectorSizePreConditions())
211                {
212                        listNames_.assign(listNames.begin(), listNames.end());
213                        listWidths_.assign(listWidths.begin(), listWidths.end());
214                        listOrder_.assign(listOrder.begin(), listOrder.end());
215                        listVisible_.assign(listVisible.begin(), listVisible.end());
216                }               
217        }
218/*     
219        void ApplyDetails()
220        {
221                vectorSizePreConditions();
222               
223                MENUITEMINFO minfo = {sizeof(MENUITEMINFO)};
224               
225                if (!menu_)
226                {
227                        menu_.CreatePopupMenu();
228                }
229                else
230                {                               
231                        minfo.fMask = MIIM_SUBMENU;
232                        minfo.fType = MFT_SEPARATOR;
233                       
234                        menu_.InsertMenuItem(menu_.GetMenuItemCount(), true, &minfo);           
235                }
236
237                minfo.fMask = MIIM_STRING|MIIM_ID|MIIM_FTYPE|MIIM_STATE;
238                minfo.fType = MFT_STRING;
239                minfo.fState = autoSort_ ? MFS_CHECKED : MFS_UNCHECKED;
240                minfo.wID = ID_LVM_AUTOSORT;
241               
242                wstring autoarrange = hal::app().res_wstr(HAL_AUTOSORT);
243                minfo.dwTypeData = (LPWSTR)autoarrange.c_str();
244               
245                menu_.InsertMenuItem(menu_.GetMenuItemCount(), true, &minfo);
246               
247                header_.Attach(this->GetHeader());
248                header_.ModifyStyle(0, HDS_DRAGDROP|HDS_FULLDRAG);
249
250                header_.Menu().CreatePopupMenu();
251
252                for (int i=header_.GetItemCount(), e=int(listNames_.size()); i<e; ++i)
253                {
254                        MENUITEMINFO minfo = {sizeof(MENUITEMINFO)};
255                        minfo.fMask = MIIM_STRING|MIIM_ID|MIIM_FTYPE|MIIM_STATE;
256                        minfo.fType = MFT_STRING;
257                        minfo.dwTypeData = (LPWSTR)listNames_[i].c_str();
258                        minfo.wID = CHaliteHeaderCtrl::COL_MENU_NAMES+i;
259
260                        AddColumn(listNames_[i].c_str(), i);
261
262                        if (listVisible_[i])
263                        {
264                                minfo.fState = MFS_CHECKED;                     
265                                SetColumnWidth(i, listWidths_[i]);
266                        }
267                        else
268                        {
269                                minfo.fState = MFS_UNCHECKED;
270                                SetColumnWidth(i, 0);
271                        }
272
273                        header_.Menu().InsertMenuItem(header_.Menu().GetMenuItemCount(), false, &minfo);
274                }
275               
276                SetColumnOrderArray(listNames_.size(), &listOrder_[0]);
277               
278                m_bSortDescending = descending_;
279                if (sortCol_ >= 0 && sortCol_ < m_arrColSortType.GetSize())
280                        SetSortColumn(sortCol_);
281        }
282*/
283        void InitialSetup(WTL::CMenuHandle menu=WTL::CMenuHandle())
284        {
285                SetExtendedListViewStyle(LVS_EX_HEADERDRAGDROP|LVS_EX_DOUBLEBUFFER);
286//              SetSortListViewExtendedStyle(SORTLV_USESHELLBITMAPS,SORTLV_USESHELLBITMAPS);
287
288                MENUITEMINFO minfo = {sizeof(MENUITEMINFO)};
289               
290                if (!menu)
291                {
292                        menu_.CreatePopupMenu();
293                }
294                else
295                {               
296                        menu_.Attach(menu.GetSubMenu(0));
297
298                        minfo.fMask = MIIM_SUBMENU;
299                        minfo.fType = MFT_SEPARATOR;
300                       
301                        menu_.InsertMenuItem(menu_.GetMenuItemCount(), true, &minfo);           
302                }
303
304                minfo.fMask = MIIM_STRING|MIIM_ID|MIIM_FTYPE|MIIM_STATE;
305                minfo.fType = MFT_STRING;
306                minfo.fState = autoSort_ ? MFS_CHECKED : MFS_UNCHECKED;
307                minfo.wID = ID_LVM_AUTOSORT;
308               
309                std::wstring autoarrange = hal::app().res_wstr(HAL_AUTOSORT);
310                minfo.dwTypeData = (LPWSTR)autoarrange.c_str();
311               
312                menu_.InsertMenuItem(menu_.GetMenuItemCount(), true, &minfo);
313
314                header_.SubclassWindow(this->GetHeader());
315                header_.ModifyStyle(0, HDS_DRAGDROP|HDS_FULLDRAG);
316                if (header_.Menu().IsNull()) 
317                        header_.Menu().CreatePopupMenu();
318        }
319       
320        void GetListViewDetails()
321        {
322                vectorSizePreConditions();             
323               
324                for (size_t i=0; i<listNames_.size(); ++i)
325                {
326                        if (listVisible_[i])
327                                listWidths_[i] = GetColumnWidth(i);
328                }
329               
330                GetColumnOrderArray(listNames_.size(), &listOrder_[0]);
331               
332/*              sortCol_ = GetSortColumn();
333                descending_ = IsSortDescending();       */
334        }
335       
336        LRESULT OnAutoSort(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
337        {
338                autoSort_ = !autoSort_;
339               
340                MENUITEMINFO minfo = {sizeof(MENUITEMINFO)};
341               
342                minfo.fMask = MIIM_STATE;
343                minfo.fState = autoSort_ ? MFS_CHECKED : MFS_UNCHECKED;
344               
345                menu_.SetMenuItemInfo(ID_LVM_AUTOSORT, false, &minfo);
346               
347                return 0;
348        }
349
350        bool OnNameChecked(int i)
351        {
352                if (!listVisible_[i])
353                {               
354                        GetColumnOrderArray(listNames_.size(), &listOrder_[0]);
355                        SetColumnWidth(i, listWidths_[i]);
356
357                        listOrder_.erase(std::find(listOrder_.begin(), listOrder_.end(), i));
358                       
359                        int index = i + std::count(listVisible_.begin()+i, listVisible_.end(), false) - 1;
360                        listOrder_.insert(listOrder_.begin()+index, i);
361
362                        SetColumnOrderArray(listNames_.size(), &listOrder_[0]);
363                        listVisible_[i] = true;
364                }
365                else
366                {
367                        listWidths_[i] = GetColumnWidth(i);     
368                        GetColumnOrderArray(listNames_.size(), &listOrder_[0]);
369
370                        SetColumnWidth(i, 0);
371
372                        listOrder_.erase(std::find(listOrder_.begin(), listOrder_.end(), i));
373                        listOrder_.insert(listOrder_.begin(), i);
374
375                        SetColumnOrderArray(listNames_.size(), &listOrder_[0]);
376                        listVisible_[i] = false;
377                }
378               
379                MENUITEMINFO minfo = {sizeof(MENUITEMINFO)};   
380                minfo.fMask = MIIM_STATE;
381                minfo.fState = listVisible_[i] ? MFS_CHECKED : MFS_UNCHECKED;   
382                header_.Menu().SetMenuItemInfo(CHaliteHeaderCtrl::COL_MENU_NAMES+i, false, &minfo);
383       
384                InvalidateRect(NULL, true);
385                return listVisible_[i];
386        }
387
388        LRESULT OnClick(int, LPNMHDR pnmh, BOOL&)
389        {
390                return 0;
391        }
392
393        LRESULT OnItemChanged(int, LPNMHDR pnmh, BOOL&)
394        {               
395                hal::try_update_lock<thisClass> lock(*this);
396               
397                if (lock) manager_.sync_list(true, true);
398               
399                return 0;
400        }
401
402        LRESULT OnRClick(int i, LPNMHDR pnmh, BOOL&)
403        {
404                LPNMITEMACTIVATE pia = (LPNMITEMACTIVATE)pnmh;
405                manager_.sync_list(true);
406               
407                if (menu_)
408                {
409                        assert (menu_.IsMenu());
410       
411                        POINT ptPoint;
412                        GetCursorPos(&ptPoint);
413                        menu_.TrackPopupMenu(0, ptPoint.x, ptPoint.y, m_hWnd);
414                }
415
416                return 0;
417        }
418
419        LRESULT OnColClick(int i, LPNMHDR pnmh, BOOL&)
420        {
421                LPNMLISTVIEW pnlv = (LPNMLISTVIEW)pnmh;
422               
423                MessageBox((lexical_cast<wstring>(pnlv->iSubItem)).c_str(), L"Hi", 0);
424                return 0;
425        }
426
427        void SortByColumn(size_t column_index)
428        {
429                /* Overwriteable */
430        }
431
432        int AddColumn(LPCTSTR strItem, int nItem, bool visible, int width=-1)
433        {
434                return AddColumn(strItem, nItem, -1,
435                        LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM,
436                        LVCFMT_LEFT, visible, width);
437        }
438
439        int AddColumn(LPCTSTR strItem, int nItem, int nSubItem = -1,
440                        int nMask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM,
441                        int nFmt = LVCFMT_LEFT, bool visible=true, int width=-1)
442        {
443                int i = parentClass::AddColumn(strItem, nItem, nSubItem, nMask, nFmt);
444
445                if (i == -1) return i;
446
447                if (width != -1) SetColumnWidth(i, width);
448
449                if (header_.Menu().IsNull()) 
450                        header_.Menu().CreatePopupMenu();
451
452                WTL::CMenuHandle menu = header_.Menu();
453
454                MENUITEMINFO minfo = {sizeof(MENUITEMINFO)};
455                minfo.fMask = MIIM_STRING|MIIM_ID|MIIM_FTYPE|MIIM_STATE;
456                minfo.fType = MFT_STRING;
457                minfo.dwTypeData = (LPTSTR)strItem;
458                minfo.wID = CHaliteHeaderCtrl::COL_MENU_NAMES+i;
459
460                if (visible)
461                        minfo.fState = MFS_CHECKED;
462                else
463                {
464                        minfo.fState = MFS_UNCHECKED;
465                        SetColumnWidth(i, 0);
466                }
467
468                int w = GetColumnWidth(i);
469
470                listNames_.push_back(strItem);
471                listVisible_.push_back(visible);
472                listWidths_.push_back(w);
473                listOrder_.push_back(i);
474
475                menu.InsertMenuItem(menu.GetMenuItemCount(), false, &minfo);
476                return i;
477        }
478
479        void SetColumnSortType(int iCol, WORD wType, ColumnAdapter* colAdapter=NULL)
480        {
481//              parentClass::SetColumnSortType(iCol, wType);
482               
483                if (WTL::LVCOLSORT_CUSTOM == wType)
484                        regColumnAdapter(iCol, colAdapter);
485        }
486
487        void SetColumnOrderState()
488        {
489                while ((int)listOrder_.size() < header_.GetItemCount())
490                        listOrder_.push_back(header_.GetItemCount());
491
492                GetColumnOrderArray(listOrder_.size(), &listOrder_[0]);
493        }
494
495        void SetSortState()
496        {
497                MENUITEMINFO minfo = {sizeof(MENUITEMINFO)};
498               
499                minfo.fMask = MIIM_STATE;
500                minfo.fState = autoSort_ ? MFS_CHECKED : MFS_UNCHECKED;
501               
502                menu_.SetMenuItemInfo(ID_LVM_AUTOSORT, false, &minfo);
503
504                if (sortCol_ >= 0 && sortCol_ < m_arrColSortType.GetSize())
505                        SetSortColumn(sortCol_);
506        }
507
508        friend class boost::serialization::access;
509        template<class Archive>
510    void save(Archive & ar, const unsigned int version) const
511    {
512                for (size_t i=0; i<listWidths_.size(); ++i)
513                {
514                        if (listVisible_[i])
515                                listWidths_[i] = GetColumnWidth(i);
516                }
517
518                GetColumnOrderArray(listOrder_.size(), &listOrder_[0]);
519//              sortCol_ = GetSortColumn();
520//              descending_ = IsSortDescending();       
521
522                using boost::serialization::make_nvp;
523
524                ar & make_nvp("width", listWidths_);
525                ar & make_nvp("order", listOrder_);
526                ar & make_nvp("visible", listVisible_);
527                ar & make_nvp("autoSort", autoSort_);
528
529                ar & make_nvp("descending", descending_);
530                ar & make_nvp("sortCol", sortCol_);
531    }
532
533    template<class Archive>
534    void load(Archive & ar, const unsigned int version)
535    {
536                using boost::serialization::make_nvp;
537
538                ar & make_nvp("width", listWidths_);
539                ar & make_nvp("order", listOrder_);
540                ar & make_nvp("visible", listVisible_);
541                ar & make_nvp("autoSort", autoSort_);
542
543                ar & make_nvp("descending", descending_);
544                ar & make_nvp("sortCol", sortCol_);
545               
546                SetColumnOrderArray(listOrder_.size(), &listOrder_[0]);
547
548/*              m_bSortDescending = descending_;
549                if (sortCol_ >= 0 && sortCol_ < m_arrColSortType.GetSize())
550                        SetSortColumn(sortCol_);
551*/
552                for (size_t i=0; i<listWidths_.size(); ++i)
553                {
554                        SetColumnWidth(i, listWidths_[i]);
555                        if (!listVisible_[i])
556                        {
557                                listVisible_[i] = true;
558                                OnNameChecked(i);
559                        }
560                }
561
562//              SetColumnOrderState();
563//              SetSortState();
564    }
565
566    BOOST_SERIALIZATION_SPLIT_MEMBER()
567
568        const SelectionManager& manager() { return manager_; }
569               
570        std::vector<int>& listColumnWidth() { return listColumnWidth_; }
571        std::vector<int>& listColumnOrder() { return listColumnOrder_; }
572       
573        const std::vector<int>& listColumnWidth() const { return listColumnWidth_; }
574        const std::vector<int>& listColumnOrder() const { return listColumnOrder_; }
575       
576        bool canUpdate() const { return updateLock_ == 0; }
577       
578        void clearFocused() { manager_.clear(); }
579        void clearSelected() { manager_.clear_all_selected(); }
580        void clearAll() { manager_.clear_all(); }
581       
582/*      int CompareItemsCustom(LVCompareParam* pItem1, LVCompareParam* pItem2, int iSortCol)
583        {
584                hal::mutex_update_lock<thisClass> lock(*this);
585               
586                TBase* pT = static_cast<TBase*>(this);
587               
588                AdapterType left = pT->CustomItemConversion(pItem1, iSortCol);
589                AdapterType right = pT->CustomItemConversion(pItem2, iSortCol);
590               
591                return pT->CustomItemComparision(left, right, iSortCol);
592        }
593        */
594        bool autoSort() { return autoSort_; }
595       
596        void ConditionallyDoAutoSort()
597        {
598/*              int iCol = GetSortColumn();
599                if (autoSort() && iCol >= 0 && iCol < m_arrColSortType.GetSize())
600                        DoSortItems(iCol, IsSortDescending());  */
601        }
602               
603        ColumnAdapter* getColumnAdapter(size_t index)
604        {
605                boost::ptr_map<size_t, ColumnAdapter>::iterator
606                        i = columnAdapters_.find(index);
607       
608                if (i != columnAdapters_.end())
609                {
610                        return i->second;
611                }               
612                return NULL;
613        }
614
615        static bool is_selected (const winstl::listview_sequence::sequence_value_type& v) 
616        { 
617                return (v.state() & LVIS_SELECTED) != 0; 
618        }
619
620protected:     
621/*      inline void* CustomItemConversion(LVCompareParam* param, int iSortCol)
622        {
623                assert(false);
624                return NULL;
625        }
626       
627        int CustomItemComparision(AdapterType left, AdapterType right, int iSortCol)
628        {
629                ColumnAdapter* pCA = getColumnAdapter(iSortCol);
630               
631                if (pCA)
632                        return pCA->compare(left, right);
633                else
634                        return 0;
635        }
636        */
637        void regColumnAdapter(size_t key, ColumnAdapter* colAdapter)
638        {
639                assert (colAdapter);
640                columnAdapters_.insert(key, colAdapter);
641        }
642
643//      AdapterType convert(const LPLVITEM item);
644//      void convert(LPLVITEM item, AdapterType adapter);
645       
646        SelectionManager manager_;
647        WTL::CMenu menu_;
648        CHaliteHeaderCtrl header_;     
649       
650private:
651        bool vectorSizePreConditions()
652        {
653                bool ret = (listNames_.size() == listWidths_.size()) &&
654                        (listNames_.size() == listOrder_.size()) &&
655                        (listNames_.size() == listVisible_.size());
656
657                return ret;
658        }       
659       
660        mutable std::vector<wstring> listNames_;
661        mutable std::vector<int> listWidths_;
662        mutable std::vector<int> listOrder_;
663        mutable std::vector<bool> listVisible_;
664        mutable bool autoSort_;
665        mutable bool descending_;
666        mutable int sortCol_;
667       
668        mutable int update_lock_;
669        mutable hal::mutex_t mutex_;
670
671        friend class hal::mutex_update_lock<thisClass>; 
672        friend class hal::try_update_lock<thisClass>;           
673       
674        boost::ptr_map<size_t, ColumnAdapter> columnAdapters_;
675       
676        WinAPIWaitableTimer syncTimer_;
677};
678
679template<>
680inline const std::wstring hal::to_wstr_shim<const winstl::listview_sequence::sequence_value_type>
681        (const winstl::listview_sequence::sequence_value_type& v)
682{
683        return std::wstring(winstl::c_str_ptr(v));
684}
685
686namespace boost {
687namespace serialization {
688        template <class TBase, typename AdapterType>
689        struct version< CHaliteSortListViewCtrl<TBase, AdapterType> >
690        {
691                typedef mpl::int_<2> type;
692                typedef mpl::integral_c_tag tag;
693                BOOST_STATIC_CONSTANT(unsigned int, value = version::type::value);                                                             
694        };
695}
696}
Note: See TracBrowser for help on using the repository browser.