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