source: trunk/src/HaliteWindow.cpp @ 757

Revision 757, 15.6 KB checked in by Eoin, 10 years ago (diff)

Midway not compiling code because incomplete for datetime picker dialog.

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