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

Revision 531, 10.2 KB checked in by Eoin, 11 years ago (diff)

Switched trunk to hal::wform.

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