source: trunk/src/HaliteListView.cpp @ 737

Revision 737, 12.0 KB checked in by Eoin, 11 years ago (diff)
Line 
1
2//         Copyright Eóin O'Callaghan 2006 - 2009.
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 <boost/iterator/filter_iterator.hpp>
10#include <winstl/controls/listview_sequence.hpp>
11
12#include "Halite.hpp"
13
14#include "halTorrent.hpp"
15
16#include "HaliteListView.hpp"
17#include "HaliteWindow.hpp"
18#include "HaliteListViewDlg.hpp"
19
20#define HAL_CUSTOMDRAW_TITLEDATA 1000000000
21
22HaliteListViewCtrl::HaliteListViewCtrl(HaliteWindow& HalWindow) :
23        halite_window_(HalWindow),
24        iniClass("listviews/halite", "HaliteListView"),
25        queue_view_(false)
26{               
27        HalWindow.connectUiUpdate(bind(&HaliteListViewCtrl::uiUpdate, this, _1));
28}
29
30void HaliteListViewCtrl::OnShowWindow(UINT, INT)
31{
32        WTL::CMenuHandle menu;
33        BOOL menu_created = menu.LoadMenu(HAL_LISTVIEW_MENU);
34        InitialSetup(menu);     
35
36        std::vector<wstring> names;     
37        wstring column_names = hal::app().res_wstr(LISTVIEW_ID_COLUMNNAMES);
38       
39        boost::split(names, column_names, boost::is_any_of(L";"));
40       
41        array<int, NumberOfColumns_s> widths = {100,110,60,60,60,42,45,61,45,45,45,45,45,45,45,45,45,45,45,45,45,30,45};
42        array<bool, NumberOfColumns_s> visible = {true,true,true,true,true,true,true,true,true,true,true,\
43                true,true,true,true,true,true,true,true,true,true,true,true};
44
45        for (int i=0, e=NumberOfColumns_s; i < e; ++i)
46        {
47                AddColumn(names[i].c_str(), i, visible[i], widths[i]);
48        }       
49
50        SafeLoadFromIni();
51
52        for (unsigned i=0, e = hal::torrent_details::queue_position_e-hal::torrent_details::name_e; i <= e; ++i)
53                SetColumnSortType(i, i + (WTL::LVCOLSORT_LAST+1+hal::torrent_details::name_e));
54       
55        queue_view_mode();
56}
57
58void HaliteListViewCtrl::OnDestroy()
59{
60        SaveSettings();
61}
62
63void HaliteListViewCtrl::SaveSettings()
64{
65        GetListViewDetails();
66        save_to_ini();
67}
68
69DWORD HaliteListViewCtrl::OnPrePaint(int idCtrl, LPNMCUSTOMDRAW lpNMCD)
70{
71        return CDRF_NOTIFYITEMDRAW;
72}
73
74DWORD HaliteListViewCtrl::OnItemPrePaint(int idCtrl, LPNMCUSTOMDRAW lpNMCD)
75{
76        NMLVCUSTOMDRAW* pnmlv = (NMLVCUSTOMDRAW*) lpNMCD;
77
78        if (HAL_CUSTOMDRAW_TITLEDATA == pnmlv->nmcd.lItemlParam)
79        {
80                pnmlv->clrText = RGB(50,50,200);
81        }
82
83        return CDRF_DODEFAULT;
84}
85
86bool HaliteListViewCtrl::sort_list_comparison(std::wstring l, std::wstring r, size_t index, bool ascending)
87{
88        return hal::hal_details_ptr_compare(
89                hal::bittorrent().torrentDetails().get(l), hal::bittorrent().torrentDetails().get(r), index, ascending);
90}
91
92LRESULT HaliteListViewCtrl::OnGetDispInfo(int, LPNMHDR pnmh, BOOL&)
93{       
94        hal::try_update_lock<listClass> lock(*this);
95        if (lock) 
96        {       
97
98        NMLVDISPINFO* pdi = (NMLVDISPINFO*)pnmh;
99        hal::torrent_details_ptr td = hal::bittorrent().torrentDetails().get(key_from_index(pdi->item.iItem));
100
101        if (td && pdi->item.mask & LVIF_TEXT)
102        {
103                wstring str = td->to_wstring(pdi->item.iSubItem);
104               
105                size_t len = str.copy(pdi->item.pszText, min(pdi->item.cchTextMax - 1, static_cast<int>(str.size())));
106                pdi->item.pszText[len] = '\0';
107        }
108
109        }
110       
111        return 0;
112}
113
114void HaliteListViewCtrl::uiUpdate(const hal::torrent_details_manager& tD)
115{
116        hal::try_update_lock<listClass> lock(*this);
117        if (lock) 
118        {               
119
120        selection_from_listview();
121               
122        std::set<std::wstring> torrent_set;
123        for (size_t td_index=0, e=tD.torrents().size(); td_index<e; ++td_index)
124        {
125                hal::torrent_details_ptr td = tD.torrents()[td_index];
126                torrent_set.insert(td->name());
127        }
128       
129        erase_based_on_set(torrent_set, true); 
130
131        if (IsSortOnce() || AutoSort())
132        {
133                if (GetSecondarySortColumn() != -1)
134                {
135                        int index = GetColumnSortType(GetSecondarySortColumn());                                       
136                        if (index > WTL::LVCOLSORT_LAST)
137                                sort(index - (WTL::LVCOLSORT_LAST+1+hal::torrent_details::name_e), IsSecondarySortDescending());
138                }
139
140                if (GetSortColumn() != -1)
141                {               
142                        int index = GetColumnSortType(GetSortColumn());                         
143                        if (index > WTL::LVCOLSORT_LAST)
144                                sort(index - (WTL::LVCOLSORT_LAST+1+hal::torrent_details::name_e), IsSortDescending());
145                }
146        }
147       
148        if (queue_view_)
149                sort(hal::torrent_details::managed_e, false);
150
151        set_keys(torrent_set); 
152        InvalidateRect(NULL,true);
153
154        }
155}
156
157LRESULT HaliteListViewCtrl::OnSortChanged(int, LPNMHDR pnmh, BOOL&)
158{
159        halite_window_.issueUiUpdate();
160       
161        return 0;
162}
163
164LRESULT HaliteListViewCtrl::OnResume(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
165{
166        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
167        {
168                hal::bittorrent().resume_torrent(val.text().c_str());
169        }
170       
171        return 0;
172}
173
174LRESULT HaliteListViewCtrl::OnPause(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
175{       
176        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
177        {
178                hal::bittorrent().pause_torrent(val.text().c_str());
179        }
180       
181        return 0;
182}
183
184LRESULT HaliteListViewCtrl::OnStop(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
185{
186        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
187        {
188                hal::bittorrent().stop_torrent(val.text().c_str());
189        }
190
191        return 0;
192}
193
194LRESULT HaliteListViewCtrl::OnRemoveFocused(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
195{
196        hal::bittorrent().remove_torrent(hal::to_utf8(is_selected_begin()->text().c_str()));
197        erase_from_list(*is_selected_begin());
198
199        return 0;
200}
201
202LRESULT HaliteListViewCtrl::OnRemove(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
203{
204        std::set<wstring>  torrent_names;
205
206        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
207                torrent_names.insert(hal::to_wstr_shim(val));
208       
209        erase_based_on_set(torrent_names, false);
210
211        foreach(wstring name, torrent_names)
212                hal::bittorrent().remove_torrent(name);
213
214        return 0;
215}
216
217LRESULT HaliteListViewCtrl::OnRecheck(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
218{
219        foreach(const list_value_type& v, std::make_pair(is_selected_begin(), is_selected_end()))
220        {
221                hal::bittorrent().recheck_torrent(v.text().c_str());
222        }
223
224        return 0;
225}
226
227LRESULT HaliteListViewCtrl::OnRemoveWipeFiles(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
228{
229        std::set<wstring>  torrent_names;
230
231        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
232                torrent_names.insert(hal::to_wstr_shim(val));
233       
234        erase_based_on_set(torrent_names, false);
235
236        foreach(wstring name, torrent_names)
237                hal::bittorrent().remove_torrent_wipe_files(name);
238
239        return 0;
240}
241
242LRESULT HaliteListViewCtrl::OnDownloadFolder(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
243{
244        HAL_DEV_MSG(L"OnDownloadFolder");
245
246        std::set<wpath> uniquePaths;
247
248        foreach(const list_value_type& v, std::make_pair(is_selected_begin(), is_selected_end()))
249        {
250                wpath saveDir = hal::bittorrent().get(v).save_directory;               
251                HAL_DEV_MSG(hal::wform(L"Name %1%, Save dir: %2%.") % v.text() % saveDir);
252
253                uniquePaths.insert(saveDir);
254        }
255
256        SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) };
257
258        for(std::set<wpath>::const_iterator i=uniquePaths.begin(), e=uniquePaths.end();
259                i != e; ++i)
260        {       
261                wstring p = (*i).file_string();
262
263                HAL_DEV_MSG(hal::wform(L"Unique Save dir: %1%.") % p);
264
265                sei.lpDirectory = p.c_str();
266                sei.lpFile = p.c_str();
267                sei.lpVerb = L"open";
268                sei.nShow = true;
269
270                if (!::ShellExecuteEx(&sei))
271                        HAL_DEV_MSG(L"Fail");
272                else
273                        HAL_DEV_MSG(L"Success");
274        }       
275
276        return 0;
277}
278
279LRESULT HaliteListViewCtrl::OnEditFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
280{
281        HAL_DEV_MSG(L"OnEditFolders");
282
283        if (hal::bit::torrent t = hal::bittorrent().get(*is_selected_begin()))
284        {
285                wstring saveDirectory = static_cast<wpath>(t.save_directory).native_file_string();
286                wstring moveToDirectory = static_cast<wpath>(t.move_to_directory).native_file_string();
287
288                bool useMoveTo = (L"" != moveToDirectory);
289                bool disableSaveDir = !t.in_session;
290
291                HaliteListViewAdjustDlg addTorrent(hal::app().res_wstr(HAL_ADDT_TITLE), saveDirectory, moveToDirectory, 
292                        useMoveTo, disableSaveDir);     
293               
294                if (IDOK == addTorrent.DoModal())
295                {
296                        if (!disableSaveDir) t.save_directory = saveDirectory;
297
298                        if (useMoveTo)
299                                t.move_to_directory = moveToDirectory;
300                        else
301                                t.move_to_directory = L"";
302                }
303        }
304
305        return 0;
306}
307
308LRESULT HaliteListViewCtrl::OnSetManaged(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
309{
310/*      hal::try_update_lock<listClass> lock(*this);
311        if (lock)
312        {               
313*/
314        std::set<wstring>  torrent_names;
315
316        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
317                torrent_names.insert(hal::to_wstr_shim(val));
318       
319//      erase_based_on_set(torrent_names, false);
320
321        foreach(wstring name, torrent_names)
322                hal::bittorrent().get(name).managed = true;
323//      }
324
325        halite_window_.issueUiUpdate();
326
327        return 0;
328}
329
330LRESULT HaliteListViewCtrl::OnSetUnmanaged(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
331{
332/*      hal::try_update_lock<listClass> lock(*this);
333        if (lock)
334        {               
335*/
336        std::set<wstring>  torrent_names;
337
338        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
339                torrent_names.insert(hal::to_wstr_shim(val));
340       
341//      erase_based_on_set(torrent_names, false);
342
343        foreach(wstring name, torrent_names)
344                hal::bittorrent().get(name).managed = false;
345//      }
346
347        halite_window_.issueUiUpdate();
348
349        return 0;
350}
351
352LRESULT HaliteListViewCtrl::OnAdjustQueuePosition(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
353{
354        foreach(const list_value_type v, std::make_pair(is_selected_begin(), is_selected_end()))
355        {
356                hal::bit::torrent t = hal::bittorrent().get(v);
357
358                switch (wID)
359                {
360                case HAL_QUEUE_MOVE_TOP:
361                        t.adjust_queue_position(hal::bit::move_to_top);
362                        break;
363                case HAL_QUEUE_MOVE_UP:
364                        t.adjust_queue_position(hal::bit::move_up);             
365                        break;
366                case HAL_QUEUE_MOVE_DOWN:
367                        t.adjust_queue_position(hal::bit::move_down);           
368                        break;
369                case HAL_QUEUE_MOVE_BOTTOM:
370                        t.adjust_queue_position(hal::bit::move_to_bottom);             
371                        break;
372                };
373        }
374
375        halite_window_.issueUiUpdate();
376       
377        return 0;
378}
379
380LRESULT HaliteListViewCtrl::OnQueueView(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
381{
382//      queue_view_ ^= true;
383        queue_view_ = false;
384
385        queue_view_mode();
386       
387        return 0;
388}
389
390void HaliteListViewCtrl::erase_torrent_name(wstring name)
391{
392        erase_from_list(name);
393}
394
395void HaliteListViewCtrl::queue_view_mode()
396{
397        erase_all_from_list();
398
399        if (queue_view_)
400        {
401                int ret = EnableGroupView(true);
402                if (IsGroupViewEnabled())
403                {
404                        LVGROUP lvg = { sizeof(LVGROUP) };
405
406                        lvg.mask = LVGF_HEADER|LVGF_GROUPID ;
407                        wstring unmanaged = hal::app().res_wstr(HAL_UNMANAGED);
408                        lvg.pszHeader = (LPWSTR)unmanaged.c_str();
409                        lvg.iGroupId = HAL_UNMANAGED;
410
411                        int grp = InsertGroup(-1, &lvg);
412
413                        lvg.mask = LVGF_HEADER|LVGF_GROUPID ;
414                        wstring managed_seed = hal::app().res_wstr(HAL_MANAGED_SEEDING);
415                        lvg.pszHeader = (LPWSTR)managed_seed.c_str();
416                        lvg.iGroupId = HAL_MANAGED_SEEDING;
417
418                        grp = InsertGroup(-1, &lvg);
419
420                        lvg.mask = LVGF_HEADER|LVGF_GROUPID ;
421                        wstring managed_down = hal::app().res_wstr(HAL_MANAGED_DOWNLOADING);
422                        lvg.pszHeader = (LPWSTR)managed_down.c_str();
423                        lvg.iGroupId = HAL_MANAGED_DOWNLOADING;
424
425                        grp = InsertGroup(-1, &lvg);
426
427                        lvg.mask = LVGF_HEADER|LVGF_GROUPID ;
428                        wstring auto_managed = hal::app().res_wstr(HAL_AUTO_MANAGED);
429                        lvg.pszHeader = (LPWSTR)auto_managed.c_str();
430                        lvg.iGroupId = HAL_AUTO_MANAGED;
431
432                        grp = InsertGroup(-1, &lvg);
433                }
434        }
435        else
436        {
437                RemoveAllGroups();
438                int ret = EnableGroupView(false);
439        }
440        halite_window_.issueUiUpdate();
441
442        MENUITEMINFO minfo = {sizeof(MENUITEMINFO)};
443       
444        minfo.fMask = MIIM_STATE;
445        minfo.fState = queue_view_ ? MFS_CHECKED : MFS_UNCHECKED;
446       
447        menu_.SetMenuItemInfo(HAL_LVM_QUEUE_VIEW, false, &minfo);
448}
449
450//LRESULT HaliteListViewCtrl::OnDeleteItem(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
451//{
452//      LPNMLISTVIEW pnmv=(LPNMLISTVIEW)pnmh;
453//      T* pItem=(T*)GetItemData(pnmv->iItem);
454//      ATLASSERT(pItem);
455//      if (pItem)      // Delete attached structure
456//              delete pItem;
457//      return 0;
458//}
Note: See TracBrowser for help on using the repository browser.