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 // ----------------------------------------------------------------------------
551 #include <crt_externs.h>
554 bool wxGetEnvMap(wxEnvVariableHashMap
*map
)
556 wxCHECK_MSG( map
, false, wxS("output pointer can't be NULL") );
558 #if defined(__VISUALC__)
559 wxChar
**env
= _tenviron
;
561 // Now this routine wil give false for OpenVMS
562 // TODO : should we do something with logicals?
564 #elif defined(__WXOSX__)
565 // Under Mac shared libraries don't have access to the global environ
566 // variable so use this Mac-specific function instead as advised by
567 // environ(7) under Darwin
568 char ***penv
= _NSGetEnviron();
572 #else // non-MSVC non-Mac
573 // Not sure if other compilers have _tenviron so use the (more standard)
574 // ANSI version only for them.
575 char **env
= environ
;
584 const wxString
var(*env
);
586 name
= var
.BeforeFirst(wxS('='), &value
);
588 (*map
)[name
] = value
;
599 // ----------------------------------------------------------------------------
601 // ----------------------------------------------------------------------------
603 // wxDoExecuteWithCapture() helper: reads an entire stream into one array
605 // returns true if ok, false if error
607 static bool ReadAll(wxInputStream
*is
, wxArrayString
& output
)
609 wxCHECK_MSG( is
, false, wxT("NULL stream in wxExecute()?") );
611 // the stream could be already at EOF or in wxSTREAM_BROKEN_PIPE state
614 wxTextInputStream
tis(*is
);
618 wxString line
= tis
.ReadLine();
620 // check for EOF before other errors as it's not really an error
623 // add the last, possibly incomplete, line
629 // any other error is fatal
638 #endif // wxUSE_STREAMS
640 // this is a private function because it hasn't a clean interface: the first
641 // array is passed by reference, the second by pointer - instead we have 2
642 // public versions of wxExecute() below
643 static long wxDoExecuteWithCapture(const wxString
& command
,
644 wxArrayString
& output
,
645 wxArrayString
* error
,
647 const wxExecuteEnv
*env
)
649 // create a wxProcess which will capture the output
650 wxProcess
*process
= new wxProcess
;
653 long rc
= wxExecute(command
, wxEXEC_SYNC
| flags
, process
, env
);
658 if ( !ReadAll(process
->GetInputStream(), output
) )
663 if ( !ReadAll(process
->GetErrorStream(), *error
) )
671 #endif // wxUSE_STREAMS/!wxUSE_STREAMS
678 long wxExecute(const wxString
& command
, wxArrayString
& output
, int flags
,
679 const wxExecuteEnv
*env
)
681 return wxDoExecuteWithCapture(command
, output
, NULL
, flags
, env
);
684 long wxExecute(const wxString
& command
,
685 wxArrayString
& output
,
686 wxArrayString
& error
,
688 const wxExecuteEnv
*env
)
690 return wxDoExecuteWithCapture(command
, output
, &error
, flags
, env
);
693 // ----------------------------------------------------------------------------
695 // ----------------------------------------------------------------------------
698 static long wxCurrentId
= 100;
702 // skip the part of IDs space that contains hard-coded values:
703 if (wxCurrentId
== wxID_LOWEST
)
704 wxCurrentId
= wxID_HIGHEST
+ 1;
706 return wxCurrentId
++;
710 wxGetCurrentId(void) { return wxCurrentId
; }
713 wxRegisterId (long id
)
715 if (id
>= wxCurrentId
)
716 wxCurrentId
= id
+ 1;
719 // ----------------------------------------------------------------------------
720 // wxQsort, adapted by RR to allow user_data
721 // ----------------------------------------------------------------------------
723 /* This file is part of the GNU C Library.
724 Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
726 Douglas Schmidt kindly gave permission to relicence the
727 code under the wxWindows licence:
729 From: "Douglas C. Schmidt" <schmidt@dre.vanderbilt.edu>
730 To: Robert Roebling <robert.roebling@uni-ulm.de>
731 Subject: Re: qsort licence
732 Date: Mon, 23 Jul 2007 03:44:25 -0500
733 Sender: schmidt@dre.vanderbilt.edu
734 Message-Id: <20070723084426.64F511000A8@tango.dre.vanderbilt.edu>
738 > [...] I'm asking if you'd be willing to relicence your code
739 > under the wxWindows licence. [...]
741 That's fine with me [...]
748 /* Byte-wise swap two items of size SIZE. */
749 #define SWAP(a, b, size) \
752 register size_t __size = (size); \
753 register char *__a = (a), *__b = (b); \
759 } while (--__size > 0); \
762 /* Discontinue quicksort algorithm when partition gets below this size.
763 This particular magic number was chosen to work best on a Sun 4/260. */
766 /* Stack node declarations used to store unfulfilled partition obligations. */
773 /* The next 4 #defines implement a very fast in-line stack abstraction. */
774 #define STACK_SIZE (8 * sizeof(unsigned long int))
775 #define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
776 #define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
777 #define STACK_NOT_EMPTY (stack < top)
780 /* Order size using quicksort. This implementation incorporates
781 four optimizations discussed in Sedgewick:
783 1. Non-recursive, using an explicit stack of pointer that store the
784 next array partition to sort. To save time, this maximum amount
785 of space required to store an array of MAX_INT is allocated on the
786 stack. Assuming a 32-bit integer, this needs only 32 *
787 sizeof(stack_node) == 136 bits. Pretty cheap, actually.
789 2. Chose the pivot element using a median-of-three decision tree.
790 This reduces the probability of selecting a bad pivot value and
791 eliminates certain extraneous comparisons.
793 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
794 insertion sort to order the MAX_THRESH items within each partition.
795 This is a big win, since insertion sort is faster for small, mostly
796 sorted array segments.
798 4. The larger of the two sub-partitions is always pushed onto the
799 stack first, with the algorithm then concentrating on the
800 smaller partition. This *guarantees* no more than log (n)
801 stack size is needed (actually O(1) in this case)! */
803 void wxQsort(void *const pbase
, size_t total_elems
,
804 size_t size
, CMPFUNCDATA cmp
, const void* user_data
)
806 register char *base_ptr
= (char *) pbase
;
807 const size_t max_thresh
= MAX_THRESH
* size
;
809 if (total_elems
== 0)
810 /* Avoid lossage with unsigned arithmetic below. */
813 if (total_elems
> MAX_THRESH
)
816 char *hi
= &lo
[size
* (total_elems
- 1)];
817 stack_node stack
[STACK_SIZE
];
818 stack_node
*top
= stack
;
822 while (STACK_NOT_EMPTY
)
827 /* Select median value from among LO, MID, and HI. Rearrange
828 LO and HI so the three values are sorted. This lowers the
829 probability of picking a pathological pivot value and
830 skips a comparison for both the LEFT_PTR and RIGHT_PTR. */
832 char *mid
= lo
+ size
* ((hi
- lo
) / size
>> 1);
834 if ((*cmp
) ((void *) mid
, (void *) lo
, user_data
) < 0)
835 SWAP (mid
, lo
, size
);
836 if ((*cmp
) ((void *) hi
, (void *) mid
, user_data
) < 0)
837 SWAP (mid
, hi
, size
);
840 if ((*cmp
) ((void *) mid
, (void *) lo
, user_data
) < 0)
841 SWAP (mid
, lo
, size
);
843 left_ptr
= lo
+ size
;
844 right_ptr
= hi
- size
;
846 /* Here's the famous ``collapse the walls'' section of quicksort.
847 Gotta like those tight inner loops! They are the main reason
848 that this algorithm runs much faster than others. */
851 while ((*cmp
) ((void *) left_ptr
, (void *) mid
, user_data
) < 0)
854 while ((*cmp
) ((void *) mid
, (void *) right_ptr
, user_data
) < 0)
857 if (left_ptr
< right_ptr
)
859 SWAP (left_ptr
, right_ptr
, size
);
862 else if (mid
== right_ptr
)
867 else if (left_ptr
== right_ptr
)
874 while (left_ptr
<= right_ptr
);
876 /* Set up pointers for next iteration. First determine whether
877 left and right partitions are below the threshold size. If so,
878 ignore one or both. Otherwise, push the larger partition's
879 bounds on the stack and continue sorting the smaller one. */
881 if ((size_t) (right_ptr
- lo
) <= max_thresh
)
883 if ((size_t) (hi
- left_ptr
) <= max_thresh
)
884 /* Ignore both small partitions. */
887 /* Ignore small left partition. */
890 else if ((size_t) (hi
- left_ptr
) <= max_thresh
)
891 /* Ignore small right partition. */
893 else if ((right_ptr
- lo
) > (hi
- left_ptr
))
895 /* Push larger left partition indices. */
896 PUSH (lo
, right_ptr
);
901 /* Push larger right partition indices. */
908 /* Once the BASE_PTR array is partially sorted by quicksort the rest
909 is completely sorted using insertion sort, since this is efficient
910 for partitions below MAX_THRESH size. BASE_PTR points to the beginning
911 of the array to sort, and END_PTR points at the very last element in
912 the array (*not* one beyond it!). */
915 char *const end_ptr
= &base_ptr
[size
* (total_elems
- 1)];
916 char *tmp_ptr
= base_ptr
;
917 char *thresh
= base_ptr
+ max_thresh
;
918 if ( thresh
> end_ptr
)
920 register char *run_ptr
;
922 /* Find smallest element in first threshold and place it at the
923 array's beginning. This is the smallest array element,
924 and the operation speeds up insertion sort's inner loop. */
926 for (run_ptr
= tmp_ptr
+ size
; run_ptr
<= thresh
; run_ptr
+= size
)
927 if ((*cmp
) ((void *) run_ptr
, (void *) tmp_ptr
, user_data
) < 0)
930 if (tmp_ptr
!= base_ptr
)
931 SWAP (tmp_ptr
, base_ptr
, size
);
933 /* Insertion sort, running from left-hand-side up to right-hand-side. */
935 run_ptr
= base_ptr
+ size
;
936 while ((run_ptr
+= size
) <= end_ptr
)
938 tmp_ptr
= run_ptr
- size
;
939 while ((*cmp
) ((void *) run_ptr
, (void *) tmp_ptr
, user_data
) < 0)
943 if (tmp_ptr
!= run_ptr
)
947 trav
= run_ptr
+ size
;
948 while (--trav
>= run_ptr
)
953 for (hi
= lo
= trav
; (lo
-= size
) >= tmp_ptr
; hi
= lo
)
966 // ============================================================================
967 // GUI-only functions from now on
968 // ============================================================================
972 // this function is only really implemented for X11-based ports, including GTK1
973 // (GTK2 sets detectable auto-repeat automatically anyhow)
974 #if !(defined(__WXX11__) || defined(__WXMOTIF__) || \
975 (defined(__WXGTK__) && !defined(__WXGTK20__)))
976 bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag
) )
980 #endif // !X11-based port
982 // ----------------------------------------------------------------------------
983 // Launch default browser
984 // ----------------------------------------------------------------------------
986 #if defined(__WXMSW__)
988 // implemented in a port-specific utils source file:
989 bool wxDoLaunchDefaultBrowser(const wxString
& url
, const wxString
& scheme
, int flags
);
991 #elif defined(__WXX11__) || defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || \
992 (defined(__WXOSX__) )
994 // implemented in a port-specific utils source file:
995 bool wxDoLaunchDefaultBrowser(const wxString
& url
, int flags
);
999 // a "generic" implementation:
1000 bool wxDoLaunchDefaultBrowser(const wxString
& url
, int flags
)
1002 // on other platforms try to use mime types or wxExecute...
1008 wxFileType
*ft
= wxTheMimeTypesManager
->GetFileTypeFromExtension(wxT("html"));
1012 ft
->GetMimeType(&mt
);
1014 ok
= ft
->GetOpenCommand(&cmd
, wxFileType::MessageParameters(url
));
1017 #endif // wxUSE_MIMETYPE
1019 if ( !ok
|| cmd
.empty() )
1021 // fallback to checking for the BROWSER environment variable
1022 if ( !wxGetEnv(wxT("BROWSER"), &cmd
) || cmd
.empty() )
1023 cmd
<< wxT(' ') << url
;
1026 ok
= ( !cmd
.empty() && wxExecute(cmd
) );
1030 // no file type for HTML extension
1031 wxLogError(_("No default application configured for HTML files."));
1037 static bool DoLaunchDefaultBrowserHelper(const wxString
& urlOrig
, int flags
)
1039 // NOTE: we don't have to care about the wxBROWSER_NOBUSYCURSOR flag
1040 // as it was already handled by wxLaunchDefaultBrowser
1044 wxString
url(urlOrig
), scheme
;
1047 // this check is useful to avoid that wxURI recognizes as scheme parts of
1048 // the filename, in case urlOrig is a local filename
1049 // (e.g. "C:\\test.txt" when parsed by wxURI reports a scheme == "C")
1050 bool hasValidScheme
= uri
.HasScheme() && uri
.GetScheme().length() > 1;
1052 #if defined(__WXMSW__)
1054 // NOTE: when testing wxMSW's wxLaunchDefaultBrowser all possible forms
1055 // of the URL/flags should be tested; e.g.:
1057 // for (int i=0; i<2; i++)
1059 // // test arguments without a valid URL scheme:
1060 // wxLaunchDefaultBrowser("C:\\test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1061 // wxLaunchDefaultBrowser("wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1063 // // test arguments with different valid schemes:
1064 // wxLaunchDefaultBrowser("file:/C%3A/test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1065 // wxLaunchDefaultBrowser("http://wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1066 // wxLaunchDefaultBrowser("mailto:user@host.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1068 // (assuming you have a C:\test.txt file)
1070 if ( !hasValidScheme
)
1072 if (wxFileExists(urlOrig
) || wxDirExists(urlOrig
))
1075 // do not prepend the file scheme to the URL as ShellExecuteEx() doesn't like it
1079 url
.Prepend(wxS("http://"));
1083 else if ( hasValidScheme
)
1085 scheme
= uri
.GetScheme();
1087 if ( uri
.GetScheme() == "file" )
1089 // TODO: extract URLToFileName() to some always compiled in
1091 #if wxUSE_FILESYSTEM
1092 // ShellExecuteEx() doesn't like the "file" scheme when opening local files;
1094 url
= wxFileSystem::URLToFileName(url
).GetFullPath();
1095 #endif // wxUSE_FILESYSTEM
1099 if (wxDoLaunchDefaultBrowser(url
, scheme
, flags
))
1101 //else: call wxLogSysError
1103 if ( !hasValidScheme
)
1105 // set the scheme of url to "http" or "file" if it does not have one
1106 if (wxFileExists(urlOrig
) || wxDirExists(urlOrig
))
1107 url
.Prepend(wxS("file://"));
1109 url
.Prepend(wxS("http://"));
1112 if (wxDoLaunchDefaultBrowser(url
, flags
))
1114 //else: call wxLogSysError
1117 wxLogSysError(_("Failed to open URL \"%s\" in default browser."),
1123 bool wxLaunchDefaultBrowser(const wxString
& url
, int flags
)
1125 // NOTE: as documented, "url" may be both a real well-formed URL
1126 // and a local file name
1128 if ( flags
& wxBROWSER_NOBUSYCURSOR
)
1129 return DoLaunchDefaultBrowserHelper(url
, flags
);
1132 return DoLaunchDefaultBrowserHelper(url
, flags
);
1135 // ----------------------------------------------------------------------------
1136 // Menu accelerators related functions
1137 // ----------------------------------------------------------------------------
1139 #if WXWIN_COMPATIBILITY_2_6
1140 wxChar
*wxStripMenuCodes(const wxChar
*in
, wxChar
*out
)
1143 wxString s
= wxMenuItem::GetLabelText(in
);
1146 wxString s
= wxStripMenuCodes(str
);
1147 #endif // wxUSE_MENUS
1150 // go smash their buffer if it's not big enough - I love char * params
1151 memcpy(out
, s
.c_str(), s
.length() * sizeof(wxChar
));
1155 out
= new wxChar
[s
.length() + 1];
1156 wxStrcpy(out
, s
.c_str());
1163 wxString
wxStripMenuCodes(const wxString
& in
, int flags
)
1165 wxASSERT_MSG( flags
, wxT("this is useless to call without any flags") );
1169 size_t len
= in
.length();
1172 for ( size_t n
= 0; n
< len
; n
++ )
1175 if ( (flags
& wxStrip_Mnemonics
) && ch
== wxT('&') )
1177 // skip it, it is used to introduce the accel char (or to quote
1178 // itself in which case it should still be skipped): note that it
1179 // can't be the last character of the string
1182 wxLogDebug(wxT("Invalid menu string '%s'"), in
.c_str());
1186 // use the next char instead
1190 else if ( (flags
& wxStrip_Accel
) && ch
== wxT('\t') )
1192 // everything after TAB is accel string, exit the loop
1202 // ----------------------------------------------------------------------------
1203 // Window search functions
1204 // ----------------------------------------------------------------------------
1207 * If parent is non-NULL, look through children for a label or title
1208 * matching the specified string. If NULL, look through all top-level windows.
1213 wxFindWindowByLabel (const wxString
& title
, wxWindow
* parent
)
1215 return wxWindow::FindWindowByLabel( title
, parent
);
1220 * If parent is non-NULL, look through children for a name
1221 * matching the specified string. If NULL, look through all top-level windows.
1226 wxFindWindowByName (const wxString
& name
, wxWindow
* parent
)
1228 return wxWindow::FindWindowByName( name
, parent
);
1231 // Returns menu item id or wxNOT_FOUND if none.
1233 wxFindMenuItemId(wxFrame
*frame
,
1234 const wxString
& menuString
,
1235 const wxString
& itemString
)
1238 wxMenuBar
*menuBar
= frame
->GetMenuBar ();
1240 return menuBar
->FindMenuItem (menuString
, itemString
);
1241 #else // !wxUSE_MENUS
1243 wxUnusedVar(menuString
);
1244 wxUnusedVar(itemString
);
1245 #endif // wxUSE_MENUS/!wxUSE_MENUS
1250 // Try to find the deepest child that contains 'pt'.
1251 // We go backwards, to try to allow for controls that are spacially
1252 // within other controls, but are still siblings (e.g. buttons within
1253 // static boxes). Static boxes are likely to be created _before_ controls
1254 // that sit inside them.
1255 wxWindow
* wxFindWindowAtPoint(wxWindow
* win
, const wxPoint
& pt
)
1257 if (!win
->IsShown())
1260 // Hack for wxNotebook case: at least in wxGTK, all pages
1261 // claim to be shown, so we must only deal with the selected one.
1263 if (win
->IsKindOf(CLASSINFO(wxNotebook
)))
1265 wxNotebook
* nb
= (wxNotebook
*) win
;
1266 int sel
= nb
->GetSelection();
1269 wxWindow
* child
= nb
->GetPage(sel
);
1270 wxWindow
* foundWin
= wxFindWindowAtPoint(child
, pt
);
1277 wxWindowList::compatibility_iterator node
= win
->GetChildren().GetLast();
1280 wxWindow
* child
= node
->GetData();
1281 wxWindow
* foundWin
= wxFindWindowAtPoint(child
, pt
);
1284 node
= node
->GetPrevious();
1287 wxPoint pos
= win
->GetPosition();
1288 wxSize sz
= win
->GetSize();
1289 if ( !win
->IsTopLevel() && win
->GetParent() )
1291 pos
= win
->GetParent()->ClientToScreen(pos
);
1294 wxRect
rect(pos
, sz
);
1295 if (rect
.Contains(pt
))
1301 wxWindow
* wxGenericFindWindowAtPoint(const wxPoint
& pt
)
1303 // Go backwards through the list since windows
1304 // on top are likely to have been appended most
1306 wxWindowList::compatibility_iterator node
= wxTopLevelWindows
.GetLast();
1309 wxWindow
* win
= node
->GetData();
1310 wxWindow
* found
= wxFindWindowAtPoint(win
, pt
);
1313 node
= node
->GetPrevious();
1318 // ----------------------------------------------------------------------------
1320 // ----------------------------------------------------------------------------
1323 * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
1324 * since otherwise the generic code may be pulled in unnecessarily.
1329 int wxMessageBox(const wxString
& message
, const wxString
& caption
, long style
,
1330 wxWindow
*parent
, int WXUNUSED(x
), int WXUNUSED(y
) )
1332 // add the appropriate icon unless this was explicitly disabled by use of
1334 if ( !(style
& wxICON_NONE
) && !(style
& wxICON_MASK
) )
1336 style
|= style
& wxYES
? wxICON_QUESTION
: wxICON_INFORMATION
;
1339 wxMessageDialog
dialog(parent
, message
, caption
, style
);
1341 int ans
= dialog
.ShowModal();
1354 wxFAIL_MSG( wxT("unexpected return code from wxMessageDialog") );
1359 void wxInfoMessageBox(wxWindow
* parent
)
1361 // don't translate these strings, they're for diagnostics purposes only
1363 msg
.Printf(wxS("wxWidgets Library (%s port)\n")
1364 wxS("Version %d.%d.%d (Unicode: %s, debug level: %d),\n")
1365 wxS("compiled at %s %s\n\n")
1366 wxS("Runtime version of toolkit used is %d.%d.\n"),
1367 wxPlatformInfo::Get().GetPortIdName(),
1371 #if wxUSE_UNICODE_UTF8
1381 wxPlatformInfo::Get().GetToolkitMajorVersion(),
1382 wxPlatformInfo::Get().GetToolkitMinorVersion()
1386 msg
+= wxString::Format("Compile-time GTK+ version is %d.%d.%d.\n",
1392 msg
+= wxS("\nCopyright (c) 1995-2010 wxWidgets team");
1394 wxMessageBox(msg
, wxT("wxWidgets information"),
1395 wxICON_INFORMATION
| wxOK
,
1399 #endif // wxUSE_MSGDLG
1403 wxString
wxGetTextFromUser(const wxString
& message
, const wxString
& caption
,
1404 const wxString
& defaultValue
, wxWindow
*parent
,
1405 wxCoord x
, wxCoord y
, bool centre
)
1408 long style
= wxTextEntryDialogStyle
;
1415 wxTextEntryDialog
dialog(parent
, message
, caption
, defaultValue
, style
, wxPoint(x
, y
));
1417 if (dialog
.ShowModal() == wxID_OK
)
1419 str
= dialog
.GetValue();
1425 wxString
wxGetPasswordFromUser(const wxString
& message
,
1426 const wxString
& caption
,
1427 const wxString
& defaultValue
,
1429 wxCoord x
, wxCoord y
, bool centre
)
1432 long style
= wxTextEntryDialogStyle
;
1439 wxPasswordEntryDialog
dialog(parent
, message
, caption
, defaultValue
,
1440 style
, wxPoint(x
, y
));
1441 if ( dialog
.ShowModal() == wxID_OK
)
1443 str
= dialog
.GetValue();
1449 #endif // wxUSE_TEXTDLG
1453 wxColour
wxGetColourFromUser(wxWindow
*parent
,
1454 const wxColour
& colInit
,
1455 const wxString
& caption
,
1456 wxColourData
*ptrData
)
1458 // contains serialized representation of wxColourData used the last time
1459 // the dialog was shown: we want to reuse it the next time in order to show
1460 // the same custom colours to the user (and we can't just have static
1461 // wxColourData itself because it's a GUI object and so should be destroyed
1462 // before GUI shutdown and doing it during static cleanup is too late)
1463 static wxString s_strColourData
;
1469 if ( !s_strColourData
.empty() )
1471 if ( !data
.FromString(s_strColourData
) )
1473 wxFAIL_MSG( "bug in wxColourData::FromString()?" );
1477 // we don't get back the "choose full" flag value from the native
1478 // dialog and so we can't preserve it between runs, so we decide to
1479 // always use it as it seems better than not using it (user can
1480 // just ignore the extra controls in the dialog but having to click
1481 // a button each time to show them would be very annoying
1482 data
.SetChooseFull(true);
1487 if ( colInit
.IsOk() )
1489 ptrData
->SetColour(colInit
);
1493 wxColourDialog
dialog(parent
, ptrData
);
1494 if (!caption
.empty())
1495 dialog
.SetTitle(caption
);
1496 if ( dialog
.ShowModal() == wxID_OK
)
1498 *ptrData
= dialog
.GetColourData();
1499 colRet
= ptrData
->GetColour();
1500 s_strColourData
= ptrData
->ToString();
1502 //else: leave colRet invalid
1507 #endif // wxUSE_COLOURDLG
1511 wxFont
wxGetFontFromUser(wxWindow
*parent
, const wxFont
& fontInit
, const wxString
& caption
)
1514 if ( fontInit
.Ok() )
1516 data
.SetInitialFont(fontInit
);
1520 wxFontDialog
dialog(parent
, data
);
1521 if (!caption
.empty())
1522 dialog
.SetTitle(caption
);
1523 if ( dialog
.ShowModal() == wxID_OK
)
1525 fontRet
= dialog
.GetFontData().GetChosenFont();
1527 //else: leave it invalid
1532 #endif // wxUSE_FONTDLG
1534 // ----------------------------------------------------------------------------
1535 // wxSafeYield and supporting functions
1536 // ----------------------------------------------------------------------------
1538 void wxEnableTopLevelWindows(bool enable
)
1540 wxWindowList::compatibility_iterator node
;
1541 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1542 node
->GetData()->Enable(enable
);
1545 wxWindowDisabler::wxWindowDisabler(bool disable
)
1547 m_disabled
= disable
;
1552 wxWindowDisabler::wxWindowDisabler(wxWindow
*winToSkip
)
1555 DoDisable(winToSkip
);
1558 void wxWindowDisabler::DoDisable(wxWindow
*winToSkip
)
1560 // remember the top level windows which were already disabled, so that we
1561 // don't reenable them later
1562 m_winDisabled
= NULL
;
1564 wxWindowList::compatibility_iterator node
;
1565 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1567 wxWindow
*winTop
= node
->GetData();
1568 if ( winTop
== winToSkip
)
1571 // we don't need to disable the hidden or already disabled windows
1572 if ( winTop
->IsEnabled() && winTop
->IsShown() )
1578 if ( !m_winDisabled
)
1580 m_winDisabled
= new wxWindowList
;
1583 m_winDisabled
->Append(winTop
);
1588 wxWindowDisabler::~wxWindowDisabler()
1593 wxWindowList::compatibility_iterator node
;
1594 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1596 wxWindow
*winTop
= node
->GetData();
1597 if ( !m_winDisabled
|| !m_winDisabled
->Find(winTop
) )
1601 //else: had been already disabled, don't reenable
1604 delete m_winDisabled
;
1607 // Yield to other apps/messages and disable user input to all windows except
1609 bool wxSafeYield(wxWindow
*win
, bool onlyIfNeeded
)
1611 wxWindowDisabler
wd(win
);
1615 rc
= wxYieldIfNeeded();
1622 // ----------------------------------------------------------------------------
1623 // wxApp::Yield() wrappers for backwards compatibility
1624 // ----------------------------------------------------------------------------
1628 return wxTheApp
&& wxTheApp
->Yield();
1631 bool wxYieldIfNeeded()
1633 return wxTheApp
&& wxTheApp
->Yield(true);