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

Revision 661, 10.3 KB checked in by Eoin, 11 years ago (diff)

File list working but very slow.

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        enum { 
153                LISTVIEW_ID_MENU = HAL_FILESLISTVIEW_MENU,
154                LISTVIEW_ID_COLUMNNAMES = HAL_DIALOGFILE_LISTVIEW_ADV,
155                LISTVIEW_ID_COLUMNWIDTHS = 0
156        };
157       
158        BEGIN_MSG_MAP_EX(thisClass)
159                MSG_WM_DESTROY(OnDestroy)
160                COMMAND_RANGE_HANDLER_EX(ID_HAL_FILE_PRIORITY_0, ID_HAL_FILE_PRIORITY_7, OnMenuPriority)
161
162                CHAIN_MSG_MAP(listClass)
163                DEFAULT_REFLECTION_HANDLER()
164        END_MSG_MAP()
165
166        FileListView();
167       
168        void saveSettings()
169        {
170                GetListViewDetails();
171                save_to_ini();
172        }
173       
174        HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
175                DWORD dwStyle = 0, DWORD dwExStyle = 0,
176                ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL);
177       
178        void OnDestroy()
179        {
180                saveSettings();
181        }
182       
183        void OnMenuPriority(UINT, int, HWND);
184       
185        friend class boost::serialization::access;
186        template<class Archive>
187        void serialize(Archive& ar, const unsigned int version)
188        {
189                ar & boost::serialization::make_nvp("listview", 
190                        boost::serialization::base_object<listClass>(*this));
191        }
192       
193/*      dataClass CustomItemConversion(LVCompareParam* param, int iSortCol)
194        {                       
195                return focused_->get_file_details()[param->dwItemData];
196        }               */
197       
198        void setFocused(const hal::torrent_details_ptr& f) { focused_ = f; }
199        const hal::torrent_details_ptr focused() { return focused_; }
200
201private:
202        hal::torrent_details_ptr focused_;
203};
204
205class FileTreeView :
206        public ATL::CWindowImpl<FileTreeView, WTL::CTreeViewCtrlEx>,
207        public hal::IniBase<FileTreeView>,
208        private boost::noncopyable
209{
210protected:
211        typedef FileTreeView thisClass;
212        typedef ATL::CWindowImpl<thisClass, WTL::CTreeViewCtrlEx> treeClass;
213        typedef hal::IniBase<thisClass> iniClass;
214
215        friend class treeClass;
216       
217public: 
218        thisClass() :
219                iniClass("treeviews/advFiles", "FileTreeView"),
220                update_lock_(0)
221        {}
222       
223        BEGIN_MSG_MAP_EX(thisClass)
224                MSG_WM_DESTROY(OnDestroy)
225
226                REFLECTED_NOTIFY_CODE_HANDLER(NM_RCLICK, OnRClick)
227                REFLECTED_NOTIFY_CODE_HANDLER(TVN_SELCHANGED, OnSelChanged)
228               
229                COMMAND_RANGE_HANDLER_EX(ID_HAL_FILE_PRIORITY_0, ID_HAL_FILE_PRIORITY_7, OnMenuPriority)
230                DEFAULT_REFLECTION_HANDLER()
231        END_MSG_MAP()
232       
233        HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
234                DWORD dwStyle = 0, DWORD dwExStyle = 0,
235                ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL);
236       
237        LRESULT OnRClick(int i, LPNMHDR pnmh, BOOL&);
238        void OnMenuPriority(UINT, int, HWND);
239       
240        wpath focused() { return focused_; }
241       
242        void attach(boost::function<void ()> fn) const { selection_.connect(fn); }
243       
244        void signal() { selection_(); }
245       
246        void determineFocused();
247       
248protected:
249        void OnDestroy()
250        {
251        //      saveSettings();
252        }
253       
254        LRESULT OnSelChanged(int, LPNMHDR pnmh, BOOL&);
255       
256        mutable int update_lock_;
257        mutable hal::mutex_t mutex_;
258
259        friend class hal::mutex_update_lock<thisClass>; 
260        friend class hal::try_update_lock<thisClass>;           
261       
262        mutable boost::signal<void ()> selection_;
263        wpath focused_;
264
265private:
266        WTL::CMenu menu_;
267};
268
269template<typename T>
270class TreeViewManager
271{
272public:
273        TreeViewManager(T& t) :
274                tree_(t)
275        {}
276       
277        struct ValidTreeItem
278        {
279                ValidTreeItem() 
280                {}
281
282                ValidTreeItem(WTL::CTreeItem& t) :
283                        valid(true),
284                        treeItem(t)
285                {}
286               
287                bool valid;
288                WTL::CTreeItem treeItem;
289        };
290       
291        typedef std::map<wpath, ValidTreeItem> MapType;
292       
293        void EnsureValid(wpath p)
294        {               
295                wpath branchPath = p;
296               
297                MapType::iterator i = map_.find(branchPath);           
298                if (i == map_.end())
299                {
300                        WTL::CTreeItem ti = tree_.GetRootItem();
301                       
302                        wpath branch;
303                        foreach (wstring b, branchPath)
304                        {
305                                branch /= b;                           
306                                MapType::iterator j = map_.find(branch);
307                               
308                                if (j == map_.end())
309                                {
310                                        WTL::CTreeItem tmp = ti.AddTail(b.c_str(), -1);
311                                        ti.Expand();
312                                        ti = tmp;
313                                        map_[branch] = ValidTreeItem(ti);
314                                }
315                                else
316                                {
317                                        (*j).second.valid = true;
318                                        ti = (*j).second.treeItem;
319                                }                               
320                        }
321                }
322                else
323                {
324                        if (!(*i).second.valid)
325                        {
326                                (*i).second.valid = true;
327                                EnsureValid(branchPath.parent_path());
328                        }
329                }
330        }
331       
332        void InvalidateAll()
333        {
334                for(MapType::iterator i=map_.begin(), e=map_.end(); i!=e; ++i)
335                {
336                        (*i).second.valid = false;
337                }
338        }
339       
340        void ClearInvalid()
341        {
342                for(MapType::iterator i=map_.begin(), e=map_.end(); i!=e; /**/)
343                {
344                        if ((*i).second.valid)
345                        {
346                                ++i;
347                        }
348                        else
349                        {
350                                (*i).second.treeItem.Delete();
351                                map_.erase(i++);
352                        }
353                }       
354        }
355       
356private:
357        T& tree_;
358        MapType map_;
359};
360
361class FileStatic :
362        public ATL::CWindowImpl<FileStatic, WTL::CStatic>
363{       
364public:
365        BEGIN_MSG_MAP_EX(FileStatic)
366                REFLECT_NOTIFICATIONS()
367        END_MSG_MAP()
368};
369
370class AdvFilesDialog :
371        public CHalTabPageImpl<AdvFilesDialog>,
372        public WTL::CDialogResize<AdvFilesDialog>,
373        public CHaliteDialogBase<AdvFilesDialog>,
374        public CWinDataExchangeEx<AdvFilesDialog>,
375        public hal::IniBase<AdvFilesDialog>,
376        private boost::noncopyable
377{
378protected:
379        typedef AdvFilesDialog thisClass;
380        typedef CHalTabPageImpl<thisClass> baseClass;
381        typedef WTL::CDialogResize<thisClass> resizeClass;
382        typedef CHaliteDialogBase<thisClass> dialogBaseClass;
383        typedef hal::IniBase<thisClass> iniClass;
384
385public:
386        enum { IDD = HAL_ADVFILES };
387
388        AdvFilesDialog(HaliteWindow& halWindow) :
389                dialogBaseClass(halWindow),
390                treeManager_(tree_),
391                iniClass("AdvFilesDlg", "settings"),
392                splitterPos(150)
393        {
394                load_from_ini();
395        }
396       
397        ~AdvFilesDialog() 
398        {}
399       
400        BOOL PreTranslateMessage(MSG* pMsg)
401        {
402                return this->IsDialogMessage(pMsg);
403        }
404
405        BEGIN_MSG_MAP_EX(thisClass)
406                MSG_WM_INITDIALOG(onInitDialog)
407                MSG_WM_CLOSE(onClose)
408                MSG_WM_DESTROY(OnDestroy)
409               
410                if (uMsg == WM_FORWARDMSG)
411                        if (PreTranslateMessage((LPMSG)lParam)) return TRUE;
412               
413                CHAIN_MSG_MAP(dialogBaseClass)
414                CHAIN_MSG_MAP(resizeClass)
415                CHAIN_MSG_MAP(baseClass)
416                REFLECT_NOTIFICATIONS()
417        END_MSG_MAP()
418
419        BEGIN_DLGRESIZE_MAP(thisClass)
420                DLGRESIZE_CONTROL(HAL_CONTAINER, DLSZ_SIZE_X|DLSZ_SIZE_Y|DLSZ_REPAINT)
421        END_DLGRESIZE_MAP()
422
423    friend class boost::serialization::access;
424    template<class Archive>
425    void serialize(Archive& ar, const unsigned int version)
426        {
427                ar & BOOST_SERIALIZATION_NVP(splitterPos);
428        }
429
430        LRESULT onInitDialog(HWND, LPARAM);
431        void onClose();
432       
433        void DlgResize_UpdateLayout(int cxWidth, int cyHeight);
434        void doUiUpdate();
435        void uiUpdate(const hal::torrent_details_manager& tD);
436        void focusChanged(const hal::torrent_details_ptr pT);
437        void OnDestroy();
438
439protected:
440        WTL::CSplitterWindow splitter_;
441        unsigned int splitterPos;
442       
443        FileStatic static_;
444        FileTreeView tree_;
445        FileListView list_;
446       
447        std::map<wpath, WTL::CTreeItem> fileTreeMap_;
448        TreeViewManager<FileTreeView> treeManager_;
449       
450        std::vector<FileLink> fileLinks_;
451       
452        hal::file_details_vec file_details_;
453        std::pair<std::vector<FileLink>::iterator, std::vector<FileLink>::iterator> range_;
454};
Note: See TracBrowser for help on using the repository browser.