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

Revision 661, 10.4 KB checked in by Eoin, 11 years ago (diff)

File list working but very slow.

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                hal::file_details_vec all_files = focusedTorrent()->get_file_details();
262                hal::file_details_vec files;
263                for (std::vector<FileLink>::iterator i=range_.first, e=range_.second;
264                        i != e; ++i)
265                {               
266                        files.push_back(all_files[(*i).order()]);
267                }
268
269                // Wipe details not present
270                for(int i = 0; i < list_.GetItemCount(); /*nothing here*/)
271                {
272                        boost::array<wchar_t, MAX_PATH> fullPath;
273                        list_.GetItemText(i, 0, fullPath.c_array(), MAX_PATH);
274                       
275                        FileLink file(wstring(fullPath.c_array()));
276                        std::vector<FileLink>::iterator iter = 
277                                std::lower_bound(range_.first, range_.second, file, &FileLinkNamesLess);
278                       
279                        if (iter == range_.second || !(FileLinkNamesEqual((*iter), file)))
280                        {
281                                list_.DeleteItem(i);
282                        }
283                        else
284                        {
285                                list_.SetItemData(i, std::distance(range_.first, iter));
286                                ++i;
287                        }
288                }
289
290                int col_sort_index = list_.GetSortColumn();
291                if (col_sort_index != -1)
292                {               
293                        int index = list_.GetColumnSortType(col_sort_index);
294                       
295                        HAL_DEV_MSG(hal::wform(L"col_sort_index() = %1%, index() = %2%") 
296                                % col_sort_index % index);
297
298                        if (index > WTL::LVCOLSORT_LAST)
299                                hal::file_details_sort(files, index - (WTL::LVCOLSORT_LAST+1+hal::file_details::branch_e), 
300                                        list_.IsSortDescending());
301                }
302
303                bool sort_once = list_.IsSortOnce();
304
305                if (list_.GetItemCount() < files.size())
306                {
307                // Add additional details
308                for (size_t index = 0, e = files.size(); index < e; ++index)
309                {
310                        hal::file_details& fd = files[index];
311                       
312                        int item_pos = index;
313               
314                        HAL_DEV_SORT_MSG(hal::wform(L"AutoSort() = %1%, SortOnce() = %2%, !AutoSort() && !SortOnce() = %3%") 
315                                % AutoSort() % sort_once % (!AutoSort() && !sort_once));
316
317                        if (!list_.AutoSort() && !sort_once)
318                        {
319                                LV_FINDINFO findInfo; 
320                                findInfo.flags = LVFI_STRING;
321                                findInfo.psz = const_cast<LPTSTR>(fd.to_wstring(hal::file_details::filename_e).c_str());
322                               
323                                item_pos = list_.FindItem(&findInfo, -1);
324                        }
325
326                        if (item_pos == -1 || item_pos > list_.GetItemCount())
327                                item_pos = list_.AddItem(list_.GetItemCount(), 0, fd.to_wstring(hal::file_details::filename_e).c_str(), 0);
328                       
329                        list_.SetItemData(item_pos, fd.order());
330                       
331                        list_.SetItemText(item_pos, 0, fd.filename.c_str());           
332                        for (size_t i = hal::file_details::filename_e; i <= hal::file_details::priority_e; ++i)
333                        {
334                                list_.SetItemText(item_pos, i, fd.to_wstring(i).c_str());
335                        }       
336                }
337                }
338
339                if (list_.AutoSort() && col_sort_index >= 0 && col_sort_index < list_.m_arrColSortType.GetSize())
340                {
341                        if (list_.GetColumnSortType(col_sort_index) <= WTL::LVCOLSORT_CUSTOM)
342                                list_.DoSortItems(col_sort_index, list_.IsSortDescending());
343                }
344        }
345}
346
347void AdvFilesDialog::focusChanged(const hal::torrent_details_ptr pT)
348{
349        fileLinks_.clear();
350        if (pT)
351        {
352                std::copy(pT->get_file_details().begin(), pT->get_file_details().end(), 
353                        std::back_inserter(fileLinks_));
354        }
355       
356        list_.setFocused(pT);
357       
358        std::sort(fileLinks_.begin(), fileLinks_.end());
359       
360        {       hal::mutex_update_lock<FileTreeView> lock(tree_);
361       
362                treeManager_.InvalidateAll();
363               
364                foreach (FileLink file, fileLinks_)
365                {
366                        treeManager_.EnsureValid(file.branch);
367                }
368               
369                treeManager_.ClearInvalid();
370        }
371       
372        tree_.determineFocused();
373       
374        range_ = std::equal_range(fileLinks_.begin(), fileLinks_.end(),
375                FileLink(tree_.focused()));
376       
377        std::sort(range_.first, range_.second, &FileLinkNamesLess);
378       
379        splitterPos = splitter_.GetSplitterPos();
380}
381
382void AdvFilesDialog::onClose()
383{       
384        if(::IsWindow(m_hWnd)) 
385        {
386                ::DestroyWindow(m_hWnd);
387        }
388}
389
390void AdvFilesDialog::OnDestroy()
391{               
392        save_to_ini(); 
393}
Note: See TracBrowser for help on using the repository browser.