source: trunk/src/HaliteListView.cpp @ 778

Revision 778, 12.9 KB checked in by Eoin, 10 years ago (diff)

Made get torrent details non-blocking. Need to do same for get session details.

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::Instance().torrentDetails().get(l), hal::bittorrent::Instance().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::Instance().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        foreach (hal::torrent_details_ptr t,  tD.torrents())
124        {
125                torrent_set.insert(t->name());
126        }
127       
128        erase_based_on_set(torrent_set, true); 
129
130        if (IsSortOnce() || AutoSort())
131        {
132                if (GetSecondarySortColumn() != -1)
133                {
134                        int index = GetColumnSortType(GetSecondarySortColumn());                                       
135                        if (index > WTL::LVCOLSORT_LAST)
136                                sort(index - (WTL::LVCOLSORT_LAST+1+hal::torrent_details::name_e), IsSecondarySortDescending());
137                }
138
139                if (GetSortColumn() != -1)
140                {               
141                        int index = GetColumnSortType(GetSortColumn());                         
142                        if (index > WTL::LVCOLSORT_LAST)
143                                sort(index - (WTL::LVCOLSORT_LAST+1+hal::torrent_details::name_e), IsSortDescending());
144                }
145        }
146       
147        if (queue_view_)
148                sort(hal::torrent_details::managed_e, false);
149
150        set_keys(torrent_set); 
151        InvalidateRect(NULL,true);
152
153        }
154}
155
156LRESULT HaliteListViewCtrl::OnSortChanged(int, LPNMHDR pnmh, BOOL&)
157{
158        halite_window_.issueUiUpdate();
159       
160        return 0;
161}
162
163LRESULT HaliteListViewCtrl::OnResume(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
164{
165        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
166        {
167                hal::bittorrent::Instance().resume_torrent(val.text().c_str());
168        }
169       
170        return 0;
171}
172
173LRESULT HaliteListViewCtrl::OnPause(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
174{       
175        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
176        {
177                hal::bittorrent::Instance().pause_torrent(val.text().c_str());
178        }
179       
180        return 0;
181}
182
183LRESULT HaliteListViewCtrl::OnStop(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
184{
185        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
186        {
187                hal::bittorrent::Instance().stop_torrent(val.text().c_str());
188        }
189
190        return 0;
191}
192
193LRESULT HaliteListViewCtrl::OnRemoveFocused(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
194{
195        hal::bittorrent::Instance().remove_torrent(hal::to_utf8(is_selected_begin()->text().c_str()));
196        erase_from_list(*is_selected_begin());
197
198        return 0;
199}
200
201LRESULT HaliteListViewCtrl::OnRemove(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
202{
203        std::set<wstring>  torrent_names;
204
205        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
206                torrent_names.insert(hal::to_wstr_shim(val));
207       
208        erase_based_on_set(torrent_names, false);
209
210        foreach(wstring name, torrent_names)
211                hal::bittorrent::Instance().remove_torrent(name);
212
213        return 0;
214}
215
216LRESULT HaliteListViewCtrl::OnRecheck(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
217{
218        foreach(const list_value_type& v, std::make_pair(is_selected_begin(), is_selected_end()))
219        {
220                hal::bittorrent::Instance().recheck_torrent(v.text().c_str());
221        }
222
223        return 0;
224}
225
226void HaliteListViewCtrl::remove_to_bin(hal::fs::wpath root, boost::shared_ptr<hal::file_details_vec> files)
227{
228        std::vector<wchar_t> file_names_buffer;
229
230        foreach(hal::file_details file, *files)
231        {
232                std::wstring file_location = (hal::wform(L"File %1%\\%2%\\%3%") 
233                        % root.file_string() % file.branch % file.filename).str();
234
235                wstring full_file = hal::fs::wpath(root / file.branch / file.filename).file_string();
236                 
237                HAL_DEV_MSG(hal::wform(L"File %1%") % full_file);
238
239                std::copy(full_file.begin(), full_file.end(), 
240                        std::back_inserter(file_names_buffer));
241                file_names_buffer.push_back(L'\0');
242        }
243        file_names_buffer.push_back(L'\0');
244
245        SHFILEOPSTRUCT shf;
246
247        shf.hwnd = *this;
248        shf.wFunc = FO_DELETE;
249        shf.pFrom = &file_names_buffer[0];
250        shf.pTo = 0;
251        shf.fFlags = FOF_ALLOWUNDO;
252
253        SHFileOperation(&shf);
254}
255
256LRESULT HaliteListViewCtrl::OnRemoveWipeFiles(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
257{
258        std::set<wstring>  torrent_names;
259
260        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
261                torrent_names.insert(hal::to_wstr_shim(val));
262       
263        erase_based_on_set(torrent_names, false);
264
265        foreach(wstring name, torrent_names)
266                hal::bittorrent::Instance().remove_torrent_wipe_files(name, bind(&HaliteListViewCtrl::remove_to_bin, this, _1, _2));
267
268        return 0;
269}
270
271LRESULT HaliteListViewCtrl::OnDownloadFolder(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
272{
273        HAL_DEV_MSG(L"OnDownloadFolder");
274
275        std::set<wpath> uniquePaths;
276
277        foreach(const list_value_type& v, std::make_pair(is_selected_begin(), is_selected_end()))
278        {
279                wpath saveDir = hal::bittorrent::Instance().get(v).save_directory;             
280                HAL_DEV_MSG(hal::wform(L"Name %1%, Save dir: %2%.") % v.text() % saveDir);
281
282                uniquePaths.insert(saveDir);
283        }
284
285        SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) };
286
287        for(std::set<wpath>::const_iterator i=uniquePaths.begin(), e=uniquePaths.end();
288                i != e; ++i)
289        {       
290                wstring p = (*i).file_string();
291
292                HAL_DEV_MSG(hal::wform(L"Unique Save dir: %1%.") % p);
293
294                sei.lpDirectory = p.c_str();
295                sei.lpFile = p.c_str();
296                sei.lpVerb = L"open";
297                sei.nShow = true;
298
299                if (!::ShellExecuteEx(&sei))
300                        HAL_DEV_MSG(L"Fail");
301                else
302                        HAL_DEV_MSG(L"Success");
303        }       
304
305        return 0;
306}
307
308LRESULT HaliteListViewCtrl::OnEditFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
309{
310        HAL_DEV_MSG(L"OnEditFolders");
311
312        if (hal::bit::torrent t = hal::bittorrent::Instance().get(*is_selected_begin()))
313        {
314                wstring saveDirectory = static_cast<wpath>(t.save_directory).native_file_string();
315                wstring moveToDirectory = static_cast<wpath>(t.move_to_directory).native_file_string();
316
317                bool useMoveTo = (L"" != moveToDirectory);
318                bool disableSaveDir = !t.in_session;
319
320                HaliteListViewAdjustDlg addTorrent(hal::app().res_wstr(HAL_ADDT_TITLE), saveDirectory, moveToDirectory, 
321                        useMoveTo, disableSaveDir);     
322               
323                if (IDOK == addTorrent.DoModal())
324                {
325                        if (!disableSaveDir) t.save_directory = saveDirectory;
326
327                        if (useMoveTo)
328                                t.move_to_directory = moveToDirectory;
329                        else
330                                t.move_to_directory = L"";
331                }
332        }
333
334        return 0;
335}
336
337LRESULT HaliteListViewCtrl::OnSetManaged(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
338{
339/*      hal::try_update_lock<listClass> lock(*this);
340        if (lock)
341        {               
342*/
343        std::set<wstring>  torrent_names;
344
345        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
346                torrent_names.insert(hal::to_wstr_shim(val));
347       
348//      erase_based_on_set(torrent_names, false);
349
350        foreach(wstring name, torrent_names)
351                hal::bittorrent::Instance().get(name).managed = true;
352//      }
353
354        halite_window_.issueUiUpdate();
355
356        return 0;
357}
358
359LRESULT HaliteListViewCtrl::OnSetUnmanaged(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
360{
361/*      hal::try_update_lock<listClass> lock(*this);
362        if (lock)
363        {               
364*/
365        std::set<wstring>  torrent_names;
366
367        foreach(const list_value_type& val, std::make_pair(is_selected_begin(), is_selected_end()))
368                torrent_names.insert(hal::to_wstr_shim(val));
369       
370//      erase_based_on_set(torrent_names, false);
371
372        foreach(wstring name, torrent_names)
373                hal::bittorrent::Instance().get(name).managed = false;
374//      }
375
376        halite_window_.issueUiUpdate();
377
378        return 0;
379}
380
381LRESULT HaliteListViewCtrl::OnAdjustQueuePosition(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
382{
383        foreach(const list_value_type v, std::make_pair(is_selected_begin(), is_selected_end()))
384        {
385                hal::bit::torrent t = hal::bittorrent::Instance().get(v);
386
387                switch (wID)
388                {
389                case HAL_QUEUE_MOVE_TOP:
390                        t.adjust_queue_position(hal::bit::move_to_top);
391                        break;
392                case HAL_QUEUE_MOVE_UP:
393                        t.adjust_queue_position(hal::bit::move_up);             
394                        break;
395                case HAL_QUEUE_MOVE_DOWN:
396                        t.adjust_queue_position(hal::bit::move_down);           
397                        break;
398                case HAL_QUEUE_MOVE_BOTTOM:
399                        t.adjust_queue_position(hal::bit::move_to_bottom);             
400                        break;
401                };
402        }
403
404        halite_window_.issueUiUpdate();
405       
406        return 0;
407}
408
409LRESULT HaliteListViewCtrl::OnQueueView(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
410{
411//      queue_view_ ^= true;
412        queue_view_ = false;
413
414        queue_view_mode();
415       
416        return 0;
417}
418
419void HaliteListViewCtrl::erase_torrent_name(wstring name)
420{
421        erase_from_list(name);
422}
423
424void HaliteListViewCtrl::queue_view_mode()
425{
426        erase_all_from_list();
427
428        if (queue_view_)
429        {
430                int ret = EnableGroupView(true);
431                if (IsGroupViewEnabled())
432                {
433                        LVGROUP lvg = { sizeof(LVGROUP) };
434
435                        lvg.mask = LVGF_HEADER|LVGF_GROUPID ;
436                        wstring unmanaged = hal::app().res_wstr(HAL_UNMANAGED);
437                        lvg.pszHeader = (LPWSTR)unmanaged.c_str();
438                        lvg.iGroupId = HAL_UNMANAGED;
439
440                        int grp = InsertGroup(-1, &lvg);
441
442                        lvg.mask = LVGF_HEADER|LVGF_GROUPID ;
443                        wstring managed_seed = hal::app().res_wstr(HAL_MANAGED_SEEDING);
444                        lvg.pszHeader = (LPWSTR)managed_seed.c_str();
445                        lvg.iGroupId = HAL_MANAGED_SEEDING;
446
447                        grp = InsertGroup(-1, &lvg);
448
449                        lvg.mask = LVGF_HEADER|LVGF_GROUPID ;
450                        wstring managed_down = hal::app().res_wstr(HAL_MANAGED_DOWNLOADING);
451                        lvg.pszHeader = (LPWSTR)managed_down.c_str();
452                        lvg.iGroupId = HAL_MANAGED_DOWNLOADING;
453
454                        grp = InsertGroup(-1, &lvg);
455
456                        lvg.mask = LVGF_HEADER|LVGF_GROUPID ;
457                        wstring auto_managed = hal::app().res_wstr(HAL_AUTO_MANAGED);
458                        lvg.pszHeader = (LPWSTR)auto_managed.c_str();
459                        lvg.iGroupId = HAL_AUTO_MANAGED;
460
461                        grp = InsertGroup(-1, &lvg);
462                }
463        }
464        else
465        {
466                RemoveAllGroups();
467                int ret = EnableGroupView(false);
468        }
469        halite_window_.issueUiUpdate();
470
471        MENUITEMINFO minfo = {sizeof(MENUITEMINFO)};
472       
473        minfo.fMask = MIIM_STATE;
474        minfo.fState = queue_view_ ? MFS_CHECKED : MFS_UNCHECKED;
475       
476        menu_.SetMenuItemInfo(HAL_LVM_QUEUE_VIEW, false, &minfo);
477}
478
479//LRESULT HaliteListViewCtrl::OnDeleteItem(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
480//{
481//      LPNMLISTVIEW pnmv=(LPNMLISTVIEW)pnmh;
482//      T* pItem=(T*)GetItemData(pnmv->iItem);
483//      ATLASSERT(pItem);
484//      if (pItem)      // Delete attached structure
485//              delete pItem;
486//      return 0;
487//}
Note: See TracBrowser for help on using the repository browser.