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

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

Switched trunk to hal::wform.

Line 
1
2//         Copyright Eóin O'Callaghan 2006 - 2007.
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#include "stdAfx.hpp"
8
9#include <algorithm>
10
11#include "../HaliteWindow.hpp"
12#include "../HaliteListViewCtrl.hpp"
13
14#include "Files.hpp"
15
16#define TVS_EX_DOUBLEBUFFER 0x0004
17
18FileListView::FileListView() :
19        iniClass("listviews/advFiles", "FileListView")
20{}
21
22HWND FileListView::Create(HWND hWndParent, ATL::_U_RECT rect, LPCTSTR szWindowName,
23        DWORD dwStyle, DWORD dwExStyle,
24        ATL::_U_MENUorID MenuOrID, LPVOID lpCreateParam)
25{
26        HWND hwnd = listClass::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
27        assert(hwnd);
28       
29        WTL::CMenuHandle menu;
30        BOOL menu_created = menu.LoadMenu(LISTVIEW_ID_MENU);
31        InitialSetup(menu);     
32
33        std::vector<wstring> names;     
34        wstring column_names = hal::app().res_wstr(LISTVIEW_ID_COLUMNNAMES);
35
36        boost::split(names, column_names, boost::is_any_of(L";"));
37       
38        array<int, 5> widths = {100,70,70,70,70};
39        array<int, 5> order = {0,1,2,3,4};
40        array<bool, 5> visible = {true,true,true,true,true};
41
42        for (int i=0, e=5; i < e; ++i)
43        {
44                AddColumn(names[i].c_str(), i, visible[i], widths[i]);
45        }       
46
47        load_from_ini();
48       
49        SetColumnSortType(2, WTL::LVCOLSORT_CUSTOM, new ColumnAdapters::Size());
50        SetColumnSortType(3, WTL::LVCOLSORT_CUSTOM, new ColumnAdapters::Progress());
51        SetColumnSortType(4, WTL::LVCOLSORT_CUSTOM, new ColumnAdapters::Priority());
52       
53        return hwnd;
54}
55
56void FileListView::OnMenuPriority(UINT uCode, int nCtrlID, HWND hwndCtrl)
57{       
58        std::vector<int> indices;
59       
60        for (int i=0, e=GetItemCount(); i<e; ++i)
61        {
62                UINT flags = GetItemState(i, LVIS_SELECTED);
63               
64                if (flags & LVIS_SELECTED)
65                        indices.push_back(GetItemData(i));
66        }
67       
68        int priority = nCtrlID-ID_HAL_FILE_PRIORITY_0; 
69
70        if (hal::bit::torrent t = hal::bittorrent().get(hal::bittorrent().torrentDetails().focusedTorrent()))
71                t.file_priorities = std::pair<std::vector<int>, int>(indices, priority);
72}
73
74HWND FileTreeView::Create(HWND hWndParent, ATL::_U_RECT rect, LPCTSTR szWindowName, DWORD dwStyle, DWORD dwExStyle,
75        ATL::_U_MENUorID MenuOrID, LPVOID lpCreateParam)
76{
77        HWND hwnd = treeClass::Create(hWndParent, (RECT &)rect.m_lpRect, szWindowName, dwStyle, dwExStyle, (UINT)MenuOrID.m_hMenu, lpCreateParam);
78        assert(hwnd);
79       
80        WTL::CMenuHandle menu;
81        BOOL menu_created = menu.LoadMenu(HAL_FILESLISTVIEW_MENU);
82        assert(menu_created);   
83       
84        menu_.Attach(menu.GetSubMenu(0));
85       
86        return hwnd;
87}
88
89LRESULT FileTreeView::OnRClick(int i, LPNMHDR pnmh, BOOL&)
90{
91        determineFocused();
92        LPNMITEMACTIVATE pia = (LPNMITEMACTIVATE)pnmh;
93       
94        if (menu_)
95        {
96                assert (menu_.IsMenu());
97
98                POINT ptPoint;
99                GetCursorPos(&ptPoint);
100                menu_.TrackPopupMenu(0, ptPoint.x, ptPoint.y, m_hWnd);
101        }
102
103        return 0;
104}
105
106void FileTreeView::OnMenuPriority(UINT uCode, int nCtrlID, HWND hwndCtrl)
107{       
108        hal::FileDetails fileDetails;
109       
110        if (hal::torrent_details_ptr torrent = hal::bittorrent().torrentDetails().focusedTorrent())
111        {
112                std::copy(torrent->fileDetails().begin(), torrent->fileDetails().end(), 
113                        std::back_inserter(fileDetails));
114        }
115
116        wpath branch;
117       
118        if (WTL::CTreeItem ti = GetSelectedItem())
119        {                       
120                do
121                {
122                        if (!ti.GetParent()) break;
123                       
124                        boost::array<wchar_t, MAX_PATH> buffer;
125                        ti.GetText(buffer.elems, MAX_PATH);
126                       
127                        branch = wstring(buffer.elems)/branch;
128                } 
129                while (ti = ti.GetParent());
130        }
131
132        std::vector<int> indices;
133       
134        for (hal::FileDetails::iterator i=fileDetails.begin(), e=fileDetails.end();
135                i != e; ++i)
136        {                       
137                if (std::equal(branch.begin(), branch.end(), (*i).branch.begin()))
138                {
139                        indices.push_back((*i).order());
140                }
141        }
142       
143        int priority = nCtrlID-ID_HAL_FILE_PRIORITY_0;
144       
145        if (hal::bit::torrent t = hal::bittorrent().get(hal::bittorrent().torrentDetails().focusedTorrent()))
146                t.file_priorities = std::pair<std::vector<int>, int>(indices, priority);
147       
148        hal::try_update_lock<thisClass> lock(*this);
149        if (lock) signal();
150}
151
152void FileTreeView::determineFocused()
153{
154        wpath branch;
155       
156        if (WTL::CTreeItem ti = GetSelectedItem())
157        {                       
158                do
159                {
160                        if (!ti.GetParent()) break;
161                       
162                        boost::array<wchar_t, MAX_PATH> buffer;
163                        ti.GetText(buffer.elems, MAX_PATH);
164                       
165                        branch = wstring(buffer.elems)/branch;
166                } 
167                while (ti = ti.GetParent());
168        }
169       
170        focused_ = branch;
171}
172
173LRESULT FileTreeView::OnSelChanged(int, LPNMHDR pnmh, BOOL&)
174{       
175        hal::try_update_lock<thisClass> lock(*this);
176        if (lock)
177        {               
178                determineFocused();
179                signal();
180        }
181       
182        return 0;
183}
184
185LRESULT AdvFilesDialog::onInitDialog(HWND, LPARAM)
186{
187        resizeClass::DlgResize_Init(false, true, WS_CLIPCHILDREN);
188       
189        WTL::CRect rc; GetClientRect(&rc);
190       
191        static_.SubclassWindow(GetDlgItem(HAL_CONTAINER));
192       
193        splitter_.Create(GetDlgItem(HAL_CONTAINER), rc, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
194        splitter_.SetSplitterExtendedStyle(!SPLIT_PROPORTIONAL, SPLIT_PROPORTIONAL);
195       
196        list_.Create(splitter_, rc, NULL, 
197                LVS_REPORT|WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|LVS_SHOWSELALWAYS,
198                WS_EX_STATICEDGE|LVS_EX_DOUBLEBUFFER);
199               
200        tree_.Create(splitter_, rc, NULL, 
201                WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|TVS_HASBUTTONS|
202                        TVS_HASLINES|TVS_TRACKSELECT|TVS_SHOWSELALWAYS,
203                TVS_EX_DOUBLEBUFFER|WS_EX_STATICEDGE);
204       
205        tree_.attach(bind(&AdvFilesDialog::doUiUpdate, this));
206       
207        splitter_.SetSplitterPanes(tree_, list_);
208        splitter_.SetSplitterPos(splitterPos);
209       
210        WTL::CTreeItem ti = tree_.InsertItem(hal::app().res_wstr(HAL_TORRENT_ROOT).c_str(), TVI_ROOT, TVI_LAST);
211       
212//      DoDataExchange(false);
213       
214        return 0;
215}
216
217void AdvFilesDialog::DlgResize_UpdateLayout(int cxWidth, int cyHeight)
218{
219        resizeClass::DlgResize_UpdateLayout(cxWidth, cyHeight);
220       
221        WTL::CRect rect; ::GetClientRect(GetDlgItem(HAL_CONTAINER), &rect);
222       
223        splitter_.SetWindowPos(NULL, rect.left, rect.top,
224                rect.right - rect.left, rect.bottom - rect.top,
225                SWP_NOZORDER | SWP_NOACTIVATE);
226}
227
228void AdvFilesDialog::doUiUpdate()
229{
230//      hal::event_log.post(shared_ptr<hal::EventDetail>(new hal::EventDebug(hal::event_logger::info, (hal::wform(L"doUiUpdate %1%") % current_torrent_name_).str().c_str())));
231
232        tree_.determineFocused();
233       
234        range_ = std::equal_range(fileLinks_.begin(), fileLinks_.end(),
235                FileLink(tree_.focused()));
236       
237        std::sort(range_.first, range_.second, &FileLinkNamesLess);
238       
239        requestUiUpdate();
240}
241
242void AdvFilesDialog::uiUpdate(const hal::torrent_details_manager& tD)
243{
244        list_.setFocused(focusedTorrent());
245       
246        if (fileLinks_.empty() || !(focusedTorrent() && !focusedTorrent()->fileDetails().empty())) 
247        {
248                list_.DeleteAllItems();
249                return;
250        }
251       
252        hal::try_update_lock<FileListView::listClass> lock(list_);
253        if (lock) 
254        {                       
255                // Wipe details not present
256                for(int i = 0; i < list_.GetItemCount(); /*nothing here*/)
257                {
258                        boost::array<wchar_t, MAX_PATH> fullPath;
259                        list_.GetItemText(i, 0, fullPath.c_array(), MAX_PATH);
260                       
261                        FileLink file(wstring(fullPath.c_array()));
262                        std::vector<FileLink>::iterator iter = 
263                                std::lower_bound(range_.first, range_.second, file, &FileLinkNamesLess);
264                       
265                        if (iter == range_.second || !(FileLinkNamesEqual((*iter), file)))
266                        {
267                                list_.DeleteItem(i);
268                        }
269                        else
270                        {
271                                list_.SetItemData(i, std::distance(range_.first, iter));
272                                ++i;
273                        }
274                }
275               
276                // Add additional details
277                for (std::vector<FileLink>::iterator i=range_.first, e=range_.second;
278                        i != e; ++i)
279                {
280                        hal::FileDetail fileD = focusedTorrent()->fileDetails()[(*i).order()];
281                       
282                        LV_FINDINFO findInfo; 
283                        findInfo.flags = LVFI_STRING;
284                        findInfo.psz = const_cast<LPTSTR>((*i).filename.c_str());
285                       
286                        int itemPos = list_.FindItem(&findInfo, -1);
287                        if (itemPos < 0)
288                                itemPos = list_.AddItem(list_.GetItemCount(), 0, (*i).filename.c_str(), 0);
289                       
290                        list_.SetItemData(itemPos, (*i).order());
291                       
292                        list_.SetItemText(itemPos, 1, (*i).branch.string().c_str());                   
293                        list_.SetItemText(itemPos, 2, list_.getColumnAdapter(2)->print(fileD).c_str());
294                        list_.SetItemText(itemPos, 3, list_.getColumnAdapter(3)->print(fileD).c_str());
295                        list_.SetItemText(itemPos, 4, list_.getColumnAdapter(4)->print(fileD).c_str());                 
296                }
297
298                list_.ConditionallyDoAutoSort();
299        }
300}
301
302void AdvFilesDialog::focusChanged(const hal::torrent_details_ptr pT)
303{
304        fileLinks_.clear();
305        if (pT)
306        {
307                std::copy(pT->fileDetails().begin(), pT->fileDetails().end(), 
308                        std::back_inserter(fileLinks_));
309        }
310       
311        list_.setFocused(pT);
312       
313        std::sort(fileLinks_.begin(), fileLinks_.end());
314       
315        {       hal::mutex_update_lock<FileTreeView> lock(tree_);
316       
317                treeManager_.InvalidateAll();
318               
319                foreach (FileLink file, fileLinks_)
320                {
321                        treeManager_.EnsureValid(file.branch);
322                }
323               
324                treeManager_.ClearInvalid();
325        }
326       
327        tree_.determineFocused();
328       
329        range_ = std::equal_range(fileLinks_.begin(), fileLinks_.end(),
330                FileLink(tree_.focused()));
331       
332        std::sort(range_.first, range_.second, &FileLinkNamesLess);
333       
334        splitterPos = splitter_.GetSplitterPos();
335}
336
337void AdvFilesDialog::onClose()
338{       
339        if(::IsWindow(m_hWnd)) 
340        {
341                ::DestroyWindow(m_hWnd);
342        }
343}
344
345void AdvFilesDialog::OnDestroy()
346{               
347        save_to_ini(); 
348}
Note: See TracBrowser for help on using the repository browser.