1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/utilscmn.cpp
3 // Purpose: Miscellaneous utility functions and classes
4 // Author: Julian Smart
8 // Copyright: (c) 1998 Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
29 #include "wx/string.h"
35 #include "wx/window.h"
38 #include "wx/msgdlg.h"
39 #include "wx/textdlg.h"
40 #include "wx/textctrl.h" // for wxTE_PASSWORD
42 #include "wx/menuitem.h"
48 #include "wx/apptrait.h"
50 #include "wx/process.h"
51 #include "wx/txtstrm.h"
53 #include "wx/mimetype.h"
54 #include "wx/config.h"
56 #if defined(__WXWINCE__) && wxUSE_DATETIME
57 #include "wx/datetime.h"
65 #if !wxONLY_WATCOM_EARLIER_THAN(1,4)
66 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
72 #include "wx/colordlg.h"
73 #include "wx/fontdlg.h"
74 #include "wx/notebook.h"
75 #include "wx/statusbr.h"
82 #include "wx/msw/wince/time.h"
84 #endif // ! __WXPALMOS5__
87 #include "wx/osx/private.h"
91 #if !defined(__MWERKS__) && !defined(__WXWINCE__)
92 #include <sys/types.h>
95 #endif // ! __WXPALMOS5__
97 #if defined(__WXMSW__)
98 #include "wx/msw/private.h"
99 #include "wx/filesys.h"
102 #if wxUSE_GUI && defined(__WXGTK__)
103 #include <gtk/gtk.h> // for GTK_XXX_VERSION constants
108 // ============================================================================
110 // ============================================================================
112 // Array used in DecToHex conversion routine.
113 static const wxChar hexArray
[] = wxT("0123456789ABCDEF");
115 // Convert 2-digit hex number to decimal
116 int wxHexToDec(const wxString
& str
)
119 buf
[0] = str
.GetChar(0);
120 buf
[1] = str
.GetChar(1);
121 return wxHexToDec((const char*) buf
);
124 // Convert decimal integer to 2-character hex string
125 void wxDecToHex(int dec
, wxChar
*buf
)
127 int firstDigit
= (int)(dec
/16.0);
128 int secondDigit
= (int)(dec
- (firstDigit
*16.0));
129 buf
[0] = hexArray
[firstDigit
];
130 buf
[1] = hexArray
[secondDigit
];
134 // Convert decimal integer to 2 characters
135 void wxDecToHex(int dec
, char* ch1
, char* ch2
)
137 int firstDigit
= (int)(dec
/16.0);
138 int secondDigit
= (int)(dec
- (firstDigit
*16.0));
139 (*ch1
) = (char) hexArray
[firstDigit
];
140 (*ch2
) = (char) hexArray
[secondDigit
];
143 // Convert decimal integer to 2-character hex string
144 wxString
wxDecToHex(int dec
)
147 wxDecToHex(dec
, buf
);
148 return wxString(buf
);
151 // ----------------------------------------------------------------------------
153 // ----------------------------------------------------------------------------
155 // Return the current date/time
160 wxDateTime now
= wxDateTime::Now();
163 return wxEmptyString
;
166 time_t now
= time(NULL
);
167 char *date
= ctime(&now
);
169 return wxString::FromAscii(date
);
173 #if WXWIN_COMPATIBILITY_2_8
174 void wxUsleep(unsigned long milliseconds
)
176 wxMilliSleep(milliseconds
);
180 const wxChar
*wxGetInstallPrefix()
184 if ( wxGetEnv(wxT("WXPREFIX"), &prefix
) )
185 return prefix
.c_str();
187 #ifdef wxINSTALL_PREFIX
188 return wxT(wxINSTALL_PREFIX
);
190 return wxEmptyString
;
194 wxString
wxGetDataDir()
196 wxString dir
= wxGetInstallPrefix();
197 dir
<< wxFILE_SEP_PATH
<< wxT("share") << wxFILE_SEP_PATH
<< wxT("wx");
201 bool wxIsPlatformLittleEndian()
203 // Are we little or big endian? This method is from Harbison & Steele.
207 char c
[sizeof(long)];
215 // ----------------------------------------------------------------------------
217 // ----------------------------------------------------------------------------
220 * Class to make it easier to specify platform-dependent values
223 wxArrayInt
* wxPlatform::sm_customPlatforms
= NULL
;
225 void wxPlatform::Copy(const wxPlatform
& platform
)
227 m_longValue
= platform
.m_longValue
;
228 m_doubleValue
= platform
.m_doubleValue
;
229 m_stringValue
= platform
.m_stringValue
;
232 wxPlatform
wxPlatform::If(int platform
, long value
)
235 return wxPlatform(value
);
240 wxPlatform
wxPlatform::IfNot(int platform
, long value
)
243 return wxPlatform(value
);
248 wxPlatform
& wxPlatform::ElseIf(int platform
, long value
)
255 wxPlatform
& wxPlatform::ElseIfNot(int platform
, long value
)
262 wxPlatform
wxPlatform::If(int platform
, double value
)
265 return wxPlatform(value
);
270 wxPlatform
wxPlatform::IfNot(int platform
, double value
)
273 return wxPlatform(value
);
278 wxPlatform
& wxPlatform::ElseIf(int platform
, double value
)
281 m_doubleValue
= value
;
285 wxPlatform
& wxPlatform::ElseIfNot(int platform
, double value
)
288 m_doubleValue
= value
;
292 wxPlatform
wxPlatform::If(int platform
, const wxString
& value
)
295 return wxPlatform(value
);
300 wxPlatform
wxPlatform::IfNot(int platform
, const wxString
& value
)
303 return wxPlatform(value
);
308 wxPlatform
& wxPlatform::ElseIf(int platform
, const wxString
& value
)
311 m_stringValue
= value
;
315 wxPlatform
& wxPlatform::ElseIfNot(int platform
, const wxString
& value
)
318 m_stringValue
= value
;
322 wxPlatform
& wxPlatform::Else(long value
)
328 wxPlatform
& wxPlatform::Else(double value
)
330 m_doubleValue
= value
;
334 wxPlatform
& wxPlatform::Else(const wxString
& value
)
336 m_stringValue
= value
;
340 void wxPlatform::AddPlatform(int platform
)
342 if (!sm_customPlatforms
)
343 sm_customPlatforms
= new wxArrayInt
;
344 sm_customPlatforms
->Add(platform
);
347 void wxPlatform::ClearPlatforms()
349 wxDELETE(sm_customPlatforms
);
352 /// Function for testing current platform
354 bool wxPlatform::Is(int platform
)
357 if (platform
== wxOS_WINDOWS
)
361 if (platform
== wxOS_WINDOWS_CE
)
367 // FIXME: wxWinPocketPC and wxWinSmartPhone are unknown symbols
369 #if defined(__WXWINCE__) && defined(__POCKETPC__)
370 if (platform
== wxWinPocketPC
)
373 #if defined(__WXWINCE__) && defined(__SMARTPHONE__)
374 if (platform
== wxWinSmartPhone
)
381 if (platform
== wxPORT_GTK
)
385 if (platform
== wxPORT_MAC
)
389 if (platform
== wxPORT_X11
)
393 if (platform
== wxOS_UNIX
)
397 if (platform
== wxPORT_MGL
)
401 if (platform
== wxOS_OS2
)
405 if (platform
== wxPORT_PM
)
409 if (platform
== wxPORT_MAC
)
413 if (sm_customPlatforms
&& sm_customPlatforms
->Index(platform
) != wxNOT_FOUND
)
419 // ----------------------------------------------------------------------------
420 // network and user id functions
421 // ----------------------------------------------------------------------------
423 // Get Full RFC822 style email address
424 bool wxGetEmailAddress(wxChar
*address
, int maxSize
)
426 wxString email
= wxGetEmailAddress();
430 wxStrlcpy(address
, email
.t_str(), maxSize
);
435 wxString
wxGetEmailAddress()
439 wxString host
= wxGetFullHostName();
442 wxString user
= wxGetUserId();
445 email
<< user
<< wxT('@') << host
;
452 wxString
wxGetUserId()
454 static const int maxLoginLen
= 256; // FIXME arbitrary number
457 bool ok
= wxGetUserId(wxStringBuffer(buf
, maxLoginLen
), maxLoginLen
);
465 wxString
wxGetUserName()
467 static const int maxUserNameLen
= 1024; // FIXME arbitrary number
470 bool ok
= wxGetUserName(wxStringBuffer(buf
, maxUserNameLen
), maxUserNameLen
);
478 wxString
wxGetHostName()
480 static const size_t hostnameSize
= 257;
483 bool ok
= wxGetHostName(wxStringBuffer(buf
, hostnameSize
), hostnameSize
);
491 wxString
wxGetFullHostName()
493 static const size_t hostnameSize
= 257;
496 bool ok
= wxGetFullHostName(wxStringBuffer(buf
, hostnameSize
), hostnameSize
);
504 wxString
wxGetHomeDir()
514 wxString
wxGetCurrentDir()
521 ok
= getcwd(dir
.GetWriteBuf(len
+ 1), len
) != NULL
;
526 if ( errno
!= ERANGE
)
528 wxLogSysError(wxT("Failed to get current directory"));
530 return wxEmptyString
;
534 // buffer was too small, retry with a larger one
546 // ----------------------------------------------------------------------------
548 // ----------------------------------------------------------------------------
550 bool wxGetEnvMap(wxEnvVariableHashMap
*map
)
552 wxCHECK_MSG( map
, false, wxS("output pointer can't be NULL") );
554 #if defined(__VISUALC__)
555 wxChar
**env
= _tenviron
;
557 // Not sure if other compilers have _tenviron so use the (more standard)
558 // ANSI version only for them.
559 char ** env
= environ
;
568 const wxString
var(*env
);
570 name
= var
.BeforeFirst(wxS('='), &value
);
572 (*map
)[name
] = value
;
583 // ----------------------------------------------------------------------------
585 // ----------------------------------------------------------------------------
587 // wxDoExecuteWithCapture() helper: reads an entire stream into one array
589 // returns true if ok, false if error
591 static bool ReadAll(wxInputStream
*is
, wxArrayString
& output
)
593 wxCHECK_MSG( is
, false, wxT("NULL stream in wxExecute()?") );
595 // the stream could be already at EOF or in wxSTREAM_BROKEN_PIPE state
598 wxTextInputStream
tis(*is
);
602 wxString line
= tis
.ReadLine();
604 // check for EOF before other errors as it's not really an error
607 // add the last, possibly incomplete, line
613 // any other error is fatal
622 #endif // wxUSE_STREAMS
624 // this is a private function because it hasn't a clean interface: the first
625 // array is passed by reference, the second by pointer - instead we have 2
626 // public versions of wxExecute() below
627 static long wxDoExecuteWithCapture(const wxString
& command
,
628 wxArrayString
& output
,
629 wxArrayString
* error
,
631 const wxExecuteEnv
*env
)
633 // create a wxProcess which will capture the output
634 wxProcess
*process
= new wxProcess
;
637 long rc
= wxExecute(command
, wxEXEC_SYNC
| flags
, process
, env
);
642 if ( !ReadAll(process
->GetInputStream(), output
) )
647 if ( !ReadAll(process
->GetErrorStream(), *error
) )
655 #endif // wxUSE_STREAMS/!wxUSE_STREAMS
662 long wxExecute(const wxString
& command
, wxArrayString
& output
, int flags
,
663 const wxExecuteEnv
*env
)
665 return wxDoExecuteWithCapture(command
, output
, NULL
, flags
, env
);
668 long wxExecute(const wxString
& command
,
669 wxArrayString
& output
,
670 wxArrayString
& error
,
672 const wxExecuteEnv
*env
)
674 return wxDoExecuteWithCapture(command
, output
, &error
, flags
, env
);
677 // ----------------------------------------------------------------------------
679 // ----------------------------------------------------------------------------
682 static long wxCurrentId
= 100;
686 // skip the part of IDs space that contains hard-coded values:
687 if (wxCurrentId
== wxID_LOWEST
)
688 wxCurrentId
= wxID_HIGHEST
+ 1;
690 return wxCurrentId
++;
694 wxGetCurrentId(void) { return wxCurrentId
; }
697 wxRegisterId (long id
)
699 if (id
>= wxCurrentId
)
700 wxCurrentId
= id
+ 1;
703 // ----------------------------------------------------------------------------
704 // wxQsort, adapted by RR to allow user_data
705 // ----------------------------------------------------------------------------
707 /* This file is part of the GNU C Library.
708 Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
710 Douglas Schmidt kindly gave permission to relicence the
711 code under the wxWindows licence:
713 From: "Douglas C. Schmidt" <schmidt@dre.vanderbilt.edu>
714 To: Robert Roebling <robert.roebling@uni-ulm.de>
715 Subject: Re: qsort licence
716 Date: Mon, 23 Jul 2007 03:44:25 -0500
717 Sender: schmidt@dre.vanderbilt.edu
718 Message-Id: <20070723084426.64F511000A8@tango.dre.vanderbilt.edu>
722 > [...] I'm asking if you'd be willing to relicence your code
723 > under the wxWindows licence. [...]
725 That's fine with me [...]
732 /* Byte-wise swap two items of size SIZE. */
733 #define SWAP(a, b, size) \
736 register size_t __size = (size); \
737 register char *__a = (a), *__b = (b); \
743 } while (--__size > 0); \
746 /* Discontinue quicksort algorithm when partition gets below this size.
747 This particular magic number was chosen to work best on a Sun 4/260. */
750 /* Stack node declarations used to store unfulfilled partition obligations. */
757 /* The next 4 #defines implement a very fast in-line stack abstraction. */
758 #define STACK_SIZE (8 * sizeof(unsigned long int))
759 #define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
760 #define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
761 #define STACK_NOT_EMPTY (stack < top)
764 /* Order size using quicksort. This implementation incorporates
765 four optimizations discussed in Sedgewick:
767 1. Non-recursive, using an explicit stack of pointer that store the
768 next array partition to sort. To save time, this maximum amount
769 of space required to store an array of MAX_INT is allocated on the
770 stack. Assuming a 32-bit integer, this needs only 32 *
771 sizeof(stack_node) == 136 bits. Pretty cheap, actually.
773 2. Chose the pivot element using a median-of-three decision tree.
774 This reduces the probability of selecting a bad pivot value and
775 eliminates certain extraneous comparisons.
777 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
778 insertion sort to order the MAX_THRESH items within each partition.
779 This is a big win, since insertion sort is faster for small, mostly
780 sorted array segments.
782 4. The larger of the two sub-partitions is always pushed onto the
783 stack first, with the algorithm then concentrating on the
784 smaller partition. This *guarantees* no more than log (n)
785 stack size is needed (actually O(1) in this case)! */
787 void wxQsort(void *const pbase
, size_t total_elems
,
788 size_t size
, CMPFUNCDATA cmp
, const void* user_data
)
790 register char *base_ptr
= (char *) pbase
;
791 const size_t max_thresh
= MAX_THRESH
* size
;
793 if (total_elems
== 0)
794 /* Avoid lossage with unsigned arithmetic below. */
797 if (total_elems
> MAX_THRESH
)
800 char *hi
= &lo
[size
* (total_elems
- 1)];
801 stack_node stack
[STACK_SIZE
];
802 stack_node
*top
= stack
;
806 while (STACK_NOT_EMPTY
)
811 /* Select median value from among LO, MID, and HI. Rearrange
812 LO and HI so the three values are sorted. This lowers the
813 probability of picking a pathological pivot value and
814 skips a comparison for both the LEFT_PTR and RIGHT_PTR. */
816 char *mid
= lo
+ size
* ((hi
- lo
) / size
>> 1);
818 if ((*cmp
) ((void *) mid
, (void *) lo
, user_data
) < 0)
819 SWAP (mid
, lo
, size
);
820 if ((*cmp
) ((void *) hi
, (void *) mid
, user_data
) < 0)
821 SWAP (mid
, hi
, size
);
824 if ((*cmp
) ((void *) mid
, (void *) lo
, user_data
) < 0)
825 SWAP (mid
, lo
, size
);
827 left_ptr
= lo
+ size
;
828 right_ptr
= hi
- size
;
830 /* Here's the famous ``collapse the walls'' section of quicksort.
831 Gotta like those tight inner loops! They are the main reason
832 that this algorithm runs much faster than others. */
835 while ((*cmp
) ((void *) left_ptr
, (void *) mid
, user_data
) < 0)
838 while ((*cmp
) ((void *) mid
, (void *) right_ptr
, user_data
) < 0)
841 if (left_ptr
< right_ptr
)
843 SWAP (left_ptr
, right_ptr
, size
);
846 else if (mid
== right_ptr
)
851 else if (left_ptr
== right_ptr
)
858 while (left_ptr
<= right_ptr
);
860 /* Set up pointers for next iteration. First determine whether
861 left and right partitions are below the threshold size. If so,
862 ignore one or both. Otherwise, push the larger partition's
863 bounds on the stack and continue sorting the smaller one. */
865 if ((size_t) (right_ptr
- lo
) <= max_thresh
)
867 if ((size_t) (hi
- left_ptr
) <= max_thresh
)
868 /* Ignore both small partitions. */
871 /* Ignore small left partition. */
874 else if ((size_t) (hi
- left_ptr
) <= max_thresh
)
875 /* Ignore small right partition. */
877 else if ((right_ptr
- lo
) > (hi
- left_ptr
))
879 /* Push larger left partition indices. */
880 PUSH (lo
, right_ptr
);
885 /* Push larger right partition indices. */
892 /* Once the BASE_PTR array is partially sorted by quicksort the rest
893 is completely sorted using insertion sort, since this is efficient
894 for partitions below MAX_THRESH size. BASE_PTR points to the beginning
895 of the array to sort, and END_PTR points at the very last element in
896 the array (*not* one beyond it!). */
899 char *const end_ptr
= &base_ptr
[size
* (total_elems
- 1)];
900 char *tmp_ptr
= base_ptr
;
901 char *thresh
= base_ptr
+ max_thresh
;
902 if ( thresh
> end_ptr
)
904 register char *run_ptr
;
906 /* Find smallest element in first threshold and place it at the
907 array's beginning. This is the smallest array element,
908 and the operation speeds up insertion sort's inner loop. */
910 for (run_ptr
= tmp_ptr
+ size
; run_ptr
<= thresh
; run_ptr
+= size
)
911 if ((*cmp
) ((void *) run_ptr
, (void *) tmp_ptr
, user_data
) < 0)
914 if (tmp_ptr
!= base_ptr
)
915 SWAP (tmp_ptr
, base_ptr
, size
);
917 /* Insertion sort, running from left-hand-side up to right-hand-side. */
919 run_ptr
= base_ptr
+ size
;
920 while ((run_ptr
+= size
) <= end_ptr
)
922 tmp_ptr
= run_ptr
- size
;
923 while ((*cmp
) ((void *) run_ptr
, (void *) tmp_ptr
, user_data
) < 0)
927 if (tmp_ptr
!= run_ptr
)
931 trav
= run_ptr
+ size
;
932 while (--trav
>= run_ptr
)
937 for (hi
= lo
= trav
; (lo
-= size
) >= tmp_ptr
; hi
= lo
)
950 // ============================================================================
951 // GUI-only functions from now on
952 // ============================================================================
956 // this function is only really implemented for X11-based ports, including GTK1
957 // (GTK2 sets detectable auto-repeat automatically anyhow)
958 #if !(defined(__WXX11__) || defined(__WXMOTIF__) || \
959 (defined(__WXGTK__) && !defined(__WXGTK20__)))
960 bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag
) )
964 #endif // !X11-based port
966 // ----------------------------------------------------------------------------
967 // Launch default browser
968 // ----------------------------------------------------------------------------
970 #if defined(__WXMSW__)
972 // implemented in a port-specific utils source file:
973 bool wxDoLaunchDefaultBrowser(const wxString
& url
, const wxString
& scheme
, int flags
);
975 #elif defined(__WXX11__) || defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || \
976 (defined(__WXOSX__) )
978 // implemented in a port-specific utils source file:
979 bool wxDoLaunchDefaultBrowser(const wxString
& url
, int flags
);
983 // a "generic" implementation:
984 bool wxDoLaunchDefaultBrowser(const wxString
& url
, int flags
)
986 // on other platforms try to use mime types or wxExecute...
992 wxFileType
*ft
= wxTheMimeTypesManager
->GetFileTypeFromExtension(wxT("html"));
996 ft
->GetMimeType(&mt
);
998 ok
= ft
->GetOpenCommand(&cmd
, wxFileType::MessageParameters(url
));
1001 #endif // wxUSE_MIMETYPE
1003 if ( !ok
|| cmd
.empty() )
1005 // fallback to checking for the BROWSER environment variable
1006 if ( !wxGetEnv(wxT("BROWSER"), &cmd
) || cmd
.empty() )
1007 cmd
<< wxT(' ') << url
;
1010 ok
= ( !cmd
.empty() && wxExecute(cmd
) );
1014 // no file type for HTML extension
1015 wxLogError(_("No default application configured for HTML files."));
1021 static bool DoLaunchDefaultBrowserHelper(const wxString
& urlOrig
, int flags
)
1023 // NOTE: we don't have to care about the wxBROWSER_NOBUSYCURSOR flag
1024 // as it was already handled by wxLaunchDefaultBrowser
1028 wxString
url(urlOrig
), scheme
;
1031 // this check is useful to avoid that wxURI recognizes as scheme parts of
1032 // the filename, in case urlOrig is a local filename
1033 // (e.g. "C:\\test.txt" when parsed by wxURI reports a scheme == "C")
1034 bool hasValidScheme
= uri
.HasScheme() && uri
.GetScheme().length() > 1;
1036 #if defined(__WXMSW__)
1038 // NOTE: when testing wxMSW's wxLaunchDefaultBrowser all possible forms
1039 // of the URL/flags should be tested; e.g.:
1041 // for (int i=0; i<2; i++)
1043 // // test arguments without a valid URL scheme:
1044 // wxLaunchDefaultBrowser("C:\\test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1045 // wxLaunchDefaultBrowser("wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1047 // // test arguments with different valid schemes:
1048 // wxLaunchDefaultBrowser("file:/C%3A/test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1049 // wxLaunchDefaultBrowser("http://wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1050 // wxLaunchDefaultBrowser("mailto:user@host.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1052 // (assuming you have a C:\test.txt file)
1054 if ( !hasValidScheme
)
1056 if (wxFileExists(urlOrig
) || wxDirExists(urlOrig
))
1059 // do not prepend the file scheme to the URL as ShellExecuteEx() doesn't like it
1063 url
.Prepend(wxS("http://"));
1067 else if ( hasValidScheme
)
1069 scheme
= uri
.GetScheme();
1071 if ( uri
.GetScheme() == "file" )
1073 // TODO: extract URLToFileName() to some always compiled in
1075 #if wxUSE_FILESYSTEM
1076 // ShellExecuteEx() doesn't like the "file" scheme when opening local files;
1078 url
= wxFileSystem::URLToFileName(url
).GetFullPath();
1079 #endif // wxUSE_FILESYSTEM
1083 if (wxDoLaunchDefaultBrowser(url
, scheme
, flags
))
1085 //else: call wxLogSysError
1087 if ( !hasValidScheme
)
1089 // set the scheme of url to "http" or "file" if it does not have one
1090 if (wxFileExists(urlOrig
) || wxDirExists(urlOrig
))
1091 url
.Prepend(wxS("file://"));
1093 url
.Prepend(wxS("http://"));
1096 if (wxDoLaunchDefaultBrowser(url
, flags
))
1098 //else: call wxLogSysError
1101 wxLogSysError(_("Failed to open URL \"%s\" in default browser."),
1107 bool wxLaunchDefaultBrowser(const wxString
& url
, int flags
)
1109 // NOTE: as documented, "url" may be both a real well-formed URL
1110 // and a local file name
1112 if ( flags
& wxBROWSER_NOBUSYCURSOR
)
1113 return DoLaunchDefaultBrowserHelper(url
, flags
);
1116 return DoLaunchDefaultBrowserHelper(url
, flags
);
1119 // ----------------------------------------------------------------------------
1120 // Menu accelerators related functions
1121 // ----------------------------------------------------------------------------
1123 #if WXWIN_COMPATIBILITY_2_6
1124 wxChar
*wxStripMenuCodes(const wxChar
*in
, wxChar
*out
)
1127 wxString s
= wxMenuItem::GetLabelText(in
);
1130 wxString s
= wxStripMenuCodes(str
);
1131 #endif // wxUSE_MENUS
1134 // go smash their buffer if it's not big enough - I love char * params
1135 memcpy(out
, s
.c_str(), s
.length() * sizeof(wxChar
));
1139 out
= new wxChar
[s
.length() + 1];
1140 wxStrcpy(out
, s
.c_str());
1147 wxString
wxStripMenuCodes(const wxString
& in
, int flags
)
1149 wxASSERT_MSG( flags
, wxT("this is useless to call without any flags") );
1153 size_t len
= in
.length();
1156 for ( size_t n
= 0; n
< len
; n
++ )
1159 if ( (flags
& wxStrip_Mnemonics
) && ch
== wxT('&') )
1161 // skip it, it is used to introduce the accel char (or to quote
1162 // itself in which case it should still be skipped): note that it
1163 // can't be the last character of the string
1166 wxLogDebug(wxT("Invalid menu string '%s'"), in
.c_str());
1170 // use the next char instead
1174 else if ( (flags
& wxStrip_Accel
) && ch
== wxT('\t') )
1176 // everything after TAB is accel string, exit the loop
1186 // ----------------------------------------------------------------------------
1187 // Window search functions
1188 // ----------------------------------------------------------------------------
1191 * If parent is non-NULL, look through children for a label or title
1192 * matching the specified string. If NULL, look through all top-level windows.
1197 wxFindWindowByLabel (const wxString
& title
, wxWindow
* parent
)
1199 return wxWindow::FindWindowByLabel( title
, parent
);
1204 * If parent is non-NULL, look through children for a name
1205 * matching the specified string. If NULL, look through all top-level windows.
1210 wxFindWindowByName (const wxString
& name
, wxWindow
* parent
)
1212 return wxWindow::FindWindowByName( name
, parent
);
1215 // Returns menu item id or wxNOT_FOUND if none.
1217 wxFindMenuItemId(wxFrame
*frame
,
1218 const wxString
& menuString
,
1219 const wxString
& itemString
)
1222 wxMenuBar
*menuBar
= frame
->GetMenuBar ();
1224 return menuBar
->FindMenuItem (menuString
, itemString
);
1225 #else // !wxUSE_MENUS
1227 wxUnusedVar(menuString
);
1228 wxUnusedVar(itemString
);
1229 #endif // wxUSE_MENUS/!wxUSE_MENUS
1234 // Try to find the deepest child that contains 'pt'.
1235 // We go backwards, to try to allow for controls that are spacially
1236 // within other controls, but are still siblings (e.g. buttons within
1237 // static boxes). Static boxes are likely to be created _before_ controls
1238 // that sit inside them.
1239 wxWindow
* wxFindWindowAtPoint(wxWindow
* win
, const wxPoint
& pt
)
1241 if (!win
->IsShown())
1244 // Hack for wxNotebook case: at least in wxGTK, all pages
1245 // claim to be shown, so we must only deal with the selected one.
1247 if (win
->IsKindOf(CLASSINFO(wxNotebook
)))
1249 wxNotebook
* nb
= (wxNotebook
*) win
;
1250 int sel
= nb
->GetSelection();
1253 wxWindow
* child
= nb
->GetPage(sel
);
1254 wxWindow
* foundWin
= wxFindWindowAtPoint(child
, pt
);
1261 wxWindowList::compatibility_iterator node
= win
->GetChildren().GetLast();
1264 wxWindow
* child
= node
->GetData();
1265 wxWindow
* foundWin
= wxFindWindowAtPoint(child
, pt
);
1268 node
= node
->GetPrevious();
1271 wxPoint pos
= win
->GetPosition();
1272 wxSize sz
= win
->GetSize();
1273 if ( !win
->IsTopLevel() && win
->GetParent() )
1275 pos
= win
->GetParent()->ClientToScreen(pos
);
1278 wxRect
rect(pos
, sz
);
1279 if (rect
.Contains(pt
))
1285 wxWindow
* wxGenericFindWindowAtPoint(const wxPoint
& pt
)
1287 // Go backwards through the list since windows
1288 // on top are likely to have been appended most
1290 wxWindowList::compatibility_iterator node
= wxTopLevelWindows
.GetLast();
1293 wxWindow
* win
= node
->GetData();
1294 wxWindow
* found
= wxFindWindowAtPoint(win
, pt
);
1297 node
= node
->GetPrevious();
1302 // ----------------------------------------------------------------------------
1304 // ----------------------------------------------------------------------------
1307 * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
1308 * since otherwise the generic code may be pulled in unnecessarily.
1313 int wxMessageBox(const wxString
& message
, const wxString
& caption
, long style
,
1314 wxWindow
*parent
, int WXUNUSED(x
), int WXUNUSED(y
) )
1316 // add the appropriate icon unless this was explicitly disabled by use of
1318 if ( !(style
& wxICON_NONE
) && !(style
& wxICON_MASK
) )
1320 style
|= style
& wxYES
? wxICON_QUESTION
: wxICON_INFORMATION
;
1323 wxMessageDialog
dialog(parent
, message
, caption
, style
);
1325 int ans
= dialog
.ShowModal();
1338 wxFAIL_MSG( wxT("unexpected return code from wxMessageDialog") );
1343 void wxInfoMessageBox(wxWindow
* parent
)
1345 // don't translate these strings, they're for diagnostics purposes only
1347 msg
.Printf(wxS("wxWidgets Library (%s port)\n")
1348 wxS("Version %d.%d.%d (Unicode: %s, debug level: %d),\n")
1349 wxS("compiled at %s %s\n\n")
1350 wxS("Runtime version of toolkit used is %d.%d.\n"),
1351 wxPlatformInfo::Get().GetPortIdName(),
1355 #if wxUSE_UNICODE_UTF8
1365 wxPlatformInfo::Get().GetToolkitMajorVersion(),
1366 wxPlatformInfo::Get().GetToolkitMinorVersion()
1370 msg
+= wxString::Format("Compile-time GTK+ version is %d.%d.%d.\n",
1376 msg
+= wxS("\nCopyright (c) 1995-2010 wxWidgets team");
1378 wxMessageBox(msg
, wxT("wxWidgets information"),
1379 wxICON_INFORMATION
| wxOK
,
1383 #endif // wxUSE_MSGDLG
1387 wxString
wxGetTextFromUser(const wxString
& message
, const wxString
& caption
,
1388 const wxString
& defaultValue
, wxWindow
*parent
,
1389 wxCoord x
, wxCoord y
, bool centre
)
1392 long style
= wxTextEntryDialogStyle
;
1399 wxTextEntryDialog
dialog(parent
, message
, caption
, defaultValue
, style
, wxPoint(x
, y
));
1401 if (dialog
.ShowModal() == wxID_OK
)
1403 str
= dialog
.GetValue();
1409 wxString
wxGetPasswordFromUser(const wxString
& message
,
1410 const wxString
& caption
,
1411 const wxString
& defaultValue
,
1413 wxCoord x
, wxCoord y
, bool centre
)
1416 long style
= wxTextEntryDialogStyle
;
1423 wxPasswordEntryDialog
dialog(parent
, message
, caption
, defaultValue
,
1424 style
, wxPoint(x
, y
));
1425 if ( dialog
.ShowModal() == wxID_OK
)
1427 str
= dialog
.GetValue();
1433 #endif // wxUSE_TEXTDLG
1437 wxColour
wxGetColourFromUser(wxWindow
*parent
,
1438 const wxColour
& colInit
,
1439 const wxString
& caption
,
1440 wxColourData
*ptrData
)
1442 // contains serialized representation of wxColourData used the last time
1443 // the dialog was shown: we want to reuse it the next time in order to show
1444 // the same custom colours to the user (and we can't just have static
1445 // wxColourData itself because it's a GUI object and so should be destroyed
1446 // before GUI shutdown and doing it during static cleanup is too late)
1447 static wxString s_strColourData
;
1453 if ( !s_strColourData
.empty() )
1455 if ( !data
.FromString(s_strColourData
) )
1457 wxFAIL_MSG( "bug in wxColourData::FromString()?" );
1461 // we don't get back the "choose full" flag value from the native
1462 // dialog and so we can't preserve it between runs, so we decide to
1463 // always use it as it seems better than not using it (user can
1464 // just ignore the extra controls in the dialog but having to click
1465 // a button each time to show them would be very annoying
1466 data
.SetChooseFull(true);
1471 if ( colInit
.IsOk() )
1473 ptrData
->SetColour(colInit
);
1477 wxColourDialog
dialog(parent
, ptrData
);
1478 if (!caption
.empty())
1479 dialog
.SetTitle(caption
);
1480 if ( dialog
.ShowModal() == wxID_OK
)
1482 *ptrData
= dialog
.GetColourData();
1483 colRet
= ptrData
->GetColour();
1484 s_strColourData
= ptrData
->ToString();
1486 //else: leave colRet invalid
1491 #endif // wxUSE_COLOURDLG
1495 wxFont
wxGetFontFromUser(wxWindow
*parent
, const wxFont
& fontInit
, const wxString
& caption
)
1498 if ( fontInit
.Ok() )
1500 data
.SetInitialFont(fontInit
);
1504 wxFontDialog
dialog(parent
, data
);
1505 if (!caption
.empty())
1506 dialog
.SetTitle(caption
);
1507 if ( dialog
.ShowModal() == wxID_OK
)
1509 fontRet
= dialog
.GetFontData().GetChosenFont();
1511 //else: leave it invalid
1516 #endif // wxUSE_FONTDLG
1518 // ----------------------------------------------------------------------------
1519 // wxSafeYield and supporting functions
1520 // ----------------------------------------------------------------------------
1522 void wxEnableTopLevelWindows(bool enable
)
1524 wxWindowList::compatibility_iterator node
;
1525 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1526 node
->GetData()->Enable(enable
);
1529 wxWindowDisabler::wxWindowDisabler(bool disable
)
1531 m_disabled
= disable
;
1536 wxWindowDisabler::wxWindowDisabler(wxWindow
*winToSkip
)
1539 DoDisable(winToSkip
);
1542 void wxWindowDisabler::DoDisable(wxWindow
*winToSkip
)
1544 // remember the top level windows which were already disabled, so that we
1545 // don't reenable them later
1546 m_winDisabled
= NULL
;
1548 wxWindowList::compatibility_iterator node
;
1549 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1551 wxWindow
*winTop
= node
->GetData();
1552 if ( winTop
== winToSkip
)
1555 // we don't need to disable the hidden or already disabled windows
1556 if ( winTop
->IsEnabled() && winTop
->IsShown() )
1562 if ( !m_winDisabled
)
1564 m_winDisabled
= new wxWindowList
;
1567 m_winDisabled
->Append(winTop
);
1572 wxWindowDisabler::~wxWindowDisabler()
1577 wxWindowList::compatibility_iterator node
;
1578 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1580 wxWindow
*winTop
= node
->GetData();
1581 if ( !m_winDisabled
|| !m_winDisabled
->Find(winTop
) )
1585 //else: had been already disabled, don't reenable
1588 delete m_winDisabled
;
1591 // Yield to other apps/messages and disable user input to all windows except
1593 bool wxSafeYield(wxWindow
*win
, bool onlyIfNeeded
)
1595 wxWindowDisabler
wd(win
);
1599 rc
= wxYieldIfNeeded();
1606 // ----------------------------------------------------------------------------
1607 // wxApp::Yield() wrappers for backwards compatibility
1608 // ----------------------------------------------------------------------------
1612 return wxTheApp
&& wxTheApp
->Yield();
1615 bool wxYieldIfNeeded()
1617 return wxTheApp
&& wxTheApp
->Yield(true);