source: trunk/src/HaliteWindow.cpp @ 739

Revision 739, 14.9 KB checked in by Eoin, 11 years ago (diff)

Cleaning up torrent removal code.

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#include "Halite.hpp"
9#include "HaliteWindow.hpp"
10
11#include "CSSFileDialog.hpp"
12#include "RadioPaneDlg.hpp"
13
14#include "HaliteDialog.hpp"
15#include "AdvHaliteDialog.hpp"
16#include "AddTorrentDialog.hpp"
17#include "NewTorrentDialog.hpp"
18#include "SplashDialog.hpp"
19
20#include "ConfigOptions.hpp"
21#include "halConfig.hpp"
22
23HaliteWindow::HaliteWindow(unsigned areYouMe = 0) :
24        iniClass("HaliteWindow", "HaliteWindow"),
25        haliteList(*this),
26        WM_AreYouMe_(areYouMe),
27        splitterPos(100),
28        use_tray(true),
29        advancedUI(false),
30        closeToTray(false),
31        confirmClose(true),
32        activeTab(0)
33{
34        rect.top = 10;
35        rect.left = 10;
36        rect.bottom = 430;
37        rect.right = 620;
38       
39        load_from_ini();
40}
41
42HaliteWindow::~HaliteWindow()
43{
44        save_to_ini();
45        ATLASSERT(!::IsWindow(m_hWnd));
46}
47
48BOOL HaliteWindow::PreTranslateMessage(MSG* pMsg)
49{
50        if(CFrameWindowImpl<thisClass>::PreTranslateMessage(pMsg))
51                return TRUE;
52
53        if (!advancedUI)
54                return mp_dlg->PreTranslateMessage(pMsg);
55        else
56                return mp_advDlg->PreTranslateMessage(pMsg);
57}
58
59LRESULT HaliteWindow::OnCreate(LPCREATESTRUCT lpcs)
60{
61        try
62        {
63        HAL_DEV_MSG(L"HaliteWindow::OnCreate");
64       
65        SetWindowText(L"Halite");
66        MoveWindow(rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, false);     
67
68//              MARGINS m = {20, 20, 0, 100};
69//              SetMargins(m);
70
71        hal::event_log.post(shared_ptr<hal::EventDetail>(
72                new hal::EventMsg(L"Loading Halite config...")));
73        hal::config().load_from_ini();
74       
75        hal::event_log.post(shared_ptr<hal::EventDetail>(
76                new hal::EventMsg(L"Applying setting...")));
77        if (!hal::config().settingsChanged())
78        {
79                hal::event_log.post(boost::shared_ptr<hal::EventDetail>(
80                        new hal::EventDebug(hal::event_logger::critical, hal::app().res_wstr(HAL_WINDOW_SOCKETS_FAILED))));
81                       
82                MessageBox(hal::app().res_wstr(HAL_WINDOW_SOCKETS_FAILED).c_str(), 0, 0);
83               
84                DestroyWindow();
85                return 0;
86        }
87       
88        hal::event_log.post(shared_ptr<hal::EventDetail>(
89                new hal::EventMsg(L"Starting GUI...")));
90       
91        RECT rc; GetClientRect(&rc);
92        SetMenu(0);
93       
94        //Init ToolBar
95        HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, HAL_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE);
96       
97        // Init ReBar
98        CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
99        AddSimpleReBarBand(hWndToolBar, NULL, TRUE);
100       
101        // Init the StatusBar   
102        m_hWndStatusBar = m_StatusBar.Create(*this);
103        UIAddStatusBar(m_hWndStatusBar);
104       
105        int panes[] = {ID_DEFAULT_PANE, IDPANE_FILTER, IDPANE_DHT, IDPANE_STATUS};
106        m_StatusBar.SetPanes(panes, 4, false);
107       
108        // Create the Splitter Control
109        m_Split.Create(m_hWnd, rc, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
110        m_Split.SetSplitterExtendedStyle(!SPLIT_PROPORTIONAL, SPLIT_PROPORTIONAL);
111        m_Split.SetSplitterPos(splitterPos);
112       
113        m_hWndClient = m_Split.m_hWnd;
114
115        hal::event_log.post(shared_ptr<hal::EventDetail>(
116                new hal::EventMsg(L"Creating main listview...")));     
117        // Create ListView and Dialog
118        haliteList.Create(m_Split.m_hWnd, rc, NULL, 
119                LVS_REPORT|WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|LVS_SHOWSELALWAYS|LVS_OWNERDATA);
120//      haliteList.manager().attach(bind(&HaliteWindow::issueUiUpdate, this));
121
122
123        hal::event_log.post(shared_ptr<hal::EventDetail>(
124                new hal::EventMsg(L"Creating classic dialog...")));             
125        mp_dlg.reset(new HaliteDialog(*this)),
126        mp_dlg->Create(m_Split.m_hWnd);
127//      mp_dlg->ShowWindow(true);
128       
129
130        hal::event_log.post(shared_ptr<hal::EventDetail>(
131                new hal::EventMsg(L"Creating advanced dialog...")));
132        mp_advDlg.reset(new AdvHaliteDialog(*this));
133        mp_advDlg->Create(m_Split.m_hWnd);
134//      mp_advDlg->ShowWindow(true);
135       
136//      m_Split.SetSplitterPanes(*mp_list, *mp_dlg);
137       
138        hal::event_log.post(shared_ptr<hal::EventDetail>(
139                new hal::EventMsg(L"Creating tray icon..."))); 
140        // Create the tray icon.
141        trayIcon_.Create(this, HAL_TRAY_MENU, L"Halite", 
142                CTrayNotifyIcon::LoadIconResource(HAL_APP_ICON), WM_TRAYNOTIFY, HAL_TRAY_MENU);
143        trayIcon_.Hide();
144       
145        // Add ToolBar and register it along with StatusBar for UIUpdates
146        UIAddToolBar(hWndToolBar);
147        UISetCheck(ID_VIEW_TOOLBAR, true);
148        UISetCheck(ID_VIEW_STATUS_BAR, true);
149        UISetCheck(HAL_TRAY_MENU, true);       
150       
151//      TBBUTTONINFO tbinfo = { sizeof(TBBUTTONINFO) };
152//      tbinfo.dwMask = TBIF_STATE;
153//      tbinfo.fsState = TBSTATE_INDETERMINATE;
154//      ::SendMessage(hWndToolBar, TB_SETBUTTONINFO, ID_FILE_NEW, (LPARAM)&tbinfo);
155
156        // Register UIEvents and the timer for the monitoring interval
157        SetTimer(ID_UPDATE_TIMER, 500);
158        SetTimer(ID_SAVE_TIMER, 300000);
159        connectUiUpdate(bind(&HaliteWindow::updateWindow, this));
160       
161        hal::event_log.post(shared_ptr<hal::EventDetail>(
162                new hal::EventMsg(L"Registering drop target...")));     
163        RegisterDropTarget();
164       
165        // Register object for message filtering and idle updates
166        WTL::CMessageLoop* pLoop = _Module.GetMessageLoop();
167        assert(pLoop != NULL);
168        pLoop->AddMessageFilter(this);
169        pLoop->AddIdleHandler(this);
170       
171//      haliteList.manager().setSelected(0);
172        setCorrectDialog();
173       
174        hal::event_log.post(shared_ptr<hal::EventDetail>(
175                new hal::EventMsg(L"Starting event reciever...")));
176        hal::bittorrent().start_event_receiver();
177        hal::event_log.post(shared_ptr<hal::EventDetail>(
178                new hal::EventMsg(L"Initial setup complete!")));
179
180        UpdateLayout();
181        issueUiUpdate();
182
183               
184        }
185        catch(const std::exception& e)
186        {
187                hal::event_log.post(boost::shared_ptr<hal::EventDetail>(
188                        new hal::EventStdException(hal::event_logger::critical, e, L"HaliteWindow::OnCreate"))); 
189
190                DestroyWindow();
191        }
192
193        return 0;
194}
195
196LRESULT HaliteWindow::OnAdvanced(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
197{
198        advancedUI = !advancedUI;
199        setCorrectDialog();
200       
201        return 0;
202}
203
204LRESULT HaliteWindow::OnTrayNotification(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam)
205{
206    trayIcon_.OnTrayNotification(wParam, lParam);
207   
208    return 0;
209}
210
211void HaliteWindow::setCorrectDialog()
212{
213        if (!advancedUI)
214        {               
215                mp_dlg->ShowWindow(SW_SHOW);
216                mp_advDlg->ShowWindow(SW_HIDE);
217                m_Split.SetSplitterPanes(haliteList, *mp_dlg);
218        }
219        else
220        {               
221                mp_dlg->ShowWindow(SW_HIDE);
222                mp_advDlg->ShowWindow(SW_SHOW);
223                m_Split.SetSplitterPanes(haliteList, *mp_advDlg);
224        }
225
226        issueUiUpdate();
227}
228
229void HaliteWindow::updateWindow()
230{
231        try
232        {
233       
234        hal::SessionDetail details = hal::bittorrent().get_session_details();
235       
236        if (details.port > -1)
237                UISetText(0, 
238                        (hal::wform(hal::app().res_wstr(HAL_PORT_OPEN)) % details.port ).str().c_str());       
239        else
240                UISetText(0, hal::app().res_wstr(HAL_NOT_LISTENING).c_str());
241       
242        wstring downloadRates = (hal::wform(hal::app().res_wstr(HAL_DOWN_RATES)) 
243                        % (details.speed.first/1024) 
244                        % (details.speed.second/1024)).str();
245       
246        UISetText(3, downloadRates.c_str());   
247        trayIcon_.SetTooltipText(downloadRates.c_str());
248       
249        if (details.dht_on)
250        {
251                wstring dht = (hal::wform(hal::app().res_wstr(HAL_DHT_ON))
252                        % details.dht_nodes).str();
253                       
254                UISetText(2, dht.c_str());
255        }
256        else
257        {
258                UISetText(2, hal::app().res_wstr(HAL_DHT_OFF).c_str());
259        }
260       
261        if (details.ip_filter_on)
262        {
263                wstring filter = (hal::wform(hal::app().res_wstr(HAL_IPFILTER_ON))
264                        % details.ip_ranges_filtered).str();
265               
266                UISetText(1, filter.c_str());
267        }
268        else
269        {
270                UISetText(1, hal::app().res_wstr(HAL_IPFILTER_OFF).c_str());
271        }
272
273        UpdateLayout();
274       
275        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"HaliteWindow::updateWindow()")
276}
277
278void HaliteWindow::OnTimer(UINT uTimerID)
279{               
280        if (uTimerID == ID_UPDATE_TIMER) 
281        {       
282                issueUiUpdate();
283        }
284        else if (uTimerID == ID_SAVE_TIMER) 
285        {
286                try
287                {
288
289                hal::ini().save_data();
290                hal::bittorrent().save_torrent_data(); 
291       
292                } HAL_GENERIC_FN_EXCEPTION_CATCH(L"HaliteWindow::OnTimer(ID_SAVE_TIMER)")
293        }
294        else 
295        {               
296                SetMsgHandled(false);
297        }       
298}       
299
300void HaliteWindow::issueUiUpdate()
301{       
302        try
303        {
304        std::set<wstring> s;
305
306        foreach(const HaliteListViewCtrl::listClass::list_value_type val, std::make_pair(haliteList.is_selected_begin(), haliteList.is_selected_end()))
307        {
308                s.insert(val.text().c_str());
309        }
310       
311        const hal::torrent_details_manager& torrents = hal::bittorrent().updatetorrent_details_manager(
312                haliteList.is_selected_begin()->text().c_str(), s);
313
314        ui_update_signal_(torrents);
315
316        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"HaliteWindow::issueUiUpdate()")
317}
318
319LRESULT HaliteWindow::OnCopyData(HWND, PCOPYDATASTRUCT pCSD)
320{
321        hal::event_log.post(shared_ptr<hal::EventDetail>(
322                new hal::EventMsg(L"I recieved data.")));
323               
324        switch (pCSD->dwData)
325        {
326                case HALITE_SENDING_CMD:
327                {       
328                        wstring filename(static_cast<wchar_t*>(pCSD->lpData), pCSD->cbData/sizeof(wchar_t));
329                       
330                        hal::event_log.post(shared_ptr<hal::EventDetail>(
331                                new hal::EventMsg((hal::wform(L"Recieved data: %1%.") % filename), hal::event_logger::info)));
332               
333                        ProcessFile(filename.c_str());
334                        break;
335                }
336                default:
337                        break;
338        }
339        return 0;
340}
341
342void HaliteWindow::ProcessFile(LPCTSTR lpszPath)
343{
344        try
345        {       
346        wstring default_save_folder = wpath(hal::config().default_save_folder_).native_file_string();
347        wstring default_move_folder = wpath(hal::config().default_move_folder_).native_file_string();
348        bool use_move_to = hal::config().use_move_to_;
349        bool startPaused = false;
350        bool managed = false;
351        hal::bit::allocations allocation_type = hal::bit::sparse_allocation;
352       
353        if (!boost::filesystem::exists(default_save_folder))
354                boost::filesystem::create_directory(default_save_folder);
355
356        if (hal::config().save_prompt_)
357        {
358                AddTorrentDialog addTorrent(default_save_folder, default_move_folder, use_move_to, startPaused, managed, allocation_type);     
359               
360                if (IDOK != addTorrent.DoModal())
361                        return;
362        }
363       
364        wpath file(lpszPath, boost::filesystem::native);       
365
366        if (use_move_to)
367                hal::bittorrent().add_torrent(file, wpath(default_save_folder), startPaused, managed, allocation_type, 
368                        wpath(default_move_folder));
369        else
370                hal::bittorrent().add_torrent(file, wpath(default_save_folder), startPaused, managed, allocation_type);
371
372        issueUiUpdate();
373
374        }
375        catch(const boost::filesystem::filesystem_error&)
376        {
377                hal::event_log.post(shared_ptr<hal::EventDetail>(
378                        new hal::EventDebug(hal::event_logger::warning, L"filesystem error")));
379        }
380}
381
382void HaliteWindow::OnClose()
383{
384        if (closeToTray && trayIcon_.IsHidden())
385        {               
386                ShowWindow(SW_HIDE);
387                trayIcon_.Show();
388        }
389        else
390        {
391                TryToCloseWithConfirmation();
392        }
393}
394
395void HaliteWindow::ShutdownThread()
396{
397        try
398        {
399        win32_exception::install_handler();
400
401        hal::bittorrent().close_all(0);
402
403        hal::bittorrent().stop_event_receiver();
404        Sleep(500);
405
406        hal::bittorrent().shutdown_session();
407
408        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"HaliteWindow::ShutdownThread()")
409}
410
411void HaliteWindow::TryToCloseWithConfirmation()
412{
413        bool noTorrentsAreActive = !hal::bittorrent().is_any_torrent_active();
414       
415        if (noTorrentsAreActive || !confirmClose || (confirmClose && 
416                MessageBox(hal::app().res_wstr(HAL_WINDOW_CLOSECONFRIM).c_str(), 
417                        hal::app().res_wstr(HAL_HALITE).c_str(), MB_YESNO) == IDYES))
418        {
419                DestroyWindow();
420        }
421}
422
423void HaliteWindow::OnDestroy()
424{       
425        try
426        {
427
428        KillTimer(ID_UPDATE_TIMER);
429        KillTimer(ID_SAVE_TIMER);
430
431        Sleep(0);
432
433        splitterPos = m_Split.GetSplitterPos();
434
435        save_to_ini();
436        hal::ini().save_data();
437       
438        if (halite().showMessage())
439        {
440                HAL_DEV_MSG(L"Showing SplashDialog");
441
442                SplashDialog splDlg;
443                splDlg.DoModal();
444        }
445        else
446        {               
447                HAL_DEV_MSG(L"No SplashDialog");
448
449                thread shutdown(bind(& HaliteWindow::ShutdownThread, this));
450                shutdown.join();
451        }
452               
453        HAL_DEV_MSG(L"Saving before quiting");
454
455        // Resave for sake of your health.
456        save_to_ini();
457        halite().save_to_ini();
458        hal::ini().save_data();
459               
460        HAL_DEV_MSG(L"Posting Quit Message");
461        PostQuitMessage(0);     
462
463        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"HaliteWindow::OnDestroy()")
464}
465
466void HaliteWindow::OnSize(UINT type, WTL::CSize)
467{
468        if (type == SIZE_MINIMIZED)
469        {
470                if (use_tray)
471                {
472                        ShowWindow(SW_HIDE);
473                        trayIcon_.Show();
474                }
475        }
476        else
477        {
478                if (trayIcon_.IsShowing())
479                        trayIcon_.Hide();
480
481                GetWindowRect(rect);
482        }
483       
484        UpdateLayout();
485        SetMsgHandled(false);
486}       
487
488void HaliteWindow::OnMove(WTL::CSize)
489{
490        WINDOWPLACEMENT wnd = { sizeof(WINDOWPLACEMENT ) };
491        GetWindowPlacement(&wnd);
492       
493        if (wnd.showCmd != SW_SHOWMINIMIZED)
494                GetWindowRect(rect);
495
496        SetMsgHandled(false);   
497}
498
499void HaliteWindow::OnShowWindow(BOOL bShow, UINT nStatus)
500{
501        SetMsgHandled(false);
502}
503
504LRESULT HaliteWindow::OnTrayOpenHalite(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
505{
506        trayIcon_.Hide();
507        ShowWindow(SW_RESTORE);
508       
509        return 0;
510}
511
512LRESULT HaliteWindow::OnTrayExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
513{
514        PostMessage(WM_CLOSE, 0, 0);
515       
516        return 0;
517}
518
519LRESULT HaliteWindow::OnFileOpen(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
520{
521        CSSFileDialog dlgOpen(TRUE, NULL, NULL, OFN_HIDEREADONLY, L"Torrents (*.torrent)|*.torrent|", m_hWnd);
522
523        if (dlgOpen.DoModal() == IDOK) 
524        {
525                ProcessFile(dlgOpen.m_ofn.lpstrFile);
526        }
527       
528        return 0;       
529}
530
531LRESULT HaliteWindow::OnFileNew(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
532{
533        wstring title = hal::app().res_wstr(HAL_NEWT_DIALOG_TITLE);
534
535        NewTorrentDialog newTorrent(title.c_str());     
536        newTorrent.DoModal();
537       
538        return 0;
539}
540
541LRESULT HaliteWindow::OnSettings(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
542{
543        ConfigOptionsProp sheet(this, L"Settings");     
544        sheet.DoModal();
545       
546        hal::config().settingsChanged();
547        setCorrectDialog();
548       
549        return 0;
550}
551
552LRESULT HaliteWindow::OnPauseAll(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
553{
554        hal::bittorrent().pause_all_torrents();
555       
556        issueUiUpdate();
557        return 0;
558}
559
560LRESULT HaliteWindow::OnResumeAll(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
561{
562        hal::bittorrent().unpause_all_torrents();
563       
564        issueUiUpdate();
565        return 0;
566}
567
568LRESULT HaliteWindow::OnHelp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
569{
570        ConfigOptionsProp sheet(this, L"Settings", 4); 
571        sheet.DoModal();
572       
573        hal::config().settingsChanged();
574       
575        return 0;
576}
577
578LRESULT HaliteWindow::OnToolbarExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
579{
580        TryToCloseWithConfirmation();
581       
582        return 0;
583}
584
585LRESULT HaliteWindow::OnAutoShutdown(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
586{       
587        return 0;
588}
589
590LRESULT HaliteWindow::OnViewStatusBar(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
591{
592        BOOL bVisible = !::IsWindowVisible(m_hWndStatusBar);
593        ::ShowWindow(m_hWndStatusBar, bVisible ? SW_SHOWNOACTIVATE : SW_HIDE);
594        UISetCheck(ID_VIEW_STATUS_BAR, bVisible);
595       
596        UpdateLayout();
597       
598        return 0;
599}       
600
601LRESULT HaliteWindow::OnEraseBkgnd(HDC dc)
602{
603        return 1;
604}
605
606LRESULT HaliteWindow::OnPaint(HDC dc)
607{
608        return 1;
609}
610
611LRESULT HaliteWindow::OnAreYouMe(UINT, WPARAM, LPARAM, BOOL&) 
612{
613        hal::event_log.post(shared_ptr<hal::EventDetail>(
614                new hal::EventMsg(L"I tried to contact me.")));         
615
616        return WM_AreYouMe_; 
617}
Note: See TracBrowser for help on using the repository browser.