source: trunk/src/HaliteWindow.cpp @ 620

Revision 620, 14.6 KB checked in by Eoin, 12 years ago (diff)

Naming scheme improvements

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 <string>
8#include <boost/format.hpp>
9#include <boost/bind.hpp>
10
11#include "stdAfx.hpp"
12#include "Halite.hpp"
13#include "HaliteWindow.hpp"
14
15#include "CSSFileDialog.hpp"
16#include "RadioPaneDlg.hpp"
17
18#include "HaliteDialog.hpp"
19#include "AdvHaliteDialog.hpp"
20#include "AddTorrentDialog.hpp"
21#include "NewTorrentDialog.hpp"
22#include "SplashDialog.hpp"
23
24#include "ConfigOptions.hpp"
25#include "halConfig.hpp"
26
27HaliteWindow::HaliteWindow(unsigned areYouMe = 0) :
28        iniClass("HaliteWindow", "HaliteWindow"),
29        haliteList(*this),
30        WM_AreYouMe_(areYouMe),
31        splitterPos(100),
32        use_tray(true),
33        advancedUI(false),
34        closeToTray(false),
35        confirmClose(true),
36        activeTab(0)
37{
38        rect.top = 10;
39        rect.left = 10;
40        rect.bottom = 430;
41        rect.right = 620;
42       
43        load_from_ini();
44}
45
46HaliteWindow::~HaliteWindow()
47{
48        save_to_ini();
49        ATLASSERT(!::IsWindow(m_hWnd));
50}
51
52BOOL HaliteWindow::PreTranslateMessage(MSG* pMsg)
53{
54        if(CFrameWindowImpl<thisClass>::PreTranslateMessage(pMsg))
55                return TRUE;
56
57        if (!advancedUI)
58                return mp_dlg->PreTranslateMessage(pMsg);
59        else
60                return mp_advDlg->PreTranslateMessage(pMsg);
61}
62
63LRESULT HaliteWindow::OnCreate(LPCREATESTRUCT lpcs)
64{
65        try
66        {
67        HAL_DEV_MSG(L"HaliteWindow::OnCreate");
68       
69        SetWindowText(L"Halite");
70        MoveWindow(rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, false);     
71
72//              MARGINS m = {20, 20, 0, 100};
73//              SetMargins(m);
74
75        hal::event_log.post(shared_ptr<hal::EventDetail>(
76                new hal::EventMsg(L"Loading Halite config...")));
77        hal::config().load_from_ini();
78       
79        hal::event_log.post(shared_ptr<hal::EventDetail>(
80                new hal::EventMsg(L"Applying setting...")));
81        if (!hal::config().settingsChanged())
82        {
83                hal::event_log.post(boost::shared_ptr<hal::EventDetail>(
84                        new hal::EventDebug(hal::event_logger::critical, hal::app().res_wstr(HAL_WINDOW_SOCKETS_FAILED))));
85                       
86                MessageBox(hal::app().res_wstr(HAL_WINDOW_SOCKETS_FAILED).c_str(), 0, 0);
87               
88                DestroyWindow();
89                return 0;
90        }
91       
92        hal::event_log.post(shared_ptr<hal::EventDetail>(
93                new hal::EventMsg(L"Starting 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);
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, 5000);
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//      haliteList.manager().setSelected(0);
176        setCorrectDialog();
177       
178        hal::event_log.post(shared_ptr<hal::EventDetail>(
179                new hal::EventMsg(L"Starting event reciever...")));
180        hal::bittorrent().startEventReceiver();
181        hal::event_log.post(shared_ptr<hal::EventDetail>(
182                new hal::EventMsg(L"Initial setup complete!")));
183
184        UpdateLayout();
185        issueUiUpdate();
186
187               
188        }
189        catch(const std::exception& e)
190        {
191                hal::event_log.post(boost::shared_ptr<hal::EventDetail>(
192                        new hal::EventStdException(hal::event_logger::critical, e, L"HaliteWindow::OnCreate"))); 
193
194                DestroyWindow();
195        }
196
197        return 0;
198}
199
200LRESULT HaliteWindow::OnAdvanced(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
201{
202        advancedUI = !advancedUI;
203        setCorrectDialog();
204       
205        return 0;
206}
207
208LRESULT HaliteWindow::OnTrayNotification(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam)
209{
210    trayIcon_.OnTrayNotification(wParam, lParam);
211   
212    return 0;
213}
214
215void HaliteWindow::setCorrectDialog()
216{
217        if (!advancedUI)
218        {               
219                mp_dlg->ShowWindow(SW_SHOW);
220                mp_advDlg->ShowWindow(SW_HIDE);
221                m_Split.SetSplitterPanes(haliteList, *mp_dlg);
222        }
223        else
224        {               
225                mp_dlg->ShowWindow(SW_HIDE);
226                mp_advDlg->ShowWindow(SW_SHOW);
227                m_Split.SetSplitterPanes(haliteList, *mp_advDlg);
228        }
229
230        issueUiUpdate();
231}
232
233void HaliteWindow::updateWindow()
234{
235        try
236        {
237       
238        hal::SessionDetail details = hal::bittorrent().getSessionDetails();
239       
240        if (details.port > -1)
241                UISetText(0, 
242                        (hal::wform(hal::app().res_wstr(HAL_PORT_OPEN)) % details.port ).str().c_str());       
243        else
244                UISetText(0, hal::app().res_wstr(HAL_NOT_LISTENING).c_str());
245       
246        wstring downloadRates = (hal::wform(hal::app().res_wstr(HAL_DOWN_RATES)) 
247                        % (details.speed.first/1024) 
248                        % (details.speed.second/1024)).str();
249       
250        UISetText(3, downloadRates.c_str());   
251        trayIcon_.SetTooltipText(downloadRates.c_str());
252       
253        if (details.dht_on)
254        {
255                wstring dht = (hal::wform(hal::app().res_wstr(HAL_DHT_ON))
256                        % details.dht_nodes).str();
257                       
258                UISetText(2, dht.c_str());
259        }
260        else
261        {
262                UISetText(2, hal::app().res_wstr(HAL_DHT_OFF).c_str());
263        }
264       
265        if (details.ip_filter_on)
266        {
267                wstring filter = (hal::wform(hal::app().res_wstr(HAL_IPFILTER_ON))
268                        % details.ip_ranges_filtered).str();
269               
270                UISetText(1, filter.c_str());
271        }
272        else
273        {
274                UISetText(1, hal::app().res_wstr(HAL_IPFILTER_OFF).c_str());
275        }
276
277        UpdateLayout();
278       
279        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"HaliteWindow::updateWindow()")
280}
281
282void HaliteWindow::OnTimer(UINT uTimerID)
283{               
284        if (uTimerID == ID_UPDATE_TIMER) 
285        {       
286                issueUiUpdate();
287        }
288        else if (uTimerID == ID_SAVE_TIMER) 
289        {
290                try
291                {
292
293                hal::ini().save_data();
294                hal::bittorrent().save_torrent_data(); 
295       
296                } HAL_GENERIC_FN_EXCEPTION_CATCH(L"HaliteWindow::OnTimer(ID_SAVE_TIMER)")
297        }
298        else 
299        {               
300                SetMsgHandled(false);
301        }       
302}       
303
304void HaliteWindow::issueUiUpdate()
305{       
306        try
307        {
308       
309        const hal::torrent_details_manager& torrents = hal::bittorrent().updatetorrent_details_manager(
310                haliteList.manager().selected(), haliteList.manager().allSelected());
311
312        ui_update_signal_(torrents);
313
314        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"HaliteWindow::issueUiUpdate()")
315}
316
317LRESULT HaliteWindow::OnCopyData(HWND, PCOPYDATASTRUCT pCSD)
318{
319        hal::event_log.post(shared_ptr<hal::EventDetail>(
320                new hal::EventMsg(L"I recieved data.")));
321               
322        switch (pCSD->dwData)
323        {
324                case HALITE_SENDING_CMD:
325                {       
326                        wstring filename(static_cast<wchar_t*>(pCSD->lpData), pCSD->cbData/sizeof(wchar_t));
327                       
328                        hal::event_log.post(shared_ptr<hal::EventDetail>(
329                                new hal::EventMsg((hal::wform(L"Recieved data: %1%.") % filename), hal::event_logger::info)));
330               
331                        ProcessFile(filename.c_str());
332                        break;
333                }
334                default:
335                        break;
336        }
337        return 0;
338}
339
340void HaliteWindow::ProcessFile(LPCTSTR lpszPath)
341{
342        try
343        {
344       
345        wstring default_save_folder = wpath(hal::config().default_save_folder_).native_file_string();
346        wstring default_move_folder = wpath(hal::config().default_move_folder_).native_file_string();
347        bool use_move_to = hal::config().use_move_to_;
348        bool startPaused = false;
349        bool managed = false;
350        hal::bit::allocations allocation_type = hal::bit::sparse_allocation;
351       
352        if (!boost::filesystem::exists(default_save_folder))
353                boost::filesystem::create_directory(default_save_folder);
354
355        if (hal::config().save_prompt_)
356        {
357                AddTorrentDialog addTorrent(default_save_folder, default_move_folder, use_move_to, startPaused, managed, allocation_type);     
358               
359                if (IDOK != addTorrent.DoModal())
360                        return;
361        }
362       
363        wpath file(lpszPath, boost::filesystem::native);       
364        hal::bittorrent().add_torrent(file, wpath(default_save_folder), startPaused, managed, allocation_type, 
365                wpath(default_move_folder), use_move_to);
366
367        issueUiUpdate();
368
369        }
370        catch(const boost::filesystem::filesystem_error&)
371        {
372                hal::event_log.post(shared_ptr<hal::EventDetail>(
373                        new hal::EventDebug(hal::event_logger::warning, L"filesystem error")));
374        }
375}
376
377void HaliteWindow::OnClose()
378{
379        if (closeToTray && trayIcon_.IsHidden())
380        {               
381                ShowWindow(SW_HIDE);
382                trayIcon_.Show();
383        }
384        else
385        {
386                if (!confirmClose || (confirmClose && 
387                        MessageBox(hal::app().res_wstr(HAL_WINDOW_CLOSECONFRIM).c_str(), 
388                                hal::app().res_wstr(HAL_HALITE).c_str(), MB_YESNO) == IDYES))
389                {
390                        DestroyWindow();
391                }
392        }
393}
394
395void HaliteWindow::ShutdownThread()
396{
397        try
398        {
399
400        win32_exception::install_handler();
401        hal::bittorrent().close_all(0);
402
403        hal::bittorrent().stopEventReceiver();
404        Sleep(3000);
405
406        hal::bittorrent().shutDownSession();
407
408        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"HaliteWindow::ShutdownThread()")
409}
410 
411void HaliteWindow::OnDestroy()
412{       
413        try
414        {
415
416        KillTimer(ID_UPDATE_TIMER);
417        KillTimer(ID_SAVE_TIMER);
418
419        Sleep(0);
420
421        splitterPos = m_Split.GetSplitterPos();
422
423        save_to_ini();
424        hal::ini().save_data();
425       
426        if (halite().showMessage())
427        {
428                HAL_DEV_MSG(L"Showing SplashDialog");
429
430                SplashDialog splDlg;
431                splDlg.DoModal();
432        }
433        else
434        {               
435                HAL_DEV_MSG(L"No SplashDialog");
436
437                thread shutdown(bind(& HaliteWindow::ShutdownThread, this));
438                shutdown.join();
439        }
440               
441        HAL_DEV_MSG(L"Saving before quiting");
442
443        // Resave for sake of your health.
444        save_to_ini();
445        halite().save_to_ini();
446        hal::ini().save_data();
447               
448        HAL_DEV_MSG(L"Posting Quit Message");
449        PostQuitMessage(0);     
450
451        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"HaliteWindow::OnDestroy()")
452}
453
454void HaliteWindow::OnSize(UINT type, WTL::CSize)
455{
456        if (type == SIZE_MINIMIZED)
457        {
458                if (use_tray)
459                {
460                        ShowWindow(SW_HIDE);
461                        trayIcon_.Show();
462                }
463        }
464        else
465        {
466                if (trayIcon_.IsShowing())
467                        trayIcon_.Hide();
468
469                GetWindowRect(rect);
470        }
471       
472        UpdateLayout();
473        SetMsgHandled(false);
474}       
475
476void HaliteWindow::OnMove(WTL::CSize)
477{
478        WINDOWPLACEMENT wnd = { sizeof(WINDOWPLACEMENT ) };
479        GetWindowPlacement(&wnd);
480       
481        if (wnd.showCmd != SW_SHOWMINIMIZED)
482                GetWindowRect(rect);
483
484        SetMsgHandled(false);   
485}
486
487void HaliteWindow::OnShowWindow(BOOL bShow, UINT nStatus)
488{
489        SetMsgHandled(false);
490}
491
492LRESULT HaliteWindow::OnTrayOpenHalite(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
493{
494        trayIcon_.Hide();
495        ShowWindow(SW_RESTORE);
496       
497        return 0;
498}
499
500LRESULT HaliteWindow::OnTrayExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
501{
502        PostMessage(WM_CLOSE, 0, 0);
503       
504        return 0;
505}
506
507LRESULT HaliteWindow::OnFileOpen(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
508{
509        CSSFileDialog dlgOpen(TRUE, NULL, NULL, OFN_HIDEREADONLY, L"Torrents (*.torrent)|*.torrent|", m_hWnd);
510
511        if (dlgOpen.DoModal() == IDOK) 
512        {
513                ProcessFile(dlgOpen.m_ofn.lpstrFile);
514        }
515       
516        return 0;       
517}
518
519LRESULT HaliteWindow::OnFileNew(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
520{
521        wstring title = hal::app().res_wstr(HAL_NEWT_DIALOG_TITLE);
522
523        NewTorrentDialog newTorrent(title.c_str());     
524    newTorrent.DoModal();
525       
526        return 0;
527}
528
529LRESULT HaliteWindow::OnSettings(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
530{
531        ConfigOptionsProp sheet(this, L"Settings");     
532    sheet.DoModal();
533       
534        hal::config().settingsChanged();
535        setCorrectDialog();
536       
537        return 0;
538}
539
540LRESULT HaliteWindow::OnPauseAll(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
541{
542        hal::bittorrent().pauseAllTorrents();
543       
544        issueUiUpdate();
545        return 0;
546}
547
548LRESULT HaliteWindow::OnResumeAll(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
549{
550        hal::bittorrent().unpauseAllTorrents();
551       
552        issueUiUpdate();
553        return 0;
554}
555
556LRESULT HaliteWindow::OnHelp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
557{
558        ConfigOptionsProp sheet(this, L"Settings", 4); 
559    sheet.DoModal();
560       
561        hal::config().settingsChanged();
562       
563        return 0;
564}
565
566LRESULT HaliteWindow::OnToolbarExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
567{
568        if (!confirmClose || (confirmClose && 
569                MessageBox(hal::app().res_wstr(HAL_WINDOW_CLOSECONFRIM).c_str(), 
570                        hal::app().res_wstr(HAL_HALITE).c_str(), MB_YESNO) == IDYES))
571        {
572                DestroyWindow();
573        }
574       
575        return 0;
576}
577
578LRESULT HaliteWindow::OnAutoShutdown(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
579{
580
581       
582        return 0;
583}
584
585LRESULT HaliteWindow::OnViewStatusBar(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
586{
587        BOOL bVisible = !::IsWindowVisible(m_hWndStatusBar);
588        ::ShowWindow(m_hWndStatusBar, bVisible ? SW_SHOWNOACTIVATE : SW_HIDE);
589        UISetCheck(ID_VIEW_STATUS_BAR, bVisible);
590       
591        UpdateLayout();
592       
593        return 0;
594}       
595
596LRESULT HaliteWindow::OnEraseBkgnd(HDC dc)
597{
598        return 1;
599}
600
601LRESULT HaliteWindow::OnPaint(HDC dc)
602{
603        return 1;
604}
605
606LRESULT HaliteWindow::OnAreYouMe(UINT, WPARAM, LPARAM, BOOL&) 
607{
608        hal::event_log.post(shared_ptr<hal::EventDetail>(
609                new hal::EventMsg(L"I tried to contact me.")));         
610
611        return WM_AreYouMe_; 
612}
Note: See TracBrowser for help on using the repository browser.