desktop: fixed bug where menu's Rename Device option got incorrectly disabled
[barry.git] / desktop / src / BaseFrame.cc
blob224890d5df33fc91fc75e51be882105cefb85223
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 "config.h"
32 #include <wx/aboutdlg.h>
33 #include <iostream>
34 #include <sstream>
36 // include icons and logos
37 #include "../images/barry_logo_icon.xpm"
38 #include "../images/logo_NetDirect.xpm"
40 using namespace std;
42 BEGIN_EVENT_TABLE(BaseFrame, wxFrame)
43 EVT_SIZE (BaseFrame::OnSize)
44 EVT_PAINT (BaseFrame::OnPaint)
45 EVT_MOTION (BaseFrame::OnMouseMotion)
46 EVT_LEFT_DOWN (BaseFrame::OnLeftDown)
47 EVT_LEFT_UP (BaseFrame::OnLeftUp)
48 EVT_BUTTON (MainMenu_BackupAndRestore, BaseFrame::OnBackupRestore)
49 EVT_BUTTON (MainMenu_Sync, BaseFrame::OnSync)
50 EVT_BUTTON (MainMenu_Modem, BaseFrame::OnModem)
51 EVT_BUTTON (MainMenu_AppLoader, BaseFrame::OnAppLoader)
52 EVT_BUTTON (MainMenu_MigrateDevice, BaseFrame::OnMigrateDevice)
53 EVT_BUTTON (MainMenu_BrowseDatabases, BaseFrame::OnBrowseDatabases)
54 EVT_BUTTON (MainMenu_MediaManagement, BaseFrame::OnMediaManagement)
55 EVT_BUTTON (MainMenu_Misc, BaseFrame::OnMisc)
56 EVT_BUTTON (MainMenu_BackButton, BaseFrame::OnBackButton)
57 EVT_BUTTON (HotImage_BarryLogo, BaseFrame::OnBarryLogoClicked)
58 EVT_BUTTON (HotImage_NetDirectLogo, BaseFrame::OnNetDirectLogoClicked)
59 EVT_TEXT (Ctrl_DeviceCombo, BaseFrame::OnDeviceComboChange)
60 EVT_MENU (SysMenu_VerboseLogging, BaseFrame::OnVerboseLogging)
61 EVT_MENU (SysMenu_RenameDevice, BaseFrame::OnRenameDevice)
62 EVT_MENU (SysMenu_ResetDevice, BaseFrame::OnResetDevice)
63 EVT_MENU (SysMenu_RescanUsb, BaseFrame::OnRescanUsb)
64 EVT_MENU (SysMenu_About, BaseFrame::OnAbout)
65 EVT_MENU (SysMenu_Exit, BaseFrame::OnExit)
66 EVT_END_PROCESS (Process_BackupAndRestore, BaseFrame::OnTermBackupAndRestore)
67 END_EVENT_TABLE()
69 //////////////////////////////////////////////////////////////////////////////
70 // BaseFrame
72 BaseFrame::BaseFrame(const wxImage &background)
73 : wxFrame(NULL, wxID_ANY, _T("Barry Desktop Control Panel"),
74 wxPoint(50, 50),
75 wxSize(background.GetWidth(), background.GetHeight()),
76 wxMINIMIZE_BOX | wxCAPTION | wxCLOSE_BOX | wxSYSTEM_MENU |
77 wxCLIP_CHILDREN)
78 , TermCatcher(this, Process_BackupAndRestore)
79 , m_width(background.GetWidth())
80 , m_height(background.GetHeight())
81 , m_current_mode(0)
82 , m_backup_process(this)
84 // This is a workaround for different size behaviour
85 // in the GTK version of wxWidgets 2.9
86 SetClientSize(wxSize(background.GetWidth(), background.GetHeight()));
88 // load base bitmaps
89 m_background.reset( new wxBitmap(background) );
91 // the main menu mode always exists, but may not always be current
92 m_main_menu_mode.reset( new MainMenuMode(this) );
93 m_current_mode = m_main_menu_mode.get();
95 m_barry_logo.reset( new ClickableImage(this,
96 wxBitmap(barry_logo_icon_xpm), HotImage_BarryLogo,
97 4, 4, false) );
98 wxBitmap nd_logo(logo_NetDirect_xpm);
99 m_netdirect_logo.reset( new ClickableImage(this,
100 nd_logo, HotImage_NetDirectLogo,
101 m_width - 3 - nd_logo.GetWidth(),
102 (MAIN_HEADER_OFFSET - nd_logo.GetHeight()) / 2, true,
103 wxNullCursor));
105 // Create the Barry Logo popup system menu
106 m_sysmenu.reset( new wxMenu );
107 m_sysmenu->Append( new wxMenuItem(m_sysmenu.get(),
108 SysMenu_VerboseLogging, _T("&Verbose Logging"),
109 _T("Enable low level USB debug output"), wxITEM_CHECK, NULL) );
110 m_sysmenu->Append(SysMenu_RenameDevice, _T("Re&name Device..."));
111 m_sysmenu->Append(SysMenu_ResetDevice, _T("Re&set Device"));
112 m_sysmenu->Append(SysMenu_RescanUsb, _T("&Rescan USB"));
113 m_sysmenu->AppendSeparator();
114 m_sysmenu->Append(SysMenu_About, _T("&About..."));
115 m_sysmenu->AppendSeparator();
116 m_sysmenu->Append(wxID_EXIT, _T("E&xit"));
118 UpdateMenuState();
119 CreateDeviceCombo(wxGetApp().GetGlobalConfig().GetLastDevice());
122 void BaseFrame::UpdateMenuState()
124 if( !m_sysmenu.get() )
125 return;
127 wxMenuItemList &list = m_sysmenu->GetMenuItems();
128 wxMenuItemList::iterator b = list.begin();
129 for( ; b != list.end(); ++b ) {
130 wxMenuItem *item = *b;
132 switch( item->GetId() )
134 case SysMenu_VerboseLogging:
135 item->Check(Barry::IsVerbose());
136 break;
141 void BaseFrame::CreateDeviceCombo(Barry::Pin pin)
143 const Barry::Probe::Results &results = wxGetApp().GetResults();
145 // default to:
146 // no device selected, if multiple available and no default given
147 // no devices available, if nothing there
148 // the first device, if only one exists
149 int selected = 0;
151 // create a list of selections
152 wxArrayString devices;
154 // if there's more than one device, let the user pick "none"
155 if( results.size() > 1 ) {
156 devices.Add(_T("No device selected"));
159 // add one entry for each device
160 for( Barry::Probe::Results::const_iterator i = results.begin();
161 i != results.end(); ++i )
163 // if this is the desired item, remember this selection
164 if( pin.Valid() && i->m_pin == pin ) {
165 selected = devices.GetCount();
168 devices.Add(wxString(i->GetDisplayName().c_str(), wxConvUTF8));
171 // if nothing is there, be descriptive
172 if( devices.GetCount() == 0 ) {
173 devices.Add(_T("No devices available"));
176 // create the combobox
177 int x = m_width - 300;
178 int y = m_height - (MAIN_HEADER_OFFSET - 5);
179 m_device_combo.reset( new wxComboBox(this, Ctrl_DeviceCombo, _T(""),
180 wxPoint(x, y), wxSize(290, -1), devices, wxCB_READONLY) );
182 // select the desired entry
183 m_device_combo->SetValue(devices[selected]);
185 // update the screenshot
186 m_main_menu_mode->UpdateScreenshot(GetCurrentComboPin());
189 Barry::Pin BaseFrame::GetCurrentComboPin()
191 // fetch newly selected device
192 wxString value = m_device_combo->GetValue();
193 istringstream iss(string(value.utf8_str()).substr(0,8));
194 Barry::Pin pin;
195 iss >> pin;
196 return pin;
199 void BaseFrame::EnableBackButton(Mode *new_mode)
201 // create the button - this goes in the bottom FOOTER area
202 // so the height must be fixed to MAIN_HEADER_OFFSET
203 // minus a border of 5px top and bottom
204 wxPoint pos(10, m_height - (MAIN_HEADER_OFFSET - 5));
205 wxSize size(-1, MAIN_HEADER_OFFSET - 5 - 5);
207 m_back_button.reset( new wxButton(this, MainMenu_BackButton,
208 _T("Main Menu"), pos, size) );
210 // set the new mode
211 m_current_mode = new_mode;
213 // destroy the device switcher combo box
214 m_device_combo.reset();
216 // without the device combo, there is no concept of a
217 // "current device" so temporarily disable the USB options
218 m_sysmenu->Enable(SysMenu_RenameDevice, false);
219 m_sysmenu->Enable(SysMenu_ResetDevice, false);
220 m_sysmenu->Enable(SysMenu_RescanUsb, false);
222 // repaint!
223 Refresh(false);
226 void BaseFrame::DisableBackButton()
228 // destroy the back button
229 m_back_button.reset();
231 // delete all modes
232 m_sync_mode.reset();
233 m_browse_mode.reset();
235 // create the device switcher combo again
236 CreateDeviceCombo(wxGetApp().GetGlobalConfig().GetLastDevice());
238 // enable the USB menu options
239 Barry::Pin pin = GetCurrentComboPin();
240 m_sysmenu->Enable(SysMenu_RenameDevice, pin.Valid());
241 m_sysmenu->Enable(SysMenu_ResetDevice, true);
242 m_sysmenu->Enable(SysMenu_RescanUsb, true);
244 // reset the current mode to main menu and repaint
245 m_current_mode = m_main_menu_mode.get();
246 Refresh(false);
249 void BaseFrame::OnSize(wxSizeEvent &event)
253 void BaseFrame::OnPaint(wxPaintEvent &event)
255 wxPaintDC dc(this);
256 dc.SetMapMode(wxMM_TEXT);
258 // paint the background image
259 dc.DrawBitmap(*m_background, 0, 0);
261 // paint the header: Barry logo
262 m_barry_logo->Draw(dc);
264 // paint the header: NetDirect logo
265 // m_netdirect_logo->Draw(dc);
267 // paint the header: text
268 auto_ptr<wxFont> font( wxFont::New(14,
269 wxFONTFAMILY_SWISS, wxFONTFLAG_ANTIALIASED,
270 _T("Luxi Sans")) );
271 dc.SetFont( *font );
272 dc.SetTextForeground( wxColour(0xd2, 0xaf, 0x0b) );
273 dc.SetTextBackground( wxColour(0, 0, 0, wxALPHA_TRANSPARENT) );
275 long width, height, descent;
276 wxString header = _T("Barry Desktop Control Panel");
277 if( m_current_mode )
278 header = m_current_mode->GetTitleText();
279 dc.GetTextExtent(header, &width, &height, &descent);
280 int x = (m_width - width) / 2;
281 int y = (MAIN_HEADER_OFFSET - height) / 2;
282 dc.DrawText(header, x, y);
284 // let the mode do its thing
285 if( m_current_mode )
286 m_current_mode->OnPaint(dc);
289 void BaseFrame::OnMouseMotion(wxMouseEvent &event)
291 wxClientDC dc(this);
292 m_barry_logo->HandleMotion(dc, event.m_x, event.m_y);
293 // m_netdirect_logo->HandleMotion(dc, event.m_x, event.m_y);
295 // the mode
296 if( m_current_mode )
297 m_current_mode->OnMouseMotion(dc, event.m_x, event.m_y);
300 void BaseFrame::OnLeftDown(wxMouseEvent &event)
302 wxClientDC dc(this);
303 m_barry_logo->HandleDown(dc, event.m_x, event.m_y);
304 // m_netdirect_logo->HandleDown(dc, event.m_x, event.m_y);
305 event.Skip();
307 // the mode
308 if( m_current_mode )
309 m_current_mode->OnLeftDown(dc, event.m_x, event.m_y);
312 void BaseFrame::OnLeftUp(wxMouseEvent &event)
314 wxClientDC dc(this);
315 m_barry_logo->HandleUp(dc, event.m_x, event.m_y);
316 // m_netdirect_logo->HandleUp(dc, event.m_x, event.m_y);
318 // the mode
319 if( m_current_mode )
320 m_current_mode->OnLeftUp(dc, event.m_x, event.m_y);
323 void BaseFrame::OnBackupRestore(wxCommandEvent &event)
325 if( m_backup_process.IsAppRunning() ) {
326 wxMessageBox(_T("The Backup program is already running!"),
327 _T("Backup and Restore"), wxOK | wxICON_INFORMATION);
328 return;
331 if( !m_backup_process.Run(this, "Backup and Restore", _T("barrybackup")) )
332 return;
335 void BaseFrame::OnSync(wxCommandEvent &event)
337 if( wxGetApp().GetOpenSync().GetAvailable() == 0 ) {
338 wxGetApp().ShowMissingOpenSyncMessage();
339 return;
342 try {
343 m_sync_mode.reset( new SyncMode(this) );
345 catch( std::exception &e ) {
346 wxString msg(_T(
347 "An error occurred that prevented the loading of Sync\n"
348 "mode. This is most likely because a critical piece\n"
349 "of OpenSync is missing. Check that all required\n"
350 "plugins are installed, and that tools like 'bidentify'\n"
351 "can find your BlackBerry(R) successfully.\n\n"
352 "Error: "));
353 msg += wxString(e.what(), wxConvUTF8);
354 wxMessageBox(msg, _T("Sync Mode"), wxOK | wxICON_ERROR);
355 return;
358 EnableBackButton(m_sync_mode.get());
361 void BaseFrame::OnModem(wxCommandEvent &event)
363 Barry::Pin pin = GetCurrentComboPin();
364 if( pin.Valid() ) {
365 ModemDlg::DoModem(this, pin);
367 else {
368 wxMessageBox(_T("Please select a device first."),
369 _T("No Device"), wxOK | wxICON_ERROR, this);
373 OpenSync::SyncChange change;
374 change.id = 1;
375 change.member_id = 1;
376 change.plugin_name = "barry-sync";
377 change.uid = "12341524235234";
378 change.printable_data =
379 "<contact>\n"
380 " <UnknownNode>\n"
381 " <NodeName>PRODID</NodeName>\n"
382 " <Content>-//OpenSync//NONSGML Barry Contact Record//EN</Content>\n"
383 " </UnknownNode>\n"
384 " <FormattedName>\n"
385 " <Content>Adame Brandee</Content>\n"
386 " </FormattedName>\n"
387 " <Name>\n"
388 " <LastName>Brandee</LastName>\n"
389 " <FirstName>Adame</FirstName>\n"
390 " </Name>\n"
391 " <AddressLabel>\n"
392 " <Content>71 Long St.\n"
393 "Toronto ON Canada\n"
394 "N0N 0N0</Content>\n"
395 " <Type>home</Type>\n"
396 " </AddressLabel>\n"
397 " <Address>\n"
398 " <Street>71 Long St.</Street>\n"
399 " <City>Toronto</City>\n"
400 " <Region>ON</Region>\n"
401 " <PostalCode>N0N 0N0</PostalCode>\n"
402 " <Country>Canada</Country>\n"
403 " <Type>home</Type>\n"
404 " </Address>\n"
405 " <Telephone>\n"
406 " <Content>+1 (416) 555-7711</Content>\n"
407 " <Type>voice</Type>\n"
408 " <Type>home</Type>\n"
409 " </Telephone>\n"
410 " <Telephone>\n"
411 " <Content>+1 (416) 955-7117</Content>\n"
412 " <Type>msg</Type>\n"
413 " <Type>cell</Type>\n"
414 " </Telephone>\n"
415 " <EMail>\n"
416 " <Content>abrandee@sympatico.ca</Content>\n"
417 " <Type>internet</Type>\n"
418 " <Type>pref</Type>\n"
419 " </EMail>\n"
420 " <Categories>\n"
421 " <Category>Personal</Category>\n"
422 " </Categories>\n"
423 " <Note>\n"
424 " <Content>Interweb salesman... 24/7</Content>\n"
425 " </Note>\n"
426 "</contact>";
428 std::vector<OpenSync::SyncChange> changes;
429 changes.push_back(change);
431 change.id = 2;
432 change.member_id = 2;
433 change.plugin_name = "evo2-sync";
434 change.uid = "asdfioausdf_1235234as_asdf12341524235234";
435 change.printable_data =
436 "<contact>\n"
437 " <Telephone>\n"
438 " <Content>+1 (416) 955-7117</Content>\n"
439 " <Type>CELL</Type>\n"
440 " <Slot>2</Slot>\n"
441 " </Telephone>\n"
442 " <Telephone>\n"
443 " <Content>+1 (416) 555-7711</Content>\n"
444 " <Type>HOME</Type>\n"
445 " <Type>VOICE</Type>\n"
446 " <Slot>1</Slot>\n"
447 " </Telephone>\n"
448 " <EMail>\n"
449 " <Content>abrandee@sympatico.ca</Content>\n"
450 " <Type>OTHER</Type>\n"
451 " <Slot>1</Slot>\n"
452 " </EMail>\n"
453 " <WantsHtml>\n"
454 " <Content>FALSE</Content>\n"
455 " </WantsHtml>\n"
456 " <Revision>\n"
457 " <Content>20100322T225303Z</Content>\n"
458 " </Revision>\n"
459 " <UnknownNode>\n"
460 " <NodeName>PRODID</NodeName>\n"
461 " <Content>-//OpenSync//NONSGML Barry Contact Record//EN</Content>\n"
462 " </UnknownNode>\n"
463 " <FormattedName>\n"
464 " <Content>Adam Brandeee</Content>\n"
465 " </FormattedName>\n"
466 " <Name>\n"
467 " <LastName>Brandeee</LastName>\n"
468 " <FirstName>Adam</FirstName>\n"
469 " </Name>\n"
470 " <AddressLabel>\n"
471 " <Content>71 Long St.\n"
472 "Toronto, ON\n"
473 "N0N 0N1\n"
474 "Canada</Content>\n"
475 " <Type>home</Type>\n"
476 " </AddressLabel>\n"
477 " <Address>\n"
478 " <Street>71 Long St.</Street>\n"
479 " <City>Toronto</City>\n"
480 " <Region>ON</Region>\n"
481 " <PostalCode>N0N 0N1</PostalCode>\n"
482 " <Country>Canada</Country>\n"
483 " <Type>home</Type>\n"
484 " </Address>\n"
485 " <Categories>\n"
486 " <Category>Personal</Category>\n"
487 " </Categories>\n"
488 " <FileAs>\n"
489 " <Content>Brandeee, Adam</Content>\n"
490 " </FileAs>\n"
491 "</contact>";
493 changes.push_back(change);
496 ConflictDlg::AlwaysMemoryBlock always;
497 ConflictDlg dlg(this, *wxGetApp().GetOpenSync().os22(),
498 "SDAIN", changes, always);
499 dlg.ShowModal();
500 wxString msg(dlg.GetCommand().c_str(), wxConvUTF8);
501 msg += _T(" ");
502 msg += always.m_always ? _T("always") : _T("not always");
503 wxMessageBox(msg);
508 void BaseFrame::OnAppLoader(wxCommandEvent &event)
511 OpenSync::SyncChange change;
512 change.id = 1;
513 change.member_id = 1;
514 change.plugin_name = "barry-sync";
515 change.uid = "12341524235234";
516 change.printable_data =
517 "<vcal>\n"
518 " <Event>\n"
519 " <Sequence>\n"
520 " <Content>0</Content>\n"
521 " </Sequence>\n"
522 " <Summary>\n"
523 " <Content>Subject</Content>\n"
524 " </Summary>\n"
525 " <Description>\n"
526 " <Content>Bring burnt offering</Content>\n"
527 " </Description>\n"
528 " <Location>\n"
529 " <Content>Tent</Content>\n"
530 " </Location>\n"
531 " <DateStarted>\n"
532 " <Content>20100506T040000Z</Content>\n"
533 " </DateStarted>\n"
534 " <DateEnd>\n"
535 " <Content>20100507T040000Z</Content>\n"
536 " </DateEnd>\n"
537 " <Alarm>\n"
538 " <AlarmAction>AUDIO</AlarmAction>\n"
539 " <AlarmTrigger>\n"
540 " <Content>20100506T034500Z</Content>\n"
541 " <Value>DATE-TIME</Value>\n"
542 " </AlarmTrigger>\n"
543 " </Alarm>\n"
544 " </Event>\n"
545 "</vcal>\n";
547 std::vector<OpenSync::SyncChange> changes;
548 changes.push_back(change);
550 change.id = 2;
551 change.member_id = 2;
552 change.plugin_name = "evo2-sync";
553 change.uid = "asdfioausdf_1235234as_asdf12341524235234";
554 change.printable_data =
555 "<vcal>\n"
556 " <Method>\n"
557 " <Content>PUBLISH</Content>\n"
558 " </Method>\n"
559 " <Timezone>\n"
560 " <TimezoneID>/softwarestudio.org/Tzfile/America/Thunder_Bay</TimezoneID>\n"
561 " <Location>America/Thunder_Bay</Location>\n"
562 " <Standard>\n"
563 " <TimezoneName>EST</TimezoneName>\n"
564 " <DateStarted>19701107T010000</DateStarted>\n"
565 " <RecurrenceRule>\n"
566 " <Rule>FREQ=YEARLY</Rule>\n"
567 " <Rule>INTERVAL=1</Rule>\n"
568 " <Rule>BYDAY=2SU</Rule>\n"
569 " <Rule>BYMONTH=11</Rule>\n"
570 " </RecurrenceRule>\n"
571 " <TZOffsetFrom>-0400</TZOffsetFrom>\n"
572 " <TZOffsetTo>-0500</TZOffsetTo>\n"
573 " </Standard>\n"
574 " <DaylightSavings>\n"
575 " <TimezoneName>EDT</TimezoneName>\n"
576 " <DateStarted>19700313T030000</DateStarted>\n"
577 " <RecurrenceRule>\n"
578 " <Rule>FREQ=YEARLY</Rule>\n"
579 " <Rule>INTERVAL=1</Rule>\n"
580 " <Rule>BYDAY=2SU</Rule>\n"
581 " <Rule>BYMONTH=3</Rule>\n"
582 " </RecurrenceRule>\n"
583 " <TZOffsetFrom>-0500</TZOffsetFrom>\n"
584 " <TZOffsetTo>-0400</TZOffsetTo>\n"
585 " </DaylightSavings>\n"
586 " </Timezone>\n"
587 " <Event>\n"
588 " <Sequence>\n"
589 " <Content>1</Content>\n"
590 " </Sequence>\n"
591 " <Summary>\n"
592 " <Content>Celebration day</Content>\n"
593 " </Summary>\n"
594 " <Location>\n"
595 " <Content>Tent of</Content>\n"
596 " </Location>\n"
597 " <DateStarted>\n"
598 " <Content>20100506T000000</Content>\n"
599 " <TimezoneID>/softwarestudio.org/Tzfile/America/Thunder_Bay</TimezoneID>\n"
600 " </DateStarted>\n"
601 " <DateEnd>\n"
602 " <Content>20100507T000000</Content>\n"
603 " <TimezoneID>/softwarestudio.org/Tzfile/America/Thunder_Bay</TimezoneID>\n"
604 " </DateEnd>\n"
605 " <DateCalendarCreated>\n"
606 " <Content>20100430T214736Z</Content>\n"
607 " </DateCalendarCreated>\n"
608 " <DateCreated>\n"
609 " <Content>20100430T214736</Content>\n"
610 " </DateCreated>\n"
611 " <LastModified>\n"
612 " <Content>20100430T214927</Content>\n"
613 " </LastModified>\n"
614 " <Description>\n"
615 " <Content>Bring burnt offering</Content>\n"
616 " </Description>\n"
617 " <Class>\n"
618 " <Content>PUBLIC</Content>\n"
619 " </Class>\n"
620 " <Transparency>\n"
621 " <Content>OPAQUE</Content>\n"
622 " </Transparency>\n"
623 " <Alarm>\n"
624 " <AlarmAction>AUDIO</AlarmAction>\n"
625 " <AlarmTrigger>\n"
626 " <Content>20100506T034500Z</Content>\n"
627 " <Value>DATE-TIME</Value>\n"
628 " </AlarmTrigger>\n"
629 " </Alarm>\n"
630 " </Event>\n"
631 "</vcal>\n";
634 changes.push_back(change);
637 ConflictDlg::AlwaysMemoryBlock always;
638 ConflictDlg dlg(this, *wxGetApp().GetOpenSync().os22(),
639 "SDAIN", changes, always);
640 dlg.ShowModal();
641 wxString msg(dlg.GetCommand().c_str(), wxConvUTF8);
642 msg += _T(" ");
643 msg += always.m_always ? _T("always") : _T("not always");
644 wxMessageBox(msg);
649 void BaseFrame::OnMigrateDevice(wxCommandEvent &event)
651 try {
653 int i = Barry::Probe::Find(wxGetApp().GetResults(),
654 GetCurrentComboPin());
656 MigrateDlg dlg(this, wxGetApp().GetResults(), i);
657 dlg.ShowModal();
660 catch( std::exception &e ) {
661 wxString msg(_T(
662 "An error occurred during device migration.\n"
663 "This could be due to a low level USB issue\n"
664 "Please make sure your device is plugged in\n"
665 "and not in Desktop Mode. If it is, try replugging\n"
666 "the device, and rescanning the USB bus from the menu.\n"
667 "\n"
668 "Error: "));
669 msg += wxString(e.what(), wxConvUTF8);
670 wxMessageBox(msg, _T("Migrate Device"), wxOK | wxICON_ERROR);
671 return;
675 void BaseFrame::OnBrowseDatabases(wxCommandEvent &event)
677 int i = Barry::Probe::Find(wxGetApp().GetResults(), GetCurrentComboPin());
678 if( i == -1 ) {
679 wxMessageBox(_T("There is no device selected in the device list. Please select a device to browse."),
680 _T("Database Browser Mode"), wxOK | wxICON_ERROR);
681 return;
684 try {
685 m_browse_mode.reset( new BrowseMode(this,
686 wxGetApp().GetResults()[i]) );
688 catch( std::exception &e ) {
689 wxString msg(_T(
690 "An error occurred that prevented the loading of Database\n"
691 "Browse mode. This could be due to a low level USB\n"
692 "issue. Please make sure your device is plugged in\n"
693 "and not in Desktop Mode. If it is, try replugging\n"
694 "the device, and rescanning the USB bus from the menu.\n"
695 "\n"
696 "Error: "));
697 msg += wxString(e.what(), wxConvUTF8);
698 wxMessageBox(msg, _T("Database Browser Mode"), wxOK | wxICON_ERROR);
699 return;
702 EnableBackButton(m_browse_mode.get());
705 void BaseFrame::OnMediaManagement(wxCommandEvent &event)
709 void BaseFrame::OnMisc(wxCommandEvent &event)
713 void BaseFrame::OnBackButton(wxCommandEvent &event)
715 DisableBackButton();
718 void BaseFrame::OnTermBackupAndRestore(wxProcessEvent &event)
720 barryverbose("OnTermBackupAndRestore(): done = "
721 << (!m_backup_process.IsAppRunning() ? "true" : "false")
722 << ", status = " << m_backup_process.GetRawAppStatus()
723 << ", exit code = " << m_backup_process.GetChildExitCode());
724 // only give a warning if the application could not be run...
725 // if there's an error code, and it's been running for longer
726 // than a second or two, then it's a real error code, or a
727 // segfault or something similar.
728 if( !m_backup_process.IsAppRunning() &&
729 m_backup_process.GetChildExitCode() &&
730 (time(NULL) - m_backup_process.GetStartTime()) < 2 )
732 wxMessageBox(_T("Unable to run barrybackup, or it returned an error. Please make sure it is installed and in your PATH."),
733 _T("Backup and Restore"), wxOK | wxICON_ERROR);
737 void BaseFrame::OnBarryLogoClicked(wxCommandEvent &event)
739 PopupMenu(m_sysmenu.get(), 20, 20);
742 void BaseFrame::OnNetDirectLogoClicked(wxCommandEvent &event)
744 // fire up a browser to point to the Barry documentation
745 wxBusyCursor wait;
746 ::wxLaunchDefaultBrowser(_T("http://netdirect.ca/barry"));
749 void BaseFrame::OnDeviceComboChange(wxCommandEvent &event)
751 Barry::Pin pin = GetCurrentComboPin();
753 // any change?
754 if( pin == wxGetApp().GetGlobalConfig().GetLastDevice() )
755 return; // nope
757 // save
758 wxGetApp().GetGlobalConfig().SetLastDevice(pin);
760 // update sys menu
761 m_sysmenu->Enable(SysMenu_RenameDevice, pin.Valid());
763 // update the main mode's screenshot
764 m_main_menu_mode->UpdateScreenshot(pin);
765 if( m_current_mode == m_main_menu_mode.get() )
766 Refresh(false);
768 // FIXME - if inside a sub menu mode, we need to destroy the mode
769 // class and start fresh
772 void BaseFrame::OnVerboseLogging(wxCommandEvent &event)
774 Barry::Verbose( !Barry::IsVerbose() );
775 wxGetApp().GetGlobalConfig().SetVerboseLogging( Barry::IsVerbose() );
776 UpdateMenuState();
779 void BaseFrame::OnRenameDevice(wxCommandEvent &event)
781 Barry::Pin pin = GetCurrentComboPin();
782 if( !pin.Valid() )
783 return;
785 // grab the current known name of the device
786 const Barry::Probe::Results &results = wxGetApp().GetResults();
787 int index = Barry::Probe::Find(results, pin);
788 if( index == -1 )
789 return;
791 wxString current_name(results[index].m_cfgDeviceName.c_str(), wxConvUTF8);
792 wxTextEntryDialog dlg(this,
793 _T("Please enter a name for the current device:"),
794 _T("Rename Device"),
795 current_name, wxTextEntryDialogStyle);
797 if( dlg.ShowModal() != wxID_OK )
798 return; // nothing to do
799 wxString name = dlg.GetValue();
800 if( name == current_name )
801 return; // nothing to do
803 wxGetApp().SetDeviceName(pin, string(name.utf8_str()));
805 // refill combo box
806 CreateDeviceCombo(wxGetApp().GetGlobalConfig().GetLastDevice());
809 void BaseFrame::OnResetDevice(wxCommandEvent &event)
811 int i = Barry::Probe::Find(wxGetApp().GetResults(), GetCurrentComboPin());
812 if( i != -1 ) {
813 Usb::Device dev(wxGetApp().GetResults()[i].m_dev);
814 dev.Reset();
815 wxBusyCursor wait;
816 wxSleep(4);
817 OnRescanUsb(event);
821 void BaseFrame::OnRescanUsb(wxCommandEvent &event)
823 if( m_current_mode == m_main_menu_mode.get() ) {
824 std::auto_ptr<UsbScanSplash> splash( new UsbScanSplash );
825 wxGetApp().Probe();
826 CreateDeviceCombo(wxGetApp().GetGlobalConfig().GetLastDevice());
828 else {
829 // FIXME - tell the user we didn't do anything?
830 // or perhaps just disable rescan while in a mode
834 void BaseFrame::OnAbout(wxCommandEvent &event)
836 wxAboutDialogInfo info;
837 info.SetName(_T("Barry Desktop Control Panel"));
838 info.SetVersion(_T(BARRY_DESKTOP_VER_STRING));
839 info.SetDescription(_T("A Free Software graphical user interface for working with the BlackBerry® smartphone."));
840 info.SetCopyright(_T("Copyright © 2009-2012, Net Direct Inc."));
841 info.SetWebSite(_T("http://netdirect.ca/barry"));
842 info.SetLicense(_T(
843 " This program is free software; you can redistribute it and/or modify\n"
844 " it under the terms of the GNU General Public License as published by\n"
845 " the Free Software Foundation; either version 2 of the License, or\n"
846 " (at your option) any later version.\n"
847 "\n"
848 " This program is distributed in the hope that it will be useful,\n"
849 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
850 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
851 "\n"
852 " See the GNU General Public License in the COPYING file at the\n"
853 " root directory of this project for more details.\n"));
855 info.AddDeveloper(_T("Net Direct Inc."));
856 // info.AddDeveloper(_T("Chris Frey <cdfrey@foursquare.net>"));
857 // info.AddDeveloper(_T("See AUTHORS file for detailed"));
858 // info.AddDeveloper(_T("contribution information."));
860 info.AddArtist(_T("Chris Frey - GUI interface"));
861 info.AddArtist(_T("Martin Owens - Barry logo"));
862 info.AddArtist(_T("Tango Desktop Project - Public domain icons"));
864 wxAboutBox(info);
867 void BaseFrame::OnExit(wxCommandEvent &event)
869 Close(true);