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

Revision 507, 10.3 KB checked in by Eoin, 12 years ago (diff)

Added ListViewIterators?.hpp.

Major find and replace of TorrentDetails? and associated classes to torrent_details.

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