]> git.saurik.com Git - wxWidgets.git/blame - src/common/utilscmn.cpp
Implement support for gradient stops for OS X.
[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 56#if defined(__WXWINCE__) && wxUSE_DATETIME
50a2e26f 57 #include "wx/datetime.h"
4676948b
JS
58#endif
59
c801d85f
KB
60#include <ctype.h>
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
e90c1d2a 64
13ff2485 65#if !wxONLY_WATCOM_EARLIER_THAN(1,4)
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 74 #include "wx/notebook.h"
d1c8aaa3 75 #include "wx/statusbr.h"
91b4c08d
VZ
76#endif // wxUSE_GUI
77
9b4da627 78#ifndef __WXPALMOS5__
1c193821 79#ifndef __WXWINCE__
50a2e26f 80 #include <time.h>
1c193821 81#else
50a2e26f 82 #include "wx/msw/wince/time.h"
1c193821 83#endif
9b4da627 84#endif // ! __WXPALMOS5__
e90c1d2a 85
f14d6dd1 86#ifdef __WXMAC__
50a2e26f 87 #include "wx/osx/private.h"
f14d6dd1
JS
88#endif
89
9b4da627 90#ifndef __WXPALMOS5__
4676948b 91#if !defined(__MWERKS__) && !defined(__WXWINCE__)
e90c1d2a
VZ
92 #include <sys/types.h>
93 #include <sys/stat.h>
469e1e5c 94#endif
9b4da627 95#endif // ! __WXPALMOS5__
c801d85f 96
82ef81ed 97#if defined(__WXMSW__)
5e1febfa 98 #include "wx/msw/private.h"
50a2e26f 99 #include "wx/filesys.h"
c801d85f
KB
100#endif
101
6ed3db08
VZ
102#if wxUSE_GUI && defined(__WXGTK__)
103 #include <gtk/gtk.h> // for GTK_XXX_VERSION constants
104#endif
105
ec67cff1 106#if wxUSE_BASE
7c072018 107
e90c1d2a
VZ
108// ============================================================================
109// implementation
110// ============================================================================
c801d85f 111
c801d85f 112// Array used in DecToHex conversion routine.
a243da29 113static const wxChar hexArray[] = wxT("0123456789ABCDEF");
c801d85f
KB
114
115// Convert 2-digit hex number to decimal
fd71308f 116int wxHexToDec(const wxString& buf)
c801d85f 117{
657a7545 118 int firstDigit, secondDigit;
3f4a0c5b 119
657a7545
WS
120 if (buf.GetChar(0) >= wxT('A'))
121 firstDigit = buf.GetChar(0) - wxT('A') + 10;
122 else
fad92e2f 123 firstDigit = buf.GetChar(0) - wxT('0');
c801d85f 124
657a7545
WS
125 if (buf.GetChar(1) >= wxT('A'))
126 secondDigit = buf.GetChar(1) - wxT('A') + 10;
127 else
128 secondDigit = buf.GetChar(1) - wxT('0');
3f4a0c5b 129
657a7545 130 return (firstDigit & 0xF) * 16 + (secondDigit & 0xF );
c801d85f
KB
131}
132
133// Convert decimal integer to 2-character hex string
84fff0b3 134void wxDecToHex(int dec, wxChar *buf)
c801d85f 135{
657a7545
WS
136 int firstDigit = (int)(dec/16.0);
137 int secondDigit = (int)(dec - (firstDigit*16.0));
138 buf[0] = hexArray[firstDigit];
139 buf[1] = hexArray[secondDigit];
140 buf[2] = 0;
c801d85f
KB
141}
142
f728025e
JS
143// Convert decimal integer to 2 characters
144void wxDecToHex(int dec, char* ch1, char* ch2)
145{
146 int firstDigit = (int)(dec/16.0);
147 int secondDigit = (int)(dec - (firstDigit*16.0));
148 (*ch1) = (char) hexArray[firstDigit];
149 (*ch2) = (char) hexArray[secondDigit];
150}
151
fd71308f
JS
152// Convert decimal integer to 2-character hex string
153wxString wxDecToHex(int dec)
154{
84fff0b3 155 wxChar buf[3];
fd71308f
JS
156 wxDecToHex(dec, buf);
157 return wxString(buf);
158}
159
7c072018
VZ
160// ----------------------------------------------------------------------------
161// misc functions
162// ----------------------------------------------------------------------------
c801d85f
KB
163
164// Return the current date/time
e90c1d2a 165wxString wxNow()
c801d85f 166{
4676948b
JS
167#ifdef __WXWINCE__
168#if wxUSE_DATETIME
169 wxDateTime now = wxDateTime::Now();
170 return now.Format();
171#else
172 return wxEmptyString;
173#endif
174#else
d3b9f782 175 time_t now = time(NULL);
2b5f62a0
VZ
176 char *date = ctime(&now);
177 date[24] = '\0';
178 return wxString::FromAscii(date);
4676948b 179#endif
c801d85f
KB
180}
181
24c4d27f 182#if WXWIN_COMPATIBILITY_2_8
08873d36
VZ
183void wxUsleep(unsigned long milliseconds)
184{
185 wxMilliSleep(milliseconds);
186}
2382f4db 187#endif
08873d36 188
7c072018
VZ
189const wxChar *wxGetInstallPrefix()
190{
191 wxString prefix;
192
193 if ( wxGetEnv(wxT("WXPREFIX"), &prefix) )
194 return prefix.c_str();
195
196#ifdef wxINSTALL_PREFIX
197 return wxT(wxINSTALL_PREFIX);
198#else
525d8583 199 return wxEmptyString;
7c072018
VZ
200#endif
201}
202
203wxString wxGetDataDir()
204{
10f206ad
RL
205 wxString dir = wxGetInstallPrefix();
206 dir << wxFILE_SEP_PATH << wxT("share") << wxFILE_SEP_PATH << wxT("wx");
7c072018
VZ
207 return dir;
208}
e90c1d2a 209
8bb6b2c0 210bool wxIsPlatformLittleEndian()
2739d4f0 211{
8bb6b2c0
VZ
212 // Are we little or big endian? This method is from Harbison & Steele.
213 union
214 {
215 long l;
216 char c[sizeof(long)];
217 } u;
218 u.l = 1;
219
220 return u.c[0] == 1;
2739d4f0 221}
1e6feb95 222
8bb6b2c0 223
fad92e2f
FM
224// ----------------------------------------------------------------------------
225// wxPlatform
226// ----------------------------------------------------------------------------
227
230c9077
JS
228/*
229 * Class to make it easier to specify platform-dependent values
230 */
231
232wxArrayInt* wxPlatform::sm_customPlatforms = NULL;
233
4bfec179 234void wxPlatform::Copy(const wxPlatform& platform)
230c9077 235{
4bfec179
JS
236 m_longValue = platform.m_longValue;
237 m_doubleValue = platform.m_doubleValue;
238 m_stringValue = platform.m_stringValue;
239}
240
241wxPlatform wxPlatform::If(int platform, long value)
242{
243 if (Is(platform))
244 return wxPlatform(value);
245 else
246 return wxPlatform();
247}
248
249wxPlatform wxPlatform::IfNot(int platform, long value)
250{
251 if (!Is(platform))
252 return wxPlatform(value);
253 else
254 return wxPlatform();
255}
256
257wxPlatform& wxPlatform::ElseIf(int platform, long value)
258{
259 if (Is(platform))
230c9077
JS
260 m_longValue = value;
261 return *this;
262}
263
4bfec179 264wxPlatform& wxPlatform::ElseIfNot(int platform, long value)
230c9077 265{
4bfec179 266 if (!Is(platform))
230c9077
JS
267 m_longValue = value;
268 return *this;
269}
270
4bfec179 271wxPlatform wxPlatform::If(int platform, double value)
230c9077 272{
4bfec179
JS
273 if (Is(platform))
274 return wxPlatform(value);
275 else
276 return wxPlatform();
277}
278
279wxPlatform wxPlatform::IfNot(int platform, double value)
280{
281 if (!Is(platform))
282 return wxPlatform(value);
283 else
284 return wxPlatform();
285}
286
287wxPlatform& wxPlatform::ElseIf(int platform, double value)
288{
289 if (Is(platform))
230c9077
JS
290 m_doubleValue = value;
291 return *this;
292}
293
4bfec179 294wxPlatform& wxPlatform::ElseIfNot(int platform, double value)
230c9077 295{
4bfec179 296 if (!Is(platform))
230c9077
JS
297 m_doubleValue = value;
298 return *this;
299}
300
4bfec179
JS
301wxPlatform wxPlatform::If(int platform, const wxString& value)
302{
303 if (Is(platform))
304 return wxPlatform(value);
305 else
306 return wxPlatform();
307}
308
309wxPlatform wxPlatform::IfNot(int platform, const wxString& value)
310{
311 if (!Is(platform))
312 return wxPlatform(value);
313 else
314 return wxPlatform();
315}
316
317wxPlatform& wxPlatform::ElseIf(int platform, const wxString& value)
230c9077 318{
4bfec179 319 if (Is(platform))
230c9077
JS
320 m_stringValue = value;
321 return *this;
322}
323
4bfec179 324wxPlatform& wxPlatform::ElseIfNot(int platform, const wxString& value)
230c9077 325{
4bfec179 326 if (!Is(platform))
230c9077
JS
327 m_stringValue = value;
328 return *this;
329}
330
4bfec179 331wxPlatform& wxPlatform::Else(long value)
230c9077
JS
332{
333 m_longValue = value;
334 return *this;
335}
336
4bfec179 337wxPlatform& wxPlatform::Else(double value)
230c9077
JS
338{
339 m_doubleValue = value;
340 return *this;
341}
342
4bfec179 343wxPlatform& wxPlatform::Else(const wxString& value)
230c9077
JS
344{
345 m_stringValue = value;
346 return *this;
347}
348
349void wxPlatform::AddPlatform(int platform)
350{
351 if (!sm_customPlatforms)
352 sm_customPlatforms = new wxArrayInt;
353 sm_customPlatforms->Add(platform);
354}
355
356void wxPlatform::ClearPlatforms()
357{
358 delete sm_customPlatforms;
359 sm_customPlatforms = NULL;
360}
361
362/// Function for testing current platform
363
4bfec179 364bool wxPlatform::Is(int platform)
230c9077
JS
365{
366#ifdef __WXMSW__
216c3543 367 if (platform == wxOS_WINDOWS)
230c9077
JS
368 return true;
369#endif
370#ifdef __WXWINCE__
216c3543 371 if (platform == wxOS_WINDOWS_CE)
230c9077
JS
372 return true;
373#endif
a6e8c584
WS
374
375#if 0
376
377// FIXME: wxWinPocketPC and wxWinSmartPhone are unknown symbols
378
230c9077
JS
379#if defined(__WXWINCE__) && defined(__POCKETPC__)
380 if (platform == wxWinPocketPC)
381 return true;
382#endif
383#if defined(__WXWINCE__) && defined(__SMARTPHONE__)
6aa68c25 384 if (platform == wxWinSmartPhone)
230c9077
JS
385 return true;
386#endif
a6e8c584
WS
387
388#endif
389
230c9077 390#ifdef __WXGTK__
216c3543 391 if (platform == wxPORT_GTK)
230c9077
JS
392 return true;
393#endif
394#ifdef __WXMAC__
216c3543 395 if (platform == wxPORT_MAC)
230c9077
JS
396 return true;
397#endif
398#ifdef __WXX11__
216c3543 399 if (platform == wxPORT_X11)
230c9077
JS
400 return true;
401#endif
402#ifdef __UNIX__
216c3543 403 if (platform == wxOS_UNIX)
230c9077
JS
404 return true;
405#endif
406#ifdef __WXMGL__
216c3543 407 if (platform == wxPORT_MGL)
230c9077
JS
408 return true;
409#endif
8ab09e65
SN
410#ifdef __OS2__
411 if (platform == wxOS_OS2)
412 return true;
413#endif
414#ifdef __WXPM__
415 if (platform == wxPORT_PM)
230c9077
JS
416 return true;
417#endif
55d452c6 418#ifdef __WXCOCOA__
216c3543 419 if (platform == wxPORT_MAC)
230c9077
JS
420 return true;
421#endif
422
423 if (sm_customPlatforms && sm_customPlatforms->Index(platform) != wxNOT_FOUND)
424 return true;
425
426 return false;
427}
428
e90c1d2a 429// ----------------------------------------------------------------------------
7c072018 430// network and user id functions
e90c1d2a 431// ----------------------------------------------------------------------------
c801d85f 432
7c072018
VZ
433// Get Full RFC822 style email address
434bool wxGetEmailAddress(wxChar *address, int maxSize)
c801d85f 435{
7c072018
VZ
436 wxString email = wxGetEmailAddress();
437 if ( !email )
cb719f2e 438 return false;
c801d85f 439
9d4943cd 440 wxStrlcpy(address, email.t_str(), maxSize);
7c072018 441
cb719f2e 442 return true;
c801d85f
KB
443}
444
7c072018 445wxString wxGetEmailAddress()
47bc1060 446{
7c072018 447 wxString email;
974e8d94 448
7c072018 449 wxString host = wxGetFullHostName();
4055ed82 450 if ( !host.empty() )
1e6feb95 451 {
7c072018 452 wxString user = wxGetUserId();
4055ed82 453 if ( !user.empty() )
1e6feb95 454 {
7c072018 455 email << user << wxT('@') << host;
974e8d94 456 }
974e8d94
VZ
457 }
458
7c072018 459 return email;
974e8d94
VZ
460}
461
7c072018 462wxString wxGetUserId()
c801d85f 463{
7c072018 464 static const int maxLoginLen = 256; // FIXME arbitrary number
c801d85f 465
7c072018 466 wxString buf;
4c3ebca9 467 bool ok = wxGetUserId(wxStringBuffer(buf, maxLoginLen), maxLoginLen);
c801d85f 468
7c072018
VZ
469 if ( !ok )
470 buf.Empty();
c801d85f 471
7c072018 472 return buf;
c801d85f
KB
473}
474
7c072018 475wxString wxGetUserName()
c801d85f 476{
7c072018 477 static const int maxUserNameLen = 1024; // FIXME arbitrary number
1e6feb95 478
7c072018 479 wxString buf;
4c3ebca9 480 bool ok = wxGetUserName(wxStringBuffer(buf, maxUserNameLen), maxUserNameLen);
7c072018
VZ
481
482 if ( !ok )
483 buf.Empty();
484
485 return buf;
59a12e90
JS
486}
487
7c072018 488wxString wxGetHostName()
59a12e90 489{
7c072018 490 static const size_t hostnameSize = 257;
c67d6888 491
7c072018 492 wxString buf;
4c3ebca9 493 bool ok = wxGetHostName(wxStringBuffer(buf, hostnameSize), hostnameSize);
59a12e90 494
7c072018
VZ
495 if ( !ok )
496 buf.Empty();
59a12e90 497
7c072018 498 return buf;
59a12e90
JS
499}
500
7c072018 501wxString wxGetFullHostName()
59a12e90 502{
7c072018 503 static const size_t hostnameSize = 257;
c801d85f 504
7c072018 505 wxString buf;
4c3ebca9 506 bool ok = wxGetFullHostName(wxStringBuffer(buf, hostnameSize), hostnameSize);
7c072018
VZ
507
508 if ( !ok )
509 buf.Empty();
c801d85f 510
7c072018
VZ
511 return buf;
512}
c801d85f 513
7c072018
VZ
514wxString wxGetHomeDir()
515{
516 wxString home;
517 wxGetHomeDir(&home);
c801d85f 518
7c072018
VZ
519 return home;
520}
c801d85f 521
c801d85f
KB
522#if 0
523
7c072018 524wxString wxGetCurrentDir()
c801d85f 525{
7c072018
VZ
526 wxString dir;
527 size_t len = 1024;
528 bool ok;
529 do
530 {
531 ok = getcwd(dir.GetWriteBuf(len + 1), len) != NULL;
532 dir.UngetWriteBuf();
c801d85f 533
7c072018
VZ
534 if ( !ok )
535 {
536 if ( errno != ERANGE )
537 {
9a83f860 538 wxLogSysError(wxT("Failed to get current directory"));
c801d85f 539
7c072018
VZ
540 return wxEmptyString;
541 }
3f4a0c5b 542 else
7c072018
VZ
543 {
544 // buffer was too small, retry with a larger one
545 len *= 2;
546 }
3f4a0c5b 547 }
7c072018
VZ
548 //else: ok
549 } while ( !ok );
c801d85f 550
7c072018 551 return dir;
c801d85f
KB
552}
553
7c072018 554#endif // 0
e90c1d2a
VZ
555
556// ----------------------------------------------------------------------------
7c072018 557// wxExecute
e90c1d2a 558// ----------------------------------------------------------------------------
ead7ce10 559
7c072018
VZ
560// wxDoExecuteWithCapture() helper: reads an entire stream into one array
561//
cb719f2e 562// returns true if ok, false if error
7c072018
VZ
563#if wxUSE_STREAMS
564static bool ReadAll(wxInputStream *is, wxArrayString& output)
dfad0599 565{
9a83f860 566 wxCHECK_MSG( is, false, wxT("NULL stream in wxExecute()?") );
dfad0599 567
7c072018
VZ
568 // the stream could be already at EOF or in wxSTREAM_BROKEN_PIPE state
569 is->Reset();
1e6feb95 570
7c072018 571 wxTextInputStream tis(*is);
1e6feb95 572
8bdc8a9c 573 for ( ;; )
d2f50933 574 {
7c072018 575 wxString line = tis.ReadLine();
8bdc8a9c
VZ
576
577 // check for EOF before other errors as it's not really an error
7c072018 578 if ( is->Eof() )
8bdc8a9c
VZ
579 {
580 // add the last, possibly incomplete, line
581 if ( !line.empty() )
582 output.Add(line);
7c072018 583 break;
8bdc8a9c 584 }
7c072018 585
8bdc8a9c 586 // any other error is fatal
7c072018 587 if ( !*is )
8bdc8a9c
VZ
588 return false;
589
590 output.Add(line);
d2f50933
VZ
591 }
592
8bdc8a9c 593 return true;
dfad0599 594}
7c072018 595#endif // wxUSE_STREAMS
d2f50933 596
7c072018
VZ
597// this is a private function because it hasn't a clean interface: the first
598// array is passed by reference, the second by pointer - instead we have 2
599// public versions of wxExecute() below
600static long wxDoExecuteWithCapture(const wxString& command,
601 wxArrayString& output,
4d172154
VZ
602 wxArrayString* error,
603 int flags)
d2f50933 604{
7c072018
VZ
605 // create a wxProcess which will capture the output
606 wxProcess *process = new wxProcess;
607 process->Redirect();
dfad0599 608
4d172154 609 long rc = wxExecute(command, wxEXEC_SYNC | flags, process);
1e6feb95 610
7c072018
VZ
611#if wxUSE_STREAMS
612 if ( rc != -1 )
bf31fa26 613 {
7c072018
VZ
614 if ( !ReadAll(process->GetInputStream(), output) )
615 rc = -1;
91b4c08d 616
7c072018
VZ
617 if ( error )
618 {
619 if ( !ReadAll(process->GetErrorStream(), *error) )
620 rc = -1;
621 }
91b4c08d 622
7c072018 623 }
e70ba80d
WS
624#else
625 wxUnusedVar(output);
626 wxUnusedVar(error);
627#endif // wxUSE_STREAMS/!wxUSE_STREAMS
91b4c08d 628
7c072018 629 delete process;
1e6feb95 630
7c072018 631 return rc;
7c072018 632}
bf31fa26 633
4d172154 634long wxExecute(const wxString& command, wxArrayString& output, int flags)
bf31fa26 635{
4d172154 636 return wxDoExecuteWithCapture(command, output, NULL, flags);
7c072018 637}
bf31fa26 638
7c072018
VZ
639long wxExecute(const wxString& command,
640 wxArrayString& output,
4d172154
VZ
641 wxArrayString& error,
642 int flags)
7c072018 643{
4d172154 644 return wxDoExecuteWithCapture(command, output, &error, flags);
bf31fa26
VZ
645}
646
c5f0d1f9 647// ----------------------------------------------------------------------------
fad92e2f 648// Id functions
c5f0d1f9
DE
649// ----------------------------------------------------------------------------
650
c5f0d1f9
DE
651// Id generation
652static long wxCurrentId = 100;
653
654long wxNewId()
655{
656 // skip the part of IDs space that contains hard-coded values:
657 if (wxCurrentId == wxID_LOWEST)
658 wxCurrentId = wxID_HIGHEST + 1;
659
660 return wxCurrentId++;
661}
662
663long
664wxGetCurrentId(void) { return wxCurrentId; }
665
666void
667wxRegisterId (long id)
668{
669 if (id >= wxCurrentId)
670 wxCurrentId = id + 1;
671}
672
fe5f448f
RR
673// ----------------------------------------------------------------------------
674// wxQsort, adapted by RR to allow user_data
675// ----------------------------------------------------------------------------
676
677/* This file is part of the GNU C Library.
678 Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
11fe6505 679
fe5f448f
RR
680 Douglas Schmidt kindly gave permission to relicence the
681 code under the wxWindows licence:
11fe6505 682
fe5f448f
RR
683From: "Douglas C. Schmidt" <schmidt@dre.vanderbilt.edu>
684To: Robert Roebling <robert.roebling@uni-ulm.de>
11fe6505 685Subject: Re: qsort licence
fe5f448f
RR
686Date: Mon, 23 Jul 2007 03:44:25 -0500
687Sender: schmidt@dre.vanderbilt.edu
688Message-Id: <20070723084426.64F511000A8@tango.dre.vanderbilt.edu>
689
690Hi Robert,
691
692> [...] I'm asking if you'd be willing to relicence your code
693> under the wxWindows licence. [...]
694
695That's fine with me [...]
696
697Thanks,
698
699 Doug */
700
701
702/* Byte-wise swap two items of size SIZE. */
11fe6505 703#define SWAP(a, b, size) \
fad92e2f
FM
704 do \
705 { \
706 register size_t __size = (size); \
707 register char *__a = (a), *__b = (b); \
11fe6505 708 do \
fad92e2f
FM
709 { \
710 char __tmp = *__a; \
11fe6505 711 *__a++ = *__b; \
fad92e2f
FM
712 *__b++ = __tmp; \
713 } while (--__size > 0); \
fe5f448f
RR
714 } while (0)
715
716/* Discontinue quicksort algorithm when partition gets below this size.
717 This particular magic number was chosen to work best on a Sun 4/260. */
718#define MAX_THRESH 4
719
720/* Stack node declarations used to store unfulfilled partition obligations. */
721typedef struct
722 {
723 char *lo;
724 char *hi;
725 } stack_node;
726
727/* The next 4 #defines implement a very fast in-line stack abstraction. */
11fe6505 728#define STACK_SIZE (8 * sizeof(unsigned long int))
e71bf8b2
VZ
729#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
730#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
731#define STACK_NOT_EMPTY (stack < top)
fe5f448f
RR
732
733
734/* Order size using quicksort. This implementation incorporates
735 four optimizations discussed in Sedgewick:
736
737 1. Non-recursive, using an explicit stack of pointer that store the
738 next array partition to sort. To save time, this maximum amount
739 of space required to store an array of MAX_INT is allocated on the
740 stack. Assuming a 32-bit integer, this needs only 32 *
741 sizeof(stack_node) == 136 bits. Pretty cheap, actually.
742
743 2. Chose the pivot element using a median-of-three decision tree.
744 This reduces the probability of selecting a bad pivot value and
745 eliminates certain extraneous comparisons.
746
747 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
748 insertion sort to order the MAX_THRESH items within each partition.
749 This is a big win, since insertion sort is faster for small, mostly
750 sorted array segments.
751
752 4. The larger of the two sub-partitions is always pushed onto the
753 stack first, with the algorithm then concentrating on the
754 smaller partition. This *guarantees* no more than log (n)
755 stack size is needed (actually O(1) in this case)! */
756
757void wxQsort(void *const pbase, size_t total_elems,
11fe6505 758 size_t size, CMPFUNCDATA cmp, const void* user_data)
fe5f448f
RR
759{
760 register char *base_ptr = (char *) pbase;
761 const size_t max_thresh = MAX_THRESH * size;
762
763 if (total_elems == 0)
764 /* Avoid lossage with unsigned arithmetic below. */
765 return;
766
767 if (total_elems > MAX_THRESH)
768 {
769 char *lo = base_ptr;
770 char *hi = &lo[size * (total_elems - 1)];
771 stack_node stack[STACK_SIZE];
772 stack_node *top = stack;
773
774 PUSH (NULL, NULL);
775
776 while (STACK_NOT_EMPTY)
777 {
778 char *left_ptr;
779 char *right_ptr;
780
11fe6505
VZ
781 /* Select median value from among LO, MID, and HI. Rearrange
782 LO and HI so the three values are sorted. This lowers the
783 probability of picking a pathological pivot value and
784 skips a comparison for both the LEFT_PTR and RIGHT_PTR. */
785
786 char *mid = lo + size * ((hi - lo) / size >> 1);
787
788 if ((*cmp) ((void *) mid, (void *) lo, user_data) < 0)
789 SWAP (mid, lo, size);
790 if ((*cmp) ((void *) hi, (void *) mid, user_data) < 0)
791 SWAP (mid, hi, size);
792 else
793 goto jump_over;
794 if ((*cmp) ((void *) mid, (void *) lo, user_data) < 0)
795 SWAP (mid, lo, size);
796 jump_over:;
797 left_ptr = lo + size;
798 right_ptr = hi - size;
799
800 /* Here's the famous ``collapse the walls'' section of quicksort.
801 Gotta like those tight inner loops! They are the main reason
802 that this algorithm runs much faster than others. */
803 do
804 {
805 while ((*cmp) ((void *) left_ptr, (void *) mid, user_data) < 0)
806 left_ptr += size;
807
808 while ((*cmp) ((void *) mid, (void *) right_ptr, user_data) < 0)
809 right_ptr -= size;
810
811 if (left_ptr < right_ptr)
812 {
813 SWAP (left_ptr, right_ptr, size);
814 if (mid == left_ptr)
815 mid = right_ptr;
816 else if (mid == right_ptr)
817 mid = left_ptr;
818 left_ptr += size;
819 right_ptr -= size;
820 }
821 else if (left_ptr == right_ptr)
822 {
823 left_ptr += size;
824 right_ptr -= size;
825 break;
826 }
827 }
828 while (left_ptr <= right_ptr);
fe5f448f
RR
829
830 /* Set up pointers for next iteration. First determine whether
831 left and right partitions are below the threshold size. If so,
832 ignore one or both. Otherwise, push the larger partition's
833 bounds on the stack and continue sorting the smaller one. */
834
835 if ((size_t) (right_ptr - lo) <= max_thresh)
836 {
837 if ((size_t) (hi - left_ptr) <= max_thresh)
11fe6505 838 /* Ignore both small partitions. */
fe5f448f
RR
839 POP (lo, hi);
840 else
11fe6505 841 /* Ignore small left partition. */
fe5f448f
RR
842 lo = left_ptr;
843 }
844 else if ((size_t) (hi - left_ptr) <= max_thresh)
11fe6505 845 /* Ignore small right partition. */
fe5f448f
RR
846 hi = right_ptr;
847 else if ((right_ptr - lo) > (hi - left_ptr))
848 {
11fe6505 849 /* Push larger left partition indices. */
fe5f448f
RR
850 PUSH (lo, right_ptr);
851 lo = left_ptr;
852 }
853 else
854 {
11fe6505 855 /* Push larger right partition indices. */
fe5f448f
RR
856 PUSH (left_ptr, hi);
857 hi = right_ptr;
858 }
859 }
860 }
861
862 /* Once the BASE_PTR array is partially sorted by quicksort the rest
863 is completely sorted using insertion sort, since this is efficient
864 for partitions below MAX_THRESH size. BASE_PTR points to the beginning
865 of the array to sort, and END_PTR points at the very last element in
866 the array (*not* one beyond it!). */
867
fe5f448f
RR
868 {
869 char *const end_ptr = &base_ptr[size * (total_elems - 1)];
870 char *tmp_ptr = base_ptr;
e71bf8b2
VZ
871 char *thresh = base_ptr + max_thresh;
872 if ( thresh > end_ptr )
873 thresh = end_ptr;
fe5f448f
RR
874 register char *run_ptr;
875
876 /* Find smallest element in first threshold and place it at the
877 array's beginning. This is the smallest array element,
878 and the operation speeds up insertion sort's inner loop. */
879
880 for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size)
881 if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, user_data) < 0)
882 tmp_ptr = run_ptr;
883
884 if (tmp_ptr != base_ptr)
885 SWAP (tmp_ptr, base_ptr, size);
886
887 /* Insertion sort, running from left-hand-side up to right-hand-side. */
888
889 run_ptr = base_ptr + size;
890 while ((run_ptr += size) <= end_ptr)
891 {
11fe6505
VZ
892 tmp_ptr = run_ptr - size;
893 while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, user_data) < 0)
894 tmp_ptr -= size;
fe5f448f 895
11fe6505 896 tmp_ptr += size;
fe5f448f
RR
897 if (tmp_ptr != run_ptr)
898 {
899 char *trav;
900
11fe6505
VZ
901 trav = run_ptr + size;
902 while (--trav >= run_ptr)
fe5f448f
RR
903 {
904 char c = *trav;
905 char *hi, *lo;
906
907 for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo)
908 *hi = *lo;
909 *hi = c;
910 }
911 }
912 }
913 }
914}
915
fad92e2f 916#endif // wxUSE_BASE
fe5f448f
RR
917
918
c5f0d1f9
DE
919
920// ============================================================================
921// GUI-only functions from now on
922// ============================================================================
923
924#if wxUSE_GUI
925
f9837e46
VZ
926// this function is only really implemented for X11-based ports, including GTK1
927// (GTK2 sets detectable auto-repeat automatically anyhow)
928#if !(defined(__WXX11__) || defined(__WXMOTIF__) || \
929 (defined(__WXGTK__) && !defined(__WXGTK20__)))
ef3da29b
VZ
930bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) )
931{
f9837e46 932 return true;
ef3da29b 933}
f9837e46 934#endif // !X11-based port
ef3da29b 935
498a1eeb
RN
936// ----------------------------------------------------------------------------
937// Launch default browser
938// ----------------------------------------------------------------------------
939
7999124f 940#if defined(__WXMSW__)
5ccb95f6 941
50a2e26f
FM
942// implemented in a port-specific utils source file:
943bool wxDoLaunchDefaultBrowser(const wxString& url, const wxString& scheme, int flags);
42d0df00 944
7e86b10b 945#elif defined(__WXX11__) || defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || \
766fc092 946 (defined(__WXOSX__) )
42d0df00 947
50a2e26f
FM
948// implemented in a port-specific utils source file:
949bool wxDoLaunchDefaultBrowser(const wxString& url, int flags);
498a1eeb 950
f728025e 951#else
ae46a7fd 952
50a2e26f
FM
953// a "generic" implementation:
954bool wxDoLaunchDefaultBrowser(const wxString& url, int flags)
955{
956 // on other platforms try to use mime types or wxExecute...
889fda0c 957
13a1e96f
DS
958 bool ok = false;
959 wxString cmd;
960
1b1b5318 961#if wxUSE_MIMETYPE
9a83f860 962 wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(wxT("html"));
7999124f 963 if ( ft )
657a7545 964 {
7999124f
VZ
965 wxString mt;
966 ft->GetMimeType(&mt);
498a1eeb 967
13a1e96f 968 ok = ft->GetOpenCommand(&cmd, wxFileType::MessageParameters(url));
7999124f 969 delete ft;
498a1eeb 970 }
1b1b5318 971#endif // wxUSE_MIMETYPE
13a1e96f
DS
972
973 if ( !ok || cmd.empty() )
2830b4a4 974 {
13a1e96f 975 // fallback to checking for the BROWSER environment variable
50a2e26f 976 if ( !wxGetEnv(wxT("BROWSER"), &cmd) || cmd.empty() )
9a83f860 977 cmd << wxT(' ') << url;
2830b4a4 978 }
13a1e96f
DS
979
980 ok = ( !cmd.empty() && wxExecute(cmd) );
981 if (ok)
982 return ok;
983
984 // no file type for HTML extension
5519074c 985 wxLogError(_("No default application configured for HTML files."));
13a1e96f 986
50a2e26f
FM
987 return false;
988}
989#endif
990
991static bool DoLaunchDefaultBrowserHelper(const wxString& urlOrig, int flags)
992{
993 // NOTE: we don't have to care about the wxBROWSER_NOBUSYCURSOR flag
994 // as it was already handled by wxLaunchDefaultBrowser
995
996 wxUnusedVar(flags);
997
998 wxString url(urlOrig), scheme;
999 wxURI uri(url);
1000
1001 // this check is useful to avoid that wxURI recognizes as scheme parts of
1002 // the filename, in case urlOrig is a local filename
1003 // (e.g. "C:\\test.txt" when parsed by wxURI reports a scheme == "C")
02b94f4e 1004 bool hasValidScheme = uri.HasScheme() && uri.GetScheme().length() > 1;
50a2e26f
FM
1005
1006#if defined(__WXMSW__)
1007
1008 // NOTE: when testing wxMSW's wxLaunchDefaultBrowser all possible forms
1009 // of the URL/flags should be tested; e.g.:
1010 //
1011 // for (int i=0; i<2; i++)
1012 // {
4290e8ed 1013 // // test arguments without a valid URL scheme:
50a2e26f
FM
1014 // wxLaunchDefaultBrowser("C:\\test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1015 // wxLaunchDefaultBrowser("wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
4290e8ed
FM
1016 //
1017 // // test arguments with different valid schemes:
50a2e26f
FM
1018 // wxLaunchDefaultBrowser("file:/C%3A/test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1019 // wxLaunchDefaultBrowser("http://wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
4290e8ed 1020 // wxLaunchDefaultBrowser("mailto:user@host.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
50a2e26f
FM
1021 // }
1022 // (assuming you have a C:\test.txt file)
1023
1024 if ( !hasValidScheme )
1025 {
1026 if (wxFileExists(urlOrig) || wxDirExists(urlOrig))
1027 {
1028 scheme = "file";
1029 // do not prepend the file scheme to the URL as ShellExecuteEx() doesn't like it
1030 }
1031 else
1032 {
1033 url.Prepend(wxS("http://"));
1034 scheme = "http";
1035 }
1036 }
1037 else if ( hasValidScheme )
1038 {
1039 scheme = uri.GetScheme();
1040
1041 if ( uri.GetScheme() == "file" )
1042 {
00aa89f4
VZ
1043 // TODO: extract URLToFileName() to some always compiled in
1044 // function
1045#if wxUSE_FILESYSTEM
4290e8ed 1046 // ShellExecuteEx() doesn't like the "file" scheme when opening local files;
50a2e26f
FM
1047 // remove it
1048 url = wxFileSystem::URLToFileName(url).GetFullPath();
00aa89f4 1049#endif // wxUSE_FILESYSTEM
50a2e26f
FM
1050 }
1051 }
1052
1053 if (wxDoLaunchDefaultBrowser(url, scheme, flags))
1054 return true;
1055 //else: call wxLogSysError
1056#else
1057 if ( !hasValidScheme )
1058 {
1059 // set the scheme of url to "http" or "file" if it does not have one
1060 if (wxFileExists(urlOrig) || wxDirExists(urlOrig))
1061 url.Prepend(wxS("file://"));
1062 else
1063 url.Prepend(wxS("http://"));
1064 }
1065
1066 if (wxDoLaunchDefaultBrowser(url, flags))
1067 return true;
1068 //else: call wxLogSysError
1069#endif
532d575b 1070
5519074c 1071 wxLogSysError(_("Failed to open URL \"%s\" in default browser."),
7999124f 1072 url.c_str());
657a7545 1073
7999124f 1074 return false;
498a1eeb
RN
1075}
1076
f75e0c15
VZ
1077bool wxLaunchDefaultBrowser(const wxString& url, int flags)
1078{
50a2e26f
FM
1079 // NOTE: as documented, "url" may be both a real well-formed URL
1080 // and a local file name
1081
f75e0c15 1082 if ( flags & wxBROWSER_NOBUSYCURSOR )
50a2e26f 1083 return DoLaunchDefaultBrowserHelper(url, flags);
f75e0c15
VZ
1084
1085 wxBusyCursor bc;
50a2e26f 1086 return DoLaunchDefaultBrowserHelper(url, flags);
f75e0c15
VZ
1087}
1088
e90c1d2a 1089// ----------------------------------------------------------------------------
7c072018 1090// Menu accelerators related functions
e90c1d2a
VZ
1091// ----------------------------------------------------------------------------
1092
50a2e26f 1093#if WXWIN_COMPATIBILITY_2_6
7c072018 1094wxChar *wxStripMenuCodes(const wxChar *in, wxChar *out)
e90c1d2a 1095{
9a6384ca 1096#if wxUSE_MENUS
52af3158 1097 wxString s = wxMenuItem::GetLabelText(in);
9a6384ca
WS
1098#else
1099 wxString str(in);
1100 wxString s = wxStripMenuCodes(str);
1101#endif // wxUSE_MENUS
7c072018
VZ
1102 if ( out )
1103 {
1104 // go smash their buffer if it's not big enough - I love char * params
1105 memcpy(out, s.c_str(), s.length() * sizeof(wxChar));
1106 }
1107 else
1108 {
f526f752
MB
1109 out = new wxChar[s.length() + 1];
1110 wxStrcpy(out, s.c_str());
7c072018
VZ
1111 }
1112
1113 return out;
e90c1d2a 1114}
50a2e26f 1115#endif
e90c1d2a 1116
74639764 1117wxString wxStripMenuCodes(const wxString& in, int flags)
e90c1d2a 1118{
9a83f860 1119 wxASSERT_MSG( flags, wxT("this is useless to call without any flags") );
74639764 1120
7c072018 1121 wxString out;
79f585d9 1122
7c072018
VZ
1123 size_t len = in.length();
1124 out.reserve(len);
79f585d9 1125
7c072018
VZ
1126 for ( size_t n = 0; n < len; n++ )
1127 {
1128 wxChar ch = in[n];
9a83f860 1129 if ( (flags & wxStrip_Mnemonics) && ch == wxT('&') )
cd6ce4a9 1130 {
7c072018
VZ
1131 // skip it, it is used to introduce the accel char (or to quote
1132 // itself in which case it should still be skipped): note that it
1133 // can't be the last character of the string
1134 if ( ++n == len )
79f585d9 1135 {
9a83f860 1136 wxLogDebug(wxT("Invalid menu string '%s'"), in.c_str());
7c072018
VZ
1137 }
1138 else
1139 {
1140 // use the next char instead
1141 ch = in[n];
79f585d9 1142 }
cd6ce4a9 1143 }
9a83f860 1144 else if ( (flags & wxStrip_Accel) && ch == wxT('\t') )
79f585d9 1145 {
7c072018
VZ
1146 // everything after TAB is accel string, exit the loop
1147 break;
79f585d9 1148 }
7c072018
VZ
1149
1150 out += ch;
225fe9d6
VZ
1151 }
1152
7c072018 1153 return out;
cd6ce4a9
VZ
1154}
1155
cbc66a27 1156// ----------------------------------------------------------------------------
7c072018 1157// Window search functions
cbc66a27
VZ
1158// ----------------------------------------------------------------------------
1159
7c072018
VZ
1160/*
1161 * If parent is non-NULL, look through children for a label or title
1162 * matching the specified string. If NULL, look through all top-level windows.
1163 *
1164 */
e2a6f233 1165
7c072018
VZ
1166wxWindow *
1167wxFindWindowByLabel (const wxString& title, wxWindow * parent)
134677bd 1168{
7c072018
VZ
1169 return wxWindow::FindWindowByLabel( title, parent );
1170}
b829bf55 1171
b829bf55 1172
7c072018
VZ
1173/*
1174 * If parent is non-NULL, look through children for a name
1175 * matching the specified string. If NULL, look through all top-level windows.
1176 *
1177 */
134677bd 1178
7c072018
VZ
1179wxWindow *
1180wxFindWindowByName (const wxString& name, wxWindow * parent)
2c18f21d 1181{
7c072018 1182 return wxWindow::FindWindowByName( name, parent );
2c18f21d
VS
1183}
1184
cb719f2e 1185// Returns menu item id or wxNOT_FOUND if none.
7c072018 1186int
8d22935d
VZ
1187wxFindMenuItemId(wxFrame *frame,
1188 const wxString& menuString,
1189 const wxString& itemString)
e2a6f233 1190{
7c072018 1191#if wxUSE_MENUS
9a6384ca
WS
1192 wxMenuBar *menuBar = frame->GetMenuBar ();
1193 if ( menuBar )
1194 return menuBar->FindMenuItem (menuString, itemString);
8d22935d
VZ
1195#else // !wxUSE_MENUS
1196 wxUnusedVar(frame);
1197 wxUnusedVar(menuString);
1198 wxUnusedVar(itemString);
1199#endif // wxUSE_MENUS/!wxUSE_MENUS
0fb67cd1 1200
9a6384ca 1201 return wxNOT_FOUND;
e2a6f233
JS
1202}
1203
7c072018
VZ
1204// Try to find the deepest child that contains 'pt'.
1205// We go backwards, to try to allow for controls that are spacially
1206// within other controls, but are still siblings (e.g. buttons within
1207// static boxes). Static boxes are likely to be created _before_ controls
1208// that sit inside them.
1209wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt)
e2a6f233 1210{
7c072018
VZ
1211 if (!win->IsShown())
1212 return NULL;
0fb67cd1 1213
7c072018
VZ
1214 // Hack for wxNotebook case: at least in wxGTK, all pages
1215 // claim to be shown, so we must only deal with the selected one.
1216#if wxUSE_NOTEBOOK
1217 if (win->IsKindOf(CLASSINFO(wxNotebook)))
e2a6f233 1218 {
7c072018
VZ
1219 wxNotebook* nb = (wxNotebook*) win;
1220 int sel = nb->GetSelection();
1221 if (sel >= 0)
1222 {
1223 wxWindow* child = nb->GetPage(sel);
1224 wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
1225 if (foundWin)
1226 return foundWin;
1227 }
e2a6f233 1228 }
7c072018 1229#endif
0fb67cd1 1230
df5168c4 1231 wxWindowList::compatibility_iterator node = win->GetChildren().GetLast();
7c072018
VZ
1232 while (node)
1233 {
1234 wxWindow* child = node->GetData();
1235 wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
1236 if (foundWin)
1237 return foundWin;
1238 node = node->GetPrevious();
1239 }
1240
1241 wxPoint pos = win->GetPosition();
1242 wxSize sz = win->GetSize();
7aa7d2d4 1243 if ( !win->IsTopLevel() && win->GetParent() )
7c072018
VZ
1244 {
1245 pos = win->GetParent()->ClientToScreen(pos);
1246 }
1247
1248 wxRect rect(pos, sz);
22a35096 1249 if (rect.Contains(pt))
7c072018 1250 return win;
622eb786
VZ
1251
1252 return NULL;
0fb67cd1
VZ
1253}
1254
7c072018 1255wxWindow* wxGenericFindWindowAtPoint(const wxPoint& pt)
0fb67cd1 1256{
7c072018
VZ
1257 // Go backwards through the list since windows
1258 // on top are likely to have been appended most
1259 // recently.
df5168c4 1260 wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetLast();
7c072018
VZ
1261 while (node)
1262 {
1263 wxWindow* win = node->GetData();
1264 wxWindow* found = wxFindWindowAtPoint(win, pt);
1265 if (found)
1266 return found;
1267 node = node->GetPrevious();
1268 }
1269 return NULL;
1270}
0fb67cd1 1271
7c072018
VZ
1272// ----------------------------------------------------------------------------
1273// GUI helpers
1274// ----------------------------------------------------------------------------
0fb67cd1 1275
7c072018
VZ
1276/*
1277 * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
1278 * since otherwise the generic code may be pulled in unnecessarily.
1279 */
0fb67cd1 1280
7c072018 1281#if wxUSE_MSGDLG
0fb67cd1 1282
7c072018
VZ
1283int wxMessageBox(const wxString& message, const wxString& caption, long style,
1284 wxWindow *parent, int WXUNUSED(x), int WXUNUSED(y) )
0fb67cd1 1285{
7e3204b4
VZ
1286 // add the appropriate icon unless this was explicitly disabled by use of
1287 // wxICON_NONE
1288 if ( !(style & wxICON_NONE) && !(style & wxICON_MASK) )
53a6ac21 1289 {
7e3204b4 1290 style |= style & wxYES ? wxICON_QUESTION : wxICON_INFORMATION;
53a6ac21
DS
1291 }
1292
7e3204b4 1293 wxMessageDialog dialog(parent, message, caption, style);
0fb67cd1 1294
7c072018
VZ
1295 int ans = dialog.ShowModal();
1296 switch ( ans )
1297 {
1298 case wxID_OK:
1299 return wxOK;
1300 case wxID_YES:
1301 return wxYES;
1302 case wxID_NO:
1303 return wxNO;
1304 case wxID_CANCEL:
1305 return wxCANCEL;
1306 }
0fb67cd1 1307
9a83f860 1308 wxFAIL_MSG( wxT("unexpected return code from wxMessageDialog") );
0fb67cd1 1309
7c072018 1310 return wxCANCEL;
e2a6f233
JS
1311}
1312
8cf304f8
VZ
1313void wxInfoMessageBox(wxWindow* parent)
1314{
1315 // don't translate these strings, they're for diagnostics purposes only
1316 wxString msg;
32be10a4
VZ
1317 msg.Printf(wxS("wxWidgets Library (%s port)\n")
1318 wxS("Version %d.%d.%d (Unicode: %s, debug level: %d),\n")
1319 wxS("compiled at %s %s\n\n")
1320 wxS("Runtime version of toolkit used is %d.%d.\n"),
1321 wxPlatformInfo::Get().GetPortIdName(),
8cf304f8
VZ
1322 wxMAJOR_VERSION,
1323 wxMINOR_VERSION,
1324 wxRELEASE_NUMBER,
32be10a4
VZ
1325#if wxUSE_UNICODE_UTF8
1326 "UTF-8",
1327#elif wxUSE_UNICODE
1328 "wchar_t",
8cf304f8 1329#else
32be10a4 1330 "none",
8cf304f8 1331#endif
32be10a4 1332 wxDEBUG_LEVEL,
8cf304f8
VZ
1333 __TDATE__,
1334 __TTIME__,
1335 wxPlatformInfo::Get().GetToolkitMajorVersion(),
32be10a4
VZ
1336 wxPlatformInfo::Get().GetToolkitMinorVersion()
1337 );
1338
8cf304f8 1339#ifdef __WXGTK__
32be10a4
VZ
1340 msg += wxString::Format("Compile-time GTK+ version is %d.%d.%d.\n",
1341 GTK_MAJOR_VERSION,
1342 GTK_MINOR_VERSION,
1343 GTK_MICRO_VERSION);
1344#endif // __WXGTK__
1345
b326934c 1346 msg += wxS("\nCopyright (c) 1995-2010 wxWidgets team");
32be10a4 1347
9a83f860 1348 wxMessageBox(msg, wxT("wxWidgets information"),
8cf304f8
VZ
1349 wxICON_INFORMATION | wxOK,
1350 parent);
1351}
1352
7c072018 1353#endif // wxUSE_MSGDLG
518b5d2f 1354
7c072018 1355#if wxUSE_TEXTDLG
518b5d2f 1356
7c072018
VZ
1357wxString wxGetTextFromUser(const wxString& message, const wxString& caption,
1358 const wxString& defaultValue, wxWindow *parent,
13d13a9e 1359 wxCoord x, wxCoord y, bool centre )
7c072018
VZ
1360{
1361 wxString str;
13d13a9e
WS
1362 long style = wxTextEntryDialogStyle;
1363
1364 if (centre)
1365 style |= wxCENTRE;
1366 else
1367 style &= ~wxCENTRE;
1368
1369 wxTextEntryDialog dialog(parent, message, caption, defaultValue, style, wxPoint(x, y));
1370
7c072018
VZ
1371 if (dialog.ShowModal() == wxID_OK)
1372 {
1373 str = dialog.GetValue();
1374 }
0fb67cd1 1375
7c072018 1376 return str;
518b5d2f
VZ
1377}
1378
7c072018
VZ
1379wxString wxGetPasswordFromUser(const wxString& message,
1380 const wxString& caption,
1381 const wxString& defaultValue,
b3bb2a74
KH
1382 wxWindow *parent,
1383 wxCoord x, wxCoord y, bool centre )
96c5bd7f 1384{
7c072018 1385 wxString str;
b3bb2a74
KH
1386 long style = wxTextEntryDialogStyle;
1387
1388 if (centre)
1389 style |= wxCENTRE;
1390 else
1391 style &= ~wxCENTRE;
1392
12cfa304
KH
1393 wxPasswordEntryDialog dialog(parent, message, caption, defaultValue,
1394 style, wxPoint(x, y));
7c072018
VZ
1395 if ( dialog.ShowModal() == wxID_OK )
1396 {
1397 str = dialog.GetValue();
1398 }
96c5bd7f 1399
7c072018
VZ
1400 return str;
1401}
96c5bd7f 1402
7c072018 1403#endif // wxUSE_TEXTDLG
96c5bd7f 1404
7c072018 1405#if wxUSE_COLOURDLG
96c5bd7f 1406
f75e0c15
VZ
1407wxColour wxGetColourFromUser(wxWindow *parent,
1408 const wxColour& colInit,
e6ef9ea4
VZ
1409 const wxString& caption,
1410 wxColourData *ptrData)
c51deffc 1411{
e6ef9ea4
VZ
1412 // contains serialized representation of wxColourData used the last time
1413 // the dialog was shown: we want to reuse it the next time in order to show
1414 // the same custom colours to the user (and we can't just have static
1415 // wxColourData itself because it's a GUI object and so should be destroyed
1416 // before GUI shutdown and doing it during static cleanup is too late)
1417 static wxString s_strColourData;
1418
7c072018 1419 wxColourData data;
e6ef9ea4 1420 if ( !ptrData )
7c072018 1421 {
e6ef9ea4
VZ
1422 ptrData = &data;
1423 if ( !s_strColourData.empty() )
1424 {
1425 if ( !data.FromString(s_strColourData) )
1426 {
1427 wxFAIL_MSG( "bug in wxColourData::FromString()?" );
1428 }
1429
1430#ifdef __WXMSW__
1431 // we don't get back the "choose full" flag value from the native
1432 // dialog and so we can't preserve it between runs, so we decide to
1433 // always use it as it seems better than not using it (user can
1434 // just ignore the extra controls in the dialog but having to click
1435 // a button each time to show them would be very annoying
1436 data.SetChooseFull(true);
1437#endif // __WXMSW__
1438 }
1439 }
1440
1441 if ( colInit.IsOk() )
1442 {
1443 ptrData->SetColour(colInit);
7c072018 1444 }
c51deffc 1445
7c072018 1446 wxColour colRet;
e6ef9ea4 1447 wxColourDialog dialog(parent, ptrData);
76b49cf4 1448 if (!caption.empty())
f14d6dd1 1449 dialog.SetTitle(caption);
7c072018
VZ
1450 if ( dialog.ShowModal() == wxID_OK )
1451 {
e6ef9ea4
VZ
1452 *ptrData = dialog.GetColourData();
1453 colRet = ptrData->GetColour();
1454 s_strColourData = ptrData->ToString();
7c072018 1455 }
e6ef9ea4 1456 //else: leave colRet invalid
7c072018
VZ
1457
1458 return colRet;
c51deffc 1459}
bc385ba9 1460
7c072018 1461#endif // wxUSE_COLOURDLG
bc385ba9 1462
7c072018
VZ
1463#if wxUSE_FONTDLG
1464
f14d6dd1 1465wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit, const wxString& caption)
bc385ba9 1466{
7c072018
VZ
1467 wxFontData data;
1468 if ( fontInit.Ok() )
bc385ba9 1469 {
7c072018
VZ
1470 data.SetInitialFont(fontInit);
1471 }
bc385ba9 1472
7c072018
VZ
1473 wxFont fontRet;
1474 wxFontDialog dialog(parent, data);
76b49cf4 1475 if (!caption.empty())
f14d6dd1 1476 dialog.SetTitle(caption);
7c072018
VZ
1477 if ( dialog.ShowModal() == wxID_OK )
1478 {
1479 fontRet = dialog.GetFontData().GetChosenFont();
1480 }
1481 //else: leave it invalid
bc385ba9 1482
7c072018 1483 return fontRet;
bc385ba9
VZ
1484}
1485
7c072018 1486#endif // wxUSE_FONTDLG
2b5f62a0 1487
7c072018
VZ
1488// ----------------------------------------------------------------------------
1489// wxSafeYield and supporting functions
1490// ----------------------------------------------------------------------------
2b5f62a0 1491
7c072018
VZ
1492void wxEnableTopLevelWindows(bool enable)
1493{
df5168c4 1494 wxWindowList::compatibility_iterator node;
7c072018
VZ
1495 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
1496 node->GetData()->Enable(enable);
1497}
2b5f62a0 1498
2ecd1756
VZ
1499wxWindowDisabler::wxWindowDisabler(bool disable)
1500{
1501 m_disabled = disable;
1502 if ( disable )
1503 DoDisable();
1504}
1505
7c072018 1506wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip)
2ecd1756
VZ
1507{
1508 m_disabled = true;
1509 DoDisable(winToSkip);
1510}
1511
1512void wxWindowDisabler::DoDisable(wxWindow *winToSkip)
7c072018
VZ
1513{
1514 // remember the top level windows which were already disabled, so that we
1515 // don't reenable them later
1516 m_winDisabled = NULL;
1517
df5168c4 1518 wxWindowList::compatibility_iterator node;
7c072018 1519 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
2b5f62a0 1520 {
7c072018
VZ
1521 wxWindow *winTop = node->GetData();
1522 if ( winTop == winToSkip )
1523 continue;
2b5f62a0 1524
7c072018
VZ
1525 // we don't need to disable the hidden or already disabled windows
1526 if ( winTop->IsEnabled() && winTop->IsShown() )
2b5f62a0 1527 {
7c072018 1528 winTop->Disable();
2b5f62a0
VZ
1529 }
1530 else
1531 {
7c072018
VZ
1532 if ( !m_winDisabled )
1533 {
1534 m_winDisabled = new wxWindowList;
1535 }
1536
1537 m_winDisabled->Append(winTop);
2b5f62a0
VZ
1538 }
1539 }
2b5f62a0
VZ
1540}
1541
7c072018 1542wxWindowDisabler::~wxWindowDisabler()
cd6ce4a9 1543{
2ecd1756
VZ
1544 if ( !m_disabled )
1545 return;
1546
df5168c4 1547 wxWindowList::compatibility_iterator node;
7c072018 1548 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
cd6ce4a9 1549 {
7c072018
VZ
1550 wxWindow *winTop = node->GetData();
1551 if ( !m_winDisabled || !m_winDisabled->Find(winTop) )
cd6ce4a9 1552 {
7c072018 1553 winTop->Enable();
cd6ce4a9 1554 }
7c072018 1555 //else: had been already disabled, don't reenable
cd6ce4a9 1556 }
f6bcfd97 1557
7c072018 1558 delete m_winDisabled;
f6bcfd97
BP
1559}
1560
7c072018
VZ
1561// Yield to other apps/messages and disable user input to all windows except
1562// the given one
1563bool wxSafeYield(wxWindow *win, bool onlyIfNeeded)
f6bcfd97 1564{
7c072018 1565 wxWindowDisabler wd(win);
21709999 1566
7c072018
VZ
1567 bool rc;
1568 if (onlyIfNeeded)
1569 rc = wxYieldIfNeeded();
1570 else
1571 rc = wxYield();
8461e4c2 1572
7c072018 1573 return rc;
8461e4c2
VZ
1574}
1575
fad92e2f
FM
1576// ----------------------------------------------------------------------------
1577// wxApp::Yield() wrappers for backwards compatibility
1578// ----------------------------------------------------------------------------
1579
1580bool wxYield()
8461e4c2 1581{
fad92e2f
FM
1582 return wxTheApp && wxTheApp->Yield();
1583}
1584
1585bool wxYieldIfNeeded()
1586{
1587 return wxTheApp && wxTheApp->Yield(true);
8461e4c2 1588}
7c072018
VZ
1589
1590#endif // wxUSE_GUI