1 // This file is part of BOINC.
2 // http://boinc.berkeley.edu
3 // Copyright (C) 2008 University of California
4 //
5 // BOINC is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU Lesser General Public License
7 // as published by the Free Software Foundation,
8 // either version 3 of the License, or (at your option) any later version.
9 //
10 // BOINC is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 // See the GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with BOINC. If not, see <http://www.gnu.org/licenses/>.
17
18
19 #if defined(__GNUG__) && !defined(__APPLE__)
20 #pragma implementation "sg_BoincSimpleFrame.h"
21 #endif
22
23 #include "stdwx.h"
24 #include "diagnostics.h"
25 #include "str_util.h"
26 #include "mfile.h"
27 #include "miofile.h"
28 #include "parse.h"
29 #include "error_numbers.h"
30 #include "BOINCGUIApp.h"
31 #include "SkinManager.h"
32 #include "MainDocument.h"
33 #include "Events.h"
34 #include "BOINCBaseFrame.h"
35 #include "browser.h"
36 #include "wizardex.h"
37 #include "BOINCBaseWizard.h"
38 #include "WizardAttach.h"
39 #include "error_numbers.h"
40 #include "version.h"
41
42 #include "sg_BoincSimpleFrame.h"
43 #include "sg_TaskPanel.h"
44 #include "sg_ProjectPanel.h"
45 #include "sg_DlgMessages.h"
46 #include "sg_DlgPreferences.h"
47 #include "DlgEventLog.h"
48 #include "DlgAbout.h"
49 #include "DlgOptions.h"
50 #include "DlgDiagnosticLogFlags.h"
51
52
53 #ifdef __WXMAC__
54 #include "util.h"
55 #include "mac_util.h"
56 #endif
57
58 // Workaround for Linux refresh problem
59 // and Mac keyboard navigation problem
60 #ifdef __WXMSW__
61 #define REFRESH_WAIT 0
62 #else
63 #define REFRESH_WAIT 1
64 #endif
65
IMPLEMENT_DYNAMIC_CLASS(CSimpleFrame,CBOINCBaseFrame)66 IMPLEMENT_DYNAMIC_CLASS(CSimpleFrame, CBOINCBaseFrame)
67
68 BEGIN_EVENT_TABLE(CSimpleFrame, CBOINCBaseFrame)
69 EVT_SIZE(CSimpleFrame::OnSize)
70 EVT_MENU_OPEN(CSimpleFrame::OnMenuOpening)
71 EVT_MENU(ID_CHANGEGUI, CSimpleFrame::OnChangeGUI)
72 EVT_MENU(ID_SGDEFAULTSKINSELECTOR, CSimpleFrame::OnSelectDefaultSkin)
73 EVT_MENU_RANGE(ID_SGFIRSTSKINSELECTOR, ID_LASTSGSKINSELECTOR, CSimpleFrame::OnSelectSkin)
74 EVT_HELP(wxID_ANY, CSimpleFrame::OnHelp)
75 EVT_FRAME_CONNECT(CSimpleFrame::OnConnect)
76 EVT_FRAME_RELOADSKIN(CSimpleFrame::OnReloadSkin)
77 EVT_FRAME_NOTIFICATION(CSimpleFrame::OnNotification)
78 EVT_MENU(ID_PREFERENCES, CSimpleFrame::OnPreferences)
79 EVT_MENU(ID_SGOPTIONS, CSimpleFrame::OnOptions)
80 EVT_MENU(ID_SGDIAGNOSTICLOGFLAGS, CSimpleFrame::OnDiagnosticLogFlags)
81 EVT_MENU(ID_WIZARDATTACHPROJECT, CSimpleFrame::OnProjectsAttachToProject)
82 EVT_MENU(ID_HELPBOINC, CSimpleFrame::OnHelpBOINC)
83 EVT_MENU(ID_HELPBOINCMANAGER, CSimpleFrame::OnHelpBOINC)
84 EVT_MENU(ID_HELPBOINCWEBSITE, CSimpleFrame::OnHelpBOINC)
85 EVT_MENU(wxID_ABOUT, CSimpleFrame::OnHelpAbout)
86 EVT_MENU(ID_CHECK_VERSION, CSimpleFrame::OnCheckVersion)
87 EVT_MENU(ID_EVENTLOG, CSimpleFrame::OnEventLog)
88 EVT_MOVE(CSimpleFrame::OnMove)
89 #ifdef __WXMAC__
90 EVT_MENU(wxID_PREFERENCES, CSimpleFrame::OnPreferences)
91 #endif
92 END_EVENT_TABLE()
93
94
95 CSimpleFrame::CSimpleFrame() {
96 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::CSimpleFrame - Default Constructor Function Begin"));
97 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::CSimpleFrame - Default Constructor Function End"));
98 }
99
100
CSimpleFrame(wxString title,wxIconBundle * icons,wxPoint position,wxSize size)101 CSimpleFrame::CSimpleFrame(wxString title, wxIconBundle* icons, wxPoint position, wxSize size) :
102 CBOINCBaseFrame((wxFrame *)NULL, ID_SIMPLEFRAME, title, position, size,
103 wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN)
104 {
105 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame:: - Overloaded Constructor Function Begin"));
106
107 // Initialize Application
108 SetIcons(*icons);
109
110 CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced();
111 wxString strMenuName;
112 wxString strMenuDescription;
113
114 wxASSERT(wxDynamicCast(pSkinAdvanced, CSkinAdvanced));
115
116 // File menu
117 wxMenu *menuFile = new wxMenu;
118
119 strMenuDescription.Printf(
120 _("Close the %s window"),
121 pSkinAdvanced->GetApplicationName().c_str()
122 );
123 strMenuName = _("&Close window");
124 strMenuName += wxT("\tCtrl+W");
125 menuFile->Append(
126 ID_CLOSEWINDOW,
127 strMenuName,
128 strMenuDescription
129 );
130
131 strMenuDescription.Printf(
132 _("Exit %s"),
133 pSkinAdvanced->GetApplicationName().c_str()
134 );
135
136 strMenuName.Printf(
137 _("Exit %s"),
138 pSkinAdvanced->GetApplicationName().c_str()
139 );
140
141 menuFile->Append(
142 wxID_EXIT,
143 strMenuName,
144 strMenuDescription
145 );
146
147 #ifdef __WXMAC__
148 // wxWidgets actually puts this in the BOINCManager menu
149 menuFile->Append(
150 wxID_PREFERENCES,
151 _("Preferences...")
152 );
153 #endif
154
155 // Skins submenu
156 m_pSubmenuSkins = new wxMenu;
157
158 BuildSkinSubmenu(m_pSubmenuSkins);
159
160 // All other skin names will be appended as radio
161 // menu items with ID_SGFIRSTSKINSELECTOR + index
162
163 // View menu
164 wxMenu *menuView = new wxMenu;
165
166
167 menuView->Append(
168 ID_SGSKINSELECTOR,
169 _("Skin"),
170 m_pSubmenuSkins,
171 _("Select the appearance of the user interface.")
172 );
173
174 // Skins submenu always contains the Default entry
175 if (m_pSubmenuSkins->GetMenuItemCount() <= 1) {
176 menuView->Enable(ID_SGSKINSELECTOR, false);
177 }
178 menuView->AppendSeparator();
179 menuView->Append(
180 ID_CHANGEGUI,
181 _("Advanced View...\tCtrl+Shift+A"),
182 _("Display the advanced graphical interface.")
183 );
184
185
186 // Options menu
187 wxMenu *menuOptions = new wxMenu;
188
189 menuOptions->Append(
190 ID_PREFERENCES,
191 _("Computing &preferences..."),
192 _("Configure computing preferences")
193 );
194
195 menuOptions->Append(
196 ID_SGOPTIONS,
197 _("&Other options..."),
198 _("Configure display options and proxy settings")
199 );
200
201 // Tools menu
202 wxMenu *menuTools = new wxMenu;
203 menuTools->Append(
204 ID_WIZARDATTACHPROJECT,
205 _("&Add project..."),
206 _("Add a project")
207 );
208 menuTools->AppendSeparator();
209 menuTools->Append(
210 ID_EVENTLOG,
211 _("Event Log...\tCtrl+Shift+E"),
212 _("Display diagnostic messages.")
213 );
214
215 // Help menu
216 wxMenu *menuHelp = new wxMenu;
217
218 strMenuName.Printf(
219 _("%s &help"),
220 pSkinAdvanced->GetApplicationShortName().c_str()
221 );
222 strMenuDescription.Printf(
223 _("Show information about %s"),
224 pSkinAdvanced->GetApplicationShortName().c_str()
225 );
226 menuHelp->Append(
227 ID_HELPBOINC,
228 strMenuName,
229 strMenuDescription
230 );
231
232 strMenuName.Printf(
233 _("&%s"),
234 pSkinAdvanced->GetApplicationName().c_str()
235 );
236 strMenuDescription.Printf(
237 _("Show information about the %s"),
238 pSkinAdvanced->GetApplicationName().c_str()
239 );
240 menuHelp->Append(
241 ID_HELPBOINCMANAGER,
242 strMenuName,
243 strMenuDescription
244 );
245 menuHelp->AppendSeparator();
246 strMenuName.Printf(
247 _("%s &web site"),
248 pSkinAdvanced->GetApplicationShortName().c_str()
249 );
250 strMenuDescription.Printf(
251 _("Show information about BOINC and %s"),
252 pSkinAdvanced->GetApplicationName().c_str()
253 );
254 menuHelp->Append(
255 ID_HELPBOINCWEBSITE,
256 strMenuName,
257 strMenuDescription
258 );
259 menuHelp->AppendSeparator();
260
261 strMenuName.Printf(
262 _("Check for new %s version"),
263 pSkinAdvanced->GetApplicationShortName().c_str()
264 );
265 strMenuDescription.Printf(
266 _("Check for new %s version"),
267 pSkinAdvanced->GetApplicationShortName().c_str()
268 );
269 menuHelp->Append(
270 ID_CHECK_VERSION,
271 strMenuName,
272 strMenuDescription
273 );
274 menuHelp->AppendSeparator();
275
276 strMenuName.Printf(
277 _("&About %s..."),
278 pSkinAdvanced->GetApplicationName().c_str()
279 );
280 menuHelp->Append(
281 wxID_ABOUT,
282 strMenuName,
283 _("Licensing and copyright information.")
284 );
285
286 // construct menu
287 m_pMenubar = new wxMenuBar;
288 m_pMenubar->Append(
289 menuFile,
290 _("&File")
291 );
292 m_pMenubar->Append(
293 menuView,
294 _("&View")
295 );
296 m_pMenubar->Append(
297 menuOptions,
298 _("&Options")
299 );
300 m_pMenubar->Append(
301 menuTools,
302 _("&Tools")
303 );
304 m_pMenubar->Append(
305 menuHelp,
306 _("&Help")
307 );
308
309 wxMenuBar* m_pOldMenubar = GetMenuBar();
310 SetMenuBar(m_pMenubar);
311 if (m_pOldMenubar) {
312 delete m_pOldMenubar;
313 }
314
315 #ifdef __WXGTK__
316 // Force a redraw of the menu under Ubuntu's new interface
317 SendSizeEvent();
318 #endif
319 #ifdef __WXMAC__
320 // Mac needs a short delay to ensure that controls are
321 // created in proper order to allow keyboard navigation
322 m_iFrameRefreshRate = 1; // 1 millisecond
323 m_pPeriodicRPCTimer->Start(m_iFrameRefreshRate);
324 #endif
325
326 m_Shortcuts[0].Set(wxACCEL_NORMAL, WXK_HELP, ID_HELPBOINCMANAGER);
327 m_Shortcuts[1].Set(wxACCEL_CTRL|wxACCEL_SHIFT, (int)'E', ID_EVENTLOG);
328 m_Shortcuts[2].Set(wxACCEL_CTRL|wxACCEL_SHIFT, (int)'F', ID_SGDIAGNOSTICLOGFLAGS);
329 m_pAccelTable = new wxAcceleratorTable(3, m_Shortcuts);
330
331 SetAcceleratorTable(*m_pAccelTable);
332
333 dlgMsgsPtr = NULL;
334
335 m_pBackgroundPanel = new CSimpleGUIPanel(this);
336
337 RestoreState();
338 }
339
340
~CSimpleFrame()341 CSimpleFrame::~CSimpleFrame() {
342 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::CSimpleFrame - Destructor Function Begin"));
343
344 SaveState();
345
346 if (m_pAccelTable)
347 delete m_pAccelTable;
348
349 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::CSimpleFrame - Destructor Function End"));
350 }
351
352
SaveWindowPosition()353 bool CSimpleFrame::SaveWindowPosition() {
354 wxConfigBase* pConfig = wxConfigBase::Get(FALSE);
355 wxString strBaseConfigLocation = wxString(wxT("/Simple"));
356 wxPoint pos = GetPosition();
357
358 wxASSERT(pConfig);
359
360 // An odd case happens every once and awhile where wxWidgets looses
361 // the pointer to the config object, or it is cleaned up before
362 // the window has finished it's cleanup duty. If we detect a NULL
363 // pointer, return false.
364 if (!pConfig) return false;
365
366 pConfig->SetPath(strBaseConfigLocation);
367
368 pConfig->Write(wxT("XPos"), pos.x);
369 pConfig->Write(wxT("YPos"), pos.y);
370 return true;
371 }
372
373
SaveState()374 bool CSimpleFrame::SaveState() {
375 CBOINCBaseFrame::SaveState();
376 return SaveWindowPosition();
377 }
378
379
RestoreState()380 bool CSimpleFrame::RestoreState() {
381 CBOINCBaseFrame::RestoreState();
382 return true;
383 }
384
385
OnMove(wxMoveEvent & event)386 void CSimpleFrame::OnMove(wxMoveEvent& event) {
387 SaveWindowPosition();
388 event.Skip();
389 }
390
391
_GetCurrentViewPage()392 int CSimpleFrame::_GetCurrentViewPage() {
393 if (isMessagesDlgOpen()) {
394 return VW_SGUI | VW_SMSG;
395 } else {
396 return VW_SGUI;
397 }
398 return 0; // Should never happen.
399 }
400
401
OnMenuOpening(wxMenuEvent & event)402 void CSimpleFrame::OnMenuOpening( wxMenuEvent &event) {
403 wxLogTrace(wxT("Function Start/End"), wxT("CAdvancedFrame::OnMenuOpening - Function Begin"));
404
405 CMainDocument* pDoc = wxGetApp().GetDocument();
406 wxMenu* menuFile = NULL;
407 wxMenu* menuHelp = NULL;
408 wxMenu* menuChangeGUI = NULL;
409
410 wxASSERT(pDoc);
411
412 bool isConnected = pDoc->IsConnected();
413 wxMenu* menu = event.GetMenu();
414
415 menu->FindItem(ID_CLOSEWINDOW, &menuFile);
416 menu->FindItem(ID_HELPBOINC, &menuHelp);
417 menu->FindItem(ID_CHANGEGUI, &menuChangeGUI);
418 size_t numItems = menu->GetMenuItemCount();
419 for (size_t pos = 0; pos < numItems; ++pos) {
420 wxMenuItem * item = menu->FindItemByPosition(pos);
421 if ((menu == menuFile) || (menu == menuHelp) || (menu == menuChangeGUI)) {
422 // Always enable all items in File menu or Help menu:
423 // ID_CLOSEWINDOW, wxID_EXIT, ID_HELPBOINC, ID_HELPBOINCMANAGER,
424 // ID_HELPBOINCWEBSITE, wxID_ABOUT, ID_CHANGEGUI
425 item->Enable(true);
426 } else {
427 // Disable other menu items if not connected to client
428 item->Enable(isConnected);
429 }
430 }
431
432 // wxID_EXIT and wxID_PREFERENCES are not in File menu on some platforms
433 wxMenuItem* exitItem = menu->FindChildItem(wxID_EXIT, NULL);
434 if (exitItem) {
435 exitItem->Enable(true);
436 }
437
438 wxLogTrace(wxT("Function Start/End"), wxT("CAdvancedFrame::OnMenuOpening - Function End"));
439 }
440
441
OnChangeGUI(wxCommandEvent & WXUNUSED (event))442 void CSimpleFrame::OnChangeGUI(wxCommandEvent& WXUNUSED(event)) {
443 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnChangeGUI - Function Begin"));
444
445 wxGetApp().SetActiveGUI(BOINC_ADVANCEDGUI, true);
446
447 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnChangeGUI - Function End"));
448 }
449
450
BuildSkinSubmenu(wxMenu * submenu)451 void CSimpleFrame::BuildSkinSubmenu( wxMenu *submenu) {
452 unsigned int i;
453 wxMenuItem *skinItem;
454 wxArrayString astrSkins;
455 wxString strSelectedSkin;
456 CSkinManager* pSkinManager = wxGetApp().GetSkinManager();
457
458 wxASSERT(pSkinManager);
459 wxASSERT(wxDynamicCast(pSkinManager, CSkinManager));
460
461
462 // The "Default" skin menu item is localized, but
463 // the name of the default skin is not localized
464 skinItem = submenu->AppendRadioItem(
465 ID_SGDEFAULTSKINSELECTOR,
466 _("Default")
467 );
468
469 astrSkins = pSkinManager->GetCurrentSkins();
470 strSelectedSkin = pSkinManager->GetSelectedSkin();
471
472 if (strSelectedSkin == pSkinManager->GetDefaultSkinName()) {
473 skinItem->Check(true);
474 }
475
476 // Skins list always contains the Default entry
477 if (astrSkins.GetCount() <= 1) {
478 skinItem->Check(true);
479 skinItem->Enable(false);
480 return; // No non-default skins
481 }
482
483 // I'd like to put a separator here, but we can't separate radio items
484
485 for (i = 0; i < astrSkins.GetCount(); i++) {
486 if (astrSkins[i] == pSkinManager->GetDefaultSkinName()) {
487 continue;
488 }
489
490 skinItem = submenu->AppendRadioItem(
491 ID_SGFIRSTSKINSELECTOR + i,
492 astrSkins[i]
493 );
494 if (astrSkins[i] == strSelectedSkin) {
495 skinItem->Check(true);
496 }
497 }
498 }
499
500
501
OnSelectDefaultSkin(wxCommandEvent & WXUNUSED (event))502 void CSimpleFrame::OnSelectDefaultSkin( wxCommandEvent& WXUNUSED(event) ) {
503 CSkinManager* pSkinManager = wxGetApp().GetSkinManager();
504
505 wxASSERT(pSkinManager);
506 wxASSERT(wxDynamicCast(pSkinManager, CSkinManager));
507
508 // The "Default" skin menu item is localized, but
509 // the name of the default skin is not localized
510 pSkinManager->ReloadSkin(pSkinManager->GetDefaultSkinName());
511 }
512
513
OnSelectSkin(wxCommandEvent & event)514 void CSimpleFrame::OnSelectSkin( wxCommandEvent& event ){
515 CSkinManager *pSkinManager = wxGetApp().GetSkinManager();
516 wxMenuItem *oldItem, *selectedItem;
517 wxMenuBar *pMenuBar = GetMenuBar();
518 int newSkinId = event.GetId();
519 int oldSkinID;
520
521 wxASSERT(pSkinManager);
522 wxASSERT(wxDynamicCast(pSkinManager, CSkinManager));
523
524
525 selectedItem = pMenuBar->FindItem(newSkinId);
526 if (!selectedItem) return;
527
528 wxString oldSkinName = pSkinManager->GetSelectedSkin();
529 wxString newSkinName = selectedItem->GetItemLabelText();
530 if (newSkinName == oldSkinName) return;
531
532 if (oldSkinName == pSkinManager->GetDefaultSkinName()) {
533 // The "Default" skin menu item is localized, but
534 // the name of the default skin is not localized
535 oldSkinID = ID_SGDEFAULTSKINSELECTOR;
536 } else {
537 oldSkinID = m_pSubmenuSkins->FindItem(oldSkinName);
538 }
539 oldItem = m_pSubmenuSkins->FindItem(oldSkinID);
540 if (oldItem) {
541 oldItem->Check(false);
542 }
543
544 selectedItem->Check(true);
545 pSkinManager->ReloadSkin(newSkinName);
546
547 wxGetApp().SaveState();
548 wxConfigBase::Get(FALSE)->Flush();
549 }
550
551
OnPreferences(wxCommandEvent & WXUNUSED (event))552 void CSimpleFrame::OnPreferences(wxCommandEvent& WXUNUSED(event)) {
553 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnPreferences - Function Begin"));
554
555 m_pBackgroundPanel->SetDlgOpen(true);
556
557 CDlgPreferences dlg(GetParent());
558 if (dlg.OKToShow()) {
559 dlg.ShowModal();
560 }
561
562 m_pBackgroundPanel->SetDlgOpen(false);
563
564 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnPreferences - Function End"));
565 }
566
567
OnOptions(wxCommandEvent & WXUNUSED (event))568 void CSimpleFrame::OnOptions(wxCommandEvent& WXUNUSED(event)) {
569 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnOptions - Function Begin"));
570
571 m_pBackgroundPanel->SetDlgOpen(true);
572
573 // TODO: Create simple language selection dialog
574 CDlgOptions dlg(this);
575 dlg.ShowModal();
576
577 m_pBackgroundPanel->SetDlgOpen(false);
578
579 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnOptions - Function End"));
580 }
581
582
OnDiagnosticLogFlags(wxCommandEvent & WXUNUSED (event))583 void CSimpleFrame::OnDiagnosticLogFlags(wxCommandEvent& WXUNUSED(event)) {
584 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnDiagnosticLogFlags - Function Begin"));
585
586 CDlgDiagnosticLogFlags dlg(this);
587 dlg.ShowModal();
588
589 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnDiagnosticLogFlags - Function End"));
590 }
591
592
593 // TODO: Create ID_HELPBOINCMANAGER web page for each organization for new BOINC version
OnHelpBOINC(wxCommandEvent & event)594 void CSimpleFrame::OnHelpBOINC(wxCommandEvent& event) {
595 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnHelpBOINC - Function Begin"));
596
597 if (IsShown()) {
598 wxString strURL = wxGetApp().GetSkinManager()->GetAdvanced()->GetOrganizationHelpUrl();
599
600 wxString wxurl;
601 wxurl.Printf(
602 wxT("%s?target=simple&version=%s&controlid=%d"),
603 strURL.c_str(),
604 wxString(BOINC_VERSION_STRING, wxConvUTF8).c_str(),
605 event.GetId()
606 );
607 wxLaunchDefaultBrowser(wxurl);
608 }
609
610 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnHelpBOINC - Function End"));
611 }
612
613
OnHelpAbout(wxCommandEvent &)614 void CSimpleFrame::OnHelpAbout(wxCommandEvent& /*event*/) {
615 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnHelpAbout - Function Begin"));
616
617 m_pBackgroundPanel->SetDlgOpen(true);
618
619 CDlgAbout dlg(this);
620 wxGetApp().SetAboutDialogIsOpen(true);
621 dlg.ShowModal();
622 wxGetApp().SetAboutDialogIsOpen(false);
623
624 m_pBackgroundPanel->SetDlgOpen(false);
625
626 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnHelpAbout - Function End"));
627 }
628
OnCheckVersion(wxCommandEvent & WXUNUSED (event))629 void CSimpleFrame::OnCheckVersion(wxCommandEvent& WXUNUSED(event)) {
630 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnCheckVersion - Function Begin"));
631
632 wxGetApp().GetDocument()->CheckForVersionUpdate(true);
633
634 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnCheckVersion - Function End"));
635 }
636
637
OnHelp(wxHelpEvent & event)638 void CSimpleFrame::OnHelp(wxHelpEvent& event) {
639 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnHelp - Function Begin"));
640
641 if (IsShown()) {
642 wxString strURL = wxGetApp().GetSkinManager()->GetAdvanced()->GetOrganizationHelpUrl();
643
644 wxString wxurl;
645 wxurl.Printf(
646 wxT("%s?target=simple&version=%s&controlid=%d"),
647 strURL.c_str(),
648 wxString(BOINC_VERSION_STRING, wxConvUTF8).c_str(),
649 event.GetId()
650 );
651 wxLaunchDefaultBrowser(wxurl);
652 }
653
654 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnHelp - Function End"));
655 }
656
657
OnReloadSkin(CFrameEvent & WXUNUSED (event))658 void CSimpleFrame::OnReloadSkin(CFrameEvent& WXUNUSED(event)) {
659 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnReloadSkin - Function Start"));
660
661 CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced();
662 wxASSERT(pSkinAdvanced);
663
664 m_pBackgroundPanel->ReskinInterface();
665 SetTitle(pSkinAdvanced->GetApplicationName());
666 SetIcon(pSkinAdvanced->GetApplicationIcon()->GetIcon(wxDefaultSize));
667
668 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnReloadSkin - Function End"));
669 }
670
671
OnNotification(CFrameEvent & WXUNUSED (event))672 void CSimpleFrame::OnNotification(CFrameEvent& WXUNUSED(event)) {
673 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnNotification - Function Begin"));
674
675 CDlgMessages dlg(GetParent());
676
677 m_pBackgroundPanel->SetDlgOpen(true);
678 SetMsgsDlgOpen(&dlg);
679
680 m_pBackgroundPanel->NoticesViewed();
681 dlg.ShowModal();
682
683 m_pBackgroundPanel->SetDlgOpen(false);
684 SetMsgsDlgOpen(NULL);
685
686 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnNotification - Function End"));
687 }
688
689
OnRefreshView(CFrameEvent & WXUNUSED (event))690 void CSimpleFrame::OnRefreshView(CFrameEvent& WXUNUSED(event)) {
691 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnRefreshView - Function Start"));
692
693 m_pBackgroundPanel->OnFrameRender();
694
695 if (dlgMsgsPtr) {
696 dlgMsgsPtr->OnRefresh();
697 }
698
699 #ifdef __WXMAC__
700 if (m_iFrameRefreshRate != 1000) {
701 m_iFrameRefreshRate = 1000;
702 m_pPeriodicRPCTimer->Start(m_iFrameRefreshRate);
703 }
704
705 // We disabled tooltips on Mac while menus were popped up because they cover menus
706 wxToolTip::Enable(true);
707 #endif
708
709 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnRefreshView - Function End"));
710 }
711
712
OnProjectsAttachToProject(wxCommandEvent & WXUNUSED (event))713 void CSimpleFrame::OnProjectsAttachToProject(wxCommandEvent& WXUNUSED(event)) {
714 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnProjectsAttachToProject - Function Begin"));
715
716 CMainDocument* pDoc = wxGetApp().GetDocument();
717
718 wxASSERT(pDoc);
719 wxASSERT(wxDynamicCast(pDoc, CMainDocument));
720
721 if (!pDoc->IsUserAuthorized())
722 return;
723
724 if (pDoc->IsConnected()) {
725
726 CWizardAttach* pWizard = new CWizardAttach(this);
727
728 pWizard->Run(
729 wxEmptyString,
730 wxEmptyString,
731 wxEmptyString,
732 wxEmptyString,
733 wxEmptyString,
734 wxEmptyString,
735 wxEmptyString,
736 false,
737 false
738 );
739
740 if (pWizard)
741 pWizard->Destroy();
742
743 } else {
744 ShowNotCurrentlyConnectedAlert();
745 }
746
747 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnProjectsAttachToProject - Function End"));
748 }
749
750
OnConnect(CFrameEvent & WXUNUSED (event))751 void CSimpleFrame::OnConnect(CFrameEvent& WXUNUSED(event)) {
752 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnConnect - Function Begin"));
753
754 CMainDocument* pDoc = wxGetApp().GetDocument();
755 CWizardAttach* pWizard = NULL;
756 wxString strComputer = wxEmptyString;
757 std::string strProjectName;
758 std::string strProjectURL;
759 std::string strProjectAuthenticator;
760 std::string strProjectInstitution;
761 std::string strProjectDescription;
762 std::string strProjectKnown;
763 std::string strProjectSetupCookie;
764 bool bAccountKeyDetected = false;
765 bool bEmbedded = false;
766 ACCT_MGR_INFO ami;
767 PROJECT_INIT_STATUS pis;
768 CC_STATUS status;
769 int wasShown = 0;
770 int wasVisible = 0;
771
772 wxASSERT(pDoc);
773 wxASSERT(wxDynamicCast(pDoc, CMainDocument));
774
775 pDoc->ForceCacheUpdate();
776 pDoc->GetCoreClientStatus(status, true);
777
778 // If we are connected to the localhost, run a really quick screensaver
779 // test to trigger a firewall popup.
780 pDoc->GetConnectedComputerName(strComputer);
781 if (pDoc->IsComputerNameLocal(strComputer)) {
782 wxGetApp().StartBOINCScreensaverTest();
783 wxGetApp().StartBOINCDefaultScreensaverTest();
784 }
785
786
787 pDoc->rpc.get_project_init_status(pis);
788 pDoc->rpc.acct_mgr_info(ami);
789
790 if (ami.acct_mgr_url.size() && ami.have_credentials) {
791 // Fall through
792 //
793 // There isn't a need to bring up the attach wizard, the account manager will
794 // take care of ataching to projects when it completes the RPCs
795 //
796 } else if (ami.acct_mgr_url.size() && !ami.have_credentials) {
797 wasShown = IsShown();
798 Show();
799 wasVisible = wxGetApp().IsApplicationVisible();
800 if (!wasVisible) {
801 wxGetApp().ShowApplication(true);
802 }
803
804 pWizard = new CWizardAttach(this);
805 if (pWizard->SyncToAccountManager()) {
806
807 // _GRIDREPUBLIC, _PROGRESSTHRUPROCESSORS and _CHARITYENGINE
808 // are defined for those branded builds on Windows only
809 #if defined(_GRIDREPUBLIC) || defined(_PROGRESSTHRUPROCESSORS) || defined(_CHARITYENGINE) || defined(__WXMAC__)
810 #ifdef __WXMAC__
811 // For GridRepublic, Charity Engine or ProgressThruProcessors,
812 // the Mac installer put a branding file in our data directory
813 long iBrandID = 0; // 0 is unbranded (default) BOINC
814
815 FILE *f = boinc_fopen("/Library/Application Support/BOINC Data/Branding", "r");
816 if (f) {
817 fscanf(f, "BrandId=%ld\n", &iBrandID);
818 fclose(f);
819 }
820 if ((iBrandID > 0) && (iBrandID < 4))
821 #endif
822 {
823 // If successful, hide the main window if we showed it
824 if (!wasVisible) {
825 wxGetApp().ShowApplication(false);
826 }
827 #ifndef __WXMAC__ // See comment in CBOINCGUIApp::OnFinishInit()
828 if (!wasShown) {
829 Hide();
830 }
831 #endif
832 }
833 #endif
834 }
835 } else if ((0 >= pDoc->GetProjectCount()) && !status.disallow_attach) {
836 if (pis.url.size() > 0) {
837
838 strProjectName = pis.name.c_str();
839 strProjectURL = pis.url.c_str();
840 strProjectSetupCookie = pis.setup_cookie.c_str();
841 bAccountKeyDetected = pis.has_account_key;
842 bEmbedded = pis.embedded;
843
844 // If credentials are not cached, then we should try one last place to look up the
845 // authenticator. Some projects will set a "Setup" cookie off of their URL with a
846 // pretty short timeout. Lets take a crack at detecting it.
847 //
848 if (pis.url.length() && !pis.has_account_key) {
849 detect_setup_authenticator(pis.url, strProjectAuthenticator);
850 }
851
852 } else {
853 detect_simple_account_credentials(
854 strProjectName, strProjectURL, strProjectAuthenticator, strProjectInstitution, strProjectDescription, strProjectKnown
855 );
856 }
857
858 Show();
859 wxGetApp().ShowApplication(true);
860 pWizard = new CWizardAttach(this);
861
862 pWizard->Run(
863 wxURI::Unescape(strProjectName),
864 wxURI::Unescape(strProjectURL),
865 wxURI::Unescape(strProjectAuthenticator),
866 wxURI::Unescape(strProjectInstitution),
867 wxURI::Unescape(strProjectDescription),
868 wxURI::Unescape(strProjectKnown),
869 wxURI::Unescape(strProjectSetupCookie),
870 bAccountKeyDetected,
871 bEmbedded
872 );
873 }
874
875 if (pWizard) {
876 pWizard->Destroy();
877 m_pBackgroundPanel->UpdateProjectView();
878 }
879
880 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnConnect - Function End"));
881 }
882
883
OnEventLog(wxCommandEvent & WXUNUSED (event))884 void CSimpleFrame::OnEventLog(wxCommandEvent& WXUNUSED(event)) {
885 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnEventLog - Function Begin"));
886
887 wxGetApp().DisplayEventLog();
888
889 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnEventLog - Function End"));
890 }
891
892
IMPLEMENT_DYNAMIC_CLASS(CSimpleGUIPanel,wxPanel)893 IMPLEMENT_DYNAMIC_CLASS(CSimpleGUIPanel, wxPanel)
894
895 BEGIN_EVENT_TABLE(CSimpleGUIPanel, wxPanel)
896 EVT_ERASE_BACKGROUND(CSimpleGUIPanel::OnEraseBackground)
897 EVT_BUTTON(ID_SGNOTICESBUTTON,CSimpleGUIPanel::OnShowNotices)
898 EVT_BUTTON(ID_SGSUSPENDRESUMEBUTTON,CSimpleGUIPanel::OnSuspendResume)
899 EVT_BUTTON(ID_SIMPLE_HELP,CSimpleGUIPanel::OnHelp)
900 EVT_TIMER(ID_SIMPLEMESSAGECHECKTIMER, CSimpleGUIPanel::OnCheckForNewNotices)
901 EVT_PAINT(CSimpleGUIPanel::OnPaint)
902 END_EVENT_TABLE()
903
904
905 CSimpleGUIPanel::CSimpleGUIPanel() {
906 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::CSimpleGUIPanel - Default Constructor Function Begin"));
907 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::CSimpleGUIPanel - Default Constructor Function End"));
908 }
909
910
CSimpleGUIPanel(wxWindow * parent)911 CSimpleGUIPanel::CSimpleGUIPanel(wxWindow* parent) :
912 wxPanel(parent, -1, wxDefaultPosition, wxDefaultSize, wxCLIP_CHILDREN | wxBORDER_NONE)
913 {
914 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::CSimpleGUIPanel - Overloaded Constructor Function Begin"));
915
916 CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced();
917
918 wxASSERT(pSkinAdvanced);
919 wxASSERT(wxDynamicCast(pSkinAdvanced, CSkinAdvanced));
920
921 m_taskPanel = NULL;
922 m_projPanel = NULL;
923 m_oldWorkCount = 0;
924 m_bNewNoticeAlert = false;
925 m_bNoticesButtonIsRed = false;
926 m_irefreshCount = 0;
927
928 checkForNewNoticesTimer = new wxTimer(this, ID_SIMPLEMESSAGECHECKTIMER);
929 checkForNewNoticesTimer->Start(5000);
930
931 dlgOpen = false;
932 m_sSuspendString = _("Suspend");
933 m_sResumeString = _("Resume");
934 m_sSuspendButtonToolTip = _("Suspend Computing");
935 m_sResumeButtonToolTip = _("Resume Computing");
936
937 m_taskPanel = new CSimpleTaskPanel(this);
938 m_projPanel = new CSimpleProjectPanel(this);
939
940 // Box Sizer
941 mainSizer = new wxBoxSizer(wxVERTICAL);
942 mainSizer->AddSpacer(ADJUSTFORYDPI(68));
943 mainSizer->Add(m_taskPanel, 1, wxLEFT | wxRIGHT | wxEXPAND | wxALIGN_CENTER, SIDEMARGINS);
944 mainSizer->AddSpacer(ADJUSTFORYDPI(8));
945 mainSizer->Add(m_projPanel, 0, wxLEFT | wxRIGHT | wxEXPAND | wxALIGN_CENTER, SIDEMARGINS);
946 mainSizer->AddSpacer(ADJUSTFORYDPI(8));
947
948 wxBoxSizer* buttonsSizer;
949 buttonsSizer = new wxBoxSizer( wxHORIZONTAL );
950
951 m_NoticesButton = new wxButton( this, ID_SGNOTICESBUTTON, _("Notices"), wxDefaultPosition, wxDefaultSize, 0 );
952 m_NoticesButton->SetToolTip( _("Open a window to view notices from projects or BOINC"));
953 buttonsSizer->Add( m_NoticesButton, 0, wxEXPAND | wxALIGN_LEFT, 0 );
954 buttonsSizer->AddStretchSpacer();
955
956 int suspendWidth, resumeWidth, y;
957 GetTextExtent(m_sSuspendString, &suspendWidth, &y);
958 GetTextExtent(m_sResumeString, &resumeWidth, &y);
959
960 m_bIsSuspended = suspendWidth > resumeWidth;
961 m_SuspendResumeButton = new wxButton( this, ID_SGSUSPENDRESUMEBUTTON,
962 m_bIsSuspended ? m_sSuspendString : m_sResumeString,
963 wxDefaultPosition, wxDefaultSize, 0 );
964 m_SuspendResumeButton->SetToolTip(wxEmptyString);
965
966 buttonsSizer->Add( m_SuspendResumeButton, 0, wxEXPAND | wxALIGN_RIGHT, 0 );
967 buttonsSizer->AddStretchSpacer();
968
969 m_HelpButton = new wxButton( this, ID_SIMPLE_HELP, _("Help"), wxDefaultPosition, wxDefaultSize, 0 );
970 buttonsSizer->Add( m_HelpButton, 0, wxEXPAND | wxALIGN_RIGHT, 0 );
971
972 wxString helpTip;
973 helpTip.Printf(_("Get help with %s"), pSkinAdvanced->GetApplicationShortName().c_str());
974 m_HelpButton->SetToolTip(helpTip);
975
976 mainSizer->Add( buttonsSizer, 0, wxLEFT | wxRIGHT | wxEXPAND, 2 * SIDEMARGINS );
977 mainSizer->AddSpacer(ADJUSTFORYDPI(10));
978
979 SetSizer(mainSizer);
980 Layout();
981
982 mainSizer->Fit(GetParent());
983
984 SetBackgroundBitmap();
985
986 #ifdef __WXMAC__
987 // Tell accessibility aids to ignore this panel (but not its contents)
988 HIObjectSetAccessibilityIgnored((HIObjectRef)GetHandle(), true);
989
990 if (compareOSVersionTo(10, 7) >= 0) {
991 m_iRedRingRadius = 4;
992 } else {
993 m_iRedRingRadius = 12;
994 }
995 #endif
996
997 m_SuspendResumeButton->Disable();
998
999 OnFrameRender();
1000
1001 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::CSimpleGUIPanel - Overloaded Constructor Function End"));
1002 }
1003
1004
~CSimpleGUIPanel()1005 CSimpleGUIPanel::~CSimpleGUIPanel()
1006 {
1007 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::CSimpleGUIPanel - Destructor Function Begin"));
1008
1009 checkForNewNoticesTimer->Stop();
1010 delete checkForNewNoticesTimer;
1011 m_bmpBg = wxNullBitmap; // Deletes old bitmap via reference counting
1012
1013 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::CSimpleGUIPanel - Destructor Function End"));
1014 }
1015
1016
SetBackgroundBitmap()1017 void CSimpleGUIPanel::SetBackgroundBitmap() {
1018 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::SetBackgroundBitmap - Function Start"));
1019
1020 CSkinSimple* pSkinSimple = wxGetApp().GetSkinManager()->GetSimple();
1021
1022 wxASSERT(pSkinSimple);
1023 wxASSERT(wxDynamicCast(pSkinSimple, CSkinSimple));
1024
1025 wxColour bgColor(*pSkinSimple->GetBackgroundImage()->GetBackgroundColor());
1026 SetBackgroundColour(bgColor);
1027 wxRect panelRect = GetRect();
1028 m_bmpBg = wxBitmap(panelRect.width, panelRect.height);
1029 wxMemoryDC dc(m_bmpBg);
1030 wxBrush bgBrush(bgColor);
1031 dc.SetBackground(bgBrush);
1032 dc.Clear();
1033 #ifdef __WXMAC__
1034 // Work around an apparent bug in wxMemoryDC::Clear() in wxCarbon 2.9.4
1035 // TODO: remove this when the wxCarbon bug is fixed
1036 dc.SetBrush(bgBrush);
1037 wxPen bgPen(bgColor);
1038 dc.SetPen(bgPen);
1039 dc.DrawRectangle(panelRect);
1040 #endif
1041
1042 int srcX, srcY, destX, destY, h, w;
1043 wxBitmap* srcBmp = pSkinSimple->GetBackgroundImage()->GetBitmap();
1044 wxSize srcSize = srcBmp->GetSize();
1045 switch(pSkinSimple->GetBackgroundImage()->GetHorizontalAnchor()) {
1046 case BKGD_ANCHOR_HORIZ_LEFT:
1047 default:
1048 srcX = 0;
1049 destX = 0;
1050 break;
1051 case BKGD_ANCHOR_HORIZ_CENTER:
1052 if (panelRect.width < srcSize.GetWidth()) {
1053 srcX = (srcSize.GetWidth() - panelRect.width) / 2;
1054 destX = 0;
1055 } else {
1056 srcX = 0;
1057 destX = (panelRect.width - srcSize.GetWidth()) / 2;
1058 }
1059 break;
1060 case BKGD_ANCHOR_HORIZ_RIGHT:
1061 if (panelRect.width < srcSize.GetWidth()) {
1062 srcX = (srcSize.GetWidth() - panelRect.width);
1063 destX = 0;
1064 } else {
1065 srcX = 0;
1066 destX = (panelRect.width - srcSize.GetWidth());
1067 }
1068 break;
1069 }
1070 w = wxMin(panelRect.width, srcSize.GetWidth());
1071
1072 switch(pSkinSimple->GetBackgroundImage()->GetVerticalAnchor()) {
1073 case BKGD_ANCHOR_VERT_TOP:
1074 default:
1075 srcY = 0;
1076 destY = 0;
1077 break;
1078 case BKGD_ANCHOR_VERT_CENTER:
1079 if (panelRect.height < srcSize.GetHeight()) {
1080 srcY = (srcSize.GetHeight() - panelRect.height) / 2;
1081 destY = 0;
1082 } else {
1083 srcY = 0;
1084 destY = (panelRect.height - srcSize.GetHeight()) / 2;
1085 }
1086 break;
1087 case BKGD_ANCHOR_VERT_BOTTOM:
1088 if (panelRect.height < srcSize.GetHeight()) {
1089 srcY = (srcSize.GetHeight() - panelRect.height);
1090 destY = 0;
1091 } else {
1092 srcY = 0;
1093 destY = (panelRect.height - srcSize.GetHeight());
1094 }
1095 break;
1096 }
1097 h = wxMin(panelRect.height, srcSize.GetHeight());
1098
1099 wxMemoryDC srcDC(*srcBmp);
1100 dc.Blit(destX, destY, w, h, &srcDC, srcX, srcY, wxCOPY);
1101
1102 // dc.DrawBitmap(*pSkinSimple->GetBackgroundImage()->GetBitmap(), 0, 0, false);
1103
1104 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::SetBackgroundBitmap - Function End"));
1105 }
1106
ReskinInterface()1107 void CSimpleGUIPanel::ReskinInterface() {
1108 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::ReskinInterface - Function Start"));
1109
1110 Freeze();
1111 //bg color
1112 m_bmpBg = wxNullBitmap; // Deletes old bitmap via reference counting
1113 SetBackgroundBitmap();
1114
1115 m_taskPanel->ReskinInterface();
1116 m_projPanel->ReskinInterface();
1117
1118 Thaw();
1119 Refresh();
1120
1121 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::ReskinInterface - Function End"));
1122 }
1123
1124
OnProjectsAttachToProject(wxCommandEvent & event)1125 void CSimpleGUIPanel::OnProjectsAttachToProject(wxCommandEvent& event) {
1126 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::OnProjectsAttachToProject - Function Begin"));
1127
1128 CSimpleFrame* pFrame = wxDynamicCast(GetParent(), CSimpleFrame);
1129 wxASSERT(pFrame);
1130
1131 pFrame->OnProjectsAttachToProject(event);
1132
1133 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::OnProjectsAttachToProject - Function End"));
1134 }
1135
1136
1137 // called from CSimpleFrame::OnRefreshView()
OnFrameRender()1138 void CSimpleGUIPanel::OnFrameRender() {
1139 CMainDocument* pDoc = wxGetApp().GetDocument();
1140 wxASSERT(pDoc);
1141 int workCount = pDoc->GetSimpleGUIWorkCount();
1142 CC_STATUS status;
1143 bool isSuspended;
1144
1145 // OnFrameRender() may be called while SimpleGUI initialization is
1146 // in progress due to completion of a periodic get_messages RPC,
1147 // causing unintended recursion in CMainDocument::RequestRPC().
1148 // Check for that situation here.
1149 if (pDoc->WaitingForRPC()) return;
1150
1151 // Workaround for Linux refresh problem
1152 if (m_irefreshCount < REFRESH_WAIT) {
1153 ++m_irefreshCount;
1154 m_taskPanel->UpdatePanel(true);
1155 return;
1156 }
1157
1158 if (workCount != m_oldWorkCount) {
1159 if (workCount < 0) {
1160 m_projPanel->Hide();
1161 } else if (m_oldWorkCount == 0) {
1162 m_projPanel->Show();
1163 }
1164 this->Layout();
1165 ReskinInterface();
1166 }
1167
1168 if (IsShown()) {
1169 if ( pDoc->IsConnected() ) {
1170
1171 // Show Resume or Suspend as appropriate
1172 pDoc->GetCoreClientStatus(status);
1173
1174 isSuspended = (RUN_MODE_NEVER == status.task_mode);
1175 if ((isSuspended != m_bIsSuspended) || (!m_SuspendResumeButton->IsEnabled())) {
1176 m_bIsSuspended = isSuspended;
1177 m_SuspendResumeButton->SetLabel(m_bIsSuspended ? m_sResumeString : m_sSuspendString);
1178 m_SuspendResumeButton->SetToolTip(m_bIsSuspended ? m_sResumeButtonToolTip : m_sSuspendButtonToolTip);
1179 }
1180 m_SuspendResumeButton->Enable();
1181 } else {
1182 m_SuspendResumeButton->SetToolTip(wxEmptyString);
1183 m_SuspendResumeButton->Disable();
1184 }
1185
1186 UpdateProjectView();
1187
1188 if (m_bNewNoticeAlert) {
1189 wxRect r = m_NoticesButton->GetRect();
1190 r.Inflate(4, 4);
1191 RefreshRect(r, m_bNoticesButtonIsRed);
1192 m_bNoticesButtonIsRed = !m_bNoticesButtonIsRed;
1193 }
1194
1195
1196 // State changes can cause the BSG to crash if a dialogue is open.
1197 // Defer state change until after the dialogue is closed
1198 if ( dlgOpen ) {
1199 return;
1200 }
1201
1202 m_oldWorkCount = workCount;
1203
1204 m_taskPanel->UpdatePanel(false);
1205 }
1206 }
1207
1208
UpdateProjectView()1209 void CSimpleGUIPanel::UpdateProjectView()
1210 {
1211 //update Project Panel
1212 m_projPanel->UpdateInterface();
1213 }
1214
1215
OnCheckForNewNotices(wxTimerEvent & WXUNUSED (event))1216 void CSimpleGUIPanel::OnCheckForNewNotices(wxTimerEvent& WXUNUSED(event)) {
1217 CMainDocument* pDoc = wxGetApp().GetDocument();
1218 if ( pDoc->GetUnreadNoticeCount() ) {
1219 m_bNewNoticeAlert = true;
1220 checkForNewNoticesTimer->Stop();
1221 }
1222 }
1223
1224
NoticesViewed()1225 void CSimpleGUIPanel::NoticesViewed() {
1226 CMainDocument* pDoc = wxGetApp().GetDocument();
1227
1228 wxASSERT(pDoc);
1229
1230 m_bNewNoticeAlert = false;
1231 m_bNoticesButtonIsRed = false;
1232 wxRect r = m_NoticesButton->GetRect();
1233 r.Inflate(4, 4);
1234 RefreshRect(r, true);
1235 m_bNoticesButtonIsRed = !m_bNoticesButtonIsRed;
1236 pDoc->UpdateUnreadNoticeState();
1237 checkForNewNoticesTimer->Start();
1238 }
1239
1240
OnShowNotices(wxCommandEvent &)1241 void CSimpleGUIPanel::OnShowNotices(wxCommandEvent& /*event*/) {
1242 NoticesViewed();
1243
1244 CDlgMessages dlg(GetParent());
1245 SetDlgOpen(true);
1246
1247 ((CSimpleFrame*)GetParent())->SetMsgsDlgOpen(&dlg);
1248
1249 dlg.ShowModal();
1250
1251 SetDlgOpen(false);
1252 ((CSimpleFrame*)GetParent())->SetMsgsDlgOpen(NULL);
1253 }
1254
1255
OnSuspendResume(wxCommandEvent &)1256 void CSimpleGUIPanel::OnSuspendResume(wxCommandEvent& /*event*/) {
1257 CMainDocument* pDoc = wxGetApp().GetDocument();
1258 CC_STATUS ccs;
1259
1260 wxASSERT(pDoc);
1261 wxASSERT(wxDynamicCast(pDoc, CMainDocument));
1262
1263 if (m_bIsSuspended) {
1264 pDoc->GetCoreClientStatus(ccs);
1265
1266 if ((RUN_MODE_NEVER == ccs.task_mode) && (0 >= ccs.task_mode_delay)) {
1267 pDoc->SetActivityRunMode(RUN_MODE_AUTO, 0);
1268 } else {
1269 pDoc->SetActivityRunMode(RUN_MODE_RESTORE, 0);
1270 }
1271 } else {
1272 pDoc->SetActivityRunMode(RUN_MODE_NEVER, 3600);
1273 }
1274
1275 m_SuspendResumeButton->SetLabel(m_bIsSuspended ? m_sResumeString : m_sSuspendString);
1276 m_SuspendResumeButton->SetToolTip(m_bIsSuspended ? m_sResumeButtonToolTip : m_sSuspendButtonToolTip);
1277 }
1278
1279
1280 // TODO: Create ID_SIMPLE_HELP web page for each organization for new BOINC version
OnHelp(wxCommandEvent & WXUNUSED (event))1281 void CSimpleGUIPanel::OnHelp(wxCommandEvent& WXUNUSED(event)) {
1282 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::OnHelp - Function Begin"));
1283
1284 wxString strURL = wxGetApp().GetSkinManager()->GetAdvanced()->GetOrganizationHelpUrl();
1285
1286 wxString wxurl;
1287 wxurl.Printf(
1288 wxT("%s?target=simple&version=%s&controlid=%d"),
1289 strURL.c_str(),
1290 wxString(BOINC_VERSION_STRING, wxConvUTF8).c_str(),
1291 ID_SIMPLE_HELP
1292
1293 );
1294
1295 wxLaunchDefaultBrowser(wxurl);
1296
1297 wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::OnHelp - Function End"));
1298 }
1299
1300
OnPaint(wxPaintEvent & WXUNUSED (event))1301 void CSimpleGUIPanel::OnPaint(wxPaintEvent& WXUNUSED(event)) {
1302 wxPaintDC myDC(this);
1303
1304 if (m_bNewNoticeAlert) {
1305 wxRect r = m_NoticesButton->GetRect();
1306 if (m_bNoticesButtonIsRed) {
1307 CSkinSimple* pSkinSimple = wxGetApp().GetSkinManager()->GetSimple();
1308 wxPen oldPen = myDC.GetPen();
1309 wxBrush oldBrush = myDC.GetBrush();
1310 int oldMode = myDC.GetBackgroundMode();
1311 wxPen bgPen(pSkinSimple->GetNoticeAlertColor(), 3);
1312 myDC.SetBackgroundMode(wxSOLID);
1313 myDC.SetPen(bgPen);
1314 myDC.SetBrush(*wxTRANSPARENT_BRUSH);
1315 #ifdef __WXMAC__
1316 r.Inflate(2, 2);
1317 myDC.DrawRoundedRectangle(r.x, r.y, r.width, r.height+1, m_iRedRingRadius);
1318 #elif defined(__WXMSW__)
1319 r.Inflate(3, 3);
1320 myDC.DrawRectangle(r.x, r.y, r.width, r.height);
1321 #else
1322 r.Inflate(3, 3);
1323 myDC.DrawRoundedRectangle(r.x, r.y, r.width, r.height, 6);
1324 #endif
1325 // Restore Mode, Pen and Brush
1326 myDC.SetBackgroundMode(oldMode);
1327 myDC.SetPen(oldPen);
1328 myDC.SetBrush(oldBrush);
1329 }
1330 }
1331 }
1332
1333
1334 // We don't reliably get EraseBackground events under Linux,
1335 // so there is a workaround at CSimplePanelBase::MakeBGBitMap()
OnEraseBackground(wxEraseEvent & event)1336 void CSimpleGUIPanel::OnEraseBackground(wxEraseEvent& event) {
1337 wxDC *dc = event.GetDC();
1338
1339 #ifdef __WXMAC__
1340 // Avoid unnecessary drawing due to Mac progress indicator's animation
1341 wxRect clipRect;
1342 wxRect taskRect = m_taskPanel->GetRect();
1343 dc->GetClippingBox(&clipRect.x, &clipRect.y, &clipRect.width, &clipRect.height);
1344 if (clipRect.IsEmpty() || taskRect.Contains(clipRect)) {
1345 return;
1346 }
1347 #endif
1348 dc->DrawBitmap(m_bmpBg, 0, 0);
1349 }
1350