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 #if defined(__GNUG__) && !defined(__APPLE__)
19 #pragma implementation "BOINCBaseFrame.h"
20 #endif
21
22 #include "stdwx.h"
23 #include "diagnostics.h"
24 #include "util.h"
25 #include "mfile.h"
26 #include "miofile.h"
27 #include "parse.h"
28 #include "error_numbers.h"
29 #include "BOINCGUIApp.h"
30 #include "SkinManager.h"
31 #include "MainDocument.h"
32 #include "BOINCClientManager.h"
33 #include "BOINCTaskBar.h"
34 #include "BOINCBaseFrame.h"
35 #include "BOINCDialupManager.h"
36 #include "Events.h"
37 #include "DlgEventLog.h"
38 #include "DlgSelectComputer.h"
39
40
41 DEFINE_EVENT_TYPE(wxEVT_FRAME_ALERT)
DEFINE_EVENT_TYPE(wxEVT_FRAME_CONNECT)42 DEFINE_EVENT_TYPE(wxEVT_FRAME_CONNECT)
43 DEFINE_EVENT_TYPE(wxEVT_FRAME_INITIALIZED)
44 DEFINE_EVENT_TYPE(wxEVT_FRAME_REFRESHVIEW)
45 DEFINE_EVENT_TYPE(wxEVT_FRAME_UPDATESTATUS)
46 DEFINE_EVENT_TYPE(wxEVT_FRAME_RELOADSKIN)
47 DEFINE_EVENT_TYPE(wxEVT_FRAME_NOTIFICATION)
48
49
50 IMPLEMENT_DYNAMIC_CLASS(CBOINCBaseFrame, wxFrame)
51
52 BEGIN_EVENT_TABLE (CBOINCBaseFrame, wxFrame)
53 EVT_TIMER(ID_DOCUMENTPOLLTIMER, CBOINCBaseFrame::OnDocumentPoll)
54 EVT_TIMER(ID_ALERTPOLLTIMER, CBOINCBaseFrame::OnAlertPoll)
55 EVT_TIMER(ID_PERIODICRPCTIMER, CBOINCBaseFrame::OnPeriodicRPC)
56 EVT_FRAME_INITIALIZED(CBOINCBaseFrame::OnInitialized)
57 EVT_FRAME_ALERT(CBOINCBaseFrame::OnAlert)
58 EVT_FRAME_REFRESH(CBOINCBaseFrame::OnRefreshView)
59 EVT_ACTIVATE(CBOINCBaseFrame::OnActivate)
60 EVT_CLOSE(CBOINCBaseFrame::OnClose)
61 EVT_MENU(ID_CLOSEWINDOW, CBOINCBaseFrame::OnCloseWindow)
62 EVT_MENU(wxID_EXIT, CBOINCBaseFrame::OnExit)
63 END_EVENT_TABLE ()
64
65
66 CBOINCBaseFrame::CBOINCBaseFrame()
67 {
68 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::CBOINCBaseFrame - Default Constructor Function Begin"));
69 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::CBOINCBaseFrame - Default Constructor Function End"));
70 }
71
72
CBOINCBaseFrame(wxWindow * parent,const wxWindowID id,const wxString & title,const wxPoint & pos,const wxSize & size,const long style)73 CBOINCBaseFrame::CBOINCBaseFrame(wxWindow* parent, const wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long style) :
74 wxFrame(parent, id, title, pos, size, style)
75 {
76 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::CBOINCBaseFrame - Function Begin"));
77
78 // Configuration Settings
79 m_iReminderFrequency = 0;
80 m_strNetworkDialupConnectionName = wxEmptyString;
81 m_aSelectedComputerMRU.Clear();
82 m_bShowConnectionFailedAlert = false;
83
84
85 m_pDialupManager = new CBOINCDialUpManager();
86 wxASSERT(m_pDialupManager->IsOk());
87
88
89 m_pDocumentPollTimer = new wxTimer(this, ID_DOCUMENTPOLLTIMER);
90 wxASSERT(m_pDocumentPollTimer);
91
92 m_pDocumentPollTimer->Start(250); // Send event every 250 milliseconds
93
94 m_pAlertPollTimer = new wxTimer(this, ID_ALERTPOLLTIMER);
95 wxASSERT(m_pAlertPollTimer);
96
97 m_pAlertPollTimer->Start(1000); // Send event every 1000 milliseconds
98
99 m_pPeriodicRPCTimer = new wxTimer(this, ID_PERIODICRPCTIMER);
100 wxASSERT(m_pPeriodicRPCTimer);
101
102 m_pPeriodicRPCTimer->Start(1000); // Send event every 1000 milliseconds
103 m_iFrameRefreshRate = 1000; // Refresh frame every 1000 milliseconds
104
105 // Limit the number of times the UI can update itself to two times a second
106 // NOTE: Linux and Mac were updating several times a second and eating
107 // CPU time
108 wxUpdateUIEvent::SetUpdateInterval(500);
109
110 m_ptFramePos = wxPoint(0, 0);
111
112 // The second half of the initialization process picks up in the OnFrameRender()
113 // routine since the menus' and status bars' are drawn in the frameworks
114 // on idle routines, on idle events are sent in between the end of the
115 // constructor and the first call to OnFrameRender
116 //
117 // Look for the 'if (!bAlreadyRunOnce) {' statement
118
119 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::CBOINCBaseFrame - Function End"));
120 }
121
122
~CBOINCBaseFrame()123 CBOINCBaseFrame::~CBOINCBaseFrame() {
124 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::~CBOINCBaseFrame - Function Begin"));
125
126 wxASSERT(m_pPeriodicRPCTimer);
127 wxASSERT(m_pAlertPollTimer);
128 wxASSERT(m_pDocumentPollTimer);
129
130 if (m_pPeriodicRPCTimer) {
131 m_pPeriodicRPCTimer->Stop();
132 delete m_pPeriodicRPCTimer;
133 }
134
135 if (m_pAlertPollTimer) {
136 m_pAlertPollTimer->Stop();
137 delete m_pAlertPollTimer;
138 }
139
140 if (m_pDocumentPollTimer) {
141 m_pDocumentPollTimer->Stop();
142 delete m_pDocumentPollTimer;
143 }
144
145 if (m_pDialupManager) {
146 delete m_pDialupManager;
147 }
148
149 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::~CBOINCBaseFrame - Function End"));
150 }
151
152
OnPeriodicRPC(wxTimerEvent & WXUNUSED (event))153 void CBOINCBaseFrame::OnPeriodicRPC(wxTimerEvent& WXUNUSED(event)) {
154 static bool bAlreadyRunningLoop = false;
155 CMainDocument* pDoc = wxGetApp().GetDocument();
156
157 wxASSERT(pDoc);
158 wxASSERT(wxDynamicCast(pDoc, CMainDocument));
159
160 #ifdef __WXMAC__
161 static bool first = true;
162 if (first) {
163 first = false;
164 wxGetApp().OnFinishInit();
165 }
166
167 wxGetApp().CheckPartialActivation();
168 #endif
169
170 if (!bAlreadyRunningLoop && m_pPeriodicRPCTimer->IsRunning()) {
171 bAlreadyRunningLoop = true;
172
173 pDoc->RunPeriodicRPCs(m_iFrameRefreshRate);
174
175 bAlreadyRunningLoop = false;
176 }
177 }
178
179
OnDocumentPoll(wxTimerEvent & WXUNUSED (event))180 void CBOINCBaseFrame::OnDocumentPoll(wxTimerEvent& WXUNUSED(event)) {
181 static bool bAlreadyRunOnce = false;
182 CMainDocument* pDoc = wxGetApp().GetDocument();
183
184 wxASSERT(pDoc);
185 wxASSERT(wxDynamicCast(pDoc, CMainDocument));
186
187 // Timer events are handled while the RPC Wait dialog is shown
188 // which may cause unintended recursion and repeatedly posting
189 // the same RPC requests from timer routines.
190 if (pDoc->WaitingForRPC()) return;
191
192 if (!bAlreadyRunOnce && m_pDocumentPollTimer->IsRunning()) {
193 // Complete any remaining initialization that has to happen after we are up
194 // and running
195 FireInitialize();
196 bAlreadyRunOnce = true;
197 }
198
199 pDoc->OnPoll();
200 }
201
202
OnAlertPoll(wxTimerEvent & WXUNUSED (event))203 void CBOINCBaseFrame::OnAlertPoll(wxTimerEvent& WXUNUSED(event)) {
204 static bool bAlreadyRunningLoop = false;
205 CMainDocument* pDoc = wxGetApp().GetDocument();
206
207 if (!bAlreadyRunningLoop && m_pAlertPollTimer->IsRunning()) {
208 bAlreadyRunningLoop = true;
209
210 // Update idle detection if needed.
211 wxGetApp().UpdateSystemIdleDetection();
212
213 // Check to see if there is anything that we need to do from the
214 // dial up user perspective.
215 if (pDoc && m_pDialupManager) {
216 // Timer events are handled while the RPC Wait dialog is shown
217 // which may cause unintended recursion and repeatedly posting
218 // the same RPC requests from timer routines.
219 if (pDoc->IsConnected() && !pDoc->WaitingForRPC()) {
220 m_pDialupManager->OnPoll();
221 }
222 }
223
224 if (m_bShowConnectionFailedAlert && IsShown()) {
225 m_bShowConnectionFailedAlert = false;
226 ShowConnectionFailedAlert();
227 }
228
229 bAlreadyRunningLoop = false;
230 }
231 }
232
233
OnInitialized(CFrameEvent & WXUNUSED (event))234 void CBOINCBaseFrame::OnInitialized(CFrameEvent& WXUNUSED(event)) {
235 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::OnInitialized - Function Begin"));
236 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::OnInitialized - Function End"));
237 }
238
239
OnRefreshView(CFrameEvent &)240 void CBOINCBaseFrame::OnRefreshView(CFrameEvent& ) {
241 }
242
243
OnAlert(CFrameAlertEvent & event)244 void CBOINCBaseFrame::OnAlert(CFrameAlertEvent& event) {
245 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::OnAlert - Function Begin"));
246 static bool bAlreadyRunningLoop = false;
247
248 if (!bAlreadyRunningLoop) {
249 bAlreadyRunningLoop = true;
250
251 #ifdef __WXMSW__
252 CTaskBarIcon* pTaskbar = wxGetApp().GetTaskBarIcon();
253 wxASSERT(pTaskbar);
254
255 if ((IsShown() && !event.m_notification_only) || (IsShown() && !pTaskbar->IsBalloonsSupported())) {
256 if (!event.m_notification_only) {
257 int retval = 0;
258
259 if (!IsShown()) {
260 Show();
261 }
262
263 retval = wxGetApp().SafeMessageBox(event.m_message, event.m_title, event.m_style, this);
264 if (event.m_alert_event_type == AlertProcessResponse) {
265 event.ProcessResponse(retval);
266 }
267 }
268 } else {
269 // If the main window is hidden or minimzed use the system tray ballon
270 // to notify the user instead. This keeps dialogs from interfering
271 // with people typing email messages or any other activity where they
272 // do not want keyboard focus changed to another window while typing.
273 unsigned int icon_type;
274
275 if (wxICON_ERROR & event.m_style) {
276 icon_type = NIIF_ERROR;
277 } else if (wxICON_WARNING & event.m_style) {
278 icon_type = NIIF_WARNING;
279 } else if (wxICON_INFORMATION & event.m_style) {
280 icon_type = NIIF_INFO;
281 } else {
282 icon_type = NIIF_NONE;
283 }
284
285 pTaskbar->SetBalloon(
286 pTaskbar->m_iconTaskBarNormal,
287 event.m_title,
288 event.m_message,
289 icon_type
290 );
291 }
292 #elif defined (__WXMAC__)
293 // SafeMessageBox() / ProcessResponse() hangs the Manager if hidden.
294 // Currently, the only non-notification-only alert is Connection Failed,
295 // which is now has logic to be displayed when Manager is maximized.
296
297 // Notification only events on platforms other than Windows are
298 // currently discarded. Otherwise the application would be restored
299 // and input focus set on the notification which interrupts whatever
300 // the user was doing.
301 if (IsShown() && !event.m_notification_only) {
302 int retval = 0;
303
304 retval = wxGetApp().SafeMessageBox(event.m_message, event.m_title, event.m_style, this);
305 if (event.m_alert_event_type == AlertProcessResponse) {
306 event.ProcessResponse(retval);
307 }
308 }
309 #endif
310
311 bAlreadyRunningLoop = false;
312 }
313
314 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::OnAlert - Function End"));
315 }
316
317
OnActivate(wxActivateEvent & event)318 void CBOINCBaseFrame::OnActivate(wxActivateEvent& event) {
319 bool isActive = event.GetActive();
320 if (isActive) wxGetApp().SetEventLogWasActive(false);
321 event.Skip();
322 }
323
324
OnClose(wxCloseEvent & event)325 void CBOINCBaseFrame::OnClose(wxCloseEvent& event) {
326 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::OnClose - Function Begin"));
327
328 if (!event.CanVeto() || IsIconized()) {
329 wxGetApp().FrameClosed();
330 Destroy();
331 } else {
332 #ifdef __WXGTK__
333 // Apparently aborting a close event just causes the main window to be displayed
334 // again. Just minimize the window instead.
335 Iconize();
336 #else
337 Hide();
338 #endif
339 }
340
341 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::OnClose - Function End"));
342 }
343
344
OnCloseWindow(wxCommandEvent & WXUNUSED (event))345 void CBOINCBaseFrame::OnCloseWindow(wxCommandEvent& WXUNUSED(event)) {
346 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::OnCloseWindow - Function Begin"));
347
348 #ifdef __WXMAC__
349 CFStringRef frontWindowTitle, eventLogTitle;
350 CDlgEventLog* eventLog = wxGetApp().GetEventLog();
351 if (eventLog) {
352 WindowRef win = FrontNonFloatingWindow();
353 if (win) {
354 CopyWindowTitleAsCFString(win, &frontWindowTitle);
355 eventLogTitle = CFStringCreateWithCString(NULL, eventLog->GetTitle().char_str(), kCFStringEncodingUTF8);
356 CFComparisonResult res = CFStringCompare(eventLogTitle, frontWindowTitle, 0);
357 CFRelease(eventLogTitle);
358 CFRelease(frontWindowTitle);
359 if (res == kCFCompareEqualTo) {
360 wxCloseEvent eventClose;
361 eventLog->OnClose(eventClose);
362 return;
363 }
364 }
365 }
366 #endif
367
368 Close();
369
370 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::OnCloseWindow - Function End"));
371 }
372
373
OnExit(wxCommandEvent & WXUNUSED (event))374 void CBOINCBaseFrame::OnExit(wxCommandEvent& WXUNUSED(event)) {
375 wxLogTrace(wxT("Function Start/End"), wxT("CAdvancedFrame::OnExit - Function Begin"));
376
377 if (wxGetApp().ConfirmExit()) {
378
379 // Save state before exiting
380 SaveState();
381
382 CDlgEventLog* eventLog = wxGetApp().GetEventLog();
383 if (eventLog) {
384 eventLog->Destroy();
385 }
386
387 Close(true);
388 }
389
390 wxLogTrace(wxT("Function Start/End"), wxT("CAdvancedFrame::OnExit - Function End"));
391 }
392
393
GetCurrentViewPage()394 int CBOINCBaseFrame::GetCurrentViewPage() {
395 return _GetCurrentViewPage();
396 }
397
398
FireInitialize()399 void CBOINCBaseFrame::FireInitialize() {
400 CFrameEvent event(wxEVT_FRAME_INITIALIZED, this);
401 AddPendingEvent(event);
402 }
403
404
FireRefreshView()405 void CBOINCBaseFrame::FireRefreshView() {
406 CMainDocument* pDoc = wxGetApp().GetDocument();
407
408 wxASSERT(pDoc);
409 wxASSERT(wxDynamicCast(pDoc, CMainDocument));
410
411 pDoc->RefreshRPCs();
412 pDoc->RunPeriodicRPCs(0);
413 }
414
415
FireConnect()416 void CBOINCBaseFrame::FireConnect() {
417 CFrameEvent event(wxEVT_FRAME_CONNECT, this);
418 AddPendingEvent(event);
419 }
420
421
FireReloadSkin()422 void CBOINCBaseFrame::FireReloadSkin() {
423 CFrameEvent event(wxEVT_FRAME_RELOADSKIN, this);
424 AddPendingEvent(event);
425 }
426
427
FireNotification()428 void CBOINCBaseFrame::FireNotification() {
429 CFrameEvent event(wxEVT_FRAME_NOTIFICATION, this);
430 AddPendingEvent(event);
431 }
432
433
SelectComputer(wxString & hostName,int & portNum,wxString & password,bool required)434 bool CBOINCBaseFrame::SelectComputer(wxString& hostName, int& portNum, wxString& password, bool required) {
435 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::SelectComputer - Function Begin"));
436
437 CDlgSelectComputer dlg(this, required);
438 size_t lIndex = 0;
439 wxArrayString aComputerNames;
440 bool bResult = false;
441
442 // Lets copy the template store in the system state
443 aComputerNames = m_aSelectedComputerMRU;
444
445 // Lets populate the combo control with the MRU list
446 dlg.m_ComputerNameCtrl->Clear();
447 for (lIndex = 0; lIndex < aComputerNames.Count(); lIndex++) {
448 dlg.m_ComputerNameCtrl->Append(aComputerNames.Item(lIndex));
449 }
450
451 if (wxID_OK == dlg.ShowModal()) {
452 hostName = dlg.m_ComputerNameCtrl->GetValue();
453 // Make a null hostname be the same thing as localhost
454 if (wxEmptyString == hostName) {
455 hostName = wxT("localhost");
456 portNum = GUI_RPC_PORT;
457 password = wxEmptyString;
458 } else {
459 // Parse the remote machine info
460 wxString sHost = dlg.m_ComputerNameCtrl->GetValue();
461 long lPort = GUI_RPC_PORT;
462 int iPos = sHost.Find(wxT(":"));
463 if (iPos != wxNOT_FOUND) {
464 wxString sPort = sHost.substr(iPos + 1);
465 if (!sPort.ToLong(&lPort)) lPort = GUI_RPC_PORT;
466 sHost.erase(iPos);
467 }
468 hostName = sHost;
469 portNum = (int)lPort;
470 password = dlg.m_ComputerPasswordCtrl->GetValue();
471 }
472
473 // Insert a copy of the current combo box value to the head of the
474 // computer names string array
475 if (wxEmptyString != dlg.m_ComputerNameCtrl->GetValue()) {
476 aComputerNames.Insert(dlg.m_ComputerNameCtrl->GetValue(), 0);
477 }
478
479 // Loops through the computer names and remove any duplicates that
480 // might exist with the new head value
481 for (lIndex = 1; lIndex < aComputerNames.Count(); lIndex++) {
482 if (aComputerNames.Item(lIndex) == aComputerNames.Item(0))
483 aComputerNames.RemoveAt(lIndex);
484 }
485
486 // Store the modified computer name MRU list back to the system state
487 m_aSelectedComputerMRU = aComputerNames;
488 bResult = true;
489 } else {
490 bResult = false; // User cancelled
491 }
492
493 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::SelectComputer - Function End"));
494 return bResult;
495 }
496
497
ShowConnectionBadPasswordAlert(bool bUsedDefaultPassword,int iReadGUIRPCAuthFailure)498 void CBOINCBaseFrame::ShowConnectionBadPasswordAlert( bool bUsedDefaultPassword, int iReadGUIRPCAuthFailure ) {
499 CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced();
500 wxString strDialogTitle = wxEmptyString;
501
502
503 wxASSERT(pSkinAdvanced);
504 wxASSERT(wxDynamicCast(pSkinAdvanced, CSkinAdvanced));
505
506
507 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowConnectionBadPasswordAlert - Function Begin"));
508
509 // %s is the application name
510 // i.e. 'BOINC Manager', 'GridRepublic Manager'
511 strDialogTitle.Printf(
512 _("%s - Connection Error"),
513 pSkinAdvanced->GetApplicationName().c_str()
514 );
515
516 if ( bUsedDefaultPassword ) {
517 #ifdef __WXMSW__
518 if ( EACCES == iReadGUIRPCAuthFailure || ENOENT == iReadGUIRPCAuthFailure ) {
519 ShowAlert(
520 strDialogTitle,
521 _("You currently are not authorized to manage the client.\nPlease contact your administrator to add you to the 'boinc_users' local user group."),
522 wxOK | wxICON_ERROR
523 );
524 } else
525 #endif
526 {
527 ShowAlert(
528 strDialogTitle,
529 #ifndef __WXMAC__
530 _("Authorization failed connecting to running client.\nMake sure you start this program in the same directory as the client."),
531 #else
532 _("Authorization failed connecting to running client."),
533 #endif
534 wxOK | wxICON_ERROR
535 );
536 }
537 } else {
538 ShowAlert(
539 strDialogTitle,
540 _("The password you have provided is incorrect, please try again."),
541 wxOK | wxICON_ERROR
542 );
543 }
544
545 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowConnectionBadPasswordAlert - Function End"));
546 }
547
548
ShowConnectionFailedAlert()549 void CBOINCBaseFrame::ShowConnectionFailedAlert() {
550 CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced();
551 CMainDocument* pDoc = wxGetApp().GetDocument();
552 wxString strConnectedCompter = wxEmptyString;
553 wxString strDialogTitle = wxEmptyString;
554 wxString strDialogMessage = wxEmptyString;
555
556 wxASSERT(pSkinAdvanced);
557 wxASSERT(wxDynamicCast(pSkinAdvanced, CSkinAdvanced));
558
559 wxASSERT(pDoc);
560 wxASSERT(wxDynamicCast(pDoc, CMainDocument));
561
562 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowConnectionFailedAlert - Function Begin"));
563
564 // Did BOINC crash on local computer? If so restart it and reconnect.
565 pDoc->GetConnectedComputerName(strConnectedCompter);
566 if (pDoc->IsComputerNameLocal(strConnectedCompter)) {
567 if (pDoc->m_pClientManager->AutoRestart()) {
568 boinc_sleep(0.5); // Allow time for Client to restart
569 if (pDoc->m_pClientManager->IsBOINCCoreRunning()) {
570 pDoc->Reconnect();
571 return;
572 }
573 } else {
574 // Don't ask whether to reconnect to local client if it is not running
575 if (!pDoc->m_pClientManager->IsBOINCCoreRunning()) {
576 return;
577 }
578 }
579 }
580
581 // %s is the application name
582 // i.e. 'BOINC Manager', 'GridRepublic Manager'
583 strDialogTitle.Printf(
584 _("%s - Connection Failed"),
585 pSkinAdvanced->GetApplicationName().c_str()
586 );
587
588 // 1st %s is the application name
589 // i.e. 'BOINC Manager', 'GridRepublic Manager'
590 // 2st %s is the project name
591 // i.e. 'BOINC', 'GridRepublic'
592 strDialogMessage.Printf(
593 _("%s is not able to connect to a %s client.\nWould you like to try to connect again?"),
594 pSkinAdvanced->GetApplicationName().c_str(),
595 pSkinAdvanced->GetApplicationShortName().c_str()
596 );
597
598 ShowAlert(
599 strDialogTitle,
600 strDialogMessage,
601 wxYES_NO | wxICON_QUESTION,
602 false,
603 AlertProcessResponse
604 );
605
606 // If we are minimized, set flag to show alert when maximized
607 m_bShowConnectionFailedAlert = !IsShown();
608
609 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowConnectionFailedAlert - Function End"));
610 }
611
612
ShowDaemonStartFailedAlert()613 void CBOINCBaseFrame::ShowDaemonStartFailedAlert() {
614 CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced();
615 wxString strDialogTitle = wxEmptyString;
616 wxString strDialogMessage = wxEmptyString;
617
618
619 wxASSERT(pSkinAdvanced);
620 wxASSERT(wxDynamicCast(pSkinAdvanced, CSkinAdvanced));
621
622
623 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowDaemonStartFailedAlert - Function Begin"));
624
625
626 // %s is the application name
627 // i.e. 'BOINC Manager', 'GridRepublic Manager'
628 strDialogTitle.Printf(
629 _("%s - Daemon Start Failed"),
630 pSkinAdvanced->GetApplicationName().c_str()
631 );
632
633 // 1st %s is the application name
634 // i.e. 'BOINC Manager', 'GridRepublic Manager'
635 // 2st %s is the project name
636 // i.e. 'BOINC', 'GridRepublic'
637 #ifdef __WXMSW__
638 strDialogMessage.Printf(
639 _("%s is not able to start a %s client.\nPlease launch the Control Panel->Administative Tools->Services applet and start the BOINC service."),
640 pSkinAdvanced->GetApplicationName().c_str(),
641 pSkinAdvanced->GetApplicationShortName().c_str()
642 );
643 #else
644 strDialogMessage.Printf(
645 _("%s is not able to start a %s client.\nPlease start the daemon and try again."),
646 pSkinAdvanced->GetApplicationName().c_str(),
647 pSkinAdvanced->GetApplicationShortName().c_str()
648 );
649 #endif
650
651 ShowAlert(
652 strDialogTitle,
653 strDialogMessage,
654 wxOK | wxICON_ERROR
655 );
656
657 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowDaemonStartFailedAlert - Function End"));
658 }
659
660
ShowNotCurrentlyConnectedAlert()661 void CBOINCBaseFrame::ShowNotCurrentlyConnectedAlert() {
662 CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced();
663 CMainDocument* pDoc = wxGetApp().GetDocument();
664 wxString strConnectedCompter = wxEmptyString;
665 wxString strDialogTitle = wxEmptyString;
666 wxString strDialogMessage = wxEmptyString;
667
668 wxASSERT(pSkinAdvanced);
669 wxASSERT(wxDynamicCast(pSkinAdvanced, CSkinAdvanced));
670
671 wxASSERT(pDoc);
672 wxASSERT(wxDynamicCast(pDoc, CMainDocument));
673
674 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowNotCurrentlyConnectedAlert - Function Begin"));
675
676 // Did BOINC crash on local computer? If so restart it and reconnect.
677 pDoc->GetConnectedComputerName(strConnectedCompter);
678 if (pDoc->IsComputerNameLocal(strConnectedCompter)) {
679 if (pDoc->m_pClientManager->AutoRestart()) {
680 boinc_sleep(0.5); // Allow time for Client to restart
681 if (pDoc->m_pClientManager->IsBOINCCoreRunning()) {
682 pDoc->Reconnect();
683 return;
684 }
685 } else {
686 // Don't ask whether to reconnect to local client if it is not running
687 if (!pDoc->m_pClientManager->IsBOINCCoreRunning()) {
688 return;
689 }
690 }
691 }
692
693 // %s is the application name
694 // i.e. 'BOINC Manager', 'GridRepublic Manager'
695 strDialogTitle.Printf(
696 _("%s - Connection Status"),
697 pSkinAdvanced->GetApplicationName().c_str()
698 );
699
700 // 1st %s is the application name
701 // i.e. 'BOINC Manager', 'GridRepublic Manager'
702 // 2nd %s is the project name
703 // i.e. 'BOINC', 'GridRepublic'
704 // 3nd %s is the project name
705 // i.e. 'BOINC', 'GridRepublic'
706 strDialogMessage.Printf(
707 _("%s is not currently connected to a %s client.\nPlease use the 'Advanced\\Select Computer...' menu option to connect up to a %s client.\nTo connect up to your local computer please use 'localhost' as the host name."),
708 pSkinAdvanced->GetApplicationName().c_str(),
709 pSkinAdvanced->GetApplicationShortName().c_str(),
710 pSkinAdvanced->GetApplicationShortName().c_str()
711 );
712 ShowAlert(
713 strDialogTitle,
714 strDialogMessage,
715 wxOK | wxICON_ERROR
716 );
717
718 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowNotCurrentlyConnectedAlert - Function End"));
719 }
720
721
StartTimers()722 void CBOINCBaseFrame::StartTimers() {
723 wxASSERT(m_pAlertPollTimer);
724 wxASSERT(m_pPeriodicRPCTimer);
725 wxASSERT(m_pDocumentPollTimer);
726 m_pAlertPollTimer->Start();
727 m_pPeriodicRPCTimer->Start();
728 m_pDocumentPollTimer->Start();
729 }
730
731
StopTimers()732 void CBOINCBaseFrame::StopTimers() {
733 wxASSERT(m_pAlertPollTimer);
734 wxASSERT(m_pPeriodicRPCTimer);
735 wxASSERT(m_pDocumentPollTimer);
736 m_pAlertPollTimer->Stop();
737 m_pPeriodicRPCTimer->Stop();
738 m_pDocumentPollTimer->Stop();
739 }
740
741
UpdateRefreshTimerInterval()742 void CBOINCBaseFrame::UpdateRefreshTimerInterval() {
743 }
744
745 #if 0
746 void CBOINCBaseFrame::UpdateStatusText(const wxChar* szStatus) {
747 CFrameEvent event(wxEVT_FRAME_UPDATESTATUS, this, szStatus);
748 ProcessEvent(event);
749 }
750 #endif
751
ShowAlert(const wxString title,const wxString message,const int style,const bool notification_only,const FrameAlertEventType alert_event_type)752 void CBOINCBaseFrame::ShowAlert( const wxString title, const wxString message, const int style, const bool notification_only, const FrameAlertEventType alert_event_type ) {
753 CFrameAlertEvent event(wxEVT_FRAME_ALERT, this, title, message, style, notification_only, alert_event_type);
754 AddPendingEvent(event);
755 }
756
757
SaveState()758 bool CBOINCBaseFrame::SaveState() {
759 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::SaveState - Function Begin"));
760
761 wxString strBaseConfigLocation = wxString(wxT("/"));
762 wxConfigBase* pConfig = wxConfigBase::Get(FALSE);
763 wxString strConfigLocation;
764 wxString strPreviousLocation;
765 wxString strBuffer;
766 int iIndex;
767 int iItemCount;
768
769
770 // An odd case happens every once and awhile where wxWidgets looses
771 // the pointer to the config object, or it is cleaned up before
772 // the window has finished it's cleanup duty. If we detect a NULL
773 // pointer, return false.
774 if (!pConfig) return false;
775
776 //
777 // Save Frame State
778 //
779 pConfig->SetPath(strBaseConfigLocation);
780
781 pConfig->Write(wxT("ReminderFrequencyV3"), m_iReminderFrequency);
782 pConfig->Write(wxT("NetworkDialupConnectionName"), m_strNetworkDialupConnectionName);
783
784
785 //
786 // Save Computer MRU list
787 //
788 strPreviousLocation = pConfig->GetPath();
789 strConfigLocation = strPreviousLocation + wxT("ComputerMRU");
790
791 pConfig->SetPath(strConfigLocation);
792
793 iItemCount = (int)m_aSelectedComputerMRU.GetCount() - 1;
794 for (iIndex = 0; iIndex <= iItemCount; iIndex++) {
795 strBuffer.Printf(wxT("%d"), iIndex);
796 pConfig->Write(
797 strBuffer,
798 m_aSelectedComputerMRU.Item(iIndex)
799 );
800 }
801
802 pConfig->SetPath(strPreviousLocation);
803
804
805 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::SaveState - Function End"));
806 return true;
807 }
808
809
RestoreState()810 bool CBOINCBaseFrame::RestoreState() {
811 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::RestoreState - Function Begin"));
812
813 wxString strBaseConfigLocation = wxString(wxT("/"));
814 wxConfigBase* pConfig = wxConfigBase::Get(FALSE);
815 wxString strConfigLocation;
816 wxString strPreviousLocation;
817 wxString strBuffer;
818 wxString strValue;
819 long iIndex;
820 bool bKeepEnumerating = false;
821
822
823 wxASSERT(pConfig);
824
825 // An odd case happens every once and awhile where wxWidgets looses
826 // the pointer to the config object, or it is cleaned up before
827 // the window has finished it's cleanup duty. If we detect a NULL
828 // pointer, return false.
829 if (!pConfig) return false;
830
831 //
832 // Restore Frame State
833 //
834 pConfig->SetPath(strBaseConfigLocation);
835
836 pConfig->Read(wxT("ReminderFrequencyV3"), &m_iReminderFrequency, 360L);
837 pConfig->Read(wxT("NetworkDialupConnectionName"), &m_strNetworkDialupConnectionName, wxEmptyString);
838
839
840 //
841 // Restore Computer MRU list
842 //
843 strPreviousLocation = pConfig->GetPath();
844 strConfigLocation = strPreviousLocation + wxT("ComputerMRU");
845
846 pConfig->SetPath(strConfigLocation);
847
848 m_aSelectedComputerMRU.Clear();
849 bKeepEnumerating = pConfig->GetFirstEntry(strBuffer, iIndex);
850 while (bKeepEnumerating) {
851 pConfig->Read(strBuffer, &strValue);
852
853 m_aSelectedComputerMRU.Add(strValue);
854 bKeepEnumerating = pConfig->GetNextEntry(strBuffer, iIndex);
855 }
856
857 pConfig->SetPath(strPreviousLocation);
858
859
860 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::RestoreState - Function End"));
861 return true;
862 }
863
Show(bool bShow)864 bool CBOINCBaseFrame::Show(bool bShow) {
865 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::Show - Function Begin"));
866 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::Show - Show: '%d'"), (int)bShow);
867
868 bool retval;
869
870 if (bShow) {
871 wxGetApp().ShowApplication(true);
872 } else {
873 if ( this == wxGetApp().GetFrame() ) {
874 if (wxGetApp().IsApplicationVisible()) {
875 wxGetApp().ShowApplication(false);
876 }
877 }
878 }
879
880 CDlgEventLog* pEventLog = wxGetApp().GetEventLog();
881 if (pEventLog) {
882 #ifdef __WXMAC__
883 if (bShow) {
884 pEventLog->Show(bShow);
885 }
886 #else
887 pEventLog->Show(bShow);
888 #endif
889 }
890
891 #ifdef __WXMAC__
892 retval = (wxGetApp().IsApplicationVisible() != bShow);
893 if (bShow) {
894 retval = wxFrame::Show(bShow);
895 }
896 #else
897 retval = wxFrame::Show(bShow);
898 #endif
899
900 wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::Show - Function End"));
901 return retval;
902 }
903
_GetCurrentViewPage()904 int CBOINCBaseFrame::_GetCurrentViewPage() {
905 wxASSERT(false);
906 return 0;
907 }
908
909
ProcessResponse(const int response) const910 void CFrameAlertEvent::ProcessResponse(const int response) const {
911 CMainDocument* pDoc = wxGetApp().GetDocument();
912
913 wxASSERT(pDoc);
914 wxASSERT(wxDynamicCast(pDoc, CMainDocument));
915
916 if ((AlertProcessResponse == m_alert_event_type) && (wxYES == response)) {
917 pDoc->Reconnect();
918 }
919 }
920
921