]> git.saurik.com Git - wxWidgets.git/blame - src/common/utilscmn.cpp
wxMotif for OS/2 adjustements. Source cleaning.
[wxWidgets.git] / src / common / utilscmn.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
3452f00b 2// Name: src/common/utilscmn.cpp
c801d85f
KB
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
65571936 9// Licence: wxWindows licence
c801d85f
KB
10/////////////////////////////////////////////////////////////////////////////
11
e90c1d2a
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
c801d85f
KB
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
e90c1d2a 24 #pragma hdrstop
c801d85f
KB
25#endif
26
27#ifndef WX_PRECOMP
fcdb9b38 28 #include "wx/app.h"
e90c1d2a
VZ
29 #include "wx/string.h"
30 #include "wx/utils.h"
974e8d94
VZ
31 #include "wx/intl.h"
32 #include "wx/log.h"
e90c1d2a
VZ
33
34 #if wxUSE_GUI
35 #include "wx/window.h"
e90c1d2a 36 #include "wx/frame.h"
1e6feb95 37 #include "wx/menu.h"
e90c1d2a
VZ
38 #include "wx/msgdlg.h"
39 #include "wx/textdlg.h"
78bcfcfc 40 #include "wx/textctrl.h" // for wxTE_PASSWORD
974e8d94
VZ
41 #if wxUSE_ACCEL
42 #include "wx/menuitem.h"
43 #include "wx/accel.h"
44 #endif // wxUSE_ACCEL
e90c1d2a
VZ
45 #endif // wxUSE_GUI
46#endif // WX_PRECOMP
c801d85f 47
2739d4f0
VZ
48#include "wx/apptrait.h"
49
cd6ce4a9
VZ
50#include "wx/process.h"
51#include "wx/txtstrm.h"
498a1eeb
RN
52#include "wx/uri.h"
53#include "wx/mimetype.h"
54#include "wx/config.h"
cd6ce4a9 55
4676948b
JS
56#if defined(__WXWINCE__) && wxUSE_DATETIME
57#include "wx/datetime.h"
58#endif
59
c801d85f
KB
60#include <ctype.h>
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
e90c1d2a 64
c801d85f 65#if !defined(__WATCOMC__)
3f4a0c5b
VZ
66 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
67 #include <errno.h>
68 #endif
c801d85f 69#endif
e90c1d2a 70
91b4c08d
VZ
71#if wxUSE_GUI
72 #include "wx/colordlg.h"
bf31fa26 73 #include "wx/fontdlg.h"
d1c8aaa3
JS
74 #include "wx/notebook.h"
75 #include "wx/frame.h"
76 #include "wx/statusbr.h"
91b4c08d
VZ
77#endif // wxUSE_GUI
78
1c193821 79#ifndef __WXWINCE__
c801d85f 80#include <time.h>
1c193821
JS
81#else
82#include "wx/msw/wince/time.h"
83#endif
e90c1d2a 84
4676948b 85#if !defined(__MWERKS__) && !defined(__WXWINCE__)
e90c1d2a
VZ
86 #include <sys/types.h>
87 #include <sys/stat.h>
469e1e5c 88#endif
c801d85f 89
82ef81ed 90#if defined(__WXMSW__)
5e1febfa 91 #include "wx/msw/private.h"
3452f00b 92 #include "wx/msw/registry.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
77ffb593
JS
102 const wxChar *wxInternalErrorStr = wxT("wxWidgets Internal Error");
103 const wxChar *wxFatalErrorStr = wxT("wxWidgets Fatal Error");
73deed44
VZ
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{
657a7545
WS
115 if (s == NULL) s = wxEmptyString;
116 size_t len = wxStrlen (s) + 1;
c801d85f 117
657a7545
WS
118 wxChar *news = new wxChar[len];
119 memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest
c801d85f 120
657a7545 121 return news;
c801d85f
KB
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 137{
657a7545
WS
138 if (s && *s && number)
139 *number = (float) wxStrtod (s, (wxChar **) NULL);
c801d85f
KB
140}
141
3f4a0c5b 142void
bc87fd68 143StringToDouble (const wxChar *s, double *number)
c801d85f 144{
657a7545
WS
145 if (s && *s && number)
146 *number = wxStrtod (s, (wxChar **) NULL);
c801d85f
KB
147}
148
0080691b
OK
149wxChar *
150FloatToString (float number, const wxChar *fmt)
c801d85f 151{
657a7545 152 static wxChar buf[256];
c801d85f 153
657a7545
WS
154 wxSprintf (buf, fmt, number);
155 return buf;
c801d85f
KB
156}
157
0080691b
OK
158wxChar *
159DoubleToString (double number, const wxChar *fmt)
c801d85f 160{
657a7545 161 static wxChar buf[256];
c801d85f 162
657a7545
WS
163 wxSprintf (buf, fmt, number);
164 return buf;
c801d85f
KB
165}
166
3f4a0c5b 167void
bc87fd68 168StringToInt (const wxChar *s, int *number)
c801d85f 169{
657a7545
WS
170 if (s && *s && number)
171 *number = (int) wxStrtol (s, (wxChar **) NULL, 10);
c801d85f
KB
172}
173
3f4a0c5b 174void
bc87fd68 175StringToLong (const wxChar *s, long *number)
c801d85f 176{
657a7545
WS
177 if (s && *s && number)
178 *number = wxStrtol (s, (wxChar **) NULL, 10);
c801d85f
KB
179}
180
84fff0b3 181wxChar *
c801d85f
KB
182IntToString (int number)
183{
657a7545 184 static wxChar buf[20];
c801d85f 185
657a7545
WS
186 wxSprintf (buf, wxT("%d"), number);
187 return buf;
c801d85f
KB
188}
189
84fff0b3 190wxChar *
c801d85f
KB
191LongToString (long number)
192{
657a7545 193 static wxChar buf[20];
c801d85f 194
657a7545
WS
195 wxSprintf (buf, wxT("%ld"), number);
196 return buf;
c801d85f
KB
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 206{
657a7545 207 int firstDigit, secondDigit;
3f4a0c5b 208
657a7545
WS
209 if (buf.GetChar(0) >= wxT('A'))
210 firstDigit = buf.GetChar(0) - wxT('A') + 10;
211 else
212 firstDigit = buf.GetChar(0) - wxT('0');
c801d85f 213
657a7545
WS
214 if (buf.GetChar(1) >= wxT('A'))
215 secondDigit = buf.GetChar(1) - wxT('A') + 10;
216 else
217 secondDigit = buf.GetChar(1) - wxT('0');
3f4a0c5b 218
657a7545 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 224{
657a7545
WS
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;
c801d85f
KB
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
08873d36
VZ
262void wxUsleep(unsigned long milliseconds)
263{
264 wxMilliSleep(milliseconds);
265}
266
7c072018
VZ
267const wxChar *wxGetInstallPrefix()
268{
269 wxString prefix;
270
271 if ( wxGetEnv(wxT("WXPREFIX"), &prefix) )
272 return prefix.c_str();
273
274#ifdef wxINSTALL_PREFIX
275 return wxT(wxINSTALL_PREFIX);
276#else
525d8583 277 return wxEmptyString;
7c072018
VZ
278#endif
279}
280
281wxString wxGetDataDir()
282{
10f206ad
RL
283 wxString dir = wxGetInstallPrefix();
284 dir << wxFILE_SEP_PATH << wxT("share") << wxFILE_SEP_PATH << wxT("wx");
7c072018
VZ
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
324899f6 296 wxToolkitInfo& info = traits->GetToolkitInfo();
a8eaaeb2 297 if ( verMaj )
324899f6 298 *verMaj = info.versionMajor;
a8eaaeb2 299 if ( verMin )
324899f6
VS
300 *verMin = info.versionMinor;
301 return info.os;
2739d4f0 302}
1e6feb95 303
e90c1d2a 304// ----------------------------------------------------------------------------
7c072018 305// network and user id functions
e90c1d2a 306// ----------------------------------------------------------------------------
c801d85f 307
7c072018
VZ
308// Get Full RFC822 style email address
309bool wxGetEmailAddress(wxChar *address, int maxSize)
c801d85f 310{
7c072018
VZ
311 wxString email = wxGetEmailAddress();
312 if ( !email )
cb719f2e 313 return false;
c801d85f 314
7c072018
VZ
315 wxStrncpy(address, email, maxSize - 1);
316 address[maxSize - 1] = wxT('\0');
317
cb719f2e 318 return true;
c801d85f
KB
319}
320
7c072018 321wxString wxGetEmailAddress()
47bc1060 322{
7c072018 323 wxString email;
974e8d94 324
7c072018 325 wxString host = wxGetFullHostName();
4055ed82 326 if ( !host.empty() )
1e6feb95 327 {
7c072018 328 wxString user = wxGetUserId();
4055ed82 329 if ( !user.empty() )
1e6feb95 330 {
7c072018 331 email << user << wxT('@') << host;
974e8d94 332 }
974e8d94
VZ
333 }
334
7c072018 335 return email;
974e8d94
VZ
336}
337
7c072018 338wxString wxGetUserId()
c801d85f 339{
7c072018 340 static const int maxLoginLen = 256; // FIXME arbitrary number
c801d85f 341
7c072018 342 wxString buf;
4c3ebca9 343 bool ok = wxGetUserId(wxStringBuffer(buf, maxLoginLen), maxLoginLen);
c801d85f 344
7c072018
VZ
345 if ( !ok )
346 buf.Empty();
c801d85f 347
7c072018 348 return buf;
c801d85f
KB
349}
350
7c072018 351wxString wxGetUserName()
c801d85f 352{
7c072018 353 static const int maxUserNameLen = 1024; // FIXME arbitrary number
1e6feb95 354
7c072018 355 wxString buf;
4c3ebca9 356 bool ok = wxGetUserName(wxStringBuffer(buf, maxUserNameLen), maxUserNameLen);
7c072018
VZ
357
358 if ( !ok )
359 buf.Empty();
360
361 return buf;
59a12e90
JS
362}
363
7c072018 364wxString wxGetHostName()
59a12e90 365{
7c072018 366 static const size_t hostnameSize = 257;
c67d6888 367
7c072018 368 wxString buf;
4c3ebca9 369 bool ok = wxGetHostName(wxStringBuffer(buf, hostnameSize), hostnameSize);
59a12e90 370
7c072018
VZ
371 if ( !ok )
372 buf.Empty();
59a12e90 373
7c072018 374 return buf;
59a12e90
JS
375}
376
7c072018 377wxString wxGetFullHostName()
59a12e90 378{
7c072018 379 static const size_t hostnameSize = 257;
c801d85f 380
7c072018 381 wxString buf;
4c3ebca9 382 bool ok = wxGetFullHostName(wxStringBuffer(buf, hostnameSize), hostnameSize);
7c072018
VZ
383
384 if ( !ok )
385 buf.Empty();
c801d85f 386
7c072018
VZ
387 return buf;
388}
c801d85f 389
7c072018
VZ
390wxString wxGetHomeDir()
391{
392 wxString home;
393 wxGetHomeDir(&home);
c801d85f 394
7c072018
VZ
395 return home;
396}
c801d85f 397
c801d85f
KB
398#if 0
399
7c072018 400wxString wxGetCurrentDir()
c801d85f 401{
7c072018
VZ
402 wxString dir;
403 size_t len = 1024;
404 bool ok;
405 do
406 {
407 ok = getcwd(dir.GetWriteBuf(len + 1), len) != NULL;
408 dir.UngetWriteBuf();
c801d85f 409
7c072018
VZ
410 if ( !ok )
411 {
412 if ( errno != ERANGE )
413 {
414 wxLogSysError(_T("Failed to get current directory"));
c801d85f 415
7c072018
VZ
416 return wxEmptyString;
417 }
3f4a0c5b 418 else
7c072018
VZ
419 {
420 // buffer was too small, retry with a larger one
421 len *= 2;
422 }
3f4a0c5b 423 }
7c072018
VZ
424 //else: ok
425 } while ( !ok );
c801d85f 426
7c072018 427 return dir;
c801d85f
KB
428}
429
7c072018 430#endif // 0
e90c1d2a
VZ
431
432// ----------------------------------------------------------------------------
7c072018 433// wxExecute
e90c1d2a 434// ----------------------------------------------------------------------------
ead7ce10 435
7c072018
VZ
436// wxDoExecuteWithCapture() helper: reads an entire stream into one array
437//
cb719f2e 438// returns true if ok, false if error
7c072018
VZ
439#if wxUSE_STREAMS
440static bool ReadAll(wxInputStream *is, wxArrayString& output)
dfad0599 441{
cb719f2e 442 wxCHECK_MSG( is, false, _T("NULL stream in wxExecute()?") );
dfad0599 443
7c072018
VZ
444 // the stream could be already at EOF or in wxSTREAM_BROKEN_PIPE state
445 is->Reset();
1e6feb95 446
7c072018 447 wxTextInputStream tis(*is);
1e6feb95 448
cb719f2e 449 bool cont = true;
7c072018 450 while ( cont )
d2f50933 451 {
7c072018
VZ
452 wxString line = tis.ReadLine();
453 if ( is->Eof() )
454 break;
455
456 if ( !*is )
457 {
cb719f2e 458 cont = false;
7c072018
VZ
459 }
460 else
461 {
462 output.Add(line);
463 }
d2f50933
VZ
464 }
465
7c072018 466 return cont;
dfad0599 467}
7c072018 468#endif // wxUSE_STREAMS
d2f50933 469
7c072018
VZ
470// this is a private function because it hasn't a clean interface: the first
471// array is passed by reference, the second by pointer - instead we have 2
472// public versions of wxExecute() below
473static long wxDoExecuteWithCapture(const wxString& command,
474 wxArrayString& output,
4d172154
VZ
475 wxArrayString* error,
476 int flags)
d2f50933 477{
7c072018
VZ
478 // create a wxProcess which will capture the output
479 wxProcess *process = new wxProcess;
480 process->Redirect();
dfad0599 481
4d172154 482 long rc = wxExecute(command, wxEXEC_SYNC | flags, process);
1e6feb95 483
7c072018
VZ
484#if wxUSE_STREAMS
485 if ( rc != -1 )
bf31fa26 486 {
7c072018
VZ
487 if ( !ReadAll(process->GetInputStream(), output) )
488 rc = -1;
91b4c08d 489
7c072018
VZ
490 if ( error )
491 {
492 if ( !ReadAll(process->GetErrorStream(), *error) )
493 rc = -1;
494 }
91b4c08d 495
7c072018 496 }
e70ba80d
WS
497#else
498 wxUnusedVar(output);
499 wxUnusedVar(error);
500#endif // wxUSE_STREAMS/!wxUSE_STREAMS
91b4c08d 501
7c072018 502 delete process;
1e6feb95 503
7c072018 504 return rc;
7c072018 505}
bf31fa26 506
4d172154 507long wxExecute(const wxString& command, wxArrayString& output, int flags)
bf31fa26 508{
4d172154 509 return wxDoExecuteWithCapture(command, output, NULL, flags);
7c072018 510}
bf31fa26 511
7c072018
VZ
512long wxExecute(const wxString& command,
513 wxArrayString& output,
4d172154
VZ
514 wxArrayString& error,
515 int flags)
7c072018 516{
4d172154 517 return wxDoExecuteWithCapture(command, output, &error, flags);
bf31fa26
VZ
518}
519
498a1eeb
RN
520// ----------------------------------------------------------------------------
521// Launch default browser
522// ----------------------------------------------------------------------------
523
42d0df00 524bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags)
498a1eeb 525{
42d0df00
VZ
526 wxUnusedVar(flags);
527
7999124f
VZ
528 // set the scheme of url to http if it does not have one
529 wxString url(urlOrig);
530 if ( !wxURI(url).HasScheme() )
531 url.Prepend(wxT("http://"));
532d575b 532
7999124f 533#if defined(__WXMSW__)
42d0df00
VZ
534 if ( flags & wxBROWSER_NEW_WINDOW )
535 {
536 // ShellExecuteEx() opens the URL in an existing window by default so
537 // we can't use it if we need a new window
538 wxRegKey key(wxRegKey::HKCR, url.BeforeFirst(':') + _T("\\shell\\open"));
539 if ( key.Exists() )
540 {
541 wxRegKey keyDDE(key, wxT("DDEExec"));
542 if ( keyDDE.Exists() )
543 {
544 const wxString ddeTopic = wxRegKey(keyDDE, wxT("topic"));
545
546 // we only know the syntax of WWW_OpenURL DDE request for IE,
547 // optimistically assume that all other browsers are compatible
548 // with it
549 wxString ddeCmd;
550 bool ok = ddeTopic == wxT("WWW_OpenURL");
551 if ( ok )
552 {
588c80de 553 ddeCmd = keyDDE.QueryDefaultValue();
42d0df00
VZ
554 ok = !ddeCmd.empty();
555 }
556
557 if ( ok )
558 {
559 // for WWW_OpenURL, the index of the window to open the URL
560 // in is -1 (meaning "current") by default, replace it with
561 // 0 which means "new" (see KB article 160957)
562 ok = ddeCmd.Replace(wxT("-1"), wxT("0"),
563 false /* only first occurence */) == 1;
564 }
565
566 if ( ok )
567 {
568 // and also replace the parameters: the topic should
569 // contain a placeholder for the URL
570 ok = ddeCmd.Replace(wxT("%1"), url, false) == 1;
571 }
572
573 if ( ok )
574 {
575 // try to send it the DDE request now but ignore the errors
576 wxLogNull noLog;
577
578 const wxString ddeServer = wxRegKey(keyDDE, wxT("application"));
579 if ( wxExecuteDDE(ddeServer, ddeTopic, ddeCmd) )
580 return true;
581
582 // this is not necessarily an error: maybe browser is
583 // simply not running, but no matter, in any case we're
584 // going to launch it using ShellExecuteEx() below now and
585 // we shouldn't try to open a new window if we open a new
586 // browser anyhow
587 }
588 }
589 }
590 }
591
7999124f
VZ
592 WinStruct<SHELLEXECUTEINFO> sei;
593 sei.lpFile = url.c_str();
594 sei.lpVerb = _T("open");
595 sei.nShow = SW_SHOWNORMAL;
498a1eeb 596
7999124f 597 ::ShellExecuteEx(&sei);
657a7545 598
7999124f 599 const int nResult = (int) sei.hInstApp;
498a1eeb 600
7999124f
VZ
601 // Firefox returns file not found for some reason, so make an exception
602 // for it
603 if ( nResult > 32 || nResult == SE_ERR_FNF )
498a1eeb 604 {
657a7545 605#ifdef __WXDEBUG__
498a1eeb 606 // Log something if SE_ERR_FNF happens
7999124f
VZ
607 if ( nResult == SE_ERR_FNF )
608 wxLogDebug(wxT("SE_ERR_FNF from ShellExecute -- maybe FireFox?"));
609#endif // __WXDEBUG__
610 return true;
657a7545 611 }
657a7545 612#elif wxUSE_MIMETYPE
498a1eeb 613 // Non-windows way
657a7545 614 wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension (_T("html"));
7999124f 615 if ( ft )
657a7545 616 {
7999124f
VZ
617 wxString mt;
618 ft->GetMimeType(&mt);
498a1eeb 619
7999124f
VZ
620 wxString cmd;
621 bool ok = ft->GetOpenCommand(&cmd, wxFileType::MessageParameters(url));
622 delete ft;
498a1eeb 623
7999124f 624 if ( !ok || cmd.empty() )
498a1eeb 625 {
7999124f
VZ
626 // fallback to checking for the BROWSER environment variable
627 cmd = wxGetenv(wxT("BROWSER"));
628 if ( !cmd.empty() )
629 cmd << _T(' ') << url;
498a1eeb 630 }
7999124f
VZ
631
632 if ( !cmd.empty() && wxExecute(cmd) )
633 return true;
498a1eeb 634 }
7999124f 635 else // no file type for html extension
2830b4a4 636 {
7999124f 637 wxLogError(_T("No default application configured for HTML files."));
2830b4a4 638 }
7999124f 639#endif // !wxUSE_MIMETYPE && !__WXMSW__
532d575b 640
7999124f
VZ
641 wxLogSysError(_T("Failed to open URL \"%s\" in default browser."),
642 url.c_str());
657a7545 643
7999124f 644 return false;
498a1eeb
RN
645}
646
91b4c08d 647// ----------------------------------------------------------------------------
7c072018 648// wxApp::Yield() wrappers for backwards compatibility
91b4c08d
VZ
649// ----------------------------------------------------------------------------
650
7c072018 651bool wxYield()
469e1e5c 652{
7c072018 653 return wxTheApp && wxTheApp->Yield();
469e1e5c 654}
7c072018
VZ
655
656bool wxYieldIfNeeded()
469e1e5c 657{
cb719f2e 658 return wxTheApp && wxTheApp->Yield(true);
469e1e5c 659}
7c072018 660
ec67cff1 661#endif // wxUSE_BASE
7c072018
VZ
662
663// ============================================================================
664// GUI-only functions from now on
665// ============================================================================
666
667#if wxUSE_GUI
668
4c3ebca9
MB
669// Id generation
670static long wxCurrentId = 100;
671
c838b68e 672long wxNewId()
4c3ebca9 673{
c838b68e
VS
674 // skip the part of IDs space that contains hard-coded values:
675 if (wxCurrentId == wxID_LOWEST)
676 wxCurrentId = wxID_HIGHEST + 1;
677
678 return wxCurrentId++;
4c3ebca9
MB
679}
680
681long
682wxGetCurrentId(void) { return wxCurrentId; }
683
684void
685wxRegisterId (long id)
686{
687 if (id >= wxCurrentId)
688 wxCurrentId = id + 1;
689}
690
7c072018 691#if wxUSE_MENUS
e90c1d2a
VZ
692
693// ----------------------------------------------------------------------------
7c072018 694// Menu accelerators related functions
e90c1d2a
VZ
695// ----------------------------------------------------------------------------
696
7c072018 697wxChar *wxStripMenuCodes(const wxChar *in, wxChar *out)
e90c1d2a 698{
7c072018
VZ
699 wxString s = wxMenuItem::GetLabelFromText(in);
700 if ( out )
701 {
702 // go smash their buffer if it's not big enough - I love char * params
703 memcpy(out, s.c_str(), s.length() * sizeof(wxChar));
704 }
705 else
706 {
f526f752
MB
707 // MYcopystring - for easier search...
708 out = new wxChar[s.length() + 1];
709 wxStrcpy(out, s.c_str());
7c072018
VZ
710 }
711
712 return out;
e90c1d2a
VZ
713}
714
7c072018 715wxString wxStripMenuCodes(const wxString& in)
e90c1d2a 716{
7c072018 717 wxString out;
79f585d9 718
7c072018
VZ
719 size_t len = in.length();
720 out.reserve(len);
79f585d9 721
7c072018
VZ
722 for ( size_t n = 0; n < len; n++ )
723 {
724 wxChar ch = in[n];
725 if ( ch == _T('&') )
cd6ce4a9 726 {
7c072018
VZ
727 // skip it, it is used to introduce the accel char (or to quote
728 // itself in which case it should still be skipped): note that it
729 // can't be the last character of the string
730 if ( ++n == len )
79f585d9 731 {
7c072018
VZ
732 wxLogDebug(_T("Invalid menu string '%s'"), in.c_str());
733 }
734 else
735 {
736 // use the next char instead
737 ch = in[n];
79f585d9 738 }
cd6ce4a9 739 }
7c072018 740 else if ( ch == _T('\t') )
79f585d9 741 {
7c072018
VZ
742 // everything after TAB is accel string, exit the loop
743 break;
79f585d9 744 }
7c072018
VZ
745
746 out += ch;
225fe9d6
VZ
747 }
748
7c072018 749 return out;
cd6ce4a9
VZ
750}
751
7c072018 752#endif // wxUSE_MENUS
e90c1d2a 753
cbc66a27 754// ----------------------------------------------------------------------------
7c072018 755// Window search functions
cbc66a27
VZ
756// ----------------------------------------------------------------------------
757
7c072018
VZ
758/*
759 * If parent is non-NULL, look through children for a label or title
760 * matching the specified string. If NULL, look through all top-level windows.
761 *
762 */
e2a6f233 763
7c072018
VZ
764wxWindow *
765wxFindWindowByLabel (const wxString& title, wxWindow * parent)
134677bd 766{
7c072018
VZ
767 return wxWindow::FindWindowByLabel( title, parent );
768}
b829bf55 769
b829bf55 770
7c072018
VZ
771/*
772 * If parent is non-NULL, look through children for a name
773 * matching the specified string. If NULL, look through all top-level windows.
774 *
775 */
134677bd 776
7c072018
VZ
777wxWindow *
778wxFindWindowByName (const wxString& name, wxWindow * parent)
2c18f21d 779{
7c072018 780 return wxWindow::FindWindowByName( name, parent );
2c18f21d
VS
781}
782
cb719f2e 783// Returns menu item id or wxNOT_FOUND if none.
7c072018
VZ
784int
785wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
e2a6f233 786{
7c072018
VZ
787#if wxUSE_MENUS
788 wxMenuBar *menuBar = frame->GetMenuBar ();
789 if ( menuBar )
790 return menuBar->FindMenuItem (menuString, itemString);
791#endif // wxUSE_MENUS
0fb67cd1 792
cb719f2e 793 return wxNOT_FOUND;
e2a6f233
JS
794}
795
7c072018
VZ
796// Try to find the deepest child that contains 'pt'.
797// We go backwards, to try to allow for controls that are spacially
798// within other controls, but are still siblings (e.g. buttons within
799// static boxes). Static boxes are likely to be created _before_ controls
800// that sit inside them.
801wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt)
e2a6f233 802{
7c072018
VZ
803 if (!win->IsShown())
804 return NULL;
0fb67cd1 805
7c072018
VZ
806 // Hack for wxNotebook case: at least in wxGTK, all pages
807 // claim to be shown, so we must only deal with the selected one.
808#if wxUSE_NOTEBOOK
809 if (win->IsKindOf(CLASSINFO(wxNotebook)))
e2a6f233 810 {
7c072018
VZ
811 wxNotebook* nb = (wxNotebook*) win;
812 int sel = nb->GetSelection();
813 if (sel >= 0)
814 {
815 wxWindow* child = nb->GetPage(sel);
816 wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
817 if (foundWin)
818 return foundWin;
819 }
e2a6f233 820 }
7c072018 821#endif
0fb67cd1 822
df5168c4 823 wxWindowList::compatibility_iterator node = win->GetChildren().GetLast();
7c072018
VZ
824 while (node)
825 {
826 wxWindow* child = node->GetData();
827 wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
828 if (foundWin)
829 return foundWin;
830 node = node->GetPrevious();
831 }
832
833 wxPoint pos = win->GetPosition();
834 wxSize sz = win->GetSize();
835 if (win->GetParent())
836 {
837 pos = win->GetParent()->ClientToScreen(pos);
838 }
839
840 wxRect rect(pos, sz);
841 if (rect.Inside(pt))
842 return win;
843 else
844 return NULL;
0fb67cd1
VZ
845}
846
7c072018 847wxWindow* wxGenericFindWindowAtPoint(const wxPoint& pt)
0fb67cd1 848{
7c072018
VZ
849 // Go backwards through the list since windows
850 // on top are likely to have been appended most
851 // recently.
df5168c4 852 wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetLast();
7c072018
VZ
853 while (node)
854 {
855 wxWindow* win = node->GetData();
856 wxWindow* found = wxFindWindowAtPoint(win, pt);
857 if (found)
858 return found;
859 node = node->GetPrevious();
860 }
861 return NULL;
862}
0fb67cd1 863
7c072018
VZ
864// ----------------------------------------------------------------------------
865// GUI helpers
866// ----------------------------------------------------------------------------
0fb67cd1 867
7c072018
VZ
868/*
869 * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
870 * since otherwise the generic code may be pulled in unnecessarily.
871 */
0fb67cd1 872
7c072018 873#if wxUSE_MSGDLG
0fb67cd1 874
7c072018
VZ
875int wxMessageBox(const wxString& message, const wxString& caption, long style,
876 wxWindow *parent, int WXUNUSED(x), int WXUNUSED(y) )
0fb67cd1 877{
53a6ac21
DS
878 long decorated_style = style;
879
880 if ( ( style & ( wxICON_EXCLAMATION | wxICON_HAND | wxICON_INFORMATION | wxICON_QUESTION ) ) == 0 )
881 {
882 decorated_style |= ( style & wxYES ) ? wxICON_QUESTION : wxICON_INFORMATION ;
883 }
884
885 wxMessageDialog dialog(parent, message, caption, decorated_style);
0fb67cd1 886
7c072018
VZ
887 int ans = dialog.ShowModal();
888 switch ( ans )
889 {
890 case wxID_OK:
891 return wxOK;
892 case wxID_YES:
893 return wxYES;
894 case wxID_NO:
895 return wxNO;
896 case wxID_CANCEL:
897 return wxCANCEL;
898 }
0fb67cd1 899
7c072018 900 wxFAIL_MSG( _T("unexpected return code from wxMessageDialog") );
0fb67cd1 901
7c072018 902 return wxCANCEL;
e2a6f233
JS
903}
904
7c072018 905#endif // wxUSE_MSGDLG
518b5d2f 906
7c072018 907#if wxUSE_TEXTDLG
518b5d2f 908
7c072018
VZ
909wxString wxGetTextFromUser(const wxString& message, const wxString& caption,
910 const wxString& defaultValue, wxWindow *parent,
13d13a9e 911 wxCoord x, wxCoord y, bool centre )
7c072018
VZ
912{
913 wxString str;
13d13a9e
WS
914 long style = wxTextEntryDialogStyle;
915
916 if (centre)
917 style |= wxCENTRE;
918 else
919 style &= ~wxCENTRE;
920
921 wxTextEntryDialog dialog(parent, message, caption, defaultValue, style, wxPoint(x, y));
922
7c072018
VZ
923 if (dialog.ShowModal() == wxID_OK)
924 {
925 str = dialog.GetValue();
926 }
0fb67cd1 927
7c072018 928 return str;
518b5d2f
VZ
929}
930
7c072018
VZ
931wxString wxGetPasswordFromUser(const wxString& message,
932 const wxString& caption,
933 const wxString& defaultValue,
b3bb2a74
KH
934 wxWindow *parent,
935 wxCoord x, wxCoord y, bool centre )
96c5bd7f 936{
7c072018 937 wxString str;
b3bb2a74
KH
938 long style = wxTextEntryDialogStyle;
939
940 if (centre)
941 style |= wxCENTRE;
942 else
943 style &= ~wxCENTRE;
944
12cfa304
KH
945 wxPasswordEntryDialog dialog(parent, message, caption, defaultValue,
946 style, wxPoint(x, y));
7c072018
VZ
947 if ( dialog.ShowModal() == wxID_OK )
948 {
949 str = dialog.GetValue();
950 }
96c5bd7f 951
7c072018
VZ
952 return str;
953}
96c5bd7f 954
7c072018 955#endif // wxUSE_TEXTDLG
96c5bd7f 956
7c072018 957#if wxUSE_COLOURDLG
96c5bd7f 958
7c072018 959wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit)
c51deffc 960{
7c072018 961 wxColourData data;
cb719f2e 962 data.SetChooseFull(true);
7c072018
VZ
963 if ( colInit.Ok() )
964 {
965 data.SetColour((wxColour &)colInit); // const_cast
966 }
c51deffc 967
7c072018
VZ
968 wxColour colRet;
969 wxColourDialog dialog(parent, &data);
970 if ( dialog.ShowModal() == wxID_OK )
971 {
972 colRet = dialog.GetColourData().GetColour();
973 }
974 //else: leave it invalid
975
976 return colRet;
c51deffc 977}
bc385ba9 978
7c072018 979#endif // wxUSE_COLOURDLG
bc385ba9 980
7c072018
VZ
981#if wxUSE_FONTDLG
982
983wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit)
bc385ba9 984{
7c072018
VZ
985 wxFontData data;
986 if ( fontInit.Ok() )
bc385ba9 987 {
7c072018
VZ
988 data.SetInitialFont(fontInit);
989 }
bc385ba9 990
7c072018
VZ
991 wxFont fontRet;
992 wxFontDialog dialog(parent, data);
993 if ( dialog.ShowModal() == wxID_OK )
994 {
995 fontRet = dialog.GetFontData().GetChosenFont();
996 }
997 //else: leave it invalid
bc385ba9 998
7c072018 999 return fontRet;
bc385ba9
VZ
1000}
1001
7c072018 1002#endif // wxUSE_FONTDLG
2b5f62a0 1003
7c072018
VZ
1004// ----------------------------------------------------------------------------
1005// wxSafeYield and supporting functions
1006// ----------------------------------------------------------------------------
2b5f62a0 1007
7c072018
VZ
1008void wxEnableTopLevelWindows(bool enable)
1009{
df5168c4 1010 wxWindowList::compatibility_iterator node;
7c072018
VZ
1011 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
1012 node->GetData()->Enable(enable);
1013}
2b5f62a0 1014
7c072018
VZ
1015wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip)
1016{
1017 // remember the top level windows which were already disabled, so that we
1018 // don't reenable them later
1019 m_winDisabled = NULL;
1020
df5168c4 1021 wxWindowList::compatibility_iterator node;
7c072018 1022 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
2b5f62a0 1023 {
7c072018
VZ
1024 wxWindow *winTop = node->GetData();
1025 if ( winTop == winToSkip )
1026 continue;
2b5f62a0 1027
7c072018
VZ
1028 // we don't need to disable the hidden or already disabled windows
1029 if ( winTop->IsEnabled() && winTop->IsShown() )
2b5f62a0 1030 {
7c072018 1031 winTop->Disable();
2b5f62a0
VZ
1032 }
1033 else
1034 {
7c072018
VZ
1035 if ( !m_winDisabled )
1036 {
1037 m_winDisabled = new wxWindowList;
1038 }
1039
1040 m_winDisabled->Append(winTop);
2b5f62a0
VZ
1041 }
1042 }
2b5f62a0
VZ
1043}
1044
7c072018 1045wxWindowDisabler::~wxWindowDisabler()
cd6ce4a9 1046{
df5168c4 1047 wxWindowList::compatibility_iterator node;
7c072018 1048 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
cd6ce4a9 1049 {
7c072018
VZ
1050 wxWindow *winTop = node->GetData();
1051 if ( !m_winDisabled || !m_winDisabled->Find(winTop) )
cd6ce4a9 1052 {
7c072018 1053 winTop->Enable();
cd6ce4a9 1054 }
7c072018 1055 //else: had been already disabled, don't reenable
cd6ce4a9 1056 }
f6bcfd97 1057
7c072018 1058 delete m_winDisabled;
f6bcfd97
BP
1059}
1060
7c072018
VZ
1061// Yield to other apps/messages and disable user input to all windows except
1062// the given one
1063bool wxSafeYield(wxWindow *win, bool onlyIfNeeded)
f6bcfd97 1064{
7c072018 1065 wxWindowDisabler wd(win);
21709999 1066
7c072018
VZ
1067 bool rc;
1068 if (onlyIfNeeded)
1069 rc = wxYieldIfNeeded();
1070 else
1071 rc = wxYield();
8461e4c2 1072
7c072018 1073 return rc;
8461e4c2
VZ
1074}
1075
7c072018
VZ
1076// Don't synthesize KeyUp events holding down a key and producing KeyDown
1077// events with autorepeat. On by default and always on in wxMSW. wxGTK version
1078// in utilsgtk.cpp.
1079#ifndef __WXGTK__
1080bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) )
8461e4c2 1081{
cb719f2e 1082 return true; // detectable auto-repeat is the only mode MSW supports
8461e4c2 1083}
7c072018
VZ
1084#endif // !wxGTK
1085
1086#endif // wxUSE_GUI