source: trunk/src/HaliteWindow.cpp @ 419

Revision 419, 13.7 KB checked in by Eoin, 12 years ago (diff)

Factored out base code for adding and editing items in ListViews?. Made the NewTorrent? Tracker ListView? editable.

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