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

Revision 660, 9.3 KB checked in by Eoin, 11 years ago (diff)

FileDetail? struct converted to file_details along with other related naming changes.

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                WTL::CPoint cur_pt;
99                GetCursorPos(&cur_pt);
100
101                WTL::CPoint pt = cur_pt;                       
102                ScreenToClient(&pt);
103
104                WTL::CTreeItem ti = HitTest(pt, 0);
105
106                menu_.TrackPopupMenu(0, pt.x, pt.y, m_hWnd);
107        }
108
109        return 0;
110}
111
112void FileTreeView::OnMenuPriority(UINT uCode, int nCtrlID, HWND hwndCtrl)
113{       
114        hal::file_details_vec file_details;
115       
116        if (hal::torrent_details_ptr torrent = hal::bittorrent().torrentDetails().focusedTorrent())
117        {
118                std::copy(torrent->get_file_details().begin(), torrent->get_file_details().end(), 
119                        std::back_inserter(file_details));
120        }
121
122        wpath branch;
123       
124        if (WTL::CTreeItem ti = GetSelectedItem())
125        {                       
126                do
127                {
128                        if (!ti.GetParent()) break;
129                       
130                        boost::array<wchar_t, MAX_PATH> buffer;
131                        ti.GetText(buffer.elems, MAX_PATH);
132                       
133                        branch = wstring(buffer.elems)/branch;
134                } 
135                while (ti = ti.GetParent());
136        }
137
138        std::vector<int> indices;
139       
140        for (hal::file_details_vec::iterator i=file_details.begin(), e=file_details.end();
141                i != e; ++i)
142        {                       
143                if (std::equal(branch.begin(), branch.end(), (*i).branch.begin()))
144                {
145                        indices.push_back((*i).order());
146                }
147        }
148       
149        int priority = nCtrlID-ID_HAL_FILE_PRIORITY_0;
150       
151        if (hal::bit::torrent t = hal::bittorrent().get(hal::bittorrent().torrentDetails().focusedTorrent()))
152                t.file_priorities = std::pair<std::vector<int>, int>(indices, priority);
153       
154        hal::try_update_lock<thisClass> lock(*this);
155        if (lock) signal();
156}
157
158void FileTreeView::determineFocused()
159{
160        wpath branch;
161       
162        if (WTL::CTreeItem ti = GetSelectedItem())
163        {                       
164                do
165                {
166                        if (!ti.GetParent()) break;
167                       
168                        boost::array<wchar_t, MAX_PATH> buffer;
169                        ti.GetText(buffer.elems, MAX_PATH);
170                       
171                        branch = wstring(buffer.elems)/branch;
172                } 
173                while (ti = ti.GetParent());
174        }
175       
176        focused_ = branch;
177}
178
179LRESULT FileTreeView::OnSelChanged(int, LPNMHDR pnmh, BOOL&)
180{       
181        hal::try_update_lock<thisClass> lock(*this);
182        if (lock)
183        {               
184                determineFocused();
185                signal();
186        }
187       
188        return 0;
189}
190
191LRESULT AdvFilesDialog::onInitDialog(HWND, LPARAM)
192{
193        resizeClass::DlgResize_Init(false, true, WS_CLIPCHILDREN);
194       
195        WTL::CRect rc; GetClientRect(&rc);
196       
197        static_.SubclassWindow(GetDlgItem(HAL_CONTAINER));
198       
199        splitter_.Create(GetDlgItem(HAL_CONTAINER), rc, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
200        splitter_.SetSplitterExtendedStyle(!SPLIT_PROPORTIONAL, SPLIT_PROPORTIONAL);
201       
202        list_.Create(splitter_, rc, NULL, 
203                LVS_REPORT|WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|LVS_SHOWSELALWAYS,
204                WS_EX_STATICEDGE|LVS_EX_DOUBLEBUFFER);
205               
206        tree_.Create(splitter_, rc, NULL, 
207                WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|TVS_HASBUTTONS|
208                        TVS_HASLINES|TVS_TRACKSELECT|TVS_SHOWSELALWAYS,
209                TVS_EX_DOUBLEBUFFER|WS_EX_STATICEDGE);
210       
211        tree_.attach(bind(&AdvFilesDialog::doUiUpdate, this));
212       
213        splitter_.SetSplitterPanes(tree_, list_);
214        splitter_.SetSplitterPos(splitterPos);
215       
216        WTL::CTreeItem ti = tree_.InsertItem(hal::app().res_wstr(HAL_TORRENT_ROOT).c_str(), TVI_ROOT, TVI_LAST);
217       
218//      DoDataExchange(false);
219       
220        return 0;
221}
222
223void AdvFilesDialog::DlgResize_UpdateLayout(int cxWidth, int cyHeight)
224{
225        resizeClass::DlgResize_UpdateLayout(cxWidth, cyHeight);
226       
227        WTL::CRect rect; ::GetClientRect(GetDlgItem(HAL_CONTAINER), &rect);
228       
229        splitter_.SetWindowPos(NULL, rect.left, rect.top,
230                rect.right - rect.left, rect.bottom - rect.top,
231                SWP_NOZORDER | SWP_NOACTIVATE);
232}
233
234void AdvFilesDialog::doUiUpdate()
235{
236//      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())));
237
238        tree_.determineFocused();
239       
240        range_ = std::equal_range(fileLinks_.begin(), fileLinks_.end(),
241                FileLink(tree_.focused()));
242       
243        std::sort(range_.first, range_.second, &FileLinkNamesLess);
244       
245        requestUiUpdate();
246}
247
248void AdvFilesDialog::uiUpdate(const hal::torrent_details_manager& tD)
249{
250        list_.setFocused(focusedTorrent());
251       
252        if (fileLinks_.empty() || !(focusedTorrent() && !focusedTorrent()->get_file_details().empty())) 
253        {
254                list_.DeleteAllItems();
255                return;
256        }
257       
258        hal::try_update_lock<FileListView::listClass> lock(list_);
259        if (lock) 
260        {                       
261                // Wipe details not present
262                for(int i = 0; i < list_.GetItemCount(); /*nothing here*/)
263                {
264                        boost::array<wchar_t, MAX_PATH> fullPath;
265                        list_.GetItemText(i, 0, fullPath.c_array(), MAX_PATH);
266                       
267                        FileLink file(wstring(fullPath.c_array()));
268                        std::vector<FileLink>::iterator iter = 
269                                std::lower_bound(range_.first, range_.second, file, &FileLinkNamesLess);
270                       
271                        if (iter == range_.second || !(FileLinkNamesEqual((*iter), file)))
272                        {
273                                list_.DeleteItem(i);
274                        }
275                        else
276                        {
277                                list_.SetItemData(i, std::distance(range_.first, iter));
278                                ++i;
279                        }
280                }
281               
282                // Add additional details
283                for (std::vector<FileLink>::iterator i=range_.first, e=range_.second;
284                        i != e; ++i)
285                {
286                        hal::file_details fileD = focusedTorrent()->get_file_details()[(*i).order()];
287                       
288                        LV_FINDINFO findInfo; 
289                        findInfo.flags = LVFI_STRING;
290                        findInfo.psz = const_cast<LPTSTR>((*i).filename.c_str());
291                       
292                        int itemPos = list_.FindItem(&findInfo, -1);
293                        if (itemPos < 0)
294                                itemPos = list_.AddItem(list_.GetItemCount(), 0, (*i).filename.c_str(), 0);
295                       
296                        list_.SetItemData(itemPos, (*i).order());
297                       
298                        list_.SetItemText(itemPos, 1, (*i).branch.string().c_str());                   
299                        list_.SetItemText(itemPos, 2, list_.getColumnAdapter(2)->print(fileD).c_str());
300                        list_.SetItemText(itemPos, 3, list_.getColumnAdapter(3)->print(fileD).c_str());
301                        list_.SetItemText(itemPos, 4, list_.getColumnAdapter(4)->print(fileD).c_str());                 
302                }
303
304//              list_.ConditionallyDoAutoSort();
305        }
306}
307
308void AdvFilesDialog::focusChanged(const hal::torrent_details_ptr pT)
309{
310        fileLinks_.clear();
311        if (pT)
312        {
313                std::copy(pT->get_file_details().begin(), pT->get_file_details().end(), 
314                        std::back_inserter(fileLinks_));
315        }
316       
317        list_.setFocused(pT);
318       
319        std::sort(fileLinks_.begin(), fileLinks_.end());
320       
321        {       hal::mutex_update_lock<FileTreeView> lock(tree_);
322       
323                treeManager_.InvalidateAll();
324               
325                foreach (FileLink file, fileLinks_)
326                {
327                        treeManager_.EnsureValid(file.branch);
328                }
329               
330                treeManager_.ClearInvalid();
331        }
332       
333        tree_.determineFocused();
334       
335        range_ = std::equal_range(fileLinks_.begin(), fileLinks_.end(),
336                FileLink(tree_.focused()));
337       
338        std::sort(range_.first, range_.second, &FileLinkNamesLess);
339       
340        splitterPos = splitter_.GetSplitterPos();
341}
342
343void AdvFilesDialog::onClose()
344{       
345        if(::IsWindow(m_hWnd)) 
346        {
347                ::DestroyWindow(m_hWnd);
348        }
349}
350
351void AdvFilesDialog::OnDestroy()
352{               
353        save_to_ini(); 
354}
Note: See TracBrowser for help on using the repository browser.