More WinCE mods.
[wxWidgets.git] / src / common / utilscmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: utilscmn.cpp
3 // Purpose: Miscellaneous utility functions and classes
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 29/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "utils.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/app.h"
33 #include "wx/string.h"
34 #include "wx/utils.h"
35 #include "wx/intl.h"
36 #include "wx/log.h"
37
38 #if wxUSE_GUI
39 #include "wx/window.h"
40 #include "wx/frame.h"
41 #include "wx/menu.h"
42 #include "wx/msgdlg.h"
43 #include "wx/textdlg.h"
44 #include "wx/textctrl.h" // for wxTE_PASSWORD
45 #if wxUSE_ACCEL
46 #include "wx/menuitem.h"
47 #include "wx/accel.h"
48 #endif // wxUSE_ACCEL
49 #endif // wxUSE_GUI
50 #endif // WX_PRECOMP
51
52 #include "wx/apptrait.h"
53
54 #include "wx/process.h"
55 #include "wx/txtstrm.h"
56
57 #include <ctype.h>
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <string.h>
61
62 #if !defined(__WATCOMC__)
63 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
64 #include <errno.h>
65 #endif
66 #endif
67
68 #if wxUSE_GUI
69 #include "wx/colordlg.h"
70 #include "wx/fontdlg.h"
71 #include "wx/notebook.h"
72 #include "wx/frame.h"
73 #include "wx/statusbr.h"
74 #endif // wxUSE_GUI
75
76 #ifndef __WXWINCE__
77 #include <time.h>
78 #else
79 #include "wx/msw/wince/time.h"
80 #endif
81
82 #ifndef __MWERKS__
83 #include <sys/types.h>
84 #include <sys/stat.h>
85 #endif
86
87 #ifdef __SALFORDC__
88 #include <clib.h>
89 #endif
90
91 #ifdef __WXMSW__
92 #include "wx/msw/private.h"
93 #endif
94
95 #if wxUSE_BASE
96
97 // ----------------------------------------------------------------------------
98 // common data
99 // ----------------------------------------------------------------------------
100
101 #if WXWIN_COMPATIBILITY_2_2
102 const wxChar *wxInternalErrorStr = wxT("wxWindows Internal Error");
103 const wxChar *wxFatalErrorStr = wxT("wxWindows Fatal Error");
104 #endif // WXWIN_COMPATIBILITY_2_2
105
106 // ============================================================================
107 // implementation
108 // ============================================================================
109
110 #if WXWIN_COMPATIBILITY_2_4
111
112 wxChar *
113 copystring (const wxChar *s)
114 {
115 if (s == NULL) s = wxT("");
116 size_t len = wxStrlen (s) + 1;
117
118 wxChar *news = new wxChar[len];
119 memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest
120
121 return news;
122 }
123
124 #endif // WXWIN_COMPATIBILITY_2_4
125
126 // Id generation
127 static long wxCurrentId = 100;
128
129 long
130 wxNewId (void)
131 {
132 return wxCurrentId++;
133 }
134
135 long
136 wxGetCurrentId(void) { return wxCurrentId; }
137
138 void
139 wxRegisterId (long id)
140 {
141 if (id >= wxCurrentId)
142 wxCurrentId = id + 1;
143 }
144
145 // ----------------------------------------------------------------------------
146 // String <-> Number conversions (deprecated)
147 // ----------------------------------------------------------------------------
148
149 #if WXWIN_COMPATIBILITY_2_4
150
151 WXDLLIMPEXP_DATA_BASE(const wxChar *) wxFloatToStringStr = wxT("%.2f");
152 WXDLLIMPEXP_DATA_BASE(const wxChar *) wxDoubleToStringStr = wxT("%.2f");
153
154 void
155 StringToFloat (const wxChar *s, float *number)
156 {
157 if (s && *s && number)
158 *number = (float) wxStrtod (s, (wxChar **) NULL);
159 }
160
161 void
162 StringToDouble (const wxChar *s, double *number)
163 {
164 if (s && *s && number)
165 *number = wxStrtod (s, (wxChar **) NULL);
166 }
167
168 wxChar *
169 FloatToString (float number, const wxChar *fmt)
170 {
171 static wxChar buf[256];
172
173 wxSprintf (buf, fmt, number);
174 return buf;
175 }
176
177 wxChar *
178 DoubleToString (double number, const wxChar *fmt)
179 {
180 static wxChar buf[256];
181
182 wxSprintf (buf, fmt, number);
183 return buf;
184 }
185
186 void
187 StringToInt (const wxChar *s, int *number)
188 {
189 if (s && *s && number)
190 *number = (int) wxStrtol (s, (wxChar **) NULL, 10);
191 }
192
193 void
194 StringToLong (const wxChar *s, long *number)
195 {
196 if (s && *s && number)
197 *number = wxStrtol (s, (wxChar **) NULL, 10);
198 }
199
200 wxChar *
201 IntToString (int number)
202 {
203 static wxChar buf[20];
204
205 wxSprintf (buf, wxT("%d"), number);
206 return buf;
207 }
208
209 wxChar *
210 LongToString (long number)
211 {
212 static wxChar buf[20];
213
214 wxSprintf (buf, wxT("%ld"), number);
215 return buf;
216 }
217
218 #endif // WXWIN_COMPATIBILITY_2_4
219
220 // Array used in DecToHex conversion routine.
221 static wxChar hexArray[] = wxT("0123456789ABCDEF");
222
223 // Convert 2-digit hex number to decimal
224 int wxHexToDec(const wxString& buf)
225 {
226 int firstDigit, secondDigit;
227
228 if (buf.GetChar(0) >= wxT('A'))
229 firstDigit = buf.GetChar(0) - wxT('A') + 10;
230 else
231 firstDigit = buf.GetChar(0) - wxT('0');
232
233 if (buf.GetChar(1) >= wxT('A'))
234 secondDigit = buf.GetChar(1) - wxT('A') + 10;
235 else
236 secondDigit = buf.GetChar(1) - wxT('0');
237
238 return (firstDigit & 0xF) * 16 + (secondDigit & 0xF );
239 }
240
241 // Convert decimal integer to 2-character hex string
242 void wxDecToHex(int dec, wxChar *buf)
243 {
244 int firstDigit = (int)(dec/16.0);
245 int secondDigit = (int)(dec - (firstDigit*16.0));
246 buf[0] = hexArray[firstDigit];
247 buf[1] = hexArray[secondDigit];
248 buf[2] = 0;
249 }
250
251 // Convert decimal integer to 2-character hex string
252 wxString wxDecToHex(int dec)
253 {
254 wxChar buf[3];
255 wxDecToHex(dec, buf);
256 return wxString(buf);
257 }
258
259 // ----------------------------------------------------------------------------
260 // misc functions
261 // ----------------------------------------------------------------------------
262
263 // Return the current date/time
264 wxString wxNow()
265 {
266 time_t now = time((time_t *) NULL);
267 char *date = ctime(&now);
268 date[24] = '\0';
269 return wxString::FromAscii(date);
270 }
271
272 const wxChar *wxGetInstallPrefix()
273 {
274 wxString prefix;
275
276 if ( wxGetEnv(wxT("WXPREFIX"), &prefix) )
277 return prefix.c_str();
278
279 #ifdef wxINSTALL_PREFIX
280 return wxT(wxINSTALL_PREFIX);
281 #else
282 return wxT("");
283 #endif
284 }
285
286 wxString wxGetDataDir()
287 {
288 wxString format = wxGetInstallPrefix();
289 format << wxFILE_SEP_PATH
290 << wxT("share") << wxFILE_SEP_PATH
291 << wxT("wx") << wxFILE_SEP_PATH
292 << wxT("%i.%i");
293 wxString dir;
294 dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
295 return dir;
296 }
297
298 int wxGetOsVersion(int *verMaj, int *verMin)
299 {
300 // we want this function to work even if there is no wxApp
301 wxConsoleAppTraits traitsConsole;
302 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
303 if ( ! traits )
304 traits = &traitsConsole;
305
306 return traits->GetOSVersion(verMaj, verMin);
307 }
308
309 // ----------------------------------------------------------------------------
310 // network and user id functions
311 // ----------------------------------------------------------------------------
312
313 // Get Full RFC822 style email address
314 bool wxGetEmailAddress(wxChar *address, int maxSize)
315 {
316 wxString email = wxGetEmailAddress();
317 if ( !email )
318 return FALSE;
319
320 wxStrncpy(address, email, maxSize - 1);
321 address[maxSize - 1] = wxT('\0');
322
323 return TRUE;
324 }
325
326 wxString wxGetEmailAddress()
327 {
328 wxString email;
329
330 wxString host = wxGetFullHostName();
331 if ( !!host )
332 {
333 wxString user = wxGetUserId();
334 if ( !!user )
335 {
336 email << user << wxT('@') << host;
337 }
338 }
339
340 return email;
341 }
342
343 wxString wxGetUserId()
344 {
345 static const int maxLoginLen = 256; // FIXME arbitrary number
346
347 wxString buf;
348 bool ok = wxGetUserId(buf.GetWriteBuf(maxLoginLen), maxLoginLen);
349 buf.UngetWriteBuf();
350
351 if ( !ok )
352 buf.Empty();
353
354 return buf;
355 }
356
357 wxString wxGetUserName()
358 {
359 static const int maxUserNameLen = 1024; // FIXME arbitrary number
360
361 wxString buf;
362 bool ok = wxGetUserName(buf.GetWriteBuf(maxUserNameLen), maxUserNameLen);
363 buf.UngetWriteBuf();
364
365 if ( !ok )
366 buf.Empty();
367
368 return buf;
369 }
370
371 wxString wxGetHostName()
372 {
373 static const size_t hostnameSize = 257;
374
375 wxString buf;
376 bool ok = wxGetHostName(buf.GetWriteBuf(hostnameSize), hostnameSize);
377
378 buf.UngetWriteBuf();
379
380 if ( !ok )
381 buf.Empty();
382
383 return buf;
384 }
385
386 wxString wxGetFullHostName()
387 {
388 static const size_t hostnameSize = 257;
389
390 wxString buf;
391 bool ok = wxGetFullHostName(buf.GetWriteBuf(hostnameSize), hostnameSize);
392
393 buf.UngetWriteBuf();
394
395 if ( !ok )
396 buf.Empty();
397
398 return buf;
399 }
400
401 wxString wxGetHomeDir()
402 {
403 wxString home;
404 wxGetHomeDir(&home);
405
406 return home;
407 }
408
409 #if 0
410
411 wxString wxGetCurrentDir()
412 {
413 wxString dir;
414 size_t len = 1024;
415 bool ok;
416 do
417 {
418 ok = getcwd(dir.GetWriteBuf(len + 1), len) != NULL;
419 dir.UngetWriteBuf();
420
421 if ( !ok )
422 {
423 if ( errno != ERANGE )
424 {
425 wxLogSysError(_T("Failed to get current directory"));
426
427 return wxEmptyString;
428 }
429 else
430 {
431 // buffer was too small, retry with a larger one
432 len *= 2;
433 }
434 }
435 //else: ok
436 } while ( !ok );
437
438 return dir;
439 }
440
441 #endif // 0
442
443 // ----------------------------------------------------------------------------
444 // wxExecute
445 // ----------------------------------------------------------------------------
446
447 // wxDoExecuteWithCapture() helper: reads an entire stream into one array
448 //
449 // returns TRUE if ok, FALSE if error
450 #if wxUSE_STREAMS
451 static bool ReadAll(wxInputStream *is, wxArrayString& output)
452 {
453 wxCHECK_MSG( is, FALSE, _T("NULL stream in wxExecute()?") );
454
455 // the stream could be already at EOF or in wxSTREAM_BROKEN_PIPE state
456 is->Reset();
457
458 wxTextInputStream tis(*is);
459
460 bool cont = TRUE;
461 while ( cont )
462 {
463 wxString line = tis.ReadLine();
464 if ( is->Eof() )
465 break;
466
467 if ( !*is )
468 {
469 cont = FALSE;
470 }
471 else
472 {
473 output.Add(line);
474 }
475 }
476
477 return cont;
478 }
479 #endif // wxUSE_STREAMS
480
481 // this is a private function because it hasn't a clean interface: the first
482 // array is passed by reference, the second by pointer - instead we have 2
483 // public versions of wxExecute() below
484 static long wxDoExecuteWithCapture(const wxString& command,
485 wxArrayString& output,
486 wxArrayString* error)
487 {
488 // create a wxProcess which will capture the output
489 wxProcess *process = new wxProcess;
490 process->Redirect();
491
492 long rc = wxExecute(command, wxEXEC_SYNC, process);
493
494 #if wxUSE_STREAMS
495 if ( rc != -1 )
496 {
497 if ( !ReadAll(process->GetInputStream(), output) )
498 rc = -1;
499
500 if ( error )
501 {
502 if ( !ReadAll(process->GetErrorStream(), *error) )
503 rc = -1;
504 }
505
506 }
507 #endif // wxUSE_STREAMS
508
509 delete process;
510
511 return rc;
512 }
513
514 long wxExecute(const wxString& command, wxArrayString& output)
515 {
516 return wxDoExecuteWithCapture(command, output, NULL);
517 }
518
519 long wxExecute(const wxString& command,
520 wxArrayString& output,
521 wxArrayString& error)
522 {
523 return wxDoExecuteWithCapture(command, output, &error);
524 }
525
526 // ----------------------------------------------------------------------------
527 // wxApp::Yield() wrappers for backwards compatibility
528 // ----------------------------------------------------------------------------
529
530 bool wxYield()
531 {
532 return wxTheApp && wxTheApp->Yield();
533 }
534
535 bool wxYieldIfNeeded()
536 {
537 return wxTheApp && wxTheApp->Yield(TRUE);
538 }
539
540 #endif // wxUSE_BASE
541
542 // ============================================================================
543 // GUI-only functions from now on
544 // ============================================================================
545
546 #if wxUSE_GUI
547
548 #if wxUSE_MENUS
549
550 // ----------------------------------------------------------------------------
551 // Menu accelerators related functions
552 // ----------------------------------------------------------------------------
553
554 wxChar *wxStripMenuCodes(const wxChar *in, wxChar *out)
555 {
556 wxString s = wxMenuItem::GetLabelFromText(in);
557 if ( out )
558 {
559 // go smash their buffer if it's not big enough - I love char * params
560 memcpy(out, s.c_str(), s.length() * sizeof(wxChar));
561 }
562 else
563 {
564 // MYcopystring - for easier search...
565 out = new wxChar[s.length() + 1];
566 wxStrcpy(out, s.c_str());
567 }
568
569 return out;
570 }
571
572 wxString wxStripMenuCodes(const wxString& in)
573 {
574 wxString out;
575
576 size_t len = in.length();
577 out.reserve(len);
578
579 for ( size_t n = 0; n < len; n++ )
580 {
581 wxChar ch = in[n];
582 if ( ch == _T('&') )
583 {
584 // skip it, it is used to introduce the accel char (or to quote
585 // itself in which case it should still be skipped): note that it
586 // can't be the last character of the string
587 if ( ++n == len )
588 {
589 wxLogDebug(_T("Invalid menu string '%s'"), in.c_str());
590 }
591 else
592 {
593 // use the next char instead
594 ch = in[n];
595 }
596 }
597 else if ( ch == _T('\t') )
598 {
599 // everything after TAB is accel string, exit the loop
600 break;
601 }
602
603 out += ch;
604 }
605
606 return out;
607 }
608
609 #endif // wxUSE_MENUS
610
611 // ----------------------------------------------------------------------------
612 // Window search functions
613 // ----------------------------------------------------------------------------
614
615 /*
616 * If parent is non-NULL, look through children for a label or title
617 * matching the specified string. If NULL, look through all top-level windows.
618 *
619 */
620
621 wxWindow *
622 wxFindWindowByLabel (const wxString& title, wxWindow * parent)
623 {
624 return wxWindow::FindWindowByLabel( title, parent );
625 }
626
627
628 /*
629 * If parent is non-NULL, look through children for a name
630 * matching the specified string. If NULL, look through all top-level windows.
631 *
632 */
633
634 wxWindow *
635 wxFindWindowByName (const wxString& name, wxWindow * parent)
636 {
637 return wxWindow::FindWindowByName( name, parent );
638 }
639
640 // Returns menu item id or -1 if none.
641 int
642 wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
643 {
644 #if wxUSE_MENUS
645 wxMenuBar *menuBar = frame->GetMenuBar ();
646 if ( menuBar )
647 return menuBar->FindMenuItem (menuString, itemString);
648 #endif // wxUSE_MENUS
649
650 return -1;
651 }
652
653 // Try to find the deepest child that contains 'pt'.
654 // We go backwards, to try to allow for controls that are spacially
655 // within other controls, but are still siblings (e.g. buttons within
656 // static boxes). Static boxes are likely to be created _before_ controls
657 // that sit inside them.
658 wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt)
659 {
660 if (!win->IsShown())
661 return NULL;
662
663 // Hack for wxNotebook case: at least in wxGTK, all pages
664 // claim to be shown, so we must only deal with the selected one.
665 #if wxUSE_NOTEBOOK
666 if (win->IsKindOf(CLASSINFO(wxNotebook)))
667 {
668 wxNotebook* nb = (wxNotebook*) win;
669 int sel = nb->GetSelection();
670 if (sel >= 0)
671 {
672 wxWindow* child = nb->GetPage(sel);
673 wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
674 if (foundWin)
675 return foundWin;
676 }
677 }
678 #endif
679
680 wxWindowList::compatibility_iterator node = win->GetChildren().GetLast();
681 while (node)
682 {
683 wxWindow* child = node->GetData();
684 wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
685 if (foundWin)
686 return foundWin;
687 node = node->GetPrevious();
688 }
689
690 wxPoint pos = win->GetPosition();
691 wxSize sz = win->GetSize();
692 if (win->GetParent())
693 {
694 pos = win->GetParent()->ClientToScreen(pos);
695 }
696
697 wxRect rect(pos, sz);
698 if (rect.Inside(pt))
699 return win;
700 else
701 return NULL;
702 }
703
704 wxWindow* wxGenericFindWindowAtPoint(const wxPoint& pt)
705 {
706 // Go backwards through the list since windows
707 // on top are likely to have been appended most
708 // recently.
709 wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetLast();
710 while (node)
711 {
712 wxWindow* win = node->GetData();
713 wxWindow* found = wxFindWindowAtPoint(win, pt);
714 if (found)
715 return found;
716 node = node->GetPrevious();
717 }
718 return NULL;
719 }
720
721 // ----------------------------------------------------------------------------
722 // GUI helpers
723 // ----------------------------------------------------------------------------
724
725 /*
726 * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
727 * since otherwise the generic code may be pulled in unnecessarily.
728 */
729
730 #if wxUSE_MSGDLG
731
732 int wxMessageBox(const wxString& message, const wxString& caption, long style,
733 wxWindow *parent, int WXUNUSED(x), int WXUNUSED(y) )
734 {
735 wxMessageDialog dialog(parent, message, caption, style);
736
737 int ans = dialog.ShowModal();
738 switch ( ans )
739 {
740 case wxID_OK:
741 return wxOK;
742 case wxID_YES:
743 return wxYES;
744 case wxID_NO:
745 return wxNO;
746 case wxID_CANCEL:
747 return wxCANCEL;
748 }
749
750 wxFAIL_MSG( _T("unexpected return code from wxMessageDialog") );
751
752 return wxCANCEL;
753 }
754
755 #endif // wxUSE_MSGDLG
756
757 #if wxUSE_TEXTDLG
758
759 wxString wxGetTextFromUser(const wxString& message, const wxString& caption,
760 const wxString& defaultValue, wxWindow *parent,
761 int x, int y, bool WXUNUSED(centre) )
762 {
763 wxString str;
764 wxTextEntryDialog dialog(parent, message, caption, defaultValue, wxOK|wxCANCEL, wxPoint(x, y));
765 if (dialog.ShowModal() == wxID_OK)
766 {
767 str = dialog.GetValue();
768 }
769
770 return str;
771 }
772
773 wxString wxGetPasswordFromUser(const wxString& message,
774 const wxString& caption,
775 const wxString& defaultValue,
776 wxWindow *parent)
777 {
778 wxString str;
779 wxTextEntryDialog dialog(parent, message, caption, defaultValue,
780 wxOK | wxCANCEL | wxTE_PASSWORD);
781 if ( dialog.ShowModal() == wxID_OK )
782 {
783 str = dialog.GetValue();
784 }
785
786 return str;
787 }
788
789 #endif // wxUSE_TEXTDLG
790
791 #if wxUSE_COLOURDLG
792
793 wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit)
794 {
795 wxColourData data;
796 data.SetChooseFull(TRUE);
797 if ( colInit.Ok() )
798 {
799 data.SetColour((wxColour &)colInit); // const_cast
800 }
801
802 wxColour colRet;
803 wxColourDialog dialog(parent, &data);
804 if ( dialog.ShowModal() == wxID_OK )
805 {
806 colRet = dialog.GetColourData().GetColour();
807 }
808 //else: leave it invalid
809
810 return colRet;
811 }
812
813 #endif // wxUSE_COLOURDLG
814
815 #if wxUSE_FONTDLG
816
817 wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit)
818 {
819 wxFontData data;
820 if ( fontInit.Ok() )
821 {
822 data.SetInitialFont(fontInit);
823 }
824
825 wxFont fontRet;
826 wxFontDialog dialog(parent, data);
827 if ( dialog.ShowModal() == wxID_OK )
828 {
829 fontRet = dialog.GetFontData().GetChosenFont();
830 }
831 //else: leave it invalid
832
833 return fontRet;
834 }
835
836 #endif // wxUSE_FONTDLG
837
838 // ----------------------------------------------------------------------------
839 // wxSafeYield and supporting functions
840 // ----------------------------------------------------------------------------
841
842 void wxEnableTopLevelWindows(bool enable)
843 {
844 wxWindowList::compatibility_iterator node;
845 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
846 node->GetData()->Enable(enable);
847 }
848
849 wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip)
850 {
851 // remember the top level windows which were already disabled, so that we
852 // don't reenable them later
853 m_winDisabled = NULL;
854
855 wxWindowList::compatibility_iterator node;
856 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
857 {
858 wxWindow *winTop = node->GetData();
859 if ( winTop == winToSkip )
860 continue;
861
862 // we don't need to disable the hidden or already disabled windows
863 if ( winTop->IsEnabled() && winTop->IsShown() )
864 {
865 winTop->Disable();
866 }
867 else
868 {
869 if ( !m_winDisabled )
870 {
871 m_winDisabled = new wxWindowList;
872 }
873
874 m_winDisabled->Append(winTop);
875 }
876 }
877 }
878
879 wxWindowDisabler::~wxWindowDisabler()
880 {
881 wxWindowList::compatibility_iterator node;
882 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
883 {
884 wxWindow *winTop = node->GetData();
885 if ( !m_winDisabled || !m_winDisabled->Find(winTop) )
886 {
887 winTop->Enable();
888 }
889 //else: had been already disabled, don't reenable
890 }
891
892 delete m_winDisabled;
893 }
894
895 // Yield to other apps/messages and disable user input to all windows except
896 // the given one
897 bool wxSafeYield(wxWindow *win, bool onlyIfNeeded)
898 {
899 wxWindowDisabler wd(win);
900
901 bool rc;
902 if (onlyIfNeeded)
903 rc = wxYieldIfNeeded();
904 else
905 rc = wxYield();
906
907 return rc;
908 }
909
910 // Don't synthesize KeyUp events holding down a key and producing KeyDown
911 // events with autorepeat. On by default and always on in wxMSW. wxGTK version
912 // in utilsgtk.cpp.
913 #ifndef __WXGTK__
914 bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) )
915 {
916 return TRUE; // detectable auto-repeat is the only mode MSW supports
917 }
918 #endif // !wxGTK
919
920 #endif // wxUSE_GUI
921