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