source: src/advtabs/Files.cpp @ 331

Revision 331, 9.0 KB checked in by Eoin, 12 years ago (diff)

File list is now accessible again for stopped torrents. File list update bug fixed.

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