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