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