source: trunk/src/WTLx/SelectionManager.hpp @ 531

Revision 531, 4.8 KB checked in by Eoin, 12 years ago (diff)

Switched trunk to hal::wform.

Line 
1
2//         Copyright Eoin 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
11namespace WTLx
12{
13
14template<typename L, typename S>
15class selection_manager : 
16        private boost::noncopyable
17{       
18public:
19        selection_manager(L& list) :
20                list_(list)
21        {}
22       
23        typedef std::wstring string_t; 
24        typedef const string_t& param_type;
25       
26        void sync_list(bool list_to_manager, bool signal_change=true)
27        {
28                if (list_to_manager)
29                {       
30                        if (from_listview() && signal_change) signal();
31                }
32                else
33                {
34                        if (managerToList() && signal_change) signal();
35                }
36        }
37       
38        bool from_listview()
39        {
40                hal::win_c_str<string_t, MAX_PATH> c_string;
41
42                std::set<string_t> all_selected;
43                string_t selected = L"";
44               
45                bool do_signal = false;
46               
47                for (int i=0, e=list_.GetItemCount(); i<e; ++i)
48                {
49                        UINT flags = list_.GetItemState(i, LVIS_SELECTED);
50                       
51                        if (flags && LVIS_SELECTED)
52                        {
53                                list_.GetItemText(i, 0, c_string, c_string.size());     
54                                all_selected.insert(c_string);
55                        }
56                        if (flags && LVIS_FOCUSED)
57                        {
58                                selected = string_t(c_string);
59                        }
60                }
61
62                if (all_selected != all_selected_)
63                {
64                        std::swap(all_selected_, all_selected);
65                        do_signal = true;
66                }
67                               
68                if (selected_ != selected)
69                {
70                        std::swap(selected_, selected);
71                        do_signal = true;
72                }
73               
74                return do_signal;
75        }
76       
77        bool managerToList()
78        {
79                // Prevent changing states from signaling another sync
80                hal::mutex_update_lock<L> lock(list_);
81               
82                boost::array<wchar_t, MAX_PATH> pathBuffer;
83                LV_FINDINFO findInfo = { sizeof(LV_FINDINFO) }; 
84                findInfo.flags = LVFI_STRING;
85               
86                bool do_signal = true; // Always signal for now!
87               
88                int total = list_.GetItemCount();
89               
90                for (int i=0; i<total; ++i)
91                {
92                        list_.GetItemText(i, 0, pathBuffer.c_array(), pathBuffer.size());
93                        string_t temp_name = pathBuffer.data();
94                       
95                        LVITEM lvi = { LVIF_STATE };
96                        lvi.state = 0;
97                        lvi.stateMask = LVIS_SELECTED|LVIS_FOCUSED;
98                       
99                        if (temp_name == selected_)
100                        {
101                                lvi.state |= LVIS_FOCUSED;
102                        }
103                        if (all_selected_.find(temp_name) != all_selected_.end())
104                        {
105                                lvi.state |= LVIS_SELECTED;
106                        }
107                       
108                        list_.SetItemState(i, &lvi);
109                }                       
110               
111                return do_signal;
112        }
113       
114        int selectMatch(const string_t& name)
115        {
116                LV_FINDINFO findInfo = { sizeof(LV_FINDINFO) }; 
117                findInfo.flags = LVFI_STRING;
118                               
119                findInfo.psz = name.c_str();
120               
121                int itemPos = list_.FindItem(&findInfo, -1);   
122                                       
123                if (itemPos == -1)
124                        return itemPos;
125                       
126                UINT flags = list_.GetItemState(itemPos, LVIS_SELECTED);
127               
128                //if (!flags && LVIS_SELECTED)
129                {
130                        LVITEM lvi = { LVIF_STATE };
131                        lvi.state = LVIS_SELECTED;
132                        lvi.stateMask = LVIS_SELECTED;
133                        list_.SetItemState(itemPos, &lvi);
134                }
135       
136                return itemPos;
137        }
138       
139        param_type selected() const { return selected_; }
140       
141        int selectedIndex() const
142        {
143                LV_FINDINFO findInfo = { sizeof(LV_FINDINFO) };         
144                findInfo.psz = selected_.c_str();
145               
146                return list_.FindItem(&findInfo, -1);           
147        }
148       
149        const std::set<string_t>& allSelected() const { return all_selected_; }
150       
151        void setSelected(const string_t& sel) 
152        {
153                selected_ = sel;
154        }
155       
156        void setSelected(int itemPos)
157        {               
158                hal::event_log.post(shared_ptr<hal::EventDetail>(new hal::EventDebug(hal::event_logger::info, (hal::wform(L"Set Selected %1%") % itemPos).str().c_str())));
159
160                LVITEM lvi = { LVIF_STATE };
161                lvi.state = LVIS_SELECTED|LVIS_FOCUSED;
162                lvi.stateMask = LVIS_SELECTED|LVIS_FOCUSED;
163                list_.SetItemState(itemPos, &lvi);
164               
165                list_.SetSelectionMark(itemPos);
166               
167                sync_list(true);
168        }
169       
170        void clear()
171        {
172                // Prevent changing states from signaling another sync
173                hal::mutex_update_lock<L> lock(list_);
174               
175                list_.DeleteItem(selectedIndex());
176               
177                sync_list(true);       
178        }
179       
180        void clear_all_selected()
181        {
182                // Prevent changing states from signaling another sync
183                hal::mutex_update_lock<L> lock(list_);
184               
185                int total = list_.GetItemCount();
186               
187                for (int i=total-1; i>=0; --i)
188                {
189                        UINT flags = list_.GetItemState(i, LVIS_SELECTED);
190                       
191                        if (flags && LVIS_SELECTED)
192                                list_.DeleteItem(i);
193                }
194                all_selected_.clear();
195               
196                sync_list(true);       
197        }
198       
199        void clear_all()
200        {
201                // Prevent changing states from signaling another sync
202                hal::mutex_update_lock<L> lock(list_);
203               
204                list_.DeleteAllItems();
205                all_selected_.clear();
206               
207                sync_list(true);               
208        }
209       
210        void attach(boost::function<void (param_type)> fn) const { selection_.connect(fn); }
211       
212        void signal() 
213        { 
214                selection_(selected_); 
215        }
216       
217private:
218        string_t selected_;
219        std::set<string_t> all_selected_;
220       
221        mutable boost::signal<void (param_type)> selection_;
222        L& list_;
223};
224
225} // anmespace WTLx
Note: See TracBrowser for help on using the repository browser.