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

Revision 697, 9.1 KB checked in by kavika, 11 years ago (diff)

Small tweak to EditHilight? and DdxEx?.hpp.

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       
43        bool operator==(const FileLink& f) const
44        {
45                return (branch == f.branch);
46        }
47       
48        bool operator<(const FileLink& f) const
49        {
50                return (branch < f.branch);
51        }
52       
53        enum FileType
54        {
55                folder,
56                file
57        };
58       
59        size_t order() { return order_; }
60       
61        boost::filesystem::wpath branch;
62        wstring filename;
63        unsigned type;
64       
65private:
66        size_t order_;
67};
68
69
70inline bool FileLinkNamesEqual(const FileLink& l, const FileLink& r)
71{
72        return l.filename == r.filename;
73}
74
75inline bool FileLinkNamesLess(const FileLink& l, const FileLink& r)
76{
77        return l.filename < r.filename;
78}
79
80class FileListView :
81        public CHaliteSortListViewCtrl<FileListView, const hal::file_details>,
82        public hal::IniBase<FileListView>,
83        private boost::noncopyable
84{
85public:
86        typedef FileListView thisClass;
87        typedef const hal::file_details dataClass;
88        typedef CHaliteSortListViewCtrl<thisClass, dataClass> listClass;
89        typedef hal::IniBase<thisClass> iniClass;
90       
91        typedef boost::function<void ()> do_ui_update_fn;
92
93        friend class listClass;
94
95public: 
96        class scoped_files
97        {
98
99        public:
100                scoped_files(hal::mutex_t& m, hal::file_details_vec* f) :
101                        l_(m),
102                        f_(f)
103                {}
104
105                hal::file_details_vec* operator->() const { return f_; }
106
107                hal::file_details_vec& operator*() const { return *f_; }
108
109        private:
110                hal::mutex_t::scoped_lock l_;
111                hal::file_details_vec* f_;
112        };
113
114        enum { 
115                LISTVIEW_ID_MENU = HAL_FILESLISTVIEW_MENU,
116                LISTVIEW_ID_COLUMNNAMES = HAL_DIALOGFILE_LISTVIEW_ADV,
117                LISTVIEW_ID_COLUMNWIDTHS = 0
118        };
119       
120        BEGIN_MSG_MAP_EX(thisClass)
121                MSG_WM_DESTROY(OnDestroy)
122
123                COMMAND_RANGE_HANDLER_EX(ID_HAL_FILE_PRIORITY_0, ID_HAL_FILE_PRIORITY_7, OnMenuPriority)
124
125                REFLECTED_NOTIFY_CODE_HANDLER(LVN_GETDISPINFO, OnGetDispInfo)
126                REFLECTED_NOTIFY_CODE_HANDLER(SLVN_SORTCHANGED, OnSortChanged)
127
128                CHAIN_MSG_MAP(listClass)
129                DEFAULT_REFLECTION_HANDLER()
130        END_MSG_MAP()
131
132        FileListView(do_ui_update_fn uiu);
133       
134        void saveSettings()
135        {
136                GetListViewDetails();
137                save_to_ini();
138        }
139       
140        HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
141                DWORD dwStyle = 0, DWORD dwExStyle = 0,
142                ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL);
143       
144        void OnDestroy()
145        {
146                saveSettings();
147        }
148       
149        void OnMenuPriority(UINT, int, HWND);
150       
151        friend class boost::serialization::access;
152        template<class Archive>
153        void serialize(Archive& ar, const unsigned int version)
154        {
155                ar & boost::serialization::make_nvp("listview", 
156                        boost::serialization::base_object<listClass>(*this));
157        }
158
159       
160        void setFocused(const hal::torrent_details_ptr& f) { focused_ = f; }
161        const hal::torrent_details_ptr focused() { return focused_; }
162
163        scoped_files files() { return scoped_files(listClass::mutex_, &files_); }
164
165protected:     
166        LRESULT OnGetDispInfo(int, LPNMHDR pnmh, BOOL&);
167        LRESULT OnSortChanged(int, LPNMHDR pnmh, BOOL&);
168
169private:
170        //mutable hal::mutex_t mutex_;
171
172        do_ui_update_fn do_ui_update_;
173        hal::file_details_vec files_;
174        hal::torrent_details_ptr focused_;
175};
176
177class FileTreeView :
178        public ATL::CWindowImpl<FileTreeView, WTL::CTreeViewCtrlEx>,
179        public hal::IniBase<FileTreeView>,
180        private boost::noncopyable
181{
182protected:
183        typedef FileTreeView thisClass;
184        typedef ATL::CWindowImpl<thisClass, WTL::CTreeViewCtrlEx> treeClass;
185        typedef hal::IniBase<thisClass> iniClass;
186       
187        typedef boost::function<void ()> do_ui_update_fn;
188
189        friend class treeClass;
190       
191public: 
192        FileTreeView(do_ui_update_fn uiu) :
193                iniClass("treeviews/advFiles", "FileTreeView"),
194                update_lock_(0),
195                do_ui_update_(uiu)
196        {}
197       
198        BEGIN_MSG_MAP_EX(thisClass)
199                MSG_WM_DESTROY(OnDestroy)
200
201                REFLECTED_NOTIFY_CODE_HANDLER(NM_RCLICK, OnRClick)
202                REFLECTED_NOTIFY_CODE_HANDLER(TVN_SELCHANGED, OnSelChanged)
203               
204                COMMAND_RANGE_HANDLER_EX(ID_HAL_FILE_PRIORITY_0, ID_HAL_FILE_PRIORITY_7, OnMenuPriority)
205                DEFAULT_REFLECTION_HANDLER()
206        END_MSG_MAP()
207       
208        HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
209                DWORD dwStyle = 0, DWORD dwExStyle = 0,
210                ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL);
211       
212        LRESULT OnRClick(int i, LPNMHDR pnmh, BOOL&);
213        void OnMenuPriority(UINT, int, HWND);
214       
215        wpath focused() { return focused_; }
216               
217        void determineFocused();
218       
219protected:
220        void OnDestroy()
221        {
222        //      saveSettings();
223        }
224       
225        LRESULT OnSelChanged(int, LPNMHDR pnmh, BOOL&);
226       
227        mutable int update_lock_;
228        mutable hal::mutex_t mutex_;
229
230        friend class hal::mutex_update_lock<thisClass>; 
231        friend class hal::try_update_lock<thisClass>;           
232       
233        wpath focused_;
234
235private:
236        do_ui_update_fn do_ui_update_;
237        WTL::CMenu menu_;
238};
239
240template<typename T>
241class TreeViewManager
242{
243public:
244        TreeViewManager(T& t) :
245                tree_(t)
246        {}
247       
248        struct ValidTreeItem
249        {
250                ValidTreeItem() 
251                {}
252
253                ValidTreeItem(WTL::CTreeItem& t) :
254                        valid(true),
255                        treeItem(t)
256                {}
257               
258                bool valid;
259                WTL::CTreeItem treeItem;
260        };
261       
262        typedef std::map<wpath, ValidTreeItem> MapType;
263       
264        void EnsureValid(wpath p)
265        {               
266                wpath branchPath = p;
267               
268                MapType::iterator i = map_.find(branchPath);           
269                if (i == map_.end())
270                {
271                        WTL::CTreeItem ti = tree_.GetRootItem();
272                       
273                        wpath branch;
274                        foreach (wstring b, branchPath)
275                        {
276                                branch /= b;                           
277                                MapType::iterator j = map_.find(branch);
278                               
279                                if (j == map_.end())
280                                {
281                                        WTL::CTreeItem tmp = ti.AddTail(b.c_str(), -1);
282                                        ti.Expand();
283                                        ti = tmp;
284                                        map_[branch] = ValidTreeItem(ti);
285                                }
286                                else
287                                {
288                                        (*j).second.valid = true;
289                                        ti = (*j).second.treeItem;
290                                }                               
291                        }
292                }
293                else
294                {
295                        if (!(*i).second.valid)
296                        {
297                                (*i).second.valid = true;
298                                EnsureValid(branchPath.parent_path());
299                        }
300                }
301        }
302       
303        void InvalidateAll()
304        {
305                for(MapType::iterator i=map_.begin(), e=map_.end(); i!=e; ++i)
306                {
307                        (*i).second.valid = false;
308                }
309        }
310       
311        void ClearInvalid()
312        {
313                for(MapType::iterator i=map_.begin(), e=map_.end(); i!=e; /**/)
314                {
315                        if ((*i).second.valid)
316                        {
317                                ++i;
318                        }
319                        else
320                        {
321                                (*i).second.treeItem.Delete();
322                                map_.erase(i++);
323                        }
324                }       
325        }
326       
327private:
328        T& tree_;
329        MapType map_;
330};
331
332class FileStatic :
333        public ATL::CWindowImpl<FileStatic, WTL::CStatic>
334{       
335public:
336        BEGIN_MSG_MAP_EX(FileStatic)
337                REFLECT_NOTIFICATIONS()
338        END_MSG_MAP()
339};
340
341class AdvFilesDialog :
342        public CHalTabPageImpl<AdvFilesDialog>,
343        public WTL::CDialogResize<AdvFilesDialog>,
344        public CHaliteDialogBase<AdvFilesDialog>,
345        public WTLx::WinDataExchangeEx<AdvFilesDialog>,
346        public hal::IniBase<AdvFilesDialog>,
347        private boost::noncopyable
348{
349protected:
350        typedef AdvFilesDialog thisClass;
351        typedef CHalTabPageImpl<thisClass> baseClass;
352        typedef WTL::CDialogResize<thisClass> resizeClass;
353        typedef CHaliteDialogBase<thisClass> dialogBaseClass;
354        typedef hal::IniBase<thisClass> iniClass;
355
356public:
357        enum { IDD = HAL_ADVFILES };
358
359        AdvFilesDialog(HaliteWindow& halWindow);
360       
361        ~AdvFilesDialog() {}
362       
363        BOOL PreTranslateMessage(MSG* pMsg)
364        {
365                return this->IsDialogMessage(pMsg);
366        }
367
368        BEGIN_MSG_MAP_EX(thisClass)
369                MSG_WM_INITDIALOG(onInitDialog)
370                MSG_WM_CLOSE(onClose)
371                MSG_WM_DESTROY(OnDestroy)
372               
373                if (uMsg == WM_FORWARDMSG)
374                        if (PreTranslateMessage((LPMSG)lParam)) return TRUE;
375               
376                CHAIN_MSG_MAP(dialogBaseClass)
377                CHAIN_MSG_MAP(resizeClass)
378                CHAIN_MSG_MAP(baseClass)
379                REFLECT_NOTIFICATIONS()
380        END_MSG_MAP()
381
382        BEGIN_DLGRESIZE_MAP(thisClass)
383                DLGRESIZE_CONTROL(HAL_CONTAINER, DLSZ_SIZE_X|DLSZ_SIZE_Y|DLSZ_REPAINT)
384        END_DLGRESIZE_MAP()
385
386    friend class boost::serialization::access;
387    template<class Archive>
388    void serialize(Archive& ar, const unsigned int version)
389        {
390                ar & BOOST_SERIALIZATION_NVP(splitterPos);
391        }
392
393        LRESULT onInitDialog(HWND, LPARAM);
394        void onClose();
395        LRESULT OnGetDispInfo(int, LPNMHDR pnmh, BOOL&);
396       
397        void DlgResize_UpdateLayout(int cxWidth, int cyHeight);
398        void doUiUpdate();
399        void uiUpdate(const hal::torrent_details_manager& tD);
400        void focusChanged(const hal::torrent_details_ptr pT);
401        void OnDestroy();
402
403protected:
404        WTL::CSplitterWindow splitter_;
405        unsigned int splitterPos;
406       
407        FileStatic static_;
408        FileTreeView tree_;
409        FileListView list_;
410       
411        std::map<wpath, WTL::CTreeItem> fileTreeMap_;
412        TreeViewManager<FileTreeView> treeManager_;
413       
414        std::vector<FileLink> fileLinks_;
415       
416        hal::file_details_vec file_details_;
417        std::pair<std::vector<FileLink>::iterator, std::vector<FileLink>::iterator> range_;
418};
Note: See TracBrowser for help on using the repository browser.