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 wxDELETE(sm_customPlatforms
);
361 /// Function for testing current platform
363 bool wxPlatform::Is(int platform
)
366 if (platform
== wxOS_WINDOWS
)
370 if (platform
== wxOS_WINDOWS_CE
)
376 // FIXME: wxWinPocketPC and wxWinSmartPhone are unknown symbols
378 #if defined(__WXWINCE__) && defined(__POCKETPC__)
379 if (platform
== wxWinPocketPC
)
382 #if defined(__WXWINCE__) && defined(__SMARTPHONE__)
383 if (platform
== wxWinSmartPhone
)
390 if (platform
== wxPORT_GTK
)
394 if (platform
== wxPORT_MAC
)
398 if (platform
== wxPORT_X11
)
402 if (platform
== wxOS_UNIX
)
406 if (platform
== wxPORT_MGL
)
410 if (platform
== wxOS_OS2
)
414 if (platform
== wxPORT_PM
)
418 if (platform
== wxPORT_MAC
)
422 if (sm_customPlatforms
&& sm_customPlatforms
->Index(platform
) != wxNOT_FOUND
)
428 // ----------------------------------------------------------------------------
429 // network and user id functions
430 // ----------------------------------------------------------------------------
432 // Get Full RFC822 style email address
433 bool wxGetEmailAddress(wxChar
*address
, int maxSize
)
435 wxString email
= wxGetEmailAddress();
439 wxStrlcpy(address
, email
.t_str(), maxSize
);
444 wxString
wxGetEmailAddress()
448 wxString host
= wxGetFullHostName();
451 wxString user
= wxGetUserId();
454 email
<< user
<< wxT('@') << host
;
461 wxString
wxGetUserId()
463 static const int maxLoginLen
= 256; // FIXME arbitrary number
466 bool ok
= wxGetUserId(wxStringBuffer(buf
, maxLoginLen
), maxLoginLen
);
474 wxString
wxGetUserName()
476 static const int maxUserNameLen
= 1024; // FIXME arbitrary number
479 bool ok
= wxGetUserName(wxStringBuffer(buf
, maxUserNameLen
), maxUserNameLen
);
487 wxString
wxGetHostName()
489 static const size_t hostnameSize
= 257;
492 bool ok
= wxGetHostName(wxStringBuffer(buf
, hostnameSize
), hostnameSize
);
500 wxString
wxGetFullHostName()
502 static const size_t hostnameSize
= 257;
505 bool ok
= wxGetFullHostName(wxStringBuffer(buf
, hostnameSize
), hostnameSize
);
513 wxString
wxGetHomeDir()
523 wxString
wxGetCurrentDir()
530 ok
= getcwd(dir
.GetWriteBuf(len
+ 1), len
) != NULL
;
535 if ( errno
!= ERANGE
)
537 wxLogSysError(wxT("Failed to get current directory"));
539 return wxEmptyString
;
543 // buffer was too small, retry with a larger one
555 // ----------------------------------------------------------------------------
557 // ----------------------------------------------------------------------------
559 // wxDoExecuteWithCapture() helper: reads an entire stream into one array
561 // returns true if ok, false if error
563 static bool ReadAll(wxInputStream
*is
, wxArrayString
& output
)
565 wxCHECK_MSG( is
, false, wxT("NULL stream in wxExecute()?") );
567 // the stream could be already at EOF or in wxSTREAM_BROKEN_PIPE state
570 wxTextInputStream
tis(*is
);
574 wxString line
= tis
.ReadLine();
576 // check for EOF before other errors as it's not really an error
579 // add the last, possibly incomplete, line
585 // any other error is fatal
594 #endif // wxUSE_STREAMS
596 // this is a private function because it hasn't a clean interface: the first
597 // array is passed by reference, the second by pointer - instead we have 2
598 // public versions of wxExecute() below
599 static long wxDoExecuteWithCapture(const wxString
& command
,
600 wxArrayString
& output
,
601 wxArrayString
* error
,
604 // create a wxProcess which will capture the output
605 wxProcess
*process
= new wxProcess
;
608 long rc
= wxExecute(command
, wxEXEC_SYNC
| flags
, process
);
613 if ( !ReadAll(process
->GetInputStream(), output
) )
618 if ( !ReadAll(process
->GetErrorStream(), *error
) )
626 #endif // wxUSE_STREAMS/!wxUSE_STREAMS
633 long wxExecute(const wxString
& command
, wxArrayString
& output
, int flags
)
635 return wxDoExecuteWithCapture(command
, output
, NULL
, flags
);
638 long wxExecute(const wxString
& command
,
639 wxArrayString
& output
,
640 wxArrayString
& error
,
643 return wxDoExecuteWithCapture(command
, output
, &error
, flags
);
646 // ----------------------------------------------------------------------------
648 // ----------------------------------------------------------------------------
651 static long wxCurrentId
= 100;
655 // skip the part of IDs space that contains hard-coded values:
656 if (wxCurrentId
== wxID_LOWEST
)
657 wxCurrentId
= wxID_HIGHEST
+ 1;
659 return wxCurrentId
++;
663 wxGetCurrentId(void) { return wxCurrentId
; }
666 wxRegisterId (long id
)
668 if (id
>= wxCurrentId
)
669 wxCurrentId
= id
+ 1;
672 // ----------------------------------------------------------------------------
673 // wxQsort, adapted by RR to allow user_data
674 // ----------------------------------------------------------------------------
676 /* This file is part of the GNU C Library.
677 Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
679 Douglas Schmidt kindly gave permission to relicence the
680 code under the wxWindows licence:
682 From: "Douglas C. Schmidt" <schmidt@dre.vanderbilt.edu>
683 To: Robert Roebling <robert.roebling@uni-ulm.de>
684 Subject: Re: qsort licence
685 Date: Mon, 23 Jul 2007 03:44:25 -0500
686 Sender: schmidt@dre.vanderbilt.edu
687 Message-Id: <20070723084426.64F511000A8@tango.dre.vanderbilt.edu>
691 > [...] I'm asking if you'd be willing to relicence your code
692 > under the wxWindows licence. [...]
694 That's fine with me [...]
701 /* Byte-wise swap two items of size SIZE. */
702 #define SWAP(a, b, size) \
705 register size_t __size = (size); \
706 register char *__a = (a), *__b = (b); \
712 } while (--__size > 0); \
715 /* Discontinue quicksort algorithm when partition gets below this size.
716 This particular magic number was chosen to work best on a Sun 4/260. */
719 /* Stack node declarations used to store unfulfilled partition obligations. */
726 /* The next 4 #defines implement a very fast in-line stack abstraction. */
727 #define STACK_SIZE (8 * sizeof(unsigned long int))
728 #define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
729 #define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
730 #define STACK_NOT_EMPTY (stack < top)
733 /* Order size using quicksort. This implementation incorporates
734 four optimizations discussed in Sedgewick:
736 1. Non-recursive, using an explicit stack of pointer that store the
737 next array partition to sort. To save time, this maximum amount
738 of space required to store an array of MAX_INT is allocated on the
739 stack. Assuming a 32-bit integer, this needs only 32 *
740 sizeof(stack_node) == 136 bits. Pretty cheap, actually.
742 2. Chose the pivot element using a median-of-three decision tree.
743 This reduces the probability of selecting a bad pivot value and
744 eliminates certain extraneous comparisons.
746 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
747 insertion sort to order the MAX_THRESH items within each partition.
748 This is a big win, since insertion sort is faster for small, mostly
749 sorted array segments.
751 4. The larger of the two sub-partitions is always pushed onto the
752 stack first, with the algorithm then concentrating on the
753 smaller partition. This *guarantees* no more than log (n)
754 stack size is needed (actually O(1) in this case)! */
756 void wxQsort(void *const pbase
, size_t total_elems
,
757 size_t size
, CMPFUNCDATA cmp
, const void* user_data
)
759 register char *base_ptr
= (char *) pbase
;
760 const size_t max_thresh
= MAX_THRESH
* size
;
762 if (total_elems
== 0)
763 /* Avoid lossage with unsigned arithmetic below. */
766 if (total_elems
> MAX_THRESH
)
769 char *hi
= &lo
[size
* (total_elems
- 1)];
770 stack_node stack
[STACK_SIZE
];
771 stack_node
*top
= stack
;
775 while (STACK_NOT_EMPTY
)
780 /* Select median value from among LO, MID, and HI. Rearrange
781 LO and HI so the three values are sorted. This lowers the
782 probability of picking a pathological pivot value and
783 skips a comparison for both the LEFT_PTR and RIGHT_PTR. */
785 char *mid
= lo
+ size
* ((hi
- lo
) / size
>> 1);
787 if ((*cmp
) ((void *) mid
, (void *) lo
, user_data
) < 0)
788 SWAP (mid
, lo
, size
);
789 if ((*cmp
) ((void *) hi
, (void *) mid
, user_data
) < 0)
790 SWAP (mid
, hi
, size
);
793 if ((*cmp
) ((void *) mid
, (void *) lo
, user_data
) < 0)
794 SWAP (mid
, lo
, size
);
796 left_ptr
= lo
+ size
;
797 right_ptr
= hi
- size
;
799 /* Here's the famous ``collapse the walls'' section of quicksort.
800 Gotta like those tight inner loops! They are the main reason
801 that this algorithm runs much faster than others. */
804 while ((*cmp
) ((void *) left_ptr
, (void *) mid
, user_data
) < 0)
807 while ((*cmp
) ((void *) mid
, (void *) right_ptr
, user_data
) < 0)
810 if (left_ptr
< right_ptr
)
812 SWAP (left_ptr
, right_ptr
, size
);
815 else if (mid
== right_ptr
)
820 else if (left_ptr
== right_ptr
)
827 while (left_ptr
<= right_ptr
);
829 /* Set up pointers for next iteration. First determine whether
830 left and right partitions are below the threshold size. If so,
831 ignore one or both. Otherwise, push the larger partition's
832 bounds on the stack and continue sorting the smaller one. */
834 if ((size_t) (right_ptr
- lo
) <= max_thresh
)
836 if ((size_t) (hi
- left_ptr
) <= max_thresh
)
837 /* Ignore both small partitions. */
840 /* Ignore small left partition. */
843 else if ((size_t) (hi
- left_ptr
) <= max_thresh
)
844 /* Ignore small right partition. */
846 else if ((right_ptr
- lo
) > (hi
- left_ptr
))
848 /* Push larger left partition indices. */
849 PUSH (lo
, right_ptr
);
854 /* Push larger right partition indices. */
861 /* Once the BASE_PTR array is partially sorted by quicksort the rest
862 is completely sorted using insertion sort, since this is efficient
863 for partitions below MAX_THRESH size. BASE_PTR points to the beginning
864 of the array to sort, and END_PTR points at the very last element in
865 the array (*not* one beyond it!). */
868 char *const end_ptr
= &base_ptr
[size
* (total_elems
- 1)];
869 char *tmp_ptr
= base_ptr
;
870 char *thresh
= base_ptr
+ max_thresh
;
871 if ( thresh
> end_ptr
)
873 register char *run_ptr
;
875 /* Find smallest element in first threshold and place it at the
876 array's beginning. This is the smallest array element,
877 and the operation speeds up insertion sort's inner loop. */
879 for (run_ptr
= tmp_ptr
+ size
; run_ptr
<= thresh
; run_ptr
+= size
)
880 if ((*cmp
) ((void *) run_ptr
, (void *) tmp_ptr
, user_data
) < 0)
883 if (tmp_ptr
!= base_ptr
)
884 SWAP (tmp_ptr
, base_ptr
, size
);
886 /* Insertion sort, running from left-hand-side up to right-hand-side. */
888 run_ptr
= base_ptr
+ size
;
889 while ((run_ptr
+= size
) <= end_ptr
)
891 tmp_ptr
= run_ptr
- size
;
892 while ((*cmp
) ((void *) run_ptr
, (void *) tmp_ptr
, user_data
) < 0)
896 if (tmp_ptr
!= run_ptr
)
900 trav
= run_ptr
+ size
;
901 while (--trav
>= run_ptr
)
906 for (hi
= lo
= trav
; (lo
-= size
) >= tmp_ptr
; hi
= lo
)
919 // ============================================================================
920 // GUI-only functions from now on
921 // ============================================================================
925 // this function is only really implemented for X11-based ports, including GTK1
926 // (GTK2 sets detectable auto-repeat automatically anyhow)
927 #if !(defined(__WXX11__) || defined(__WXMOTIF__) || \
928 (defined(__WXGTK__) && !defined(__WXGTK20__)))
929 bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag
) )
933 #endif // !X11-based port
935 // ----------------------------------------------------------------------------
936 // Launch default browser
937 // ----------------------------------------------------------------------------
939 #if defined(__WXMSW__)
941 // implemented in a port-specific utils source file:
942 bool wxDoLaunchDefaultBrowser(const wxString
& url
, const wxString
& scheme
, int flags
);
944 #elif defined(__WXX11__) || defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || \
945 (defined(__WXOSX__) )
947 // implemented in a port-specific utils source file:
948 bool wxDoLaunchDefaultBrowser(const wxString
& url
, int flags
);
952 // a "generic" implementation:
953 bool wxDoLaunchDefaultBrowser(const wxString
& url
, int flags
)
955 // on other platforms try to use mime types or wxExecute...
961 wxFileType
*ft
= wxTheMimeTypesManager
->GetFileTypeFromExtension(wxT("html"));
965 ft
->GetMimeType(&mt
);
967 ok
= ft
->GetOpenCommand(&cmd
, wxFileType::MessageParameters(url
));
970 #endif // wxUSE_MIMETYPE
972 if ( !ok
|| cmd
.empty() )
974 // fallback to checking for the BROWSER environment variable
975 if ( !wxGetEnv(wxT("BROWSER"), &cmd
) || cmd
.empty() )
976 cmd
<< wxT(' ') << url
;
979 ok
= ( !cmd
.empty() && wxExecute(cmd
) );
983 // no file type for HTML extension
984 wxLogError(_("No default application configured for HTML files."));
990 static bool DoLaunchDefaultBrowserHelper(const wxString
& urlOrig
, int flags
)
992 // NOTE: we don't have to care about the wxBROWSER_NOBUSYCURSOR flag
993 // as it was already handled by wxLaunchDefaultBrowser
997 wxString
url(urlOrig
), scheme
;
1000 // this check is useful to avoid that wxURI recognizes as scheme parts of
1001 // the filename, in case urlOrig is a local filename
1002 // (e.g. "C:\\test.txt" when parsed by wxURI reports a scheme == "C")
1003 bool hasValidScheme
= uri
.HasScheme() && uri
.GetScheme().length() > 1;
1005 #if defined(__WXMSW__)
1007 // NOTE: when testing wxMSW's wxLaunchDefaultBrowser all possible forms
1008 // of the URL/flags should be tested; e.g.:
1010 // for (int i=0; i<2; i++)
1012 // // test arguments without a valid URL scheme:
1013 // wxLaunchDefaultBrowser("C:\\test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1014 // wxLaunchDefaultBrowser("wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1016 // // test arguments with different valid schemes:
1017 // wxLaunchDefaultBrowser("file:/C%3A/test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1018 // wxLaunchDefaultBrowser("http://wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1019 // wxLaunchDefaultBrowser("mailto:user@host.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1021 // (assuming you have a C:\test.txt file)
1023 if ( !hasValidScheme
)
1025 if (wxFileExists(urlOrig
) || wxDirExists(urlOrig
))
1028 // do not prepend the file scheme to the URL as ShellExecuteEx() doesn't like it
1032 url
.Prepend(wxS("http://"));
1036 else if ( hasValidScheme
)
1038 scheme
= uri
.GetScheme();
1040 if ( uri
.GetScheme() == "file" )
1042 // TODO: extract URLToFileName() to some always compiled in
1044 #if wxUSE_FILESYSTEM
1045 // ShellExecuteEx() doesn't like the "file" scheme when opening local files;
1047 url
= wxFileSystem::URLToFileName(url
).GetFullPath();
1048 #endif // wxUSE_FILESYSTEM
1052 if (wxDoLaunchDefaultBrowser(url
, scheme
, flags
))
1054 //else: call wxLogSysError
1056 if ( !hasValidScheme
)
1058 // set the scheme of url to "http" or "file" if it does not have one
1059 if (wxFileExists(urlOrig
) || wxDirExists(urlOrig
))
1060 url
.Prepend(wxS("file://"));
1062 url
.Prepend(wxS("http://"));
1065 if (wxDoLaunchDefaultBrowser(url
, flags
))
1067 //else: call wxLogSysError
1070 wxLogSysError(_("Failed to open URL \"%s\" in default browser."),
1076 bool wxLaunchDefaultBrowser(const wxString
& url
, int flags
)
1078 // NOTE: as documented, "url" may be both a real well-formed URL
1079 // and a local file name
1081 if ( flags
& wxBROWSER_NOBUSYCURSOR
)
1082 return DoLaunchDefaultBrowserHelper(url
, flags
);
1085 return DoLaunchDefaultBrowserHelper(url
, flags
);
1088 // ----------------------------------------------------------------------------
1089 // Menu accelerators related functions
1090 // ----------------------------------------------------------------------------
1092 #if WXWIN_COMPATIBILITY_2_6
1093 wxChar
*wxStripMenuCodes(const wxChar
*in
, wxChar
*out
)
1096 wxString s
= wxMenuItem::GetLabelText(in
);
1099 wxString s
= wxStripMenuCodes(str
);
1100 #endif // wxUSE_MENUS
1103 // go smash their buffer if it's not big enough - I love char * params
1104 memcpy(out
, s
.c_str(), s
.length() * sizeof(wxChar
));
1108 out
= new wxChar
[s
.length() + 1];
1109 wxStrcpy(out
, s
.c_str());
1116 wxString
wxStripMenuCodes(const wxString
& in
, int flags
)
1118 wxASSERT_MSG( flags
, wxT("this is useless to call without any flags") );
1122 size_t len
= in
.length();
1125 for ( size_t n
= 0; n
< len
; n
++ )
1128 if ( (flags
& wxStrip_Mnemonics
) && ch
== wxT('&') )
1130 // skip it, it is used to introduce the accel char (or to quote
1131 // itself in which case it should still be skipped): note that it
1132 // can't be the last character of the string
1135 wxLogDebug(wxT("Invalid menu string '%s'"), in
.c_str());
1139 // use the next char instead
1143 else if ( (flags
& wxStrip_Accel
) && ch
== wxT('\t') )
1145 // everything after TAB is accel string, exit the loop
1155 // ----------------------------------------------------------------------------
1156 // Window search functions
1157 // ----------------------------------------------------------------------------
1160 * If parent is non-NULL, look through children for a label or title
1161 * matching the specified string. If NULL, look through all top-level windows.
1166 wxFindWindowByLabel (const wxString
& title
, wxWindow
* parent
)
1168 return wxWindow::FindWindowByLabel( title
, parent
);
1173 * If parent is non-NULL, look through children for a name
1174 * matching the specified string. If NULL, look through all top-level windows.
1179 wxFindWindowByName (const wxString
& name
, wxWindow
* parent
)
1181 return wxWindow::FindWindowByName( name
, parent
);
1184 // Returns menu item id or wxNOT_FOUND if none.
1186 wxFindMenuItemId(wxFrame
*frame
,
1187 const wxString
& menuString
,
1188 const wxString
& itemString
)
1191 wxMenuBar
*menuBar
= frame
->GetMenuBar ();
1193 return menuBar
->FindMenuItem (menuString
, itemString
);
1194 #else // !wxUSE_MENUS
1196 wxUnusedVar(menuString
);
1197 wxUnusedVar(itemString
);
1198 #endif // wxUSE_MENUS/!wxUSE_MENUS
1203 // Try to find the deepest child that contains 'pt'.
1204 // We go backwards, to try to allow for controls that are spacially
1205 // within other controls, but are still siblings (e.g. buttons within
1206 // static boxes). Static boxes are likely to be created _before_ controls
1207 // that sit inside them.
1208 wxWindow
* wxFindWindowAtPoint(wxWindow
* win
, const wxPoint
& pt
)
1210 if (!win
->IsShown())
1213 // Hack for wxNotebook case: at least in wxGTK, all pages
1214 // claim to be shown, so we must only deal with the selected one.
1216 if (win
->IsKindOf(CLASSINFO(wxNotebook
)))
1218 wxNotebook
* nb
= (wxNotebook
*) win
;
1219 int sel
= nb
->GetSelection();
1222 wxWindow
* child
= nb
->GetPage(sel
);
1223 wxWindow
* foundWin
= wxFindWindowAtPoint(child
, pt
);
1230 wxWindowList::compatibility_iterator node
= win
->GetChildren().GetLast();
1233 wxWindow
* child
= node
->GetData();
1234 wxWindow
* foundWin
= wxFindWindowAtPoint(child
, pt
);
1237 node
= node
->GetPrevious();
1240 wxPoint pos
= win
->GetPosition();
1241 wxSize sz
= win
->GetSize();
1242 if ( !win
->IsTopLevel() && win
->GetParent() )
1244 pos
= win
->GetParent()->ClientToScreen(pos
);
1247 wxRect
rect(pos
, sz
);
1248 if (rect
.Contains(pt
))
1254 wxWindow
* wxGenericFindWindowAtPoint(const wxPoint
& pt
)
1256 // Go backwards through the list since windows
1257 // on top are likely to have been appended most
1259 wxWindowList::compatibility_iterator node
= wxTopLevelWindows
.GetLast();
1262 wxWindow
* win
= node
->GetData();
1263 wxWindow
* found
= wxFindWindowAtPoint(win
, pt
);
1266 node
= node
->GetPrevious();
1271 // ----------------------------------------------------------------------------
1273 // ----------------------------------------------------------------------------
1276 * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
1277 * since otherwise the generic code may be pulled in unnecessarily.
1282 int wxMessageBox(const wxString
& message
, const wxString
& caption
, long style
,
1283 wxWindow
*parent
, int WXUNUSED(x
), int WXUNUSED(y
) )
1285 // add the appropriate icon unless this was explicitly disabled by use of
1287 if ( !(style
& wxICON_NONE
) && !(style
& wxICON_MASK
) )
1289 style
|= style
& wxYES
? wxICON_QUESTION
: wxICON_INFORMATION
;
1292 wxMessageDialog
dialog(parent
, message
, caption
, style
);
1294 int ans
= dialog
.ShowModal();
1307 wxFAIL_MSG( wxT("unexpected return code from wxMessageDialog") );
1312 void wxInfoMessageBox(wxWindow
* parent
)
1314 // don't translate these strings, they're for diagnostics purposes only
1316 msg
.Printf(wxS("wxWidgets Library (%s port)\n")
1317 wxS("Version %d.%d.%d (Unicode: %s, debug level: %d),\n")
1318 wxS("compiled at %s %s\n\n")
1319 wxS("Runtime version of toolkit used is %d.%d.\n"),
1320 wxPlatformInfo::Get().GetPortIdName(),
1324 #if wxUSE_UNICODE_UTF8
1334 wxPlatformInfo::Get().GetToolkitMajorVersion(),
1335 wxPlatformInfo::Get().GetToolkitMinorVersion()
1339 msg
+= wxString::Format("Compile-time GTK+ version is %d.%d.%d.\n",
1345 msg
+= wxS("\nCopyright (c) 1995-2010 wxWidgets team");
1347 wxMessageBox(msg
, wxT("wxWidgets information"),
1348 wxICON_INFORMATION
| wxOK
,
1352 #endif // wxUSE_MSGDLG
1356 wxString
wxGetTextFromUser(const wxString
& message
, const wxString
& caption
,
1357 const wxString
& defaultValue
, wxWindow
*parent
,
1358 wxCoord x
, wxCoord y
, bool centre
)
1361 long style
= wxTextEntryDialogStyle
;
1368 wxTextEntryDialog
dialog(parent
, message
, caption
, defaultValue
, style
, wxPoint(x
, y
));
1370 if (dialog
.ShowModal() == wxID_OK
)
1372 str
= dialog
.GetValue();
1378 wxString
wxGetPasswordFromUser(const wxString
& message
,
1379 const wxString
& caption
,
1380 const wxString
& defaultValue
,
1382 wxCoord x
, wxCoord y
, bool centre
)
1385 long style
= wxTextEntryDialogStyle
;
1392 wxPasswordEntryDialog
dialog(parent
, message
, caption
, defaultValue
,
1393 style
, wxPoint(x
, y
));
1394 if ( dialog
.ShowModal() == wxID_OK
)
1396 str
= dialog
.GetValue();
1402 #endif // wxUSE_TEXTDLG
1406 wxColour
wxGetColourFromUser(wxWindow
*parent
,
1407 const wxColour
& colInit
,
1408 const wxString
& caption
,
1409 wxColourData
*ptrData
)
1411 // contains serialized representation of wxColourData used the last time
1412 // the dialog was shown: we want to reuse it the next time in order to show
1413 // the same custom colours to the user (and we can't just have static
1414 // wxColourData itself because it's a GUI object and so should be destroyed
1415 // before GUI shutdown and doing it during static cleanup is too late)
1416 static wxString s_strColourData
;
1422 if ( !s_strColourData
.empty() )
1424 if ( !data
.FromString(s_strColourData
) )
1426 wxFAIL_MSG( "bug in wxColourData::FromString()?" );
1430 // we don't get back the "choose full" flag value from the native
1431 // dialog and so we can't preserve it between runs, so we decide to
1432 // always use it as it seems better than not using it (user can
1433 // just ignore the extra controls in the dialog but having to click
1434 // a button each time to show them would be very annoying
1435 data
.SetChooseFull(true);
1440 if ( colInit
.IsOk() )
1442 ptrData
->SetColour(colInit
);
1446 wxColourDialog
dialog(parent
, ptrData
);
1447 if (!caption
.empty())
1448 dialog
.SetTitle(caption
);
1449 if ( dialog
.ShowModal() == wxID_OK
)
1451 *ptrData
= dialog
.GetColourData();
1452 colRet
= ptrData
->GetColour();
1453 s_strColourData
= ptrData
->ToString();
1455 //else: leave colRet invalid
1460 #endif // wxUSE_COLOURDLG
1464 wxFont
wxGetFontFromUser(wxWindow
*parent
, const wxFont
& fontInit
, const wxString
& caption
)
1467 if ( fontInit
.Ok() )
1469 data
.SetInitialFont(fontInit
);
1473 wxFontDialog
dialog(parent
, data
);
1474 if (!caption
.empty())
1475 dialog
.SetTitle(caption
);
1476 if ( dialog
.ShowModal() == wxID_OK
)
1478 fontRet
= dialog
.GetFontData().GetChosenFont();
1480 //else: leave it invalid
1485 #endif // wxUSE_FONTDLG
1487 // ----------------------------------------------------------------------------
1488 // wxSafeYield and supporting functions
1489 // ----------------------------------------------------------------------------
1491 void wxEnableTopLevelWindows(bool enable
)
1493 wxWindowList::compatibility_iterator node
;
1494 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1495 node
->GetData()->Enable(enable
);
1498 wxWindowDisabler::wxWindowDisabler(bool disable
)
1500 m_disabled
= disable
;
1505 wxWindowDisabler::wxWindowDisabler(wxWindow
*winToSkip
)
1508 DoDisable(winToSkip
);
1511 void wxWindowDisabler::DoDisable(wxWindow
*winToSkip
)
1513 // remember the top level windows which were already disabled, so that we
1514 // don't reenable them later
1515 m_winDisabled
= NULL
;
1517 wxWindowList::compatibility_iterator node
;
1518 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1520 wxWindow
*winTop
= node
->GetData();
1521 if ( winTop
== winToSkip
)
1524 // we don't need to disable the hidden or already disabled windows
1525 if ( winTop
->IsEnabled() && winTop
->IsShown() )
1531 if ( !m_winDisabled
)
1533 m_winDisabled
= new wxWindowList
;
1536 m_winDisabled
->Append(winTop
);
1541 wxWindowDisabler::~wxWindowDisabler()
1546 wxWindowList::compatibility_iterator node
;
1547 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1549 wxWindow
*winTop
= node
->GetData();
1550 if ( !m_winDisabled
|| !m_winDisabled
->Find(winTop
) )
1554 //else: had been already disabled, don't reenable
1557 delete m_winDisabled
;
1560 // Yield to other apps/messages and disable user input to all windows except
1562 bool wxSafeYield(wxWindow
*win
, bool onlyIfNeeded
)
1564 wxWindowDisabler
wd(win
);
1568 rc
= wxYieldIfNeeded();
1575 // ----------------------------------------------------------------------------
1576 // wxApp::Yield() wrappers for backwards compatibility
1577 // ----------------------------------------------------------------------------
1581 return wxTheApp
&& wxTheApp
->Yield();
1584 bool wxYieldIfNeeded()
1586 return wxTheApp
&& wxTheApp
->Yield(true);