desktop: fixed ExecHelper usage, to use child exit code
[barry/progweb.git] / desktop / src / BaseFrame.cc
blob914de04a6c6c55d6195a7fb386bc648650d1e1df
1 ///
2 /// \file BaseFrame.cc
3 /// Class for the fixed-size frame that holds the main app
4 ///
6 /*
7 Copyright (C) 2009-2012, Net Direct Inc. (http://www.netdirect.ca/)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
22 #include "BaseFrame.h"
23 #include "Mode_MainMenu.h"
24 #include "Mode_Sync.h"
25 #include "Mode_Browse.h"
26 #include "MigrateDlg.h"
27 #include "ClickImage.h"
28 #include "barrydesktop.h"
29 #include "windowids.h"
30 #include <wx/aboutdlg.h>
31 #include <iostream>
32 #include <sstream>
34 // include icons and logos
35 #include "../images/barry_logo_icon.xpm"
36 #include "../images/logo_NetDirect.xpm"
38 using namespace std;
40 BEGIN_EVENT_TABLE(BaseFrame, wxFrame)
41 EVT_SIZE (BaseFrame::OnSize)
42 EVT_PAINT (BaseFrame::OnPaint)
43 EVT_MOTION (BaseFrame::OnMouseMotion)
44 EVT_LEFT_DOWN (BaseFrame::OnLeftDown)
45 EVT_LEFT_UP (BaseFrame::OnLeftUp)
46 EVT_BUTTON (MainMenu_BackupAndRestore, BaseFrame::OnBackupRestore)
47 EVT_BUTTON (MainMenu_Sync, BaseFrame::OnSync)
48 EVT_BUTTON (MainMenu_Modem, BaseFrame::OnModem)
49 EVT_BUTTON (MainMenu_AppLoader, BaseFrame::OnAppLoader)
50 EVT_BUTTON (MainMenu_MigrateDevice, BaseFrame::OnMigrateDevice)
51 EVT_BUTTON (MainMenu_BrowseDatabases, BaseFrame::OnBrowseDatabases)
52 EVT_BUTTON (MainMenu_MediaManagement, BaseFrame::OnMediaManagement)
53 EVT_BUTTON (MainMenu_Misc, BaseFrame::OnMisc)
54 EVT_BUTTON (MainMenu_BackButton, BaseFrame::OnBackButton)
55 EVT_BUTTON (HotImage_BarryLogo, BaseFrame::OnBarryLogoClicked)
56 EVT_BUTTON (HotImage_NetDirectLogo, BaseFrame::OnNetDirectLogoClicked)
57 EVT_TEXT (Ctrl_DeviceCombo, BaseFrame::OnDeviceComboChange)
58 EVT_MENU (SysMenu_VerboseLogging, BaseFrame::OnVerboseLogging)
59 EVT_MENU (SysMenu_RenameDevice, BaseFrame::OnRenameDevice)
60 EVT_MENU (SysMenu_ResetDevice, BaseFrame::OnResetDevice)
61 EVT_MENU (SysMenu_RescanUsb, BaseFrame::OnRescanUsb)
62 EVT_MENU (SysMenu_About, BaseFrame::OnAbout)
63 EVT_MENU (SysMenu_Exit, BaseFrame::OnExit)
64 EVT_END_PROCESS (Process_BackupAndRestore, BaseFrame::OnTermBackupAndRestore)
65 END_EVENT_TABLE()
67 //////////////////////////////////////////////////////////////////////////////
68 // BaseFrame
70 BaseFrame::BaseFrame(const wxImage &background)
71 : wxFrame(NULL, wxID_ANY, _T("Barry Desktop Control Panel"),
72 wxPoint(50, 50),
73 wxSize(background.GetWidth(), background.GetHeight()),
74 wxMINIMIZE_BOX | wxCAPTION | wxCLOSE_BOX | wxSYSTEM_MENU |
75 wxCLIP_CHILDREN)
76 , TermCatcher(this, Process_BackupAndRestore)
77 , m_width(background.GetWidth())
78 , m_height(background.GetHeight())
79 , m_current_mode(0)
80 , m_backup_process(this)
82 // This is a workaround for different size behaviour
83 // in the GTK version of wxWidgets 2.9
84 SetClientSize(wxSize(background.GetWidth(), background.GetHeight()));
86 // load base bitmaps
87 m_background.reset( new wxBitmap(background) );
89 // the main menu mode always exists, but may not always be current
90 m_main_menu_mode.reset( new MainMenuMode(this) );
91 m_current_mode = m_main_menu_mode.get();
93 m_barry_logo.reset( new ClickableImage(this,
94 wxBitmap(barry_logo_icon_xpm), HotImage_BarryLogo,
95 4, 4, false) );
96 wxBitmap nd_logo(logo_NetDirect_xpm);
97 m_netdirect_logo.reset( new ClickableImage(this,
98 nd_logo, HotImage_NetDirectLogo,
99 m_width - 3 - nd_logo.GetWidth(),
100 (MAIN_HEADER_OFFSET - nd_logo.GetHeight()) / 2, true,
101 wxNullCursor));
103 // Create the Barry Logo popup system menu
104 m_sysmenu.reset( new wxMenu );
105 m_sysmenu->Append( new wxMenuItem(m_sysmenu.get(),
106 SysMenu_VerboseLogging, _T("&Verbose Logging"),
107 _T("Enable low level USB debug output"), wxITEM_CHECK, NULL) );
108 m_sysmenu->Append(SysMenu_RenameDevice, _T("Re&name Device..."));
109 m_sysmenu->Append(SysMenu_ResetDevice, _T("Re&set Device"));
110 m_sysmenu->Append(SysMenu_RescanUsb, _T("&Rescan USB"));
111 m_sysmenu->AppendSeparator();
112 m_sysmenu->Append(SysMenu_About, _T("&About..."));
113 m_sysmenu->AppendSeparator();
114 m_sysmenu->Append(wxID_EXIT, _T("E&xit"));
116 UpdateMenuState();
117 CreateDeviceCombo(wxGetApp().GetGlobalConfig().GetLastDevice());
120 void BaseFrame::UpdateMenuState()
122 if( !m_sysmenu.get() )
123 return;
125 wxMenuItemList &list = m_sysmenu->GetMenuItems();
126 wxMenuItemList::iterator b = list.begin();
127 for( ; b != list.end(); ++b ) {
128 wxMenuItem *item = *b;
130 switch( item->GetId() )
132 case SysMenu_VerboseLogging:
133 item->Check(Barry::IsVerbose());
134 break;
139 void BaseFrame::CreateDeviceCombo(Barry::Pin pin)
141 const Barry::Probe::Results &results = wxGetApp().GetResults();
143 // default to:
144 // no device selected, if multiple available and no default given
145 // no devices available, if nothing there
146 // the first device, if only one exists
147 int selected = 0;
149 // create a list of selections
150 wxArrayString devices;
152 // if there's more than one device, let the user pick "none"
153 if( results.size() > 1 ) {
154 devices.Add(_T("No device selected"));
157 // add one entry for each device
158 for( Barry::Probe::Results::const_iterator i = results.begin();
159 i != results.end(); ++i )
161 // if this is the desired item, remember this selection
162 if( pin.Valid() && i->m_pin == pin ) {
163 selected = devices.GetCount();
166 devices.Add(wxString(i->GetDisplayName().c_str(), wxConvUTF8));
169 // if nothing is there, be descriptive
170 if( devices.GetCount() == 0 ) {
171 devices.Add(_T("No devices available"));
174 // create the combobox
175 int x = m_width - 300;
176 int y = m_height - (MAIN_HEADER_OFFSET - 5);
177 m_device_combo.reset( new wxComboBox(this, Ctrl_DeviceCombo, _T(""),
178 wxPoint(x, y), wxSize(290, -1), devices, wxCB_READONLY) );
180 // select the desired entry
181 m_device_combo->SetValue(devices[selected]);
183 // update the screenshot
184 m_main_menu_mode->UpdateScreenshot(GetCurrentComboPin());
187 Barry::Pin BaseFrame::GetCurrentComboPin()
189 // fetch newly selected device
190 wxString value = m_device_combo->GetValue();
191 istringstream iss(string(value.utf8_str()).substr(0,8));
192 Barry::Pin pin;
193 iss >> pin;
194 return pin;
197 void BaseFrame::EnableBackButton(Mode *new_mode)
199 // create the button - this goes in the bottom FOOTER area
200 // so the height must be fixed to MAIN_HEADER_OFFSET
201 // minus a border of 5px top and bottom
202 wxPoint pos(10, m_height - (MAIN_HEADER_OFFSET - 5));
203 wxSize size(-1, MAIN_HEADER_OFFSET - 5 - 5);
205 m_back_button.reset( new wxButton(this, MainMenu_BackButton,
206 _T("Main Menu"), pos, size) );
208 // set the new mode
209 m_current_mode = new_mode;
211 // destroy the device switcher combo box
212 m_device_combo.reset();
214 // without the device combo, there is no concept of a
215 // "current device" so temporarily disable the USB options
216 m_sysmenu->Enable(SysMenu_RenameDevice, false);
217 m_sysmenu->Enable(SysMenu_ResetDevice, false);
218 m_sysmenu->Enable(SysMenu_RescanUsb, false);
220 // repaint!
221 Refresh(false);
224 void BaseFrame::DisableBackButton()
226 // destroy the back button
227 m_back_button.reset();
229 // delete all modes
230 m_sync_mode.reset();
231 m_browse_mode.reset();
233 // create the device switcher combo again
234 CreateDeviceCombo(wxGetApp().GetGlobalConfig().GetLastDevice());
236 // enable the USB menu options
237 Barry::Pin pin = GetCurrentComboPin();
238 m_sysmenu->Enable(SysMenu_RenameDevice, pin.Valid());
239 m_sysmenu->Enable(SysMenu_ResetDevice, true);
240 m_sysmenu->Enable(SysMenu_RescanUsb, true);
242 // reset the current mode to main menu and repaint
243 m_current_mode = m_main_menu_mode.get();
244 Refresh(false);
247 void BaseFrame::OnSize(wxSizeEvent &event)
251 void BaseFrame::OnPaint(wxPaintEvent &event)
253 wxPaintDC dc(this);
254 dc.SetMapMode(wxMM_TEXT);
256 // paint the background image
257 dc.DrawBitmap(*m_background, 0, 0);
259 // paint the header: Barry logo
260 m_barry_logo->Draw(dc);
262 // paint the header: NetDirect logo
263 // m_netdirect_logo->Draw(dc);
265 // paint the header: text
266 auto_ptr<wxFont> font( wxFont::New(14,
267 wxFONTFAMILY_SWISS, wxFONTFLAG_ANTIALIASED,
268 _T("Luxi Sans")) );
269 dc.SetFont( *font );
270 dc.SetTextForeground( wxColour(0xd2, 0xaf, 0x0b) );
271 dc.SetTextBackground( wxColour(0, 0, 0, wxALPHA_TRANSPARENT) );
273 long width, height, descent;
274 wxString header = _T("Barry Desktop Control Panel");
275 if( m_current_mode )
276 header = m_current_mode->GetTitleText();
277 dc.GetTextExtent(header, &width, &height, &descent);
278 int x = (m_width - width) / 2;
279 int y = (MAIN_HEADER_OFFSET - height) / 2;
280 dc.DrawText(header, x, y);
282 // let the mode do its thing
283 if( m_current_mode )
284 m_current_mode->OnPaint(dc);
287 void BaseFrame::OnMouseMotion(wxMouseEvent &event)
289 wxClientDC dc(this);
290 m_barry_logo->HandleMotion(dc, event.m_x, event.m_y);
291 // m_netdirect_logo->HandleMotion(dc, event.m_x, event.m_y);
293 // the mode
294 if( m_current_mode )
295 m_current_mode->OnMouseMotion(dc, event.m_x, event.m_y);
298 void BaseFrame::OnLeftDown(wxMouseEvent &event)
300 wxClientDC dc(this);
301 m_barry_logo->HandleDown(dc, event.m_x, event.m_y);
302 // m_netdirect_logo->HandleDown(dc, event.m_x, event.m_y);
303 event.Skip();
305 // the mode
306 if( m_current_mode )
307 m_current_mode->OnLeftDown(dc, event.m_x, event.m_y);
310 void BaseFrame::OnLeftUp(wxMouseEvent &event)
312 wxClientDC dc(this);
313 m_barry_logo->HandleUp(dc, event.m_x, event.m_y);
314 // m_netdirect_logo->HandleUp(dc, event.m_x, event.m_y);
316 // the mode
317 if( m_current_mode )
318 m_current_mode->OnLeftUp(dc, event.m_x, event.m_y);
321 void BaseFrame::OnBackupRestore(wxCommandEvent &event)
323 if( m_backup_process.IsAppRunning() ) {
324 wxMessageBox(_T("The Backup program is already running!"),
325 _T("Backup and Restore"), wxOK | wxICON_INFORMATION);
326 return;
329 if( !m_backup_process.Run(this, "Backup and Restore", _T("barrybackup")) )
330 return;
333 void BaseFrame::OnSync(wxCommandEvent &event)
335 if( wxGetApp().GetOpenSync().GetAvailable() == 0 ) {
336 wxGetApp().ShowMissingOpenSyncMessage();
337 return;
340 try {
341 m_sync_mode.reset( new SyncMode(this) );
343 catch( std::exception &e ) {
344 wxString msg(_T(
345 "An error occurred that prevented the loading of Sync\n"
346 "mode. This is most likely because a critical piece\n"
347 "of OpenSync is missing. Check that all required\n"
348 "plugins are installed, and that tools like 'bidentify'\n"
349 "can find your BlackBerry(R) successfully.\n\n"
350 "Error: "));
351 msg += wxString(e.what(), wxConvUTF8);
352 wxMessageBox(msg, _T("Sync Mode"), wxOK | wxICON_ERROR);
353 return;
356 EnableBackButton(m_sync_mode.get());
359 //#include "EvoSources.h"
360 //#include "EvoCfgDlg.h"
361 //#include "EvoDefaultDlg.h"
362 //void DumpItems(const EvoSources::List &list)
364 // EvoSources::List::const_iterator i;
365 // for( i = list.begin(); i != list.end(); ++i ) {
366 // cout << i->m_GroupName << ", "
367 // << i->m_SourceName << ", "
368 // << i->m_SourcePath << endl;
369 // }
371 //#include "ConflictDlg.h"
372 void BaseFrame::OnModem(wxCommandEvent &event)
375 EvoDefaultDlg dlg(this);
376 dlg.ShowModal();
380 EvoSources es;
381 cout << "Addressbook:\n";
382 DumpItems(es.GetAddressBook());
383 cout << "Events:\n";
384 DumpItems(es.GetEvents());
385 cout << "Tasks:\n";
386 DumpItems(es.GetTasks());
387 cout << "Memos:\n";
388 DumpItems(es.GetMemos());
390 OpenSync::Config::Evolution ecfg;
392 EvoCfgDlg dlg(this, ecfg, es);
393 dlg.ShowModal();
394 dlg.SetPaths(ecfg);
395 cout << "Resulting paths:\n"
396 << ecfg.GetAddressPath() << endl
397 << ecfg.GetCalendarPath() << endl
398 << ecfg.GetTasksPath() << endl
399 << ecfg.GetMemosPath() << endl;
403 OpenSync::SyncChange change;
404 change.id = 1;
405 change.member_id = 1;
406 change.plugin_name = "barry-sync";
407 change.uid = "12341524235234";
408 change.printable_data =
409 "<contact>\n"
410 " <UnknownNode>\n"
411 " <NodeName>PRODID</NodeName>\n"
412 " <Content>-//OpenSync//NONSGML Barry Contact Record//EN</Content>\n"
413 " </UnknownNode>\n"
414 " <FormattedName>\n"
415 " <Content>Adame Brandee</Content>\n"
416 " </FormattedName>\n"
417 " <Name>\n"
418 " <LastName>Brandee</LastName>\n"
419 " <FirstName>Adame</FirstName>\n"
420 " </Name>\n"
421 " <AddressLabel>\n"
422 " <Content>71 Long St.\n"
423 "Toronto ON Canada\n"
424 "N0N 0N0</Content>\n"
425 " <Type>home</Type>\n"
426 " </AddressLabel>\n"
427 " <Address>\n"
428 " <Street>71 Long St.</Street>\n"
429 " <City>Toronto</City>\n"
430 " <Region>ON</Region>\n"
431 " <PostalCode>N0N 0N0</PostalCode>\n"
432 " <Country>Canada</Country>\n"
433 " <Type>home</Type>\n"
434 " </Address>\n"
435 " <Telephone>\n"
436 " <Content>+1 (416) 555-7711</Content>\n"
437 " <Type>voice</Type>\n"
438 " <Type>home</Type>\n"
439 " </Telephone>\n"
440 " <Telephone>\n"
441 " <Content>+1 (416) 955-7117</Content>\n"
442 " <Type>msg</Type>\n"
443 " <Type>cell</Type>\n"
444 " </Telephone>\n"
445 " <EMail>\n"
446 " <Content>abrandee@sympatico.ca</Content>\n"
447 " <Type>internet</Type>\n"
448 " <Type>pref</Type>\n"
449 " </EMail>\n"
450 " <Categories>\n"
451 " <Category>Personal</Category>\n"
452 " </Categories>\n"
453 " <Note>\n"
454 " <Content>Interweb salesman... 24/7</Content>\n"
455 " </Note>\n"
456 "</contact>";
458 std::vector<OpenSync::SyncChange> changes;
459 changes.push_back(change);
461 change.id = 2;
462 change.member_id = 2;
463 change.plugin_name = "evo2-sync";
464 change.uid = "asdfioausdf_1235234as_asdf12341524235234";
465 change.printable_data =
466 "<contact>\n"
467 " <Telephone>\n"
468 " <Content>+1 (416) 955-7117</Content>\n"
469 " <Type>CELL</Type>\n"
470 " <Slot>2</Slot>\n"
471 " </Telephone>\n"
472 " <Telephone>\n"
473 " <Content>+1 (416) 555-7711</Content>\n"
474 " <Type>HOME</Type>\n"
475 " <Type>VOICE</Type>\n"
476 " <Slot>1</Slot>\n"
477 " </Telephone>\n"
478 " <EMail>\n"
479 " <Content>abrandee@sympatico.ca</Content>\n"
480 " <Type>OTHER</Type>\n"
481 " <Slot>1</Slot>\n"
482 " </EMail>\n"
483 " <WantsHtml>\n"
484 " <Content>FALSE</Content>\n"
485 " </WantsHtml>\n"
486 " <Revision>\n"
487 " <Content>20100322T225303Z</Content>\n"
488 " </Revision>\n"
489 " <UnknownNode>\n"
490 " <NodeName>PRODID</NodeName>\n"
491 " <Content>-//OpenSync//NONSGML Barry Contact Record//EN</Content>\n"
492 " </UnknownNode>\n"
493 " <FormattedName>\n"
494 " <Content>Adam Brandeee</Content>\n"
495 " </FormattedName>\n"
496 " <Name>\n"
497 " <LastName>Brandeee</LastName>\n"
498 " <FirstName>Adam</FirstName>\n"
499 " </Name>\n"
500 " <AddressLabel>\n"
501 " <Content>71 Long St.\n"
502 "Toronto, ON\n"
503 "N0N 0N1\n"
504 "Canada</Content>\n"
505 " <Type>home</Type>\n"
506 " </AddressLabel>\n"
507 " <Address>\n"
508 " <Street>71 Long St.</Street>\n"
509 " <City>Toronto</City>\n"
510 " <Region>ON</Region>\n"
511 " <PostalCode>N0N 0N1</PostalCode>\n"
512 " <Country>Canada</Country>\n"
513 " <Type>home</Type>\n"
514 " </Address>\n"
515 " <Categories>\n"
516 " <Category>Personal</Category>\n"
517 " </Categories>\n"
518 " <FileAs>\n"
519 " <Content>Brandeee, Adam</Content>\n"
520 " </FileAs>\n"
521 "</contact>";
523 changes.push_back(change);
526 ConflictDlg::AlwaysMemoryBlock always;
527 ConflictDlg dlg(this, *wxGetApp().GetOpenSync().os22(),
528 "SDAIN", changes, always);
529 dlg.ShowModal();
530 wxString msg(dlg.GetCommand().c_str(), wxConvUTF8);
531 msg += _T(" ");
532 msg += always.m_always ? _T("always") : _T("not always");
533 wxMessageBox(msg);
538 void BaseFrame::OnAppLoader(wxCommandEvent &event)
541 OpenSync::SyncChange change;
542 change.id = 1;
543 change.member_id = 1;
544 change.plugin_name = "barry-sync";
545 change.uid = "12341524235234";
546 change.printable_data =
547 "<vcal>\n"
548 " <Event>\n"
549 " <Sequence>\n"
550 " <Content>0</Content>\n"
551 " </Sequence>\n"
552 " <Summary>\n"
553 " <Content>Subject</Content>\n"
554 " </Summary>\n"
555 " <Description>\n"
556 " <Content>Bring burnt offering</Content>\n"
557 " </Description>\n"
558 " <Location>\n"
559 " <Content>Tent</Content>\n"
560 " </Location>\n"
561 " <DateStarted>\n"
562 " <Content>20100506T040000Z</Content>\n"
563 " </DateStarted>\n"
564 " <DateEnd>\n"
565 " <Content>20100507T040000Z</Content>\n"
566 " </DateEnd>\n"
567 " <Alarm>\n"
568 " <AlarmAction>AUDIO</AlarmAction>\n"
569 " <AlarmTrigger>\n"
570 " <Content>20100506T034500Z</Content>\n"
571 " <Value>DATE-TIME</Value>\n"
572 " </AlarmTrigger>\n"
573 " </Alarm>\n"
574 " </Event>\n"
575 "</vcal>\n";
577 std::vector<OpenSync::SyncChange> changes;
578 changes.push_back(change);
580 change.id = 2;
581 change.member_id = 2;
582 change.plugin_name = "evo2-sync";
583 change.uid = "asdfioausdf_1235234as_asdf12341524235234";
584 change.printable_data =
585 "<vcal>\n"
586 " <Method>\n"
587 " <Content>PUBLISH</Content>\n"
588 " </Method>\n"
589 " <Timezone>\n"
590 " <TimezoneID>/softwarestudio.org/Tzfile/America/Thunder_Bay</TimezoneID>\n"
591 " <Location>America/Thunder_Bay</Location>\n"
592 " <Standard>\n"
593 " <TimezoneName>EST</TimezoneName>\n"
594 " <DateStarted>19701107T010000</DateStarted>\n"
595 " <RecurrenceRule>\n"
596 " <Rule>FREQ=YEARLY</Rule>\n"
597 " <Rule>INTERVAL=1</Rule>\n"
598 " <Rule>BYDAY=2SU</Rule>\n"
599 " <Rule>BYMONTH=11</Rule>\n"
600 " </RecurrenceRule>\n"
601 " <TZOffsetFrom>-0400</TZOffsetFrom>\n"
602 " <TZOffsetTo>-0500</TZOffsetTo>\n"
603 " </Standard>\n"
604 " <DaylightSavings>\n"
605 " <TimezoneName>EDT</TimezoneName>\n"
606 " <DateStarted>19700313T030000</DateStarted>\n"
607 " <RecurrenceRule>\n"
608 " <Rule>FREQ=YEARLY</Rule>\n"
609 " <Rule>INTERVAL=1</Rule>\n"
610 " <Rule>BYDAY=2SU</Rule>\n"
611 " <Rule>BYMONTH=3</Rule>\n"
612 " </RecurrenceRule>\n"
613 " <TZOffsetFrom>-0500</TZOffsetFrom>\n"
614 " <TZOffsetTo>-0400</TZOffsetTo>\n"
615 " </DaylightSavings>\n"
616 " </Timezone>\n"
617 " <Event>\n"
618 " <Sequence>\n"
619 " <Content>1</Content>\n"
620 " </Sequence>\n"
621 " <Summary>\n"
622 " <Content>Celebration day</Content>\n"
623 " </Summary>\n"
624 " <Location>\n"
625 " <Content>Tent of</Content>\n"
626 " </Location>\n"
627 " <DateStarted>\n"
628 " <Content>20100506T000000</Content>\n"
629 " <TimezoneID>/softwarestudio.org/Tzfile/America/Thunder_Bay</TimezoneID>\n"
630 " </DateStarted>\n"
631 " <DateEnd>\n"
632 " <Content>20100507T000000</Content>\n"
633 " <TimezoneID>/softwarestudio.org/Tzfile/America/Thunder_Bay</TimezoneID>\n"
634 " </DateEnd>\n"
635 " <DateCalendarCreated>\n"
636 " <Content>20100430T214736Z</Content>\n"
637 " </DateCalendarCreated>\n"
638 " <DateCreated>\n"
639 " <Content>20100430T214736</Content>\n"
640 " </DateCreated>\n"
641 " <LastModified>\n"
642 " <Content>20100430T214927</Content>\n"
643 " </LastModified>\n"
644 " <Description>\n"
645 " <Content>Bring burnt offering</Content>\n"
646 " </Description>\n"
647 " <Class>\n"
648 " <Content>PUBLIC</Content>\n"
649 " </Class>\n"
650 " <Transparency>\n"
651 " <Content>OPAQUE</Content>\n"
652 " </Transparency>\n"
653 " <Alarm>\n"
654 " <AlarmAction>AUDIO</AlarmAction>\n"
655 " <AlarmTrigger>\n"
656 " <Content>20100506T034500Z</Content>\n"
657 " <Value>DATE-TIME</Value>\n"
658 " </AlarmTrigger>\n"
659 " </Alarm>\n"
660 " </Event>\n"
661 "</vcal>\n";
664 changes.push_back(change);
667 ConflictDlg::AlwaysMemoryBlock always;
668 ConflictDlg dlg(this, *wxGetApp().GetOpenSync().os22(),
669 "SDAIN", changes, always);
670 dlg.ShowModal();
671 wxString msg(dlg.GetCommand().c_str(), wxConvUTF8);
672 msg += _T(" ");
673 msg += always.m_always ? _T("always") : _T("not always");
674 wxMessageBox(msg);
679 void BaseFrame::OnMigrateDevice(wxCommandEvent &event)
681 try {
683 int i = Barry::Probe::Find(wxGetApp().GetResults(),
684 GetCurrentComboPin());
686 MigrateDlg dlg(this, wxGetApp().GetResults(), i);
687 dlg.ShowModal();
690 catch( std::exception &e ) {
691 wxString msg(_T(
692 "An error occurred during device migration.\n"
693 "This could be due to a low level USB issue\n"
694 "Please make sure your device is plugged in\n"
695 "and not in Desktop Mode. If it is, try replugging\n"
696 "the device, and rescanning the USB bus from the menu.\n"
697 "\n"
698 "Error: "));
699 msg += wxString(e.what(), wxConvUTF8);
700 wxMessageBox(msg, _T("Migrate Device"), wxOK | wxICON_ERROR);
701 return;
705 void BaseFrame::OnBrowseDatabases(wxCommandEvent &event)
707 int i = Barry::Probe::Find(wxGetApp().GetResults(), GetCurrentComboPin());
708 if( i == -1 ) {
709 wxMessageBox(_T("There is no device selected in the device list. Please select a device to browse."),
710 _T("Database Browser Mode"), wxOK | wxICON_ERROR);
711 return;
714 try {
715 m_browse_mode.reset( new BrowseMode(this,
716 wxGetApp().GetResults()[i]) );
718 catch( std::exception &e ) {
719 wxString msg(_T(
720 "An error occurred that prevented the loading of Database\n"
721 "Browse mode. This could be due to a low level USB\n"
722 "issue. Please make sure your device is plugged in\n"
723 "and not in Desktop Mode. If it is, try replugging\n"
724 "the device, and rescanning the USB bus from the menu.\n"
725 "\n"
726 "Error: "));
727 msg += wxString(e.what(), wxConvUTF8);
728 wxMessageBox(msg, _T("Database Browser Mode"), wxOK | wxICON_ERROR);
729 return;
732 EnableBackButton(m_browse_mode.get());
735 void BaseFrame::OnMediaManagement(wxCommandEvent &event)
739 void BaseFrame::OnMisc(wxCommandEvent &event)
743 void BaseFrame::OnBackButton(wxCommandEvent &event)
745 DisableBackButton();
748 void BaseFrame::OnTermBackupAndRestore(wxProcessEvent &event)
750 barryverbose("OnTermBackupAndRestore(): done = "
751 << (!m_backup_process.IsAppRunning() ? "true" : "false")
752 << ", status = " << m_backup_process.GetRawAppStatus()
753 << ", exit code = " << m_backup_process.GetChildExitCode());
754 // only give a warning if the application could not be run...
755 // if there's an error code, and it's been running for longer
756 // than a second or two, then it's a real error code, or a
757 // segfault or something similar.
758 if( !m_backup_process.IsAppRunning() &&
759 m_backup_process.GetChildExitCode() &&
760 (time(NULL) - m_backup_process.GetStartTime()) < 2 )
762 wxMessageBox(_T("Unable to run barrybackup, or it returned an error. Please make sure it is installed and in your PATH."),
763 _T("Backup and Restore"), wxOK | wxICON_ERROR);
767 void BaseFrame::OnBarryLogoClicked(wxCommandEvent &event)
769 PopupMenu(m_sysmenu.get(), 20, 20);
772 void BaseFrame::OnNetDirectLogoClicked(wxCommandEvent &event)
774 // fire up a browser to point to the Barry documentation
775 wxBusyCursor wait;
776 ::wxLaunchDefaultBrowser(_T("http://netdirect.ca/barry"));
779 void BaseFrame::OnDeviceComboChange(wxCommandEvent &event)
781 Barry::Pin pin = GetCurrentComboPin();
783 // any change?
784 if( pin == wxGetApp().GetGlobalConfig().GetLastDevice() )
785 return; // nope
787 // save
788 wxGetApp().GetGlobalConfig().SetLastDevice(pin);
790 // update sys menu
791 m_sysmenu->Enable(SysMenu_RenameDevice, false);
793 // update the main mode's screenshot
794 m_main_menu_mode->UpdateScreenshot(pin);
795 if( m_current_mode == m_main_menu_mode.get() )
796 Refresh(false);
798 // FIXME - if inside a sub menu mode, we need to destroy the mode
799 // class and start fresh
802 void BaseFrame::OnVerboseLogging(wxCommandEvent &event)
804 Barry::Verbose( !Barry::IsVerbose() );
805 wxGetApp().GetGlobalConfig().SetVerboseLogging( Barry::IsVerbose() );
806 UpdateMenuState();
809 void BaseFrame::OnRenameDevice(wxCommandEvent &event)
811 Barry::Pin pin = GetCurrentComboPin();
812 if( !pin.Valid() )
813 return;
815 // grab the current known name of the device
816 const Barry::Probe::Results &results = wxGetApp().GetResults();
817 int index = Barry::Probe::Find(results, pin);
818 if( index == -1 )
819 return;
821 wxString current_name(results[index].m_cfgDeviceName.c_str(), wxConvUTF8);
822 wxTextEntryDialog dlg(this,
823 _T("Please enter a name for the current device:"),
824 _T("Rename Device"),
825 current_name, wxTextEntryDialogStyle);
827 if( dlg.ShowModal() != wxID_OK )
828 return; // nothing to do
829 wxString name = dlg.GetValue();
830 if( name == current_name )
831 return; // nothing to do
833 wxGetApp().SetDeviceName(pin, string(name.utf8_str()));
835 // refill combo box
836 CreateDeviceCombo(wxGetApp().GetGlobalConfig().GetLastDevice());
839 void BaseFrame::OnResetDevice(wxCommandEvent &event)
841 int i = Barry::Probe::Find(wxGetApp().GetResults(), GetCurrentComboPin());
842 if( i != -1 ) {
843 Usb::Device dev(wxGetApp().GetResults()[i].m_dev);
844 dev.Reset();
845 wxBusyCursor wait;
846 wxSleep(4);
847 OnRescanUsb(event);
851 void BaseFrame::OnRescanUsb(wxCommandEvent &event)
853 if( m_current_mode == m_main_menu_mode.get() ) {
854 std::auto_ptr<UsbScanSplash> splash( new UsbScanSplash );
855 wxGetApp().Probe();
856 CreateDeviceCombo(wxGetApp().GetGlobalConfig().GetLastDevice());
858 else {
859 // FIXME - tell the user we didn't do anything?
860 // or perhaps just disable rescan while in a mode
864 void BaseFrame::OnAbout(wxCommandEvent &event)
866 wxAboutDialogInfo info;
867 info.SetName(_T("Barry Desktop Control Panel"));
868 info.SetVersion(_T("0.18.0"));
869 info.SetDescription(_T("A Free Software graphical user interface for working with the BlackBerry® smartphone."));
870 info.SetCopyright(_T("Copyright © 2009-2012, Net Direct Inc."));
871 info.SetWebSite(_T("http://netdirect.ca/barry"));
872 info.SetLicense(_T(
873 " This program is free software; you can redistribute it and/or modify\n"
874 " it under the terms of the GNU General Public License as published by\n"
875 " the Free Software Foundation; either version 2 of the License, or\n"
876 " (at your option) any later version.\n"
877 "\n"
878 " This program is distributed in the hope that it will be useful,\n"
879 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
880 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
881 "\n"
882 " See the GNU General Public License in the COPYING file at the\n"
883 " root directory of this project for more details.\n"));
885 info.AddDeveloper(_T("Net Direct Inc."));
886 // info.AddDeveloper(_T("Chris Frey <cdfrey@foursquare.net>"));
887 // info.AddDeveloper(_T("See AUTHORS file for detailed"));
888 // info.AddDeveloper(_T("contribution information."));
890 info.AddArtist(_T("Chris Frey - GUI interface"));
891 info.AddArtist(_T("Martin Owens - Barry logo"));
892 info.AddArtist(_T("Tango Desktop Project - Public domain icons"));
894 wxAboutBox(info);
897 void BaseFrame::OnExit(wxCommandEvent &event)
899 Close(true);