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 "sg_DlgMessages.h"
20 #endif
21
22 #include "stdwx.h"
23 #include "common_defs.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 "Events.h"
31 #include "BOINCGUIApp.h"
32 #include "SkinManager.h"
33 #include "MainDocument.h"
34 #include "BOINCBaseFrame.h"
35 #include "version.h"
36 #include "sg_DlgMessages.h"
37 #include "NoticeListCtrl.h"
38
39 #define TEST_BACKGROUND_WITH_MAGENTA_FILL 0
40
41 ////@begin includes
42 ////@end includes
43
44 ////@begin XPM images
45 ////@end XPM images
46
47
48 #define COLUMN_PROJECT 0
49 #define COLUMN_TIME 1
50 #define COLUMN_MESSAGE 2
51
52 /*!
53 * CPanelMessages type definition
54 */
55
IMPLEMENT_DYNAMIC_CLASS(CPanelMessages,wxPanel)56 IMPLEMENT_DYNAMIC_CLASS( CPanelMessages, wxPanel )
57
58 /*!
59 * CPanelMessages event table definition
60 */
61
62 BEGIN_EVENT_TABLE( CPanelMessages, wxPanel )
63 ////@begin CPanelMessages event table entries
64 EVT_ERASE_BACKGROUND( CPanelMessages::OnEraseBackground )
65 EVT_BUTTON( wxID_OK, CPanelMessages::OnOK )
66 EVT_BUTTON(ID_SIMPLE_HELP, CPanelMessages::OnButtonHelp)
67 ////@end CPanelMessages event table entries
68 END_EVENT_TABLE()
69
70 /*!
71 * CPanelMessages constructors
72 */
73
74 CPanelMessages::CPanelMessages( )
75 {
76 }
77
78
CPanelMessages(wxWindow * parent)79 CPanelMessages::CPanelMessages( wxWindow* parent ) :
80 wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER)
81 {
82 Create();
83 }
84
85
86 /*!
87 * CPanelMessages creator
88 */
89
Create()90 bool CPanelMessages::Create()
91 {
92 ////@begin CPanelMessages member initialisation
93 m_bProcessingRefreshEvent = false;
94 ////@end CPanelMessages member initialisation
95
96 CreateControls();
97
98 GetSizer()->Fit(this);
99 GetSizer()->SetSizeHints(this);
100
101 return true;
102 }
103
104
~CPanelMessages()105 CPanelMessages::~CPanelMessages()
106 {
107 }
108
109
110 /*!
111 * Control creation for CPanelMessages
112 */
113
CreateControls()114 void CPanelMessages::CreateControls()
115 {
116 CPanelMessages* itemDialog1 = this;
117
118 wxFlexGridSizer* itemFlexGridSizer2 = new wxFlexGridSizer(5, 1, 1, 0);
119 itemFlexGridSizer2->AddGrowableRow(2);
120 itemFlexGridSizer2->AddGrowableCol(0);
121
122 m_FetchingNoticesText = new wxStaticText(
123 this, wxID_ANY,
124 _("Fetching notices; please wait..."),
125 wxPoint(20, 20), wxDefaultSize, 0
126 );
127 m_FetchingNoticesText->SetBackgroundColour(*wxWHITE);
128 itemFlexGridSizer2->Add(m_FetchingNoticesText, 0, wxEXPAND | wxLEFT | wxRIGHT, ADJUSTFORXDPI(5));
129
130 m_NoNoticesText = new wxStaticText(
131 this, wxID_ANY,
132 _("There are no notices at this time."),
133 wxPoint(20, 20), wxDefaultSize, 0
134 );
135 m_NoNoticesText->SetBackgroundColour(*wxWHITE);
136 itemFlexGridSizer2->Add(m_NoNoticesText, 0, wxEXPAND | wxLEFT | wxRIGHT, ADJUSTFORXDPI(5));
137
138
139 m_pHtmlListPane = new CNoticeListCtrl(itemDialog1);
140 wxASSERT(m_pHtmlListPane);
141
142 itemFlexGridSizer2->Add(m_pHtmlListPane, 0, wxGROW|wxALL, ADJUSTFORXDPI(5));
143
144 wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
145
146 wxButton* itemButton44 = new wxButton(itemDialog1, wxID_OK, _("Close"), wxDefaultPosition, wxDefaultSize);
147
148 itemBoxSizer4->Add(itemButton44, 0, wxALIGN_CENTER_VERTICAL|wxALL, ADJUSTFORXDPI(5));
149
150 #ifdef __WXMAC__ // Don't let Close button overlap window's grow icon
151 itemFlexGridSizer2->Add(itemBoxSizer4, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, ADJUSTFORXDPI(12));
152 #else
153 itemFlexGridSizer2->Add(itemBoxSizer4, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, ADJUSTFORXDPI(5));
154 #endif
155
156 itemDialog1->SetSizer(itemFlexGridSizer2);
157
158 m_FetchingNoticesText->Hide();
159 m_bFetchingNoticesTextWasDisplayed = false;
160
161 m_NoNoticesText->Hide();
162 m_bNoNoticesTextWasDisplayed = false;
163 Layout();
164 }
165
166
167 /*!
168 * wxEVT_ERASE_BACKGROUND event handler for ID_DLGMESSAGES
169 */
170
OnEraseBackground(wxEraseEvent & event)171 void CPanelMessages::OnEraseBackground(wxEraseEvent& event){
172 CSkinSimple* pSkinSimple = wxGetApp().GetSkinManager()->GetSimple();
173
174 wxASSERT(pSkinSimple);
175 wxASSERT(wxDynamicCast(pSkinSimple, CSkinSimple));
176
177 wxMemoryDC memDC;
178 wxCoord w, h, x, y;
179
180 // Get the desired background bitmap
181 wxBitmap bmp(*pSkinSimple->GetDialogBackgroundImage()->GetBitmap());
182
183 // Dialog dimensions
184 wxSize sz = GetClientSize();
185
186 // Create a buffered device context to reduce flicker
187 wxBufferedDC dc(event.GetDC(), sz, wxBUFFER_CLIENT_AREA);
188
189 // bitmap dimensions
190 w = bmp.GetWidth();
191 h = bmp.GetHeight();
192
193 #if TEST_BACKGROUND_WITH_MAGENTA_FILL
194 // Fill the dialog with a magenta color so people can detect when something
195 // is wrong
196 dc.SetBrush(wxBrush(wxColour(255,0,255)));
197 dc.SetPen(wxPen(wxColour(255,0,255)));
198 dc.DrawRectangle(0, 0, sz.GetWidth(), sz.GetHeight());
199 #else
200 wxColour bgColor(*pSkinSimple->GetDialogBackgroundImage()->GetBackgroundColor());
201 SetBackgroundColour(bgColor);
202 #endif
203
204 // Is the bitmap smaller than the window?
205 if ( (w < sz.x) || (h < sz.y) ) {
206 // Check to see if they need to be rescaled to fit in the window
207 wxImage img = bmp.ConvertToImage();
208 img.Rescale((int) sz.x, (int) sz.y);
209
210 // Draw our cool background (centered)
211 dc.DrawBitmap(wxBitmap(img), 0, 0);
212 } else {
213 // Snag the center of the bitmap and use it
214 // for the background image
215 x = wxMax(0, (w - sz.x)/2);
216 y = wxMax(0, (h - sz.y)/2);
217
218 // Select the desired bitmap into the memory DC so we can take
219 // the center chunk of it.
220 memDC.SelectObject(bmp);
221
222 // Draw the center chunk on the window
223 dc.Blit(0, 0, w, h, &memDC, x, y, wxCOPY);
224
225 // Drop the bitmap
226 memDC.SelectObject(wxNullBitmap);
227 }
228 }
229
230
231 /*!
232 * called from CSimpleFrame::OnRefreshView()
233 */
234
OnRefresh()235 void CPanelMessages::OnRefresh() {
236 if (!m_bProcessingRefreshEvent) {
237 m_bProcessingRefreshEvent = true;
238
239 static wxString strLastMachineName = wxEmptyString;
240 wxString strNewMachineName = wxEmptyString;
241 CC_STATUS status;
242 CMainDocument* pDoc = wxGetApp().GetDocument();
243
244 wxASSERT(pDoc);
245 wxASSERT(m_pHtmlListPane);
246 wxASSERT(wxDynamicCast(pDoc, CMainDocument));
247
248 if (pDoc->IsConnected()) {
249 pDoc->GetConnectedComputerName(strNewMachineName);
250 if (strLastMachineName != strNewMachineName) {
251 strLastMachineName = strNewMachineName;
252 m_FetchingNoticesText->Show();
253 m_NoNoticesText->Hide();
254 m_pHtmlListPane->Clear();
255 if (m_bNoNoticesTextWasDisplayed || !m_bFetchingNoticesTextWasDisplayed) {
256 Layout();
257 }
258 m_bFetchingNoticesTextWasDisplayed = true;
259 m_bNoNoticesTextWasDisplayed = false;
260 }
261 } else {
262 m_pHtmlListPane->Clear();
263 }
264
265 // Don't call Freeze() / Thaw() here because it causes an unnecessary redraw
266 m_pHtmlListPane->UpdateUI();
267
268 if (m_bFetchingNoticesTextWasDisplayed != m_pHtmlListPane->m_bDisplayFetchingNotices) {
269 m_bFetchingNoticesTextWasDisplayed = m_pHtmlListPane->m_bDisplayFetchingNotices;
270 m_FetchingNoticesText->Show(m_bFetchingNoticesTextWasDisplayed);
271 Layout();
272 }
273 if (m_bNoNoticesTextWasDisplayed != m_pHtmlListPane->m_bDisplayEmptyNotice) {
274 m_bNoNoticesTextWasDisplayed = m_pHtmlListPane->m_bDisplayEmptyNotice;
275 m_NoNoticesText->Show(m_bNoNoticesTextWasDisplayed);
276 Layout();
277 }
278
279 pDoc->UpdateUnreadNoticeState();
280 }
281 }
282
283
284 /*!
285 * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_OK
286 */
287
OnOK(wxCommandEvent & event)288 void CPanelMessages::OnOK( wxCommandEvent& event ) {
289 event.Skip();
290 }
291
292
293 /*!
294 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_SIMPLE_HELP
295 */
296
OnButtonHelp(wxCommandEvent & WXUNUSED (event))297 void CPanelMessages::OnButtonHelp( wxCommandEvent& WXUNUSED(event) ) {
298 wxLogTrace(wxT("Function Start/End"), wxT("CPanelMessages::OnHelp - Function Begin"));
299
300 if (IsShown()) {
301 wxString strURL = wxGetApp().GetSkinManager()->GetAdvanced()->GetOrganizationHelpUrl();
302
303 wxString wxurl;
304 wxurl.Printf(
305 wxT("%s?target=simple_messages&version=%s&controlid=%d"),
306 strURL.c_str(),
307 wxString(BOINC_VERSION_STRING, wxConvUTF8).c_str(),
308 ID_SIMPLE_HELP
309 );
310 wxLaunchDefaultBrowser(wxurl);
311 }
312
313 wxLogTrace(wxT("Function Start/End"), wxT("CPanelMessages::OnHelp - Function End"));
314 }
315
316
317 /*!
318 * wxEVT_NOTICELIST_ITEM_DISPLAY event handler for ID_LIST_NOTIFICATIONSVIEW
319 */
320
321
OnSaveState(wxConfigBase *)322 bool CPanelMessages::OnSaveState(wxConfigBase* /* pConfig */) {
323 return true;
324 }
325
326
OnRestoreState(wxConfigBase *)327 bool CPanelMessages::OnRestoreState(wxConfigBase* /* pConfig */) {
328 return true;
329 }
330
331
332 /*!
333 * CDlgMessages type definition
334 */
335
IMPLEMENT_DYNAMIC_CLASS(CDlgMessages,wxDialog)336 IMPLEMENT_DYNAMIC_CLASS( CDlgMessages, wxDialog )
337
338 /*!
339 * CDlgMessages event table definition
340 */
341
342 BEGIN_EVENT_TABLE( CDlgMessages, wxDialog )
343 ////@begin CDlgMessages event table entries
344 EVT_HELP(wxID_ANY, CDlgMessages::OnHelp)
345 EVT_SHOW( CDlgMessages::OnShow )
346 EVT_BUTTON( wxID_OK, CDlgMessages::OnOK )
347 EVT_SIZE(CDlgMessages::OnSize)
348 EVT_MOVE(CDlgMessages::OnMove)
349 ////@end CDlgMessages event table entries
350 END_EVENT_TABLE()
351
352 /*!
353 * CDlgMessages constructors
354 */
355
356 CDlgMessages::CDlgMessages( )
357 {
358 }
359
360
CDlgMessages(wxWindow * parent,wxWindowID id,const wxString & caption,const wxPoint & pos,const wxSize & size,long style)361 CDlgMessages::CDlgMessages( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
362 {
363 Create(parent, id, caption, pos, size, style);
364 }
365
366
~CDlgMessages()367 CDlgMessages::~CDlgMessages() {
368 wxLogTrace(wxT("Function Start/End"), wxT("CDlgMessages::CDlgMessages - Destructor Function Begin"));
369
370 SaveState(); // Save state if close box on window frame clicked
371 wxConfigBase::Get(FALSE)->Flush();
372
373 wxLogTrace(wxT("Function Start/End"), wxT("CDlgMessages::CDlgMessages - Destructor Function End"));
374 }
375
376
377 /*!
378 * CDlgMessages creator
379 */
380
Create(wxWindow * parent,wxWindowID id,const wxString & caption,const wxPoint & pos,const wxSize & size,long style)381 bool CDlgMessages::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
382 {
383 CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced();
384 wxASSERT(pSkinAdvanced);
385 wxASSERT(wxDynamicCast(pSkinAdvanced, CSkinAdvanced));
386
387
388 SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS);
389
390 wxDialog::Create( parent, id, caption, pos, size, style );
391
392 wxString strCaption = caption;
393 if (strCaption.IsEmpty()) {
394 strCaption.Printf(_("%s - Notices"), pSkinAdvanced->GetApplicationName().c_str());
395 }
396 SetTitle(strCaption);
397
398 // Initialize Application Icon
399 SetIcons(*pSkinAdvanced->GetApplicationIcon());
400
401 Freeze();
402
403 SetBackgroundStyle(wxBG_STYLE_CUSTOM);
404
405 #if TEST_BACKGROUND_WITH_MAGENTA_FILL
406 SetBackgroundColour(wxColour(255, 0, 255));
407 #endif
408 SetForegroundColour(*wxBLACK);
409
410 CreateControls();
411
412 GetSizer()->Fit(this);
413 GetSizer()->SetSizeHints(this);
414
415 // To work properly on Mac, RestoreState() must be called _after_
416 // calling GetSizer()->Fit(), GetSizer()->SetSizeHints() and Center()
417 RestoreState();
418
419 Thaw();
420
421 return true;
422 }
423
424
425 /*!
426 * Control creation for CDlgMessages
427 */
428
CreateControls()429 void CDlgMessages::CreateControls(){
430 wxFlexGridSizer* itemFlexGridSizer2 = new wxFlexGridSizer(1, 1, 0, 0);
431 itemFlexGridSizer2->AddGrowableRow(0);
432 itemFlexGridSizer2->AddGrowableCol(0);
433 SetSizer(itemFlexGridSizer2);
434
435 m_pBackgroundPanel = new CPanelMessages(this);
436 itemFlexGridSizer2->Add(m_pBackgroundPanel, 0, wxGROW, 0);
437
438 SetSizer(itemFlexGridSizer2);
439 }
440
441
442 /*!
443 * wxEVT_SHOW event handler for ID_DLGMESSAGES
444 */
445
OnShow(wxShowEvent & event)446 void CDlgMessages::OnShow(wxShowEvent& event) {
447 wxLogTrace(wxT("Function Start/End"), wxT("CDlgMessages::OnShow - Function Begin"));
448 static bool bAlreadyRunning = false;
449
450 if ((event.GetEventObject() == this) && !bAlreadyRunning) {
451 bAlreadyRunning = true;
452
453 wxLogTrace(wxT("Function Status"), wxT("CDlgMessages::OnShow - Show/Hide Event for CAdvancedFrame detected"));
454 if (event.IsShown()) {
455 RestoreWindowDimensions();
456 } else {
457 SaveWindowDimensions();
458 }
459
460 bAlreadyRunning = false;
461 } else {
462 event.Skip();
463 }
464
465 wxLogTrace(wxT("Function Start/End"), wxT("CDlgMessages::OnShow - Function End"));
466 }
467
468
469 /*!
470 * wxEVT_HELP event handler for ID_DLGMESSAGES
471 */
472
OnHelp(wxHelpEvent & WXUNUSED (event))473 void CDlgMessages::OnHelp(wxHelpEvent& WXUNUSED(event)) {
474 wxLogTrace(wxT("Function Start/End"), wxT("CDlgMessages::OnHelp - Function Begin"));
475
476 if (IsShown()) {
477 wxString strURL = wxGetApp().GetSkinManager()->GetAdvanced()->GetOrganizationHelpUrl();
478
479 wxString wxurl;
480 wxurl.Printf(
481 wxT("%s?target=simple_messages&version=%s&controlid=%d"),
482 strURL.c_str(),
483 wxString(BOINC_VERSION_STRING, wxConvUTF8).c_str(),
484 ID_SIMPLE_HELP
485 );
486 wxLaunchDefaultBrowser(wxurl);
487 }
488
489 wxLogTrace(wxT("Function Start/End"), wxT("CDlgMessages::OnHelp - Function End"));
490 }
491
492
493 /*!
494 * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_OK
495 */
496
OnOK(wxCommandEvent &)497 void CDlgMessages::OnOK( wxCommandEvent& /*event*/ ) {
498 EndModal(wxID_OK);
499 }
500
501
SaveState()502 bool CDlgMessages::SaveState() {
503 wxLogTrace(wxT("Function Start/End"), wxT("CDlgMessages::SaveState - Function Begin"));
504
505 wxString strBaseConfigLocation = wxString(wxT("/Simple/Messages"));
506 wxConfigBase* pConfig = wxConfigBase::Get(FALSE);
507
508 wxASSERT(pConfig);
509
510 // An odd case happens every once and awhile where wxWidgets looses
511 // the pointer to the config object, or it is cleaned up before
512 // the window has finished it's cleanup duty. If we detect a NULL
513 // pointer, return false.
514 if (!pConfig) return false;
515
516 //
517 // Save Frame State
518 //
519 pConfig->SetPath(strBaseConfigLocation);
520
521 // Reterieve and store the latest window dimensions.
522 SaveWindowDimensions();
523
524 // Save the list ctrl state
525 m_pBackgroundPanel->OnSaveState(pConfig);
526
527 wxLogTrace(wxT("Function Start/End"), wxT("CDlgMessages::SaveState - Function End"));
528 return true;
529 }
530
531
SaveWindowDimensions()532 void CDlgMessages::SaveWindowDimensions() {
533 wxString strBaseConfigLocation = wxString(wxT("/Simple/Messages"));
534 wxConfigBase* pConfig = wxConfigBase::Get(FALSE);
535
536 wxASSERT(pConfig);
537
538 pConfig->SetPath(strBaseConfigLocation);
539
540 pConfig->Write(wxT("WindowIconized"), IsIconized());
541 pConfig->Write(wxT("WindowMaximized"), IsMaximized());
542 if (!IsIconized()) {
543 pConfig->Write(wxT("Width"), GetSize().GetWidth());
544 pConfig->Write(wxT("Height"), GetSize().GetHeight());
545 pConfig->Write(wxT("XPos"), GetPosition().x);
546 pConfig->Write(wxT("YPos"), GetPosition().y);
547 }
548 }
549
550
RestoreState()551 bool CDlgMessages::RestoreState() {
552 wxLogTrace(wxT("Function Start/End"), wxT("CDlgMessages::RestoreState - Function Begin"));
553
554 wxString strBaseConfigLocation = wxString(wxT("/Simple/Messages"));
555 wxConfigBase* pConfig = wxConfigBase::Get(FALSE);
556
557 wxASSERT(pConfig);
558
559 // An odd case happens every once and awhile where wxWidgets looses
560 // the pointer to the config object, or it is cleaned up before
561 // the window has finished it's cleanup duty. If we detect a NULL
562 // pointer, return false.
563 if (!pConfig) return false;
564
565 //
566 // Restore Frame State
567 //
568 pConfig->SetPath(strBaseConfigLocation);
569
570 // Restore the windows properties
571 RestoreWindowDimensions();
572
573 // Restore the list ctrl state
574 m_pBackgroundPanel->OnRestoreState(pConfig);
575
576 wxLogTrace(wxT("Function Start/End"), wxT("CDlgMessages::RestoreState - Function End"));
577 return true;
578 }
579
580
RestoreWindowDimensions()581 void CDlgMessages::RestoreWindowDimensions() {
582 wxString strBaseConfigLocation = wxString(wxT("/Simple/Messages"));
583 wxConfigBase* pConfig = wxConfigBase::Get(FALSE);
584 bool bWindowIconized = false;
585 bool bWindowMaximized = false;
586 int iHeight = 0;
587 int iWidth = 0;
588 int iTop = 0;
589 int iLeft = 0;
590
591 wxASSERT(pConfig);
592
593 pConfig->SetPath(strBaseConfigLocation);
594
595 pConfig->Read(wxT("YPos"), &iTop, 30);
596 pConfig->Read(wxT("XPos"), &iLeft, 30);
597 pConfig->Read(wxT("Width"), &iWidth, 640);
598 pConfig->Read(wxT("Height"), &iHeight, 480);
599 pConfig->Read(wxT("WindowIconized"), &bWindowIconized, false);
600 pConfig->Read(wxT("WindowMaximized"), &bWindowMaximized, false);
601
602 // Guard against a rare situation where registry values are zero
603 if (iWidth < 50) iWidth = 640;
604 if (iHeight < 50) iHeight = 480;
605
606 #ifndef __WXMAC__
607
608 // If either co-ordinate is less then 0 then set it equal to 0 to ensure
609 // it displays on the screen.
610 if ( iLeft < 0 ) iLeft = 30;
611 if ( iTop < 0 ) iTop = 30;
612
613 // Read the size of the screen
614 wxInt32 iMaxWidth = wxSystemSettings::GetMetric( wxSYS_SCREEN_X );
615 wxInt32 iMaxHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
616
617 // Max sure that it doesn't go off to the right or bottom
618 if ( iLeft + iWidth > iMaxWidth ) iLeft = iMaxWidth - iWidth;
619 if ( iTop + iHeight > iMaxHeight ) iTop = iMaxHeight - iHeight;
620
621 if (!IsIconized() && !IsMaximized()) {
622 SetSize(iLeft, iTop, iWidth, iHeight);
623 }
624 Iconize(bWindowIconized);
625 Maximize(bWindowMaximized);
626
627 #else // ! __WXMAC__
628
629 // If the user has changed the arrangement of multiple
630 // displays, make sure the window title bar is still on-screen.
631 if (!IsWindowOnScreen(iLeft, iTop, iWidth, iHeight)) {
632 iTop = iLeft = 30;
633 }
634 SetSize(iLeft, iTop, iWidth, iHeight);
635 #endif // ! __WXMAC__
636 }
637
OnSize(wxSizeEvent & event)638 void CDlgMessages::OnSize(wxSizeEvent& event) {
639 if (IsShown()) {
640 SaveWindowDimensions();
641 }
642 event.Skip();
643 }
644
645
OnMove(wxMoveEvent & event)646 void CDlgMessages::OnMove(wxMoveEvent& event) {
647 if (IsShown()) {
648 SaveWindowDimensions();
649 }
650 event.Skip();
651 }
652