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

Revision 495, 9.1 KB checked in by Eoin, 12 years ago (diff)

Changes seem ok.

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