]> git.saurik.com Git - wxWidgets.git/blame - src/common/utilscmn.cpp
More WinCE mods
[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
c801d85f
KB
57#include <ctype.h>
58#include <stdio.h>
59#include <stdlib.h>
60#include <string.h>
e90c1d2a 61
c801d85f 62#if !defined(__WATCOMC__)
3f4a0c5b
VZ
63 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
64 #include <errno.h>
65 #endif
c801d85f 66#endif
e90c1d2a 67
91b4c08d
VZ
68#if wxUSE_GUI
69 #include "wx/colordlg.h"
bf31fa26 70 #include "wx/fontdlg.h"
d1c8aaa3
JS
71 #include "wx/notebook.h"
72 #include "wx/frame.h"
73 #include "wx/statusbr.h"
91b4c08d
VZ
74#endif // wxUSE_GUI
75
1c193821 76#ifndef __WXWINCE__
c801d85f 77#include <time.h>
1c193821
JS
78#else
79#include "wx/msw/wince/time.h"
80#endif
e90c1d2a 81
469e1e5c 82#ifndef __MWERKS__
e90c1d2a
VZ
83 #include <sys/types.h>
84 #include <sys/stat.h>
469e1e5c 85#endif
c801d85f 86
ce3ed50d 87#ifdef __SALFORDC__
e90c1d2a 88 #include <clib.h>
ce3ed50d
JS
89#endif
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{
2b5f62a0
VZ
266 time_t now = time((time_t *) NULL);
267 char *date = ctime(&now);
268 date[24] = '\0';
269 return wxString::FromAscii(date);
c801d85f
KB
270}
271
7c072018
VZ
272const 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
286wxString 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}
e90c1d2a 297
2739d4f0
VZ
298int 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}
1e6feb95 308
e90c1d2a 309// ----------------------------------------------------------------------------
7c072018 310// network and user id functions
e90c1d2a 311// ----------------------------------------------------------------------------
c801d85f 312
7c072018
VZ
313// Get Full RFC822 style email address
314bool wxGetEmailAddress(wxChar *address, int maxSize)
c801d85f 315{
7c072018
VZ
316 wxString email = wxGetEmailAddress();
317 if ( !email )
318 return FALSE;
c801d85f 319
7c072018
VZ
320 wxStrncpy(address, email, maxSize - 1);
321 address[maxSize - 1] = wxT('\0');
322
323 return TRUE;
c801d85f
KB
324}
325
7c072018 326wxString wxGetEmailAddress()
47bc1060 327{
7c072018 328 wxString email;
974e8d94 329
7c072018
VZ
330 wxString host = wxGetFullHostName();
331 if ( !!host )
1e6feb95 332 {
7c072018
VZ
333 wxString user = wxGetUserId();
334 if ( !!user )
1e6feb95 335 {
7c072018 336 email << user << wxT('@') << host;
974e8d94 337 }
974e8d94
VZ
338 }
339
7c072018 340 return email;
974e8d94
VZ
341}
342
7c072018 343wxString wxGetUserId()
c801d85f 344{
7c072018 345 static const int maxLoginLen = 256; // FIXME arbitrary number
c801d85f 346
7c072018
VZ
347 wxString buf;
348 bool ok = wxGetUserId(buf.GetWriteBuf(maxLoginLen), maxLoginLen);
349 buf.UngetWriteBuf();
c801d85f 350
7c072018
VZ
351 if ( !ok )
352 buf.Empty();
c801d85f 353
7c072018 354 return buf;
c801d85f
KB
355}
356
7c072018 357wxString wxGetUserName()
c801d85f 358{
7c072018 359 static const int maxUserNameLen = 1024; // FIXME arbitrary number
1e6feb95 360
7c072018
VZ
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;
59a12e90
JS
369}
370
7c072018 371wxString wxGetHostName()
59a12e90 372{
7c072018 373 static const size_t hostnameSize = 257;
c67d6888 374
7c072018
VZ
375 wxString buf;
376 bool ok = wxGetHostName(buf.GetWriteBuf(hostnameSize), hostnameSize);
d1c8aaa3 377
7c072018 378 buf.UngetWriteBuf();
59a12e90 379
7c072018
VZ
380 if ( !ok )
381 buf.Empty();
59a12e90 382
7c072018 383 return buf;
59a12e90
JS
384}
385
7c072018 386wxString wxGetFullHostName()
59a12e90 387{
7c072018 388 static const size_t hostnameSize = 257;
c801d85f 389
7c072018
VZ
390 wxString buf;
391 bool ok = wxGetFullHostName(buf.GetWriteBuf(hostnameSize), hostnameSize);
e90c1d2a 392
7c072018
VZ
393 buf.UngetWriteBuf();
394
395 if ( !ok )
396 buf.Empty();
c801d85f 397
7c072018
VZ
398 return buf;
399}
c801d85f 400
7c072018
VZ
401wxString wxGetHomeDir()
402{
403 wxString home;
404 wxGetHomeDir(&home);
c801d85f 405
7c072018
VZ
406 return home;
407}
c801d85f 408
c801d85f
KB
409#if 0
410
7c072018 411wxString wxGetCurrentDir()
c801d85f 412{
7c072018
VZ
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();
c801d85f 420
7c072018
VZ
421 if ( !ok )
422 {
423 if ( errno != ERANGE )
424 {
425 wxLogSysError(_T("Failed to get current directory"));
c801d85f 426
7c072018
VZ
427 return wxEmptyString;
428 }
3f4a0c5b 429 else
7c072018
VZ
430 {
431 // buffer was too small, retry with a larger one
432 len *= 2;
433 }
3f4a0c5b 434 }
7c072018
VZ
435 //else: ok
436 } while ( !ok );
c801d85f 437
7c072018 438 return dir;
c801d85f
KB
439}
440
7c072018 441#endif // 0
e90c1d2a
VZ
442
443// ----------------------------------------------------------------------------
7c072018 444// wxExecute
e90c1d2a 445// ----------------------------------------------------------------------------
ead7ce10 446
7c072018
VZ
447// wxDoExecuteWithCapture() helper: reads an entire stream into one array
448//
449// returns TRUE if ok, FALSE if error
450#if wxUSE_STREAMS
451static bool ReadAll(wxInputStream *is, wxArrayString& output)
dfad0599 452{
7c072018 453 wxCHECK_MSG( is, FALSE, _T("NULL stream in wxExecute()?") );
dfad0599 454
7c072018
VZ
455 // the stream could be already at EOF or in wxSTREAM_BROKEN_PIPE state
456 is->Reset();
1e6feb95 457
7c072018 458 wxTextInputStream tis(*is);
1e6feb95 459
7c072018
VZ
460 bool cont = TRUE;
461 while ( cont )
d2f50933 462 {
7c072018
VZ
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 }
d2f50933
VZ
475 }
476
7c072018 477 return cont;
dfad0599 478}
7c072018 479#endif // wxUSE_STREAMS
d2f50933 480
7c072018
VZ
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
484static long wxDoExecuteWithCapture(const wxString& command,
485 wxArrayString& output,
486 wxArrayString* error)
d2f50933 487{
7c072018
VZ
488 // create a wxProcess which will capture the output
489 wxProcess *process = new wxProcess;
490 process->Redirect();
dfad0599 491
7c072018 492 long rc = wxExecute(command, wxEXEC_SYNC, process);
1e6feb95 493
7c072018
VZ
494#if wxUSE_STREAMS
495 if ( rc != -1 )
bf31fa26 496 {
7c072018
VZ
497 if ( !ReadAll(process->GetInputStream(), output) )
498 rc = -1;
91b4c08d 499
7c072018
VZ
500 if ( error )
501 {
502 if ( !ReadAll(process->GetErrorStream(), *error) )
503 rc = -1;
504 }
91b4c08d 505
7c072018
VZ
506 }
507#endif // wxUSE_STREAMS
91b4c08d 508
7c072018 509 delete process;
1e6feb95 510
7c072018 511 return rc;
7c072018 512}
bf31fa26 513
7c072018 514long wxExecute(const wxString& command, wxArrayString& output)
bf31fa26 515{
7c072018
VZ
516 return wxDoExecuteWithCapture(command, output, NULL);
517}
bf31fa26 518
7c072018
VZ
519long wxExecute(const wxString& command,
520 wxArrayString& output,
521 wxArrayString& error)
522{
523 return wxDoExecuteWithCapture(command, output, &error);
bf31fa26
VZ
524}
525
91b4c08d 526// ----------------------------------------------------------------------------
7c072018 527// wxApp::Yield() wrappers for backwards compatibility
91b4c08d
VZ
528// ----------------------------------------------------------------------------
529
7c072018 530bool wxYield()
469e1e5c 531{
7c072018 532 return wxTheApp && wxTheApp->Yield();
469e1e5c 533}
7c072018
VZ
534
535bool wxYieldIfNeeded()
469e1e5c 536{
7c072018 537 return wxTheApp && wxTheApp->Yield(TRUE);
469e1e5c 538}
7c072018 539
ec67cff1 540#endif // wxUSE_BASE
7c072018
VZ
541
542// ============================================================================
543// GUI-only functions from now on
544// ============================================================================
545
546#if wxUSE_GUI
547
548#if wxUSE_MENUS
e90c1d2a
VZ
549
550// ----------------------------------------------------------------------------
7c072018 551// Menu accelerators related functions
e90c1d2a
VZ
552// ----------------------------------------------------------------------------
553
7c072018 554wxChar *wxStripMenuCodes(const wxChar *in, wxChar *out)
e90c1d2a 555{
7c072018
VZ
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 {
f526f752
MB
564 // MYcopystring - for easier search...
565 out = new wxChar[s.length() + 1];
566 wxStrcpy(out, s.c_str());
7c072018
VZ
567 }
568
569 return out;
e90c1d2a
VZ
570}
571
7c072018 572wxString wxStripMenuCodes(const wxString& in)
e90c1d2a 573{
7c072018 574 wxString out;
79f585d9 575
7c072018
VZ
576 size_t len = in.length();
577 out.reserve(len);
79f585d9 578
7c072018
VZ
579 for ( size_t n = 0; n < len; n++ )
580 {
581 wxChar ch = in[n];
582 if ( ch == _T('&') )
cd6ce4a9 583 {
7c072018
VZ
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 )
79f585d9 588 {
7c072018
VZ
589 wxLogDebug(_T("Invalid menu string '%s'"), in.c_str());
590 }
591 else
592 {
593 // use the next char instead
594 ch = in[n];
79f585d9 595 }
cd6ce4a9 596 }
7c072018 597 else if ( ch == _T('\t') )
79f585d9 598 {
7c072018
VZ
599 // everything after TAB is accel string, exit the loop
600 break;
79f585d9 601 }
7c072018
VZ
602
603 out += ch;
225fe9d6
VZ
604 }
605
7c072018 606 return out;
cd6ce4a9
VZ
607}
608
7c072018 609#endif // wxUSE_MENUS
e90c1d2a 610
cbc66a27 611// ----------------------------------------------------------------------------
7c072018 612// Window search functions
cbc66a27
VZ
613// ----------------------------------------------------------------------------
614
7c072018
VZ
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 */
e2a6f233 620
7c072018
VZ
621wxWindow *
622wxFindWindowByLabel (const wxString& title, wxWindow * parent)
134677bd 623{
7c072018
VZ
624 return wxWindow::FindWindowByLabel( title, parent );
625}
b829bf55 626
b829bf55 627
7c072018
VZ
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 */
134677bd 633
7c072018
VZ
634wxWindow *
635wxFindWindowByName (const wxString& name, wxWindow * parent)
2c18f21d 636{
7c072018 637 return wxWindow::FindWindowByName( name, parent );
2c18f21d
VS
638}
639
7c072018
VZ
640// Returns menu item id or -1 if none.
641int
642wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
e2a6f233 643{
7c072018
VZ
644#if wxUSE_MENUS
645 wxMenuBar *menuBar = frame->GetMenuBar ();
646 if ( menuBar )
647 return menuBar->FindMenuItem (menuString, itemString);
648#endif // wxUSE_MENUS
0fb67cd1 649
7c072018 650 return -1;
e2a6f233
JS
651}
652
7c072018
VZ
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.
658wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt)
e2a6f233 659{
7c072018
VZ
660 if (!win->IsShown())
661 return NULL;
0fb67cd1 662
7c072018
VZ
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)))
e2a6f233 667 {
7c072018
VZ
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 }
e2a6f233 677 }
7c072018 678#endif
0fb67cd1 679
df5168c4 680 wxWindowList::compatibility_iterator node = win->GetChildren().GetLast();
7c072018
VZ
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;
0fb67cd1
VZ
702}
703
7c072018 704wxWindow* wxGenericFindWindowAtPoint(const wxPoint& pt)
0fb67cd1 705{
7c072018
VZ
706 // Go backwards through the list since windows
707 // on top are likely to have been appended most
708 // recently.
df5168c4 709 wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetLast();
7c072018
VZ
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}
0fb67cd1 720
7c072018
VZ
721// ----------------------------------------------------------------------------
722// GUI helpers
723// ----------------------------------------------------------------------------
0fb67cd1 724
7c072018
VZ
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 */
0fb67cd1 729
7c072018 730#if wxUSE_MSGDLG
0fb67cd1 731
7c072018
VZ
732int wxMessageBox(const wxString& message, const wxString& caption, long style,
733 wxWindow *parent, int WXUNUSED(x), int WXUNUSED(y) )
0fb67cd1 734{
7c072018 735 wxMessageDialog dialog(parent, message, caption, style);
0fb67cd1 736
7c072018
VZ
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 }
0fb67cd1 749
7c072018 750 wxFAIL_MSG( _T("unexpected return code from wxMessageDialog") );
0fb67cd1 751
7c072018 752 return wxCANCEL;
e2a6f233
JS
753}
754
7c072018 755#endif // wxUSE_MSGDLG
518b5d2f 756
7c072018 757#if wxUSE_TEXTDLG
518b5d2f 758
7c072018
VZ
759wxString 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 }
0fb67cd1 769
7c072018 770 return str;
518b5d2f
VZ
771}
772
7c072018
VZ
773wxString wxGetPasswordFromUser(const wxString& message,
774 const wxString& caption,
775 const wxString& defaultValue,
776 wxWindow *parent)
96c5bd7f 777{
7c072018
VZ
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 }
96c5bd7f 785
7c072018
VZ
786 return str;
787}
96c5bd7f 788
7c072018 789#endif // wxUSE_TEXTDLG
96c5bd7f 790
7c072018 791#if wxUSE_COLOURDLG
96c5bd7f 792
7c072018 793wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit)
c51deffc 794{
7c072018
VZ
795 wxColourData data;
796 data.SetChooseFull(TRUE);
797 if ( colInit.Ok() )
798 {
799 data.SetColour((wxColour &)colInit); // const_cast
800 }
c51deffc 801
7c072018
VZ
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;
c51deffc 811}
bc385ba9 812
7c072018 813#endif // wxUSE_COLOURDLG
bc385ba9 814
7c072018
VZ
815#if wxUSE_FONTDLG
816
817wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit)
bc385ba9 818{
7c072018
VZ
819 wxFontData data;
820 if ( fontInit.Ok() )
bc385ba9 821 {
7c072018
VZ
822 data.SetInitialFont(fontInit);
823 }
bc385ba9 824
7c072018
VZ
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
bc385ba9 832
7c072018 833 return fontRet;
bc385ba9
VZ
834}
835
7c072018 836#endif // wxUSE_FONTDLG
2b5f62a0 837
7c072018
VZ
838// ----------------------------------------------------------------------------
839// wxSafeYield and supporting functions
840// ----------------------------------------------------------------------------
2b5f62a0 841
7c072018
VZ
842void wxEnableTopLevelWindows(bool enable)
843{
df5168c4 844 wxWindowList::compatibility_iterator node;
7c072018
VZ
845 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
846 node->GetData()->Enable(enable);
847}
2b5f62a0 848
7c072018
VZ
849wxWindowDisabler::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
df5168c4 855 wxWindowList::compatibility_iterator node;
7c072018 856 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
2b5f62a0 857 {
7c072018
VZ
858 wxWindow *winTop = node->GetData();
859 if ( winTop == winToSkip )
860 continue;
2b5f62a0 861
7c072018
VZ
862 // we don't need to disable the hidden or already disabled windows
863 if ( winTop->IsEnabled() && winTop->IsShown() )
2b5f62a0 864 {
7c072018 865 winTop->Disable();
2b5f62a0
VZ
866 }
867 else
868 {
7c072018
VZ
869 if ( !m_winDisabled )
870 {
871 m_winDisabled = new wxWindowList;
872 }
873
874 m_winDisabled->Append(winTop);
2b5f62a0
VZ
875 }
876 }
2b5f62a0
VZ
877}
878
7c072018 879wxWindowDisabler::~wxWindowDisabler()
cd6ce4a9 880{
df5168c4 881 wxWindowList::compatibility_iterator node;
7c072018 882 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
cd6ce4a9 883 {
7c072018
VZ
884 wxWindow *winTop = node->GetData();
885 if ( !m_winDisabled || !m_winDisabled->Find(winTop) )
cd6ce4a9 886 {
7c072018 887 winTop->Enable();
cd6ce4a9 888 }
7c072018 889 //else: had been already disabled, don't reenable
cd6ce4a9 890 }
f6bcfd97 891
7c072018 892 delete m_winDisabled;
f6bcfd97
BP
893}
894
7c072018
VZ
895// Yield to other apps/messages and disable user input to all windows except
896// the given one
897bool wxSafeYield(wxWindow *win, bool onlyIfNeeded)
f6bcfd97 898{
7c072018 899 wxWindowDisabler wd(win);
21709999 900
7c072018
VZ
901 bool rc;
902 if (onlyIfNeeded)
903 rc = wxYieldIfNeeded();
904 else
905 rc = wxYield();
8461e4c2 906
7c072018 907 return rc;
8461e4c2
VZ
908}
909
7c072018
VZ
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__
914bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) )
8461e4c2 915{
7c072018 916 return TRUE; // detectable auto-repeat is the only mode MSW supports
8461e4c2 917}
7c072018
VZ
918#endif // !wxGTK
919
920#endif // wxUSE_GUI
21709999 921