source: trunk/src/HaliteListView.cpp @ 658

Revision 658, 12.6 KB checked in by Eoin, 11 years ago (diff)

All sorting playing nice. Now gotta expand code to other listviews.

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