source: trunk/src/HaliteWindow.cpp @ 531

Revision 531, 14.0 KB checked in by Eoin, 11 years ago (diff)

Switched trunk to hal::wform.

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