source: trunk/src/advtabs/Files.hpp @ 662

Revision 662, 10.9 KB checked in by Eoin, 11 years ago (diff)

Virtual FileListView? working but not redrawing correctly.

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#include "Halite.hpp"
11
12#include "DdxEx.hpp"
13#include "global/string_conv.hpp"
14
15#include "../HaliteTabPage.hpp"
16#include "../HaliteListManager.hpp"
17#include "../HaliteDialogBase.hpp"
18#include "../halIni.hpp"
19#include "../HaliteListViewCtrl.hpp"
20
21#include "../HaliteUpdateLock.hpp"
22
23struct FileLink
24{
25        FileLink(const boost::filesystem::wpath& b, size_t o=0) :
26                branch(b),
27                filename(L""),
28                order_(o)
29        {}
30
31        FileLink(const wstring& f, size_t o=0) :
32                branch(L""),
33                filename(f),
34                order_(o)
35        {}
36
37        FileLink(const hal::file_details& f) :
38                branch(f.branch),
39                filename(f.filename),
40                order_(f.order())
41        {
42//              hal::event_log.post(shared_ptr<hal::EventDetail>(
43//                      new hal::EventMsg(hal::wform(L"Con -> %1% - %2%.") % filename % order())));     
44        }
45       
46        bool operator==(const FileLink& f) const
47        {
48                return (branch == f.branch);
49        }
50       
51        bool operator<(const FileLink& f) const
52        {
53                return (branch < f.branch);
54        }
55       
56        enum FileType
57        {
58                folder,
59                file
60        };
61       
62        size_t order() { return order_; }
63       
64        boost::filesystem::wpath branch;
65        wstring filename;
66        unsigned type;
67       
68private:
69        size_t order_;
70};
71
72
73inline bool FileLinkNamesEqual(const FileLink& l, const FileLink& r)
74{
75        return l.filename == r.filename;
76}
77
78inline bool FileLinkNamesLess(const FileLink& l, const FileLink& r)
79{
80        return l.filename < r.filename;
81}
82
83class FileListView :
84        public CHaliteSortListViewCtrl<FileListView, const hal::file_details>,
85        public hal::IniBase<FileListView>,
86        private boost::noncopyable
87{
88public:
89        typedef FileListView thisClass;
90        typedef const hal::file_details dataClass;
91        typedef CHaliteSortListViewCtrl<thisClass, dataClass> listClass;
92        typedef hal::IniBase<thisClass> iniClass;
93
94        friend class listClass;
95       
96/*      struct ColumnAdapters
97        {       
98        typedef listClass::ColumnAdapter ColAdapter_t; 
99       
100        struct Size : public ColAdapter_t
101        {
102                virtual int compare(dataClass& l, dataClass& r) { return hal::compare(l.size, r.size); }               
103                virtual std::wstring print(dataClass& dc)
104                {
105                        return (hal::wform(L"%1$.2fMB") %
106                                (static_cast<double>(dc.size)/(1024*1024))).str();
107                }               
108        };
109       
110        struct Progress : public ColAdapter_t
111        {
112                virtual int compare(dataClass& l, dataClass& r) { return hal::compare(static_cast<double>(l.progress)/l.size,
113                        static_cast<double>(r.progress)/r.size); }             
114                virtual std::wstring print(dataClass& t)
115                {
116                        return (hal::wform(L"%1$.2f%%") % (static_cast<double>(t.progress)/t.size*100)).str();
117                }               
118        };
119       
120        struct Priority : public ColAdapter_t
121        {
122                virtual int compare(dataClass& l, dataClass& r) { return hal::compare(l.priority, r.priority); }               
123                virtual std::wstring print(dataClass& dc)
124                {
125                        switch (dc.priority)
126                        {
127                        case 0:
128                                return hal::app().res_wstr(HAL_FILE_PRIORITY_0);
129                        case 1:
130                                return hal::app().res_wstr(HAL_FILE_PRIORITY_1);
131                        case 2:
132                                return hal::app().res_wstr(HAL_FILE_PRIORITY_2);
133                        case 3:
134                                return hal::app().res_wstr(HAL_FILE_PRIORITY_3);
135                        case 4:
136                                return hal::app().res_wstr(HAL_FILE_PRIORITY_4);
137                        case 5:
138                                return hal::app().res_wstr(HAL_FILE_PRIORITY_5);
139                        case 6:
140                                return hal::app().res_wstr(HAL_FILE_PRIORITY_6);
141                        case 7:
142                                return hal::app().res_wstr(HAL_FILE_PRIORITY_7);
143                        default:
144                                return hal::app().res_wstr(HAL_FILE_PRIORITY_0);
145                        }       
146                }               
147        };
148       
149        };
150*/
151public: 
152
153        class scoped_files
154        {
155
156        public:
157                scoped_files(hal::mutex_t& m, hal::file_details_vec* f) :
158                        l_(m),
159                        f_(f)
160                {}
161
162                hal::file_details_vec* operator->() const { return f_; }
163
164        private:
165                hal::mutex_t::scoped_lock l_;
166                hal::file_details_vec* f_;
167        };
168
169
170        enum { 
171                LISTVIEW_ID_MENU = HAL_FILESLISTVIEW_MENU,
172                LISTVIEW_ID_COLUMNNAMES = HAL_DIALOGFILE_LISTVIEW_ADV,
173                LISTVIEW_ID_COLUMNWIDTHS = 0
174        };
175       
176        BEGIN_MSG_MAP_EX(thisClass)
177                MSG_WM_DESTROY(OnDestroy)
178                COMMAND_RANGE_HANDLER_EX(ID_HAL_FILE_PRIORITY_0, ID_HAL_FILE_PRIORITY_7, OnMenuPriority)
179                REFLECTED_NOTIFY_CODE_HANDLER(LVN_GETDISPINFO, OnGetDispInfo)
180
181                CHAIN_MSG_MAP(listClass)
182                FORWARD_NOTIFICATIONS()
183        END_MSG_MAP()
184
185        FileListView();
186       
187        void saveSettings()
188        {
189                GetListViewDetails();
190                save_to_ini();
191        }
192       
193        HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
194                DWORD dwStyle = 0, DWORD dwExStyle = 0,
195                ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL);
196       
197        void OnDestroy()
198        {
199                saveSettings();
200        }
201       
202        void OnMenuPriority(UINT, int, HWND);
203       
204        friend class boost::serialization::access;
205        template<class Archive>
206        void serialize(Archive& ar, const unsigned int version)
207        {
208                ar & boost::serialization::make_nvp("listview", 
209                        boost::serialization::base_object<listClass>(*this));
210        }
211       
212/*      dataClass CustomItemConversion(LVCompareParam* param, int iSortCol)
213        {                       
214                return focused_->get_file_details()[param->dwItemData];
215        }               */
216       
217        void setFocused(const hal::torrent_details_ptr& f) { focused_ = f; }
218        const hal::torrent_details_ptr focused() { return focused_; }
219
220        scoped_files files() { return scoped_files(listClass::mutex_, &files_); }
221
222protected:     
223        LRESULT OnGetDispInfo(int, LPNMHDR pnmh, BOOL&);
224
225private:
226        //mutable hal::mutex_t mutex_;
227
228        hal::file_details_vec files_;
229        hal::torrent_details_ptr focused_;
230};
231
232class FileTreeView :
233        public ATL::CWindowImpl<FileTreeView, WTL::CTreeViewCtrlEx>,
234        public hal::IniBase<FileTreeView>,
235        private boost::noncopyable
236{
237protected:
238        typedef FileTreeView thisClass;
239        typedef ATL::CWindowImpl<thisClass, WTL::CTreeViewCtrlEx> treeClass;
240        typedef hal::IniBase<thisClass> iniClass;
241
242        friend class treeClass;
243       
244public: 
245        thisClass() :
246                iniClass("treeviews/advFiles", "FileTreeView"),
247                update_lock_(0)
248        {}
249       
250        BEGIN_MSG_MAP_EX(thisClass)
251                MSG_WM_DESTROY(OnDestroy)
252
253                REFLECTED_NOTIFY_CODE_HANDLER(NM_RCLICK, OnRClick)
254                REFLECTED_NOTIFY_CODE_HANDLER(TVN_SELCHANGED, OnSelChanged)
255               
256                COMMAND_RANGE_HANDLER_EX(ID_HAL_FILE_PRIORITY_0, ID_HAL_FILE_PRIORITY_7, OnMenuPriority)
257                DEFAULT_REFLECTION_HANDLER()
258        END_MSG_MAP()
259       
260        HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
261                DWORD dwStyle = 0, DWORD dwExStyle = 0,
262                ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL);
263       
264        LRESULT OnRClick(int i, LPNMHDR pnmh, BOOL&);
265        void OnMenuPriority(UINT, int, HWND);
266       
267        wpath focused() { return focused_; }
268       
269        void attach(boost::function<void ()> fn) const { selection_.connect(fn); }
270       
271        void signal() { selection_(); }
272       
273        void determineFocused();
274       
275protected:
276        void OnDestroy()
277        {
278        //      saveSettings();
279        }
280       
281        LRESULT OnSelChanged(int, LPNMHDR pnmh, BOOL&);
282       
283        mutable int update_lock_;
284        mutable hal::mutex_t mutex_;
285
286        friend class hal::mutex_update_lock<thisClass>; 
287        friend class hal::try_update_lock<thisClass>;           
288       
289        mutable boost::signal<void ()> selection_;
290        wpath focused_;
291
292private:
293        WTL::CMenu menu_;
294};
295
296template<typename T>
297class TreeViewManager
298{
299public:
300        TreeViewManager(T& t) :
301                tree_(t)
302        {}
303       
304        struct ValidTreeItem
305        {
306                ValidTreeItem() 
307                {}
308
309                ValidTreeItem(WTL::CTreeItem& t) :
310                        valid(true),
311                        treeItem(t)
312                {}
313               
314                bool valid;
315                WTL::CTreeItem treeItem;
316        };
317       
318        typedef std::map<wpath, ValidTreeItem> MapType;
319       
320        void EnsureValid(wpath p)
321        {               
322                wpath branchPath = p;
323               
324                MapType::iterator i = map_.find(branchPath);           
325                if (i == map_.end())
326                {
327                        WTL::CTreeItem ti = tree_.GetRootItem();
328                       
329                        wpath branch;
330                        foreach (wstring b, branchPath)
331                        {
332                                branch /= b;                           
333                                MapType::iterator j = map_.find(branch);
334                               
335                                if (j == map_.end())
336                                {
337                                        WTL::CTreeItem tmp = ti.AddTail(b.c_str(), -1);
338                                        ti.Expand();
339                                        ti = tmp;
340                                        map_[branch] = ValidTreeItem(ti);
341                                }
342                                else
343                                {
344                                        (*j).second.valid = true;
345                                        ti = (*j).second.treeItem;
346                                }                               
347                        }
348                }
349                else
350                {
351                        if (!(*i).second.valid)
352                        {
353                                (*i).second.valid = true;
354                                EnsureValid(branchPath.parent_path());
355                        }
356                }
357        }
358       
359        void InvalidateAll()
360        {
361                for(MapType::iterator i=map_.begin(), e=map_.end(); i!=e; ++i)
362                {
363                        (*i).second.valid = false;
364                }
365        }
366       
367        void ClearInvalid()
368        {
369                for(MapType::iterator i=map_.begin(), e=map_.end(); i!=e; /**/)
370                {
371                        if ((*i).second.valid)
372                        {
373                                ++i;
374                        }
375                        else
376                        {
377                                (*i).second.treeItem.Delete();
378                                map_.erase(i++);
379                        }
380                }       
381        }
382       
383private:
384        T& tree_;
385        MapType map_;
386};
387
388class FileStatic :
389        public ATL::CWindowImpl<FileStatic, WTL::CStatic>
390{       
391public:
392        BEGIN_MSG_MAP_EX(FileStatic)
393                REFLECT_NOTIFICATIONS()
394        END_MSG_MAP()
395};
396
397class AdvFilesDialog :
398        public CHalTabPageImpl<AdvFilesDialog>,
399        public WTL::CDialogResize<AdvFilesDialog>,
400        public CHaliteDialogBase<AdvFilesDialog>,
401        public CWinDataExchangeEx<AdvFilesDialog>,
402        public hal::IniBase<AdvFilesDialog>,
403        private boost::noncopyable
404{
405protected:
406        typedef AdvFilesDialog thisClass;
407        typedef CHalTabPageImpl<thisClass> baseClass;
408        typedef WTL::CDialogResize<thisClass> resizeClass;
409        typedef CHaliteDialogBase<thisClass> dialogBaseClass;
410        typedef hal::IniBase<thisClass> iniClass;
411
412public:
413        enum { IDD = HAL_ADVFILES };
414
415        AdvFilesDialog(HaliteWindow& halWindow) :
416                dialogBaseClass(halWindow),
417                treeManager_(tree_),
418                iniClass("AdvFilesDlg", "settings"),
419                splitterPos(150)
420        {
421                load_from_ini();
422        }
423       
424        ~AdvFilesDialog() 
425        {}
426       
427        BOOL PreTranslateMessage(MSG* pMsg)
428        {
429                return this->IsDialogMessage(pMsg);
430        }
431
432        BEGIN_MSG_MAP_EX(thisClass)
433                MSG_WM_INITDIALOG(onInitDialog)
434                MSG_WM_CLOSE(onClose)
435                NOTIFY_HANDLER(31415, LVN_GETDISPINFO, OnGetDispInfo)
436                MSG_WM_DESTROY(OnDestroy)
437               
438                if (uMsg == WM_FORWARDMSG)
439                        if (PreTranslateMessage((LPMSG)lParam)) return TRUE;
440               
441                CHAIN_MSG_MAP(dialogBaseClass)
442                CHAIN_MSG_MAP(resizeClass)
443                CHAIN_MSG_MAP(baseClass)
444                REFLECT_NOTIFICATIONS()
445        END_MSG_MAP()
446
447        BEGIN_DLGRESIZE_MAP(thisClass)
448                DLGRESIZE_CONTROL(HAL_CONTAINER, DLSZ_SIZE_X|DLSZ_SIZE_Y|DLSZ_REPAINT)
449        END_DLGRESIZE_MAP()
450
451    friend class boost::serialization::access;
452    template<class Archive>
453    void serialize(Archive& ar, const unsigned int version)
454        {
455                ar & BOOST_SERIALIZATION_NVP(splitterPos);
456        }
457
458        LRESULT onInitDialog(HWND, LPARAM);
459        void onClose();
460        LRESULT OnGetDispInfo(int, LPNMHDR pnmh, BOOL&);
461       
462        void DlgResize_UpdateLayout(int cxWidth, int cyHeight);
463        void doUiUpdate();
464        void uiUpdate(const hal::torrent_details_manager& tD);
465        void focusChanged(const hal::torrent_details_ptr pT);
466        void OnDestroy();
467
468protected:
469        WTL::CSplitterWindow splitter_;
470        unsigned int splitterPos;
471       
472        FileStatic static_;
473        FileTreeView tree_;
474        FileListView list_;
475       
476        std::map<wpath, WTL::CTreeItem> fileTreeMap_;
477        TreeViewManager<FileTreeView> treeManager_;
478       
479        std::vector<FileLink> fileLinks_;
480       
481        hal::file_details_vec file_details_;
482        std::pair<std::vector<FileLink>::iterator, std::vector<FileLink>::iterator> range_;
483};
Note: See TracBrowser for help on using the repository browser.