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

Revision 665, 9.9 KB checked in by Eoin, 11 years ago (diff)

Files ui update calls 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 "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(do_ui_update_fn uiu) :
19        iniClass("listviews/advFiles", "FileListView"),
20        do_ui_update_(uiu)
21{}
22
23HWND FileListView::Create(HWND hWndParent, ATL::_U_RECT rect, LPCTSTR szWindowName,
24        DWORD dwStyle, DWORD dwExStyle,
25        ATL::_U_MENUorID MenuOrID, LPVOID lpCreateParam)
26{
27        HWND hwnd = listClass::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle|LVS_OWNERDATA, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
28        assert(hwnd);
29       
30        WTL::CMenuHandle menu;
31        BOOL menu_created = menu.LoadMenu(LISTVIEW_ID_MENU);
32        InitialSetup(menu);     
33
34        std::vector<wstring> names;     
35        wstring column_names = hal::app().res_wstr(LISTVIEW_ID_COLUMNNAMES);
36
37        boost::split(names, column_names, boost::is_any_of(L";"));
38       
39        array<int, 5> widths = {100,70,70,70,70};
40        array<int, 5> order = {0,1,2,3,4};
41        array<bool, 5> visible = {true,true,true,true,true};
42
43        for (int i=0, e=5; i < e; ++i)
44        {
45                AddColumn(names[i].c_str(), i, visible[i], widths[i]);
46        }       
47       
48        for (unsigned i=0, e = hal::file_details::priority_e-hal::file_details::filename_e; i <= e; ++i)
49                SetColumnSortType(i, i + (WTL::LVCOLSORT_LAST+1+hal::file_details::filename_e), NULL);
50
51        load_from_ini();
52
53        return hwnd;
54}
55
56void FileListView::OnMenuPriority(UINT uCode, int nCtrlID, HWND hwndCtrl)
57{       
58        hal::mutex_t::scoped_lock l(mutex_);
59
60        std::vector<int> indices;
61       
62        foreach(const list_value_type val, std::make_pair(is_selected_begin(), is_selected_end()))
63        {
64                HAL_DEV_MSG(hal::wform(L"OnMenuPriority() = %1%, %2%, %3%") 
65                                % std::wstring(winstl::c_str_ptr(val)) % val.index() % files_[val.index()].order());
66                indices.push_back(files_[val.index()].order());
67        }
68       
69        int priority = nCtrlID-ID_HAL_FILE_PRIORITY_0; 
70
71        if (hal::bit::torrent t = hal::bittorrent().get(hal::bittorrent().torrentDetails().focusedTorrent()))
72                t.file_priorities = std::pair<std::vector<int>, int>(indices, priority);
73
74        do_ui_update_();
75}
76
77LRESULT FileListView::OnGetDispInfo(int, LPNMHDR pnmh, BOOL&)
78{       
79        hal::mutex_t::scoped_lock l(mutex_);
80
81        NMLVDISPINFO* pdi = (NMLVDISPINFO*)pnmh;
82
83        if (pdi->item.iItem < files_.size())
84        {
85                if (pdi->item.mask & LVIF_TEXT)
86                {
87                        wstring str = files_[pdi->item.iItem].to_wstring(pdi->item.iSubItem);
88                       
89                        int len = str.copy(pdi->item.pszText, min(pdi->item.cchTextMax - 1, str.size()));
90                        pdi->item.pszText[len] = '\0';
91                }       
92               
93                if (pdi->item.mask & LVIF_PARAM)
94                {                       
95                        HAL_DEV_MSG(hal::wform(L"LVIF_PARAM() = %1%, %2%") 
96                                % pdi->item.iItem % files_[pdi->item.iItem].order());
97
98                        pdi->item.lParam = files_[pdi->item.iItem].order();
99                }
100        }
101       
102        return 0;
103}
104
105LRESULT FileListView::OnSortChanged(int, LPNMHDR pnmh, BOOL&)
106{
107        do_ui_update_();
108       
109        return 0;
110}
111
112HWND FileTreeView::Create(HWND hWndParent, ATL::_U_RECT rect, LPCTSTR szWindowName, DWORD dwStyle, DWORD dwExStyle,
113        ATL::_U_MENUorID MenuOrID, LPVOID lpCreateParam)
114{
115        HWND hwnd = treeClass::Create(hWndParent, (RECT &)rect.m_lpRect, szWindowName, dwStyle, dwExStyle, (UINT)MenuOrID.m_hMenu, lpCreateParam);
116        assert(hwnd);
117       
118        WTL::CMenuHandle menu;
119        BOOL menu_created = menu.LoadMenu(HAL_FILESLISTVIEW_MENU);
120        assert(menu_created);   
121       
122        menu_.Attach(menu.GetSubMenu(0));
123       
124        return hwnd;
125}
126
127LRESULT FileTreeView::OnRClick(int i, LPNMHDR pnmh, BOOL&)
128{
129        determineFocused();
130        LPNMITEMACTIVATE pia = (LPNMITEMACTIVATE)pnmh;
131       
132        if (menu_)
133        {
134                assert(menu_.IsMenu());
135
136                WTL::CPoint cur_pt;
137                GetCursorPos(&cur_pt);
138
139                WTL::CPoint pt = cur_pt;                       
140                ScreenToClient(&pt);
141
142                WTL::CTreeItem ti = HitTest(pt, 0);
143
144                menu_.TrackPopupMenu(0, pt.x, pt.y, m_hWnd);
145        }
146
147        return 0;
148}
149
150void FileTreeView::OnMenuPriority(UINT uCode, int nCtrlID, HWND hwndCtrl)
151{       
152        hal::file_details_vec file_details;
153       
154        if (hal::torrent_details_ptr torrent = hal::bittorrent().torrentDetails().focusedTorrent())
155        {
156                std::copy(torrent->get_file_details().begin(), torrent->get_file_details().end(), 
157                        std::back_inserter(file_details));
158        }
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        std::vector<int> indices;
177       
178        for (hal::file_details_vec::iterator i=file_details.begin(), e=file_details.end();
179                i != e; ++i)
180        {                       
181                if (std::equal(branch.begin(), branch.end(), (*i).branch.begin()))
182                {
183                        indices.push_back((*i).order());
184                }
185        }
186       
187        int priority = nCtrlID-ID_HAL_FILE_PRIORITY_0;
188       
189        if (hal::bit::torrent t = hal::bittorrent().get(hal::bittorrent().torrentDetails().focusedTorrent()))
190                t.file_priorities = std::pair<std::vector<int>, int>(indices, priority);
191       
192        hal::try_update_lock<thisClass> lock(*this);
193        if (lock) do_ui_update_();
194}
195
196void FileTreeView::determineFocused()
197{
198        wpath branch;
199       
200        if (WTL::CTreeItem ti = GetSelectedItem())
201        {                       
202                do
203                {
204                        if (!ti.GetParent()) break;
205                       
206                        boost::array<wchar_t, MAX_PATH> buffer;
207                        ti.GetText(buffer.elems, MAX_PATH);
208                       
209                        branch = wstring(buffer.elems)/branch;
210                } 
211                while (ti = ti.GetParent());
212        }
213       
214        focused_ = branch;
215}
216
217LRESULT FileTreeView::OnSelChanged(int, LPNMHDR pnmh, BOOL&)
218{       
219        hal::try_update_lock<thisClass> lock(*this);
220        if (lock)
221        {               
222                determineFocused();
223                do_ui_update_();
224        }       
225        return 0;
226}
227
228AdvFilesDialog::AdvFilesDialog(HaliteWindow& halWindow) :
229        dialogBaseClass(halWindow),
230        treeManager_(tree_),
231        iniClass("AdvFilesDlg", "settings"),
232        splitterPos(150),
233        tree_(boost::bind(&AdvFilesDialog::doUiUpdate, this)),
234        list_(boost::bind(&AdvFilesDialog::doUiUpdate, this))
235{
236        load_from_ini();
237}
238
239LRESULT AdvFilesDialog::onInitDialog(HWND, LPARAM)
240{
241        resizeClass::DlgResize_Init(false, true, WS_CLIPCHILDREN);
242       
243        WTL::CRect rc; GetClientRect(&rc);
244       
245        static_.SubclassWindow(GetDlgItem(HAL_CONTAINER));
246       
247        splitter_.Create(GetDlgItem(HAL_CONTAINER), rc, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
248        splitter_.SetSplitterExtendedStyle(!SPLIT_PROPORTIONAL, SPLIT_PROPORTIONAL);
249       
250        list_.Create(splitter_, rc, NULL, 
251                LVS_REPORT|WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|LVS_SHOWSELALWAYS,
252                WS_EX_STATICEDGE|LVS_EX_DOUBLEBUFFER);
253               
254        tree_.Create(splitter_, rc, NULL, 
255                WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|TVS_HASBUTTONS|
256                        TVS_HASLINES|TVS_TRACKSELECT|TVS_SHOWSELALWAYS,
257                TVS_EX_DOUBLEBUFFER|WS_EX_STATICEDGE);
258               
259        splitter_.SetSplitterPanes(tree_, list_);
260        splitter_.SetSplitterPos(splitterPos);
261       
262        WTL::CTreeItem ti = tree_.InsertItem(hal::app().res_wstr(HAL_TORRENT_ROOT).c_str(), TVI_ROOT, TVI_LAST);
263               
264        return 0;
265}
266
267void AdvFilesDialog::DlgResize_UpdateLayout(int cxWidth, int cyHeight)
268{
269        resizeClass::DlgResize_UpdateLayout(cxWidth, cyHeight);
270       
271        WTL::CRect rect; ::GetClientRect(GetDlgItem(HAL_CONTAINER), &rect);
272       
273        splitter_.SetWindowPos(NULL, rect.left, rect.top,
274                rect.right - rect.left, rect.bottom - rect.top,
275                SWP_NOZORDER | SWP_NOACTIVATE);
276}
277
278void AdvFilesDialog::doUiUpdate()
279{
280        tree_.determineFocused();
281       
282        range_ = std::equal_range(fileLinks_.begin(), fileLinks_.end(),
283                FileLink(tree_.focused()));
284       
285        std::sort(range_.first, range_.second, &FileLinkNamesLess);
286
287        if (focusedTorrent())
288        {
289                hal::file_details_vec all_files = focusedTorrent()->get_file_details(); 
290                FileListView::scoped_files list_files = list_.files();
291
292                list_files->clear();
293
294                for (std::vector<FileLink>::iterator i=range_.first, e=range_.second;
295                        i != e; ++i)
296                {               
297                        list_files->push_back(all_files[(*i).order()]);
298                }
299                       
300                list_.SetItemCountEx(list_files->size(),LVSICF_NOSCROLL);
301        }
302
303        requestUiUpdate();
304}
305
306void AdvFilesDialog::uiUpdate(const hal::torrent_details_manager& tD)
307{
308        list_.setFocused(focusedTorrent());
309       
310        if (fileLinks_.empty() || !(focusedTorrent() && !focusedTorrent()->get_file_details().empty())) 
311        {
312                list_.DeleteAllItems();
313                return;
314        }
315       
316        hal::try_update_lock<FileListView::listClass> lock(list_);
317        if (lock) 
318        {
319                hal::file_details_vec all_files = focusedTorrent()->get_file_details(); 
320                FileListView::scoped_files list_files = list_.files();
321
322                foreach (hal::file_details& file, *list_files)
323                {
324                        file = all_files[file.order()];
325                }
326
327                if (list_.AutoSort() || list_.IsSortOnce())
328                {
329                        int col_sort_index = list_.GetSortColumn();
330
331                        if (col_sort_index != -1)
332                        {               
333                                int index = list_.GetColumnSortType(col_sort_index);
334               
335                                if (index > WTL::LVCOLSORT_LAST)
336                                {
337                                        hal::file_details_sort(*list_files, index - (WTL::LVCOLSORT_LAST+1+hal::file_details::filename_e), 
338                                                list_.IsSortDescending());
339                                }
340                        }
341                }
342        }
343
344        list_.InvalidateRect(NULL,true);
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.