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

Revision 662, 11.6 KB checked in by Eoin, 11 years ago (diff)

Virtual FileListView? working but not redrawing correctly.

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|LVS_OWNERDATA, 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
74LRESULT FileListView::OnGetDispInfo(int, LPNMHDR pnmh, BOOL&)
75{       
76        hal::mutex_t::scoped_lock l(mutex_);
77
78        NMLVDISPINFO* pdi = (NMLVDISPINFO*)pnmh;
79
80        HAL_DEV_MSG(hal::wform(L"OnGetDispInfo() LV Item = %1%, Subitem = %2%") 
81                % pdi->item.iItem % pdi->item.iSubItem);
82
83        if (pdi->item.mask & LVIF_TEXT && pdi->item.iItem < files_.size())
84        {
85                wstring str = files_[pdi->item.iItem].to_wstring(pdi->item.iSubItem);
86               
87                int len = str.copy(pdi->item.pszText, min(pdi->item.cchTextMax - 1, str.size()));
88                pdi->item.pszText[len] = '\0';
89
90                HAL_DEV_MSG(hal::wform(L"OnGetDispInfo() LV String = %1%, length = %2%, max = %3%, len = %4%") 
91                        % str % str.size() % pdi->item.cchTextMax % len);
92        }       
93       
94        return 0;
95}
96
97LRESULT AdvFilesDialog::OnGetDispInfo(int, LPNMHDR pnmh, BOOL&)
98{       
99        NMLVDISPINFO* pdi = (NMLVDISPINFO*)pnmh;
100
101        HAL_DEV_MSG(hal::wform(L"OnGetDispInfo() Dlg Item = %1%, Subitem = %2%") 
102                % pdi->item.iItem % pdi->item.iSubItem);
103       
104        return 0;
105}
106
107HWND FileTreeView::Create(HWND hWndParent, ATL::_U_RECT rect, LPCTSTR szWindowName, DWORD dwStyle, DWORD dwExStyle,
108        ATL::_U_MENUorID MenuOrID, LPVOID lpCreateParam)
109{
110        HWND hwnd = treeClass::Create(hWndParent, (RECT &)rect.m_lpRect, szWindowName, dwStyle, dwExStyle, (UINT)MenuOrID.m_hMenu, lpCreateParam);
111        assert(hwnd);
112       
113        WTL::CMenuHandle menu;
114        BOOL menu_created = menu.LoadMenu(HAL_FILESLISTVIEW_MENU);
115        assert(menu_created);   
116       
117        menu_.Attach(menu.GetSubMenu(0));
118       
119        return hwnd;
120}
121
122LRESULT FileTreeView::OnRClick(int i, LPNMHDR pnmh, BOOL&)
123{
124        determineFocused();
125        LPNMITEMACTIVATE pia = (LPNMITEMACTIVATE)pnmh;
126       
127        if (menu_)
128        {
129                assert(menu_.IsMenu());
130
131                WTL::CPoint cur_pt;
132                GetCursorPos(&cur_pt);
133
134                WTL::CPoint pt = cur_pt;                       
135                ScreenToClient(&pt);
136
137                WTL::CTreeItem ti = HitTest(pt, 0);
138
139                menu_.TrackPopupMenu(0, pt.x, pt.y, m_hWnd);
140        }
141
142        return 0;
143}
144
145void FileTreeView::OnMenuPriority(UINT uCode, int nCtrlID, HWND hwndCtrl)
146{       
147        hal::file_details_vec file_details;
148       
149        if (hal::torrent_details_ptr torrent = hal::bittorrent().torrentDetails().focusedTorrent())
150        {
151                std::copy(torrent->get_file_details().begin(), torrent->get_file_details().end(), 
152                        std::back_inserter(file_details));
153        }
154
155        wpath branch;
156       
157        if (WTL::CTreeItem ti = GetSelectedItem())
158        {                       
159                do
160                {
161                        if (!ti.GetParent()) break;
162                       
163                        boost::array<wchar_t, MAX_PATH> buffer;
164                        ti.GetText(buffer.elems, MAX_PATH);
165                       
166                        branch = wstring(buffer.elems)/branch;
167                } 
168                while (ti = ti.GetParent());
169        }
170
171        std::vector<int> indices;
172       
173        for (hal::file_details_vec::iterator i=file_details.begin(), e=file_details.end();
174                i != e; ++i)
175        {                       
176                if (std::equal(branch.begin(), branch.end(), (*i).branch.begin()))
177                {
178                        indices.push_back((*i).order());
179                }
180        }
181       
182        int priority = nCtrlID-ID_HAL_FILE_PRIORITY_0;
183       
184        if (hal::bit::torrent t = hal::bittorrent().get(hal::bittorrent().torrentDetails().focusedTorrent()))
185                t.file_priorities = std::pair<std::vector<int>, int>(indices, priority);
186       
187        hal::try_update_lock<thisClass> lock(*this);
188        if (lock) signal();
189}
190
191void FileTreeView::determineFocused()
192{
193        wpath branch;
194       
195        if (WTL::CTreeItem ti = GetSelectedItem())
196        {                       
197                do
198                {
199                        if (!ti.GetParent()) break;
200                       
201                        boost::array<wchar_t, MAX_PATH> buffer;
202                        ti.GetText(buffer.elems, MAX_PATH);
203                       
204                        branch = wstring(buffer.elems)/branch;
205                } 
206                while (ti = ti.GetParent());
207        }
208       
209        focused_ = branch;
210}
211
212LRESULT FileTreeView::OnSelChanged(int, LPNMHDR pnmh, BOOL&)
213{       
214        hal::try_update_lock<thisClass> lock(*this);
215        if (lock)
216        {               
217                determineFocused();
218                signal();
219        }
220       
221        return 0;
222}
223
224LRESULT AdvFilesDialog::onInitDialog(HWND, LPARAM)
225{
226        resizeClass::DlgResize_Init(false, true, WS_CLIPCHILDREN);
227       
228        WTL::CRect rc; GetClientRect(&rc);
229       
230        static_.SubclassWindow(GetDlgItem(HAL_CONTAINER));
231       
232        splitter_.Create(GetDlgItem(HAL_CONTAINER), rc, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
233        splitter_.SetSplitterExtendedStyle(!SPLIT_PROPORTIONAL, SPLIT_PROPORTIONAL);
234       
235        list_.Create(splitter_, rc, NULL, 
236                LVS_REPORT|WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|LVS_SHOWSELALWAYS,
237                WS_EX_STATICEDGE|LVS_EX_DOUBLEBUFFER);
238
239        list_.SetDlgCtrlID(31415);
240               
241        tree_.Create(splitter_, rc, NULL, 
242                WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|TVS_HASBUTTONS|
243                        TVS_HASLINES|TVS_TRACKSELECT|TVS_SHOWSELALWAYS,
244                TVS_EX_DOUBLEBUFFER|WS_EX_STATICEDGE);
245       
246        tree_.attach(bind(&AdvFilesDialog::doUiUpdate, this));
247       
248        splitter_.SetSplitterPanes(tree_, list_);
249        splitter_.SetSplitterPos(splitterPos);
250       
251        WTL::CTreeItem ti = tree_.InsertItem(hal::app().res_wstr(HAL_TORRENT_ROOT).c_str(), TVI_ROOT, TVI_LAST);
252       
253//      DoDataExchange(false);
254       
255        return 0;
256}
257
258void AdvFilesDialog::DlgResize_UpdateLayout(int cxWidth, int cyHeight)
259{
260        resizeClass::DlgResize_UpdateLayout(cxWidth, cyHeight);
261       
262        WTL::CRect rect; ::GetClientRect(GetDlgItem(HAL_CONTAINER), &rect);
263       
264        splitter_.SetWindowPos(NULL, rect.left, rect.top,
265                rect.right - rect.left, rect.bottom - rect.top,
266                SWP_NOZORDER | SWP_NOACTIVATE);
267}
268
269void AdvFilesDialog::doUiUpdate()
270{
271//      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())));
272
273        tree_.determineFocused();
274       
275        range_ = std::equal_range(fileLinks_.begin(), fileLinks_.end(),
276                FileLink(tree_.focused()));
277       
278        std::sort(range_.first, range_.second, &FileLinkNamesLess);
279       
280        requestUiUpdate();
281}
282
283void AdvFilesDialog::uiUpdate(const hal::torrent_details_manager& tD)
284{
285        list_.setFocused(focusedTorrent());
286       
287        if (fileLinks_.empty() || !(focusedTorrent() && !focusedTorrent()->get_file_details().empty())) 
288        {
289                list_.DeleteAllItems();
290                return;
291        }
292       
293        hal::try_update_lock<FileListView::listClass> lock(list_);
294        if (lock) 
295        {
296                hal::file_details_vec all_files = focusedTorrent()->get_file_details();
297
298                FileListView::scoped_files list_files = list_.files();
299                list_files->clear();
300
301                for (std::vector<FileLink>::iterator i=range_.first, e=range_.second;
302                        i != e; ++i)
303                {               
304                        list_files->push_back(all_files[(*i).order()]);
305                }
306
307                if (list_files->size() != list_.GetItemCount())
308                        list_.SetItemCount(list_files->size());
309
310                // Wipe details not present
311/*              for(int i = 0; i < list_.GetItemCount(); /*nothing here*//*)
312                {
313                        boost::array<wchar_t, MAX_PATH> fullPath;
314                        list_.GetItemText(i, 0, fullPath.c_array(), MAX_PATH);
315                       
316                        FileLink file(wstring(fullPath.c_array()));
317                        std::vector<FileLink>::iterator iter =
318                                std::lower_bound(range_.first, range_.second, file, &FileLinkNamesLess);
319                       
320                        if (iter == range_.second || !(FileLinkNamesEqual((*iter), file)))
321                        {
322                                list_.DeleteItem(i);
323                        }
324                        else
325                        {
326                                list_.SetItemData(i, std::distance(range_.first, iter));
327                                ++i;
328                        }
329                }
330
331                int col_sort_index = list_.GetSortColumn();
332                if (col_sort_index != -1)
333                {               
334                        int index = list_.GetColumnSortType(col_sort_index);
335                       
336                        HAL_DEV_MSG(hal::wform(L"col_sort_index() = %1%, index() = %2%")
337                                % col_sort_index % index);
338
339                        if (index > WTL::LVCOLSORT_LAST)
340                                hal::file_details_sort(files, index - (WTL::LVCOLSORT_LAST+1+hal::file_details::branch_e),
341                                        list_.IsSortDescending());
342                }
343
344                bool sort_once = list_.IsSortOnce();
345
346                if (list_.GetItemCount() < files.size())
347                {
348                // Add additional details
349                for (size_t index = 0, e = files.size(); index < e; ++index)
350                {
351                        hal::file_details& fd = files[index];
352                       
353                        int item_pos = index;
354               
355                        HAL_DEV_SORT_MSG(hal::wform(L"AutoSort() = %1%, SortOnce() = %2%, !AutoSort() && !SortOnce() = %3%")
356                                % AutoSort() % sort_once % (!AutoSort() && !sort_once));
357
358                        if (!list_.AutoSort() && !sort_once)
359                        {
360                                LV_FINDINFO findInfo;
361                                findInfo.flags = LVFI_STRING;
362                                findInfo.psz = const_cast<LPTSTR>(fd.to_wstring(hal::file_details::filename_e).c_str());
363                               
364                                item_pos = list_.FindItem(&findInfo, -1);
365                        }
366
367                        if (item_pos == -1 || item_pos > list_.GetItemCount())
368                                item_pos = list_.AddItem(list_.GetItemCount(), 0, fd.to_wstring(hal::file_details::filename_e).c_str(), 0);
369                       
370                        list_.SetItemData(item_pos, fd.order());
371                       
372                        list_.SetItemText(item_pos, 0, fd.filename.c_str());           
373                        for (size_t i = hal::file_details::filename_e; i <= hal::file_details::priority_e; ++i)
374                        {
375                                list_.SetItemText(item_pos, i, fd.to_wstring(i).c_str());
376                        }       
377                }
378                }
379
380                if (list_.AutoSort() && col_sort_index >= 0 && col_sort_index < list_.m_arrColSortType.GetSize())
381                {
382                        if (list_.GetColumnSortType(col_sort_index) <= WTL::LVCOLSORT_CUSTOM)
383                                list_.DoSortItems(col_sort_index, list_.IsSortDescending());
384                }
385                */
386        }
387
388        list_.InvalidateRect(NULL,true);
389}
390
391void AdvFilesDialog::focusChanged(const hal::torrent_details_ptr pT)
392{
393        fileLinks_.clear();
394        if (pT)
395        {
396                std::copy(pT->get_file_details().begin(), pT->get_file_details().end(), 
397                        std::back_inserter(fileLinks_));
398        }
399       
400        list_.setFocused(pT);
401       
402        std::sort(fileLinks_.begin(), fileLinks_.end());
403       
404        {       hal::mutex_update_lock<FileTreeView> lock(tree_);
405       
406                treeManager_.InvalidateAll();
407               
408                foreach (FileLink file, fileLinks_)
409                {
410                        treeManager_.EnsureValid(file.branch);
411                }
412               
413                treeManager_.ClearInvalid();
414        }
415       
416        tree_.determineFocused();
417       
418        range_ = std::equal_range(fileLinks_.begin(), fileLinks_.end(),
419                FileLink(tree_.focused()));
420       
421        std::sort(range_.first, range_.second, &FileLinkNamesLess);
422       
423        splitterPos = splitter_.GetSplitterPos();
424}
425
426void AdvFilesDialog::onClose()
427{       
428        if(::IsWindow(m_hWnd)) 
429        {
430                ::DestroyWindow(m_hWnd);
431        }
432}
433
434void AdvFilesDialog::OnDestroy()
435{               
436        save_to_ini(); 
437}
Note: See TracBrowser for help on using the repository browser.