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
& buf
)
118 int firstDigit
, secondDigit
;
120 if (buf
.GetChar(0) >= wxT('A'))
121 firstDigit
= buf
.GetChar(0) - wxT('A') + 10;
123 firstDigit
= buf
.GetChar(0) - wxT('0');
125 if (buf
.GetChar(1) >= wxT('A'))
126 secondDigit
= buf
.GetChar(1) - wxT('A') + 10;
128 secondDigit
= buf
.GetChar(1) - wxT('0');
130 return (firstDigit
& 0xF) * 16 + (secondDigit
& 0xF );
133 // Convert decimal integer to 2-character hex string
134 void wxDecToHex(int dec
, wxChar
*buf
)
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
];
143 // Convert decimal integer to 2 characters
144 void wxDecToHex(int dec
, char* ch1
, char* ch2
)
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
];
152 // Convert decimal integer to 2-character hex string
153 wxString
wxDecToHex(int dec
)
156 wxDecToHex(dec
, buf
);
157 return wxString(buf
);
160 // ----------------------------------------------------------------------------
162 // ----------------------------------------------------------------------------
164 // Return the current date/time
169 wxDateTime now
= wxDateTime::Now();
172 return wxEmptyString
;
175 time_t now
= time(NULL
);
176 char *date
= ctime(&now
);
178 return wxString::FromAscii(date
);
182 #if WXWIN_COMPATIBILITY_2_8
183 void wxUsleep(unsigned long milliseconds
)
185 wxMilliSleep(milliseconds
);
189 const wxChar
*wxGetInstallPrefix()
193 if ( wxGetEnv(wxT("WXPREFIX"), &prefix
) )
194 return prefix
.c_str();
196 #ifdef wxINSTALL_PREFIX
197 return wxT(wxINSTALL_PREFIX
);
199 return wxEmptyString
;
203 wxString
wxGetDataDir()
205 wxString dir
= wxGetInstallPrefix();
206 dir
<< wxFILE_SEP_PATH
<< wxT("share") << wxFILE_SEP_PATH
<< wxT("wx");
210 bool wxIsPlatformLittleEndian()
212 // Are we little or big endian? This method is from Harbison & Steele.
216 char c
[sizeof(long)];
224 // ----------------------------------------------------------------------------
226 // ----------------------------------------------------------------------------
229 * Class to make it easier to specify platform-dependent values
232 wxArrayInt
* wxPlatform::sm_customPlatforms
= NULL
;
234 void wxPlatform::Copy(const wxPlatform
& platform
)
236 m_longValue
= platform
.m_longValue
;
237 m_doubleValue
= platform
.m_doubleValue
;
238 m_stringValue
= platform
.m_stringValue
;
241 wxPlatform
wxPlatform::If(int platform
, long value
)
244 return wxPlatform(value
);
249 wxPlatform
wxPlatform::IfNot(int platform
, long value
)
252 return wxPlatform(value
);
257 wxPlatform
& wxPlatform::ElseIf(int platform
, long value
)
264 wxPlatform
& wxPlatform::ElseIfNot(int platform
, long value
)
271 wxPlatform
wxPlatform::If(int platform
, double value
)
274 return wxPlatform(value
);
279 wxPlatform
wxPlatform::IfNot(int platform
, double value
)
282 return wxPlatform(value
);
287 wxPlatform
& wxPlatform::ElseIf(int platform
, double value
)
290 m_doubleValue
= value
;
294 wxPlatform
& wxPlatform::ElseIfNot(int platform
, double value
)
297 m_doubleValue
= value
;
301 wxPlatform
wxPlatform::If(int platform
, const wxString
& value
)
304 return wxPlatform(value
);
309 wxPlatform
wxPlatform::IfNot(int platform
, const wxString
& value
)
312 return wxPlatform(value
);
317 wxPlatform
& wxPlatform::ElseIf(int platform
, const wxString
& value
)
320 m_stringValue
= value
;
324 wxPlatform
& wxPlatform::ElseIfNot(int platform
, const wxString
& value
)
327 m_stringValue
= value
;
331 wxPlatform
& wxPlatform::Else(long value
)
337 wxPlatform
& wxPlatform::Else(double value
)
339 m_doubleValue
= value
;
343 wxPlatform
& wxPlatform::Else(const wxString
& value
)
345 m_stringValue
= value
;
349 void wxPlatform::AddPlatform(int platform
)
351 if (!sm_customPlatforms
)
352 sm_customPlatforms
= new wxArrayInt
;
353 sm_customPlatforms
->Add(platform
);
356 void wxPlatform::ClearPlatforms()
358 delete sm_customPlatforms
;
359 sm_customPlatforms
= NULL
;
362 /// Function for testing current platform
364 bool wxPlatform::Is(int platform
)
367 if (platform
== wxOS_WINDOWS
)
371 if (platform
== wxOS_WINDOWS_CE
)
377 // FIXME: wxWinPocketPC and wxWinSmartPhone are unknown symbols
379 #if defined(__WXWINCE__) && defined(__POCKETPC__)
380 if (platform
== wxWinPocketPC
)
383 #if defined(__WXWINCE__) && defined(__SMARTPHONE__)
384 if (platform
== wxWinSmartPhone
)
391 if (platform
== wxPORT_GTK
)
395 if (platform
== wxPORT_MAC
)
399 if (platform
== wxPORT_X11
)
403 if (platform
== wxOS_UNIX
)
407 if (platform
== wxPORT_MGL
)
411 if (platform
== wxOS_OS2
)
415 if (platform
== wxPORT_PM
)
419 if (platform
== wxPORT_MAC
)
423 if (sm_customPlatforms
&& sm_customPlatforms
->Index(platform
) != wxNOT_FOUND
)
429 // ----------------------------------------------------------------------------
430 // network and user id functions
431 // ----------------------------------------------------------------------------
433 // Get Full RFC822 style email address
434 bool wxGetEmailAddress(wxChar
*address
, int maxSize
)
436 wxString email
= wxGetEmailAddress();
440 wxStrlcpy(address
, email
.t_str(), maxSize
);
445 wxString
wxGetEmailAddress()
449 wxString host
= wxGetFullHostName();
452 wxString user
= wxGetUserId();
455 email
<< user
<< wxT('@') << host
;
462 wxString
wxGetUserId()
464 static const int maxLoginLen
= 256; // FIXME arbitrary number
467 bool ok
= wxGetUserId(wxStringBuffer(buf
, maxLoginLen
), maxLoginLen
);
475 wxString
wxGetUserName()
477 static const int maxUserNameLen
= 1024; // FIXME arbitrary number
480 bool ok
= wxGetUserName(wxStringBuffer(buf
, maxUserNameLen
), maxUserNameLen
);
488 wxString
wxGetHostName()
490 static const size_t hostnameSize
= 257;
493 bool ok
= wxGetHostName(wxStringBuffer(buf
, hostnameSize
), hostnameSize
);
501 wxString
wxGetFullHostName()
503 static const size_t hostnameSize
= 257;
506 bool ok
= wxGetFullHostName(wxStringBuffer(buf
, hostnameSize
), hostnameSize
);
514 wxString
wxGetHomeDir()
524 wxString
wxGetCurrentDir()
531 ok
= getcwd(dir
.GetWriteBuf(len
+ 1), len
) != NULL
;
536 if ( errno
!= ERANGE
)
538 wxLogSysError(wxT("Failed to get current directory"));
540 return wxEmptyString
;
544 // buffer was too small, retry with a larger one
556 // ----------------------------------------------------------------------------
558 // ----------------------------------------------------------------------------
560 // wxDoExecuteWithCapture() helper: reads an entire stream into one array
562 // returns true if ok, false if error
564 static bool ReadAll(wxInputStream
*is
, wxArrayString
& output
)
566 wxCHECK_MSG( is
, false, wxT("NULL stream in wxExecute()?") );
568 // the stream could be already at EOF or in wxSTREAM_BROKEN_PIPE state
571 wxTextInputStream
tis(*is
);
575 wxString line
= tis
.ReadLine();
577 // check for EOF before other errors as it's not really an error
580 // add the last, possibly incomplete, line
586 // any other error is fatal
595 #endif // wxUSE_STREAMS
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
600 static long wxDoExecuteWithCapture(const wxString
& command
,
601 wxArrayString
& output
,
602 wxArrayString
* error
,
605 // create a wxProcess which will capture the output
606 wxProcess
*process
= new wxProcess
;
609 long rc
= wxExecute(command
, wxEXEC_SYNC
| flags
, process
);
614 if ( !ReadAll(process
->GetInputStream(), output
) )
619 if ( !ReadAll(process
->GetErrorStream(), *error
) )
627 #endif // wxUSE_STREAMS/!wxUSE_STREAMS
634 long wxExecute(const wxString
& command
, wxArrayString
& output
, int flags
)
636 return wxDoExecuteWithCapture(command
, output
, NULL
, flags
);
639 long wxExecute(const wxString
& command
,
640 wxArrayString
& output
,
641 wxArrayString
& error
,
644 return wxDoExecuteWithCapture(command
, output
, &error
, flags
);
647 // ----------------------------------------------------------------------------
649 // ----------------------------------------------------------------------------
652 static long wxCurrentId
= 100;
656 // skip the part of IDs space that contains hard-coded values:
657 if (wxCurrentId
== wxID_LOWEST
)
658 wxCurrentId
= wxID_HIGHEST
+ 1;
660 return wxCurrentId
++;
664 wxGetCurrentId(void) { return wxCurrentId
; }
667 wxRegisterId (long id
)
669 if (id
>= wxCurrentId
)
670 wxCurrentId
= id
+ 1;
673 // ----------------------------------------------------------------------------
674 // wxQsort, adapted by RR to allow user_data
675 // ----------------------------------------------------------------------------
677 /* This file is part of the GNU C Library.
678 Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
680 Douglas Schmidt kindly gave permission to relicence the
681 code under the wxWindows licence:
683 From: "Douglas C. Schmidt" <schmidt@dre.vanderbilt.edu>
684 To: Robert Roebling <robert.roebling@uni-ulm.de>
685 Subject: Re: qsort licence
686 Date: Mon, 23 Jul 2007 03:44:25 -0500
687 Sender: schmidt@dre.vanderbilt.edu
688 Message-Id: <20070723084426.64F511000A8@tango.dre.vanderbilt.edu>
692 > [...] I'm asking if you'd be willing to relicence your code
693 > under the wxWindows licence. [...]
695 That's fine with me [...]
702 /* Byte-wise swap two items of size SIZE. */
703 #define SWAP(a, b, size) \
706 register size_t __size = (size); \
707 register char *__a = (a), *__b = (b); \
713 } while (--__size > 0); \
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. */
720 /* Stack node declarations used to store unfulfilled partition obligations. */
727 /* The next 4 #defines implement a very fast in-line stack abstraction. */
728 #define STACK_SIZE (8 * sizeof(unsigned long int))
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)
734 /* Order size using quicksort. This implementation incorporates
735 four optimizations discussed in Sedgewick:
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.
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.
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.
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)! */
757 void wxQsort(void *const pbase
, size_t total_elems
,
758 size_t size
, CMPFUNCDATA cmp
, const void* user_data
)
760 register char *base_ptr
= (char *) pbase
;
761 const size_t max_thresh
= MAX_THRESH
* size
;
763 if (total_elems
== 0)
764 /* Avoid lossage with unsigned arithmetic below. */
767 if (total_elems
> MAX_THRESH
)
770 char *hi
= &lo
[size
* (total_elems
- 1)];
771 stack_node stack
[STACK_SIZE
];
772 stack_node
*top
= stack
;
776 while (STACK_NOT_EMPTY
)
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. */
786 char *mid
= lo
+ size
* ((hi
- lo
) / size
>> 1);
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
);
794 if ((*cmp
) ((void *) mid
, (void *) lo
, user_data
) < 0)
795 SWAP (mid
, lo
, size
);
797 left_ptr
= lo
+ size
;
798 right_ptr
= hi
- size
;
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. */
805 while ((*cmp
) ((void *) left_ptr
, (void *) mid
, user_data
) < 0)
808 while ((*cmp
) ((void *) mid
, (void *) right_ptr
, user_data
) < 0)
811 if (left_ptr
< right_ptr
)
813 SWAP (left_ptr
, right_ptr
, size
);
816 else if (mid
== right_ptr
)
821 else if (left_ptr
== right_ptr
)
828 while (left_ptr
<= right_ptr
);
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. */
835 if ((size_t) (right_ptr
- lo
) <= max_thresh
)
837 if ((size_t) (hi
- left_ptr
) <= max_thresh
)
838 /* Ignore both small partitions. */
841 /* Ignore small left partition. */
844 else if ((size_t) (hi
- left_ptr
) <= max_thresh
)
845 /* Ignore small right partition. */
847 else if ((right_ptr
- lo
) > (hi
- left_ptr
))
849 /* Push larger left partition indices. */
850 PUSH (lo
, right_ptr
);
855 /* Push larger right partition indices. */
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!). */
869 char *const end_ptr
= &base_ptr
[size
* (total_elems
- 1)];
870 char *tmp_ptr
= base_ptr
;
871 char *thresh
= base_ptr
+ max_thresh
;
872 if ( thresh
> end_ptr
)
874 register char *run_ptr
;
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. */
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)
884 if (tmp_ptr
!= base_ptr
)
885 SWAP (tmp_ptr
, base_ptr
, size
);
887 /* Insertion sort, running from left-hand-side up to right-hand-side. */
889 run_ptr
= base_ptr
+ size
;
890 while ((run_ptr
+= size
) <= end_ptr
)
892 tmp_ptr
= run_ptr
- size
;
893 while ((*cmp
) ((void *) run_ptr
, (void *) tmp_ptr
, user_data
) < 0)
897 if (tmp_ptr
!= run_ptr
)
901 trav
= run_ptr
+ size
;
902 while (--trav
>= run_ptr
)
907 for (hi
= lo
= trav
; (lo
-= size
) >= tmp_ptr
; hi
= lo
)
920 // ============================================================================
921 // GUI-only functions from now on
922 // ============================================================================
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__)))
930 bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag
) )
934 #endif // !X11-based port
936 // ----------------------------------------------------------------------------
937 // Launch default browser
938 // ----------------------------------------------------------------------------
940 #if defined(__WXMSW__)
942 // implemented in a port-specific utils source file:
943 bool wxDoLaunchDefaultBrowser(const wxString
& url
, const wxString
& scheme
, int flags
);
945 #elif defined(__WXX11__) || defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || \
946 (defined(__WXOSX__) )
948 // implemented in a port-specific utils source file:
949 bool wxDoLaunchDefaultBrowser(const wxString
& url
, int flags
);
953 // a "generic" implementation:
954 bool wxDoLaunchDefaultBrowser(const wxString
& url
, int flags
)
956 // on other platforms try to use mime types or wxExecute...
962 wxFileType
*ft
= wxTheMimeTypesManager
->GetFileTypeFromExtension(wxT("html"));
966 ft
->GetMimeType(&mt
);
968 ok
= ft
->GetOpenCommand(&cmd
, wxFileType::MessageParameters(url
));
971 #endif // wxUSE_MIMETYPE
973 if ( !ok
|| cmd
.empty() )
975 // fallback to checking for the BROWSER environment variable
976 if ( !wxGetEnv(wxT("BROWSER"), &cmd
) || cmd
.empty() )
977 cmd
<< wxT(' ') << url
;
980 ok
= ( !cmd
.empty() && wxExecute(cmd
) );
984 // no file type for HTML extension
985 wxLogError(_("No default application configured for HTML files."));
991 static bool DoLaunchDefaultBrowserHelper(const wxString
& urlOrig
, int flags
)
993 // NOTE: we don't have to care about the wxBROWSER_NOBUSYCURSOR flag
994 // as it was already handled by wxLaunchDefaultBrowser
998 wxString
url(urlOrig
), scheme
;
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")
1004 bool hasValidScheme
= uri
.HasScheme() && uri
.GetScheme().length() > 1;
1006 #if defined(__WXMSW__)
1008 // NOTE: when testing wxMSW's wxLaunchDefaultBrowser all possible forms
1009 // of the URL/flags should be tested; e.g.:
1011 // for (int i=0; i<2; i++)
1013 // // test arguments without a valid URL scheme:
1014 // wxLaunchDefaultBrowser("C:\\test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1015 // wxLaunchDefaultBrowser("wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1017 // // test arguments with different valid schemes:
1018 // wxLaunchDefaultBrowser("file:/C%3A/test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1019 // wxLaunchDefaultBrowser("http://wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1020 // wxLaunchDefaultBrowser("mailto:user@host.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1022 // (assuming you have a C:\test.txt file)
1024 if ( !hasValidScheme
)
1026 if (wxFileExists(urlOrig
) || wxDirExists(urlOrig
))
1029 // do not prepend the file scheme to the URL as ShellExecuteEx() doesn't like it
1033 url
.Prepend(wxS("http://"));
1037 else if ( hasValidScheme
)
1039 scheme
= uri
.GetScheme();
1041 if ( uri
.GetScheme() == "file" )
1043 // TODO: extract URLToFileName() to some always compiled in
1045 #if wxUSE_FILESYSTEM
1046 // ShellExecuteEx() doesn't like the "file" scheme when opening local files;
1048 url
= wxFileSystem::URLToFileName(url
).GetFullPath();
1049 #endif // wxUSE_FILESYSTEM
1053 if (wxDoLaunchDefaultBrowser(url
, scheme
, flags
))
1055 //else: call wxLogSysError
1057 if ( !hasValidScheme
)
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://"));
1063 url
.Prepend(wxS("http://"));
1066 if (wxDoLaunchDefaultBrowser(url
, flags
))
1068 //else: call wxLogSysError
1071 wxLogSysError(_("Failed to open URL \"%s\" in default browser."),
1077 bool wxLaunchDefaultBrowser(const wxString
& url
, int flags
)
1079 // NOTE: as documented, "url" may be both a real well-formed URL
1080 // and a local file name
1082 if ( flags
& wxBROWSER_NOBUSYCURSOR
)
1083 return DoLaunchDefaultBrowserHelper(url
, flags
);
1086 return DoLaunchDefaultBrowserHelper(url
, flags
);
1089 // ----------------------------------------------------------------------------
1090 // Menu accelerators related functions
1091 // ----------------------------------------------------------------------------
1093 #if WXWIN_COMPATIBILITY_2_6
1094 wxChar
*wxStripMenuCodes(const wxChar
*in
, wxChar
*out
)
1097 wxString s
= wxMenuItem::GetLabelText(in
);
1100 wxString s
= wxStripMenuCodes(str
);
1101 #endif // wxUSE_MENUS
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
));
1109 out
= new wxChar
[s
.length() + 1];
1110 wxStrcpy(out
, s
.c_str());
1117 wxString
wxStripMenuCodes(const wxString
& in
, int flags
)
1119 wxASSERT_MSG( flags
, wxT("this is useless to call without any flags") );
1123 size_t len
= in
.length();
1126 for ( size_t n
= 0; n
< len
; n
++ )
1129 if ( (flags
& wxStrip_Mnemonics
) && ch
== wxT('&') )
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
1136 wxLogDebug(wxT("Invalid menu string '%s'"), in
.c_str());
1140 // use the next char instead
1144 else if ( (flags
& wxStrip_Accel
) && ch
== wxT('\t') )
1146 // everything after TAB is accel string, exit the loop
1156 // ----------------------------------------------------------------------------
1157 // Window search functions
1158 // ----------------------------------------------------------------------------
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.
1167 wxFindWindowByLabel (const wxString
& title
, wxWindow
* parent
)
1169 return wxWindow::FindWindowByLabel( title
, parent
);
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.
1180 wxFindWindowByName (const wxString
& name
, wxWindow
* parent
)
1182 return wxWindow::FindWindowByName( name
, parent
);
1185 // Returns menu item id or wxNOT_FOUND if none.
1187 wxFindMenuItemId(wxFrame
*frame
,
1188 const wxString
& menuString
,
1189 const wxString
& itemString
)
1192 wxMenuBar
*menuBar
= frame
->GetMenuBar ();
1194 return menuBar
->FindMenuItem (menuString
, itemString
);
1195 #else // !wxUSE_MENUS
1197 wxUnusedVar(menuString
);
1198 wxUnusedVar(itemString
);
1199 #endif // wxUSE_MENUS/!wxUSE_MENUS
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.
1209 wxWindow
* wxFindWindowAtPoint(wxWindow
* win
, const wxPoint
& pt
)
1211 if (!win
->IsShown())
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.
1217 if (win
->IsKindOf(CLASSINFO(wxNotebook
)))
1219 wxNotebook
* nb
= (wxNotebook
*) win
;
1220 int sel
= nb
->GetSelection();
1223 wxWindow
* child
= nb
->GetPage(sel
);
1224 wxWindow
* foundWin
= wxFindWindowAtPoint(child
, pt
);
1231 wxWindowList::compatibility_iterator node
= win
->GetChildren().GetLast();
1234 wxWindow
* child
= node
->GetData();
1235 wxWindow
* foundWin
= wxFindWindowAtPoint(child
, pt
);
1238 node
= node
->GetPrevious();
1241 wxPoint pos
= win
->GetPosition();
1242 wxSize sz
= win
->GetSize();
1243 if ( !win
->IsTopLevel() && win
->GetParent() )
1245 pos
= win
->GetParent()->ClientToScreen(pos
);
1248 wxRect
rect(pos
, sz
);
1249 if (rect
.Contains(pt
))
1255 wxWindow
* wxGenericFindWindowAtPoint(const wxPoint
& pt
)
1257 // Go backwards through the list since windows
1258 // on top are likely to have been appended most
1260 wxWindowList::compatibility_iterator node
= wxTopLevelWindows
.GetLast();
1263 wxWindow
* win
= node
->GetData();
1264 wxWindow
* found
= wxFindWindowAtPoint(win
, pt
);
1267 node
= node
->GetPrevious();
1272 // ----------------------------------------------------------------------------
1274 // ----------------------------------------------------------------------------
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.
1283 int wxMessageBox(const wxString
& message
, const wxString
& caption
, long style
,
1284 wxWindow
*parent
, int WXUNUSED(x
), int WXUNUSED(y
) )
1286 // add the appropriate icon unless this was explicitly disabled by use of
1288 if ( !(style
& wxICON_NONE
) && !(style
& wxICON_MASK
) )
1290 style
|= style
& wxYES
? wxICON_QUESTION
: wxICON_INFORMATION
;
1293 wxMessageDialog
dialog(parent
, message
, caption
, style
);
1295 int ans
= dialog
.ShowModal();
1308 wxFAIL_MSG( wxT("unexpected return code from wxMessageDialog") );
1313 void wxInfoMessageBox(wxWindow
* parent
)
1315 // don't translate these strings, they're for diagnostics purposes only
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(),
1325 #if wxUSE_UNICODE_UTF8
1335 wxPlatformInfo::Get().GetToolkitMajorVersion(),
1336 wxPlatformInfo::Get().GetToolkitMinorVersion()
1340 msg
+= wxString::Format("Compile-time GTK+ version is %d.%d.%d.\n",
1346 msg
+= wxS("\nCopyright (c) 1995-2009 wxWidgets team");
1348 wxMessageBox(msg
, wxT("wxWidgets information"),
1349 wxICON_INFORMATION
| wxOK
,
1353 #endif // wxUSE_MSGDLG
1357 wxString
wxGetTextFromUser(const wxString
& message
, const wxString
& caption
,
1358 const wxString
& defaultValue
, wxWindow
*parent
,
1359 wxCoord x
, wxCoord y
, bool centre
)
1362 long style
= wxTextEntryDialogStyle
;
1369 wxTextEntryDialog
dialog(parent
, message
, caption
, defaultValue
, style
, wxPoint(x
, y
));
1371 if (dialog
.ShowModal() == wxID_OK
)
1373 str
= dialog
.GetValue();
1379 wxString
wxGetPasswordFromUser(const wxString
& message
,
1380 const wxString
& caption
,
1381 const wxString
& defaultValue
,
1383 wxCoord x
, wxCoord y
, bool centre
)
1386 long style
= wxTextEntryDialogStyle
;
1393 wxPasswordEntryDialog
dialog(parent
, message
, caption
, defaultValue
,
1394 style
, wxPoint(x
, y
));
1395 if ( dialog
.ShowModal() == wxID_OK
)
1397 str
= dialog
.GetValue();
1403 #endif // wxUSE_TEXTDLG
1407 wxColour
wxGetColourFromUser(wxWindow
*parent
,
1408 const wxColour
& colInit
,
1409 const wxString
& caption
,
1410 wxColourData
*ptrData
)
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
;
1423 if ( !s_strColourData
.empty() )
1425 if ( !data
.FromString(s_strColourData
) )
1427 wxFAIL_MSG( "bug in wxColourData::FromString()?" );
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);
1441 if ( colInit
.IsOk() )
1443 ptrData
->SetColour(colInit
);
1447 wxColourDialog
dialog(parent
, ptrData
);
1448 if (!caption
.empty())
1449 dialog
.SetTitle(caption
);
1450 if ( dialog
.ShowModal() == wxID_OK
)
1452 *ptrData
= dialog
.GetColourData();
1453 colRet
= ptrData
->GetColour();
1454 s_strColourData
= ptrData
->ToString();
1456 //else: leave colRet invalid
1461 #endif // wxUSE_COLOURDLG
1465 wxFont
wxGetFontFromUser(wxWindow
*parent
, const wxFont
& fontInit
, const wxString
& caption
)
1468 if ( fontInit
.Ok() )
1470 data
.SetInitialFont(fontInit
);
1474 wxFontDialog
dialog(parent
, data
);
1475 if (!caption
.empty())
1476 dialog
.SetTitle(caption
);
1477 if ( dialog
.ShowModal() == wxID_OK
)
1479 fontRet
= dialog
.GetFontData().GetChosenFont();
1481 //else: leave it invalid
1486 #endif // wxUSE_FONTDLG
1488 // ----------------------------------------------------------------------------
1489 // wxSafeYield and supporting functions
1490 // ----------------------------------------------------------------------------
1492 void wxEnableTopLevelWindows(bool enable
)
1494 wxWindowList::compatibility_iterator node
;
1495 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1496 node
->GetData()->Enable(enable
);
1499 wxWindowDisabler::wxWindowDisabler(bool disable
)
1501 m_disabled
= disable
;
1506 wxWindowDisabler::wxWindowDisabler(wxWindow
*winToSkip
)
1509 DoDisable(winToSkip
);
1512 void wxWindowDisabler::DoDisable(wxWindow
*winToSkip
)
1514 // remember the top level windows which were already disabled, so that we
1515 // don't reenable them later
1516 m_winDisabled
= NULL
;
1518 wxWindowList::compatibility_iterator node
;
1519 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1521 wxWindow
*winTop
= node
->GetData();
1522 if ( winTop
== winToSkip
)
1525 // we don't need to disable the hidden or already disabled windows
1526 if ( winTop
->IsEnabled() && winTop
->IsShown() )
1532 if ( !m_winDisabled
)
1534 m_winDisabled
= new wxWindowList
;
1537 m_winDisabled
->Append(winTop
);
1542 wxWindowDisabler::~wxWindowDisabler()
1547 wxWindowList::compatibility_iterator node
;
1548 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1550 wxWindow
*winTop
= node
->GetData();
1551 if ( !m_winDisabled
|| !m_winDisabled
->Find(winTop
) )
1555 //else: had been already disabled, don't reenable
1558 delete m_winDisabled
;
1561 // Yield to other apps/messages and disable user input to all windows except
1563 bool wxSafeYield(wxWindow
*win
, bool onlyIfNeeded
)
1565 wxWindowDisabler
wd(win
);
1569 rc
= wxYieldIfNeeded();
1576 // ----------------------------------------------------------------------------
1577 // wxApp::Yield() wrappers for backwards compatibility
1578 // ----------------------------------------------------------------------------
1582 return wxTheApp
&& wxTheApp
->Yield();
1585 bool wxYieldIfNeeded()
1587 return wxTheApp
&& wxTheApp
->Yield(true);