1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/utilscmn.cpp
3 // Purpose: Miscellaneous utility functions and classes
4 // Author: Julian Smart
8 // Copyright: (c) 1998 Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
29 #include "wx/string.h"
35 #include "wx/window.h"
38 #include "wx/msgdlg.h"
39 #include "wx/textdlg.h"
40 #include "wx/textctrl.h" // for wxTE_PASSWORD
42 #include "wx/menuitem.h"
48 #include "wx/apptrait.h"
50 #include "wx/process.h"
51 #include "wx/txtstrm.h"
53 #include "wx/mimetype.h"
54 #include "wx/config.h"
56 #if defined(__WXWINCE__) && wxUSE_DATETIME
57 #include "wx/datetime.h"
65 #if !wxONLY_WATCOM_EARLIER_THAN(1,4)
66 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
72 #include "wx/colordlg.h"
73 #include "wx/fontdlg.h"
74 #include "wx/notebook.h"
75 #include "wx/statusbr.h"
82 #include "wx/msw/wince/time.h"
84 #endif // ! __WXPALMOS5__
87 #include "wx/osx/private.h"
91 #if !defined(__MWERKS__) && !defined(__WXWINCE__)
92 #include <sys/types.h>
95 #endif // ! __WXPALMOS5__
97 #if defined(__WXMSW__)
98 #include "wx/msw/private.h"
99 #include "wx/filesys.h"
102 #if wxUSE_GUI && defined(__WXGTK__)
103 #include <gtk/gtk.h> // for GTK_XXX_VERSION constants
108 // ============================================================================
110 // ============================================================================
112 // Array used in DecToHex conversion routine.
113 static const wxChar hexArray
[] = wxT("0123456789ABCDEF");
115 // Convert 2-digit hex number to decimal
116 int wxHexToDec(const wxString
& str
)
119 buf
[0] = str
.GetChar(0);
120 buf
[1] = str
.GetChar(1);
121 return wxHexToDec((const char*) buf
);
124 // Convert decimal integer to 2-character hex string
125 void wxDecToHex(int dec
, wxChar
*buf
)
127 int firstDigit
= (int)(dec
/16.0);
128 int secondDigit
= (int)(dec
- (firstDigit
*16.0));
129 buf
[0] = hexArray
[firstDigit
];
130 buf
[1] = hexArray
[secondDigit
];
134 // Convert decimal integer to 2 characters
135 void wxDecToHex(int dec
, char* ch1
, char* ch2
)
137 int firstDigit
= (int)(dec
/16.0);
138 int secondDigit
= (int)(dec
- (firstDigit
*16.0));
139 (*ch1
) = (char) hexArray
[firstDigit
];
140 (*ch2
) = (char) hexArray
[secondDigit
];
143 // Convert decimal integer to 2-character hex string
144 wxString
wxDecToHex(int dec
)
147 wxDecToHex(dec
, buf
);
148 return wxString(buf
);
151 // ----------------------------------------------------------------------------
153 // ----------------------------------------------------------------------------
155 // Return the current date/time
160 wxDateTime now
= wxDateTime::Now();
163 return wxEmptyString
;
166 time_t now
= time(NULL
);
167 char *date
= ctime(&now
);
169 return wxString::FromAscii(date
);
173 #if WXWIN_COMPATIBILITY_2_8
174 void wxUsleep(unsigned long milliseconds
)
176 wxMilliSleep(milliseconds
);
180 const wxChar
*wxGetInstallPrefix()
184 if ( wxGetEnv(wxT("WXPREFIX"), &prefix
) )
185 return prefix
.c_str();
187 #ifdef wxINSTALL_PREFIX
188 return wxT(wxINSTALL_PREFIX
);
190 return wxEmptyString
;
194 wxString
wxGetDataDir()
196 wxString dir
= wxGetInstallPrefix();
197 dir
<< wxFILE_SEP_PATH
<< wxT("share") << wxFILE_SEP_PATH
<< wxT("wx");
201 bool wxIsPlatformLittleEndian()
203 // Are we little or big endian? This method is from Harbison & Steele.
207 char c
[sizeof(long)];
215 // ----------------------------------------------------------------------------
217 // ----------------------------------------------------------------------------
220 * Class to make it easier to specify platform-dependent values
223 wxArrayInt
* wxPlatform::sm_customPlatforms
= NULL
;
225 void wxPlatform::Copy(const wxPlatform
& platform
)
227 m_longValue
= platform
.m_longValue
;
228 m_doubleValue
= platform
.m_doubleValue
;
229 m_stringValue
= platform
.m_stringValue
;
232 wxPlatform
wxPlatform::If(int platform
, long value
)
235 return wxPlatform(value
);
240 wxPlatform
wxPlatform::IfNot(int platform
, long value
)
243 return wxPlatform(value
);
248 wxPlatform
& wxPlatform::ElseIf(int platform
, long value
)
255 wxPlatform
& wxPlatform::ElseIfNot(int platform
, long value
)
262 wxPlatform
wxPlatform::If(int platform
, double value
)
265 return wxPlatform(value
);
270 wxPlatform
wxPlatform::IfNot(int platform
, double value
)
273 return wxPlatform(value
);
278 wxPlatform
& wxPlatform::ElseIf(int platform
, double value
)
281 m_doubleValue
= value
;
285 wxPlatform
& wxPlatform::ElseIfNot(int platform
, double value
)
288 m_doubleValue
= value
;
292 wxPlatform
wxPlatform::If(int platform
, const wxString
& value
)
295 return wxPlatform(value
);
300 wxPlatform
wxPlatform::IfNot(int platform
, const wxString
& value
)
303 return wxPlatform(value
);
308 wxPlatform
& wxPlatform::ElseIf(int platform
, const wxString
& value
)
311 m_stringValue
= value
;
315 wxPlatform
& wxPlatform::ElseIfNot(int platform
, const wxString
& value
)
318 m_stringValue
= value
;
322 wxPlatform
& wxPlatform::Else(long value
)
328 wxPlatform
& wxPlatform::Else(double value
)
330 m_doubleValue
= value
;
334 wxPlatform
& wxPlatform::Else(const wxString
& value
)
336 m_stringValue
= value
;
340 void wxPlatform::AddPlatform(int platform
)
342 if (!sm_customPlatforms
)
343 sm_customPlatforms
= new wxArrayInt
;
344 sm_customPlatforms
->Add(platform
);
347 void wxPlatform::ClearPlatforms()
349 wxDELETE(sm_customPlatforms
);
352 /// Function for testing current platform
354 bool wxPlatform::Is(int platform
)
357 if (platform
== wxOS_WINDOWS
)
361 if (platform
== wxOS_WINDOWS_CE
)
367 // FIXME: wxWinPocketPC and wxWinSmartPhone are unknown symbols
369 #if defined(__WXWINCE__) && defined(__POCKETPC__)
370 if (platform
== wxWinPocketPC
)
373 #if defined(__WXWINCE__) && defined(__SMARTPHONE__)
374 if (platform
== wxWinSmartPhone
)
381 if (platform
== wxPORT_GTK
)
385 if (platform
== wxPORT_MAC
)
389 if (platform
== wxPORT_X11
)
393 if (platform
== wxOS_UNIX
)
397 if (platform
== wxPORT_MGL
)
401 if (platform
== wxOS_OS2
)
405 if (platform
== wxPORT_PM
)
409 if (platform
== wxPORT_MAC
)
413 if (sm_customPlatforms
&& sm_customPlatforms
->Index(platform
) != wxNOT_FOUND
)
419 // ----------------------------------------------------------------------------
420 // network and user id functions
421 // ----------------------------------------------------------------------------
423 // Get Full RFC822 style email address
424 bool wxGetEmailAddress(wxChar
*address
, int maxSize
)
426 wxString email
= wxGetEmailAddress();
430 wxStrlcpy(address
, email
.t_str(), maxSize
);
435 wxString
wxGetEmailAddress()
439 wxString host
= wxGetFullHostName();
442 wxString user
= wxGetUserId();
445 email
<< user
<< wxT('@') << host
;
452 wxString
wxGetUserId()
454 static const int maxLoginLen
= 256; // FIXME arbitrary number
457 bool ok
= wxGetUserId(wxStringBuffer(buf
, maxLoginLen
), maxLoginLen
);
465 wxString
wxGetUserName()
467 static const int maxUserNameLen
= 1024; // FIXME arbitrary number
470 bool ok
= wxGetUserName(wxStringBuffer(buf
, maxUserNameLen
), maxUserNameLen
);
478 wxString
wxGetHostName()
480 static const size_t hostnameSize
= 257;
483 bool ok
= wxGetHostName(wxStringBuffer(buf
, hostnameSize
), hostnameSize
);
491 wxString
wxGetFullHostName()
493 static const size_t hostnameSize
= 257;
496 bool ok
= wxGetFullHostName(wxStringBuffer(buf
, hostnameSize
), hostnameSize
);
504 wxString
wxGetHomeDir()
514 wxString
wxGetCurrentDir()
521 ok
= getcwd(dir
.GetWriteBuf(len
+ 1), len
) != NULL
;
526 if ( errno
!= ERANGE
)
528 wxLogSysError(wxT("Failed to get current directory"));
530 return wxEmptyString
;
534 // buffer was too small, retry with a larger one
546 // ----------------------------------------------------------------------------
548 // ----------------------------------------------------------------------------
550 // wxDoExecuteWithCapture() helper: reads an entire stream into one array
552 // returns true if ok, false if error
554 static bool ReadAll(wxInputStream
*is
, wxArrayString
& output
)
556 wxCHECK_MSG( is
, false, wxT("NULL stream in wxExecute()?") );
558 // the stream could be already at EOF or in wxSTREAM_BROKEN_PIPE state
561 wxTextInputStream
tis(*is
);
565 wxString line
= tis
.ReadLine();
567 // check for EOF before other errors as it's not really an error
570 // add the last, possibly incomplete, line
576 // any other error is fatal
585 #endif // wxUSE_STREAMS
587 // this is a private function because it hasn't a clean interface: the first
588 // array is passed by reference, the second by pointer - instead we have 2
589 // public versions of wxExecute() below
590 static long wxDoExecuteWithCapture(const wxString
& command
,
591 wxArrayString
& output
,
592 wxArrayString
* error
,
595 // create a wxProcess which will capture the output
596 wxProcess
*process
= new wxProcess
;
599 long rc
= wxExecute(command
, wxEXEC_SYNC
| flags
, process
);
604 if ( !ReadAll(process
->GetInputStream(), output
) )
609 if ( !ReadAll(process
->GetErrorStream(), *error
) )
617 #endif // wxUSE_STREAMS/!wxUSE_STREAMS
624 long wxExecute(const wxString
& command
, wxArrayString
& output
, int flags
)
626 return wxDoExecuteWithCapture(command
, output
, NULL
, flags
);
629 long wxExecute(const wxString
& command
,
630 wxArrayString
& output
,
631 wxArrayString
& error
,
634 return wxDoExecuteWithCapture(command
, output
, &error
, flags
);
637 // ----------------------------------------------------------------------------
639 // ----------------------------------------------------------------------------
642 static long wxCurrentId
= 100;
646 // skip the part of IDs space that contains hard-coded values:
647 if (wxCurrentId
== wxID_LOWEST
)
648 wxCurrentId
= wxID_HIGHEST
+ 1;
650 return wxCurrentId
++;
654 wxGetCurrentId(void) { return wxCurrentId
; }
657 wxRegisterId (long id
)
659 if (id
>= wxCurrentId
)
660 wxCurrentId
= id
+ 1;
663 // ----------------------------------------------------------------------------
664 // wxQsort, adapted by RR to allow user_data
665 // ----------------------------------------------------------------------------
667 /* This file is part of the GNU C Library.
668 Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
670 Douglas Schmidt kindly gave permission to relicence the
671 code under the wxWindows licence:
673 From: "Douglas C. Schmidt" <schmidt@dre.vanderbilt.edu>
674 To: Robert Roebling <robert.roebling@uni-ulm.de>
675 Subject: Re: qsort licence
676 Date: Mon, 23 Jul 2007 03:44:25 -0500
677 Sender: schmidt@dre.vanderbilt.edu
678 Message-Id: <20070723084426.64F511000A8@tango.dre.vanderbilt.edu>
682 > [...] I'm asking if you'd be willing to relicence your code
683 > under the wxWindows licence. [...]
685 That's fine with me [...]
692 /* Byte-wise swap two items of size SIZE. */
693 #define SWAP(a, b, size) \
696 register size_t __size = (size); \
697 register char *__a = (a), *__b = (b); \
703 } while (--__size > 0); \
706 /* Discontinue quicksort algorithm when partition gets below this size.
707 This particular magic number was chosen to work best on a Sun 4/260. */
710 /* Stack node declarations used to store unfulfilled partition obligations. */
717 /* The next 4 #defines implement a very fast in-line stack abstraction. */
718 #define STACK_SIZE (8 * sizeof(unsigned long int))
719 #define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
720 #define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
721 #define STACK_NOT_EMPTY (stack < top)
724 /* Order size using quicksort. This implementation incorporates
725 four optimizations discussed in Sedgewick:
727 1. Non-recursive, using an explicit stack of pointer that store the
728 next array partition to sort. To save time, this maximum amount
729 of space required to store an array of MAX_INT is allocated on the
730 stack. Assuming a 32-bit integer, this needs only 32 *
731 sizeof(stack_node) == 136 bits. Pretty cheap, actually.
733 2. Chose the pivot element using a median-of-three decision tree.
734 This reduces the probability of selecting a bad pivot value and
735 eliminates certain extraneous comparisons.
737 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
738 insertion sort to order the MAX_THRESH items within each partition.
739 This is a big win, since insertion sort is faster for small, mostly
740 sorted array segments.
742 4. The larger of the two sub-partitions is always pushed onto the
743 stack first, with the algorithm then concentrating on the
744 smaller partition. This *guarantees* no more than log (n)
745 stack size is needed (actually O(1) in this case)! */
747 void wxQsort(void *const pbase
, size_t total_elems
,
748 size_t size
, CMPFUNCDATA cmp
, const void* user_data
)
750 register char *base_ptr
= (char *) pbase
;
751 const size_t max_thresh
= MAX_THRESH
* size
;
753 if (total_elems
== 0)
754 /* Avoid lossage with unsigned arithmetic below. */
757 if (total_elems
> MAX_THRESH
)
760 char *hi
= &lo
[size
* (total_elems
- 1)];
761 stack_node stack
[STACK_SIZE
];
762 stack_node
*top
= stack
;
766 while (STACK_NOT_EMPTY
)
771 /* Select median value from among LO, MID, and HI. Rearrange
772 LO and HI so the three values are sorted. This lowers the
773 probability of picking a pathological pivot value and
774 skips a comparison for both the LEFT_PTR and RIGHT_PTR. */
776 char *mid
= lo
+ size
* ((hi
- lo
) / size
>> 1);
778 if ((*cmp
) ((void *) mid
, (void *) lo
, user_data
) < 0)
779 SWAP (mid
, lo
, size
);
780 if ((*cmp
) ((void *) hi
, (void *) mid
, user_data
) < 0)
781 SWAP (mid
, hi
, size
);
784 if ((*cmp
) ((void *) mid
, (void *) lo
, user_data
) < 0)
785 SWAP (mid
, lo
, size
);
787 left_ptr
= lo
+ size
;
788 right_ptr
= hi
- size
;
790 /* Here's the famous ``collapse the walls'' section of quicksort.
791 Gotta like those tight inner loops! They are the main reason
792 that this algorithm runs much faster than others. */
795 while ((*cmp
) ((void *) left_ptr
, (void *) mid
, user_data
) < 0)
798 while ((*cmp
) ((void *) mid
, (void *) right_ptr
, user_data
) < 0)
801 if (left_ptr
< right_ptr
)
803 SWAP (left_ptr
, right_ptr
, size
);
806 else if (mid
== right_ptr
)
811 else if (left_ptr
== right_ptr
)
818 while (left_ptr
<= right_ptr
);
820 /* Set up pointers for next iteration. First determine whether
821 left and right partitions are below the threshold size. If so,
822 ignore one or both. Otherwise, push the larger partition's
823 bounds on the stack and continue sorting the smaller one. */
825 if ((size_t) (right_ptr
- lo
) <= max_thresh
)
827 if ((size_t) (hi
- left_ptr
) <= max_thresh
)
828 /* Ignore both small partitions. */
831 /* Ignore small left partition. */
834 else if ((size_t) (hi
- left_ptr
) <= max_thresh
)
835 /* Ignore small right partition. */
837 else if ((right_ptr
- lo
) > (hi
- left_ptr
))
839 /* Push larger left partition indices. */
840 PUSH (lo
, right_ptr
);
845 /* Push larger right partition indices. */
852 /* Once the BASE_PTR array is partially sorted by quicksort the rest
853 is completely sorted using insertion sort, since this is efficient
854 for partitions below MAX_THRESH size. BASE_PTR points to the beginning
855 of the array to sort, and END_PTR points at the very last element in
856 the array (*not* one beyond it!). */
859 char *const end_ptr
= &base_ptr
[size
* (total_elems
- 1)];
860 char *tmp_ptr
= base_ptr
;
861 char *thresh
= base_ptr
+ max_thresh
;
862 if ( thresh
> end_ptr
)
864 register char *run_ptr
;
866 /* Find smallest element in first threshold and place it at the
867 array's beginning. This is the smallest array element,
868 and the operation speeds up insertion sort's inner loop. */
870 for (run_ptr
= tmp_ptr
+ size
; run_ptr
<= thresh
; run_ptr
+= size
)
871 if ((*cmp
) ((void *) run_ptr
, (void *) tmp_ptr
, user_data
) < 0)
874 if (tmp_ptr
!= base_ptr
)
875 SWAP (tmp_ptr
, base_ptr
, size
);
877 /* Insertion sort, running from left-hand-side up to right-hand-side. */
879 run_ptr
= base_ptr
+ size
;
880 while ((run_ptr
+= size
) <= end_ptr
)
882 tmp_ptr
= run_ptr
- size
;
883 while ((*cmp
) ((void *) run_ptr
, (void *) tmp_ptr
, user_data
) < 0)
887 if (tmp_ptr
!= run_ptr
)
891 trav
= run_ptr
+ size
;
892 while (--trav
>= run_ptr
)
897 for (hi
= lo
= trav
; (lo
-= size
) >= tmp_ptr
; hi
= lo
)
910 // ============================================================================
911 // GUI-only functions from now on
912 // ============================================================================
916 // this function is only really implemented for X11-based ports, including GTK1
917 // (GTK2 sets detectable auto-repeat automatically anyhow)
918 #if !(defined(__WXX11__) || defined(__WXMOTIF__) || \
919 (defined(__WXGTK__) && !defined(__WXGTK20__)))
920 bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag
) )
924 #endif // !X11-based port
926 // ----------------------------------------------------------------------------
927 // Launch default browser
928 // ----------------------------------------------------------------------------
930 #if defined(__WXMSW__)
932 // implemented in a port-specific utils source file:
933 bool wxDoLaunchDefaultBrowser(const wxString
& url
, const wxString
& scheme
, int flags
);
935 #elif defined(__WXX11__) || defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || \
936 (defined(__WXOSX__) )
938 // implemented in a port-specific utils source file:
939 bool wxDoLaunchDefaultBrowser(const wxString
& url
, int flags
);
943 // a "generic" implementation:
944 bool wxDoLaunchDefaultBrowser(const wxString
& url
, int flags
)
946 // on other platforms try to use mime types or wxExecute...
952 wxFileType
*ft
= wxTheMimeTypesManager
->GetFileTypeFromExtension(wxT("html"));
956 ft
->GetMimeType(&mt
);
958 ok
= ft
->GetOpenCommand(&cmd
, wxFileType::MessageParameters(url
));
961 #endif // wxUSE_MIMETYPE
963 if ( !ok
|| cmd
.empty() )
965 // fallback to checking for the BROWSER environment variable
966 if ( !wxGetEnv(wxT("BROWSER"), &cmd
) || cmd
.empty() )
967 cmd
<< wxT(' ') << url
;
970 ok
= ( !cmd
.empty() && wxExecute(cmd
) );
974 // no file type for HTML extension
975 wxLogError(_("No default application configured for HTML files."));
981 static bool DoLaunchDefaultBrowserHelper(const wxString
& urlOrig
, int flags
)
983 // NOTE: we don't have to care about the wxBROWSER_NOBUSYCURSOR flag
984 // as it was already handled by wxLaunchDefaultBrowser
988 wxString
url(urlOrig
), scheme
;
991 // this check is useful to avoid that wxURI recognizes as scheme parts of
992 // the filename, in case urlOrig is a local filename
993 // (e.g. "C:\\test.txt" when parsed by wxURI reports a scheme == "C")
994 bool hasValidScheme
= uri
.HasScheme() && uri
.GetScheme().length() > 1;
996 #if defined(__WXMSW__)
998 // NOTE: when testing wxMSW's wxLaunchDefaultBrowser all possible forms
999 // of the URL/flags should be tested; e.g.:
1001 // for (int i=0; i<2; i++)
1003 // // test arguments without a valid URL scheme:
1004 // wxLaunchDefaultBrowser("C:\\test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1005 // wxLaunchDefaultBrowser("wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1007 // // test arguments with different valid schemes:
1008 // wxLaunchDefaultBrowser("file:/C%3A/test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1009 // wxLaunchDefaultBrowser("http://wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1010 // wxLaunchDefaultBrowser("mailto:user@host.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
1012 // (assuming you have a C:\test.txt file)
1014 if ( !hasValidScheme
)
1016 if (wxFileExists(urlOrig
) || wxDirExists(urlOrig
))
1019 // do not prepend the file scheme to the URL as ShellExecuteEx() doesn't like it
1023 url
.Prepend(wxS("http://"));
1027 else if ( hasValidScheme
)
1029 scheme
= uri
.GetScheme();
1031 if ( uri
.GetScheme() == "file" )
1033 // TODO: extract URLToFileName() to some always compiled in
1035 #if wxUSE_FILESYSTEM
1036 // ShellExecuteEx() doesn't like the "file" scheme when opening local files;
1038 url
= wxFileSystem::URLToFileName(url
).GetFullPath();
1039 #endif // wxUSE_FILESYSTEM
1043 if (wxDoLaunchDefaultBrowser(url
, scheme
, flags
))
1045 //else: call wxLogSysError
1047 if ( !hasValidScheme
)
1049 // set the scheme of url to "http" or "file" if it does not have one
1050 if (wxFileExists(urlOrig
) || wxDirExists(urlOrig
))
1051 url
.Prepend(wxS("file://"));
1053 url
.Prepend(wxS("http://"));
1056 if (wxDoLaunchDefaultBrowser(url
, flags
))
1058 //else: call wxLogSysError
1061 wxLogSysError(_("Failed to open URL \"%s\" in default browser."),
1067 bool wxLaunchDefaultBrowser(const wxString
& url
, int flags
)
1069 // NOTE: as documented, "url" may be both a real well-formed URL
1070 // and a local file name
1072 if ( flags
& wxBROWSER_NOBUSYCURSOR
)
1073 return DoLaunchDefaultBrowserHelper(url
, flags
);
1076 return DoLaunchDefaultBrowserHelper(url
, flags
);
1079 // ----------------------------------------------------------------------------
1080 // Menu accelerators related functions
1081 // ----------------------------------------------------------------------------
1083 #if WXWIN_COMPATIBILITY_2_6
1084 wxChar
*wxStripMenuCodes(const wxChar
*in
, wxChar
*out
)
1087 wxString s
= wxMenuItem::GetLabelText(in
);
1090 wxString s
= wxStripMenuCodes(str
);
1091 #endif // wxUSE_MENUS
1094 // go smash their buffer if it's not big enough - I love char * params
1095 memcpy(out
, s
.c_str(), s
.length() * sizeof(wxChar
));
1099 out
= new wxChar
[s
.length() + 1];
1100 wxStrcpy(out
, s
.c_str());
1107 wxString
wxStripMenuCodes(const wxString
& in
, int flags
)
1109 wxASSERT_MSG( flags
, wxT("this is useless to call without any flags") );
1113 size_t len
= in
.length();
1116 for ( size_t n
= 0; n
< len
; n
++ )
1119 if ( (flags
& wxStrip_Mnemonics
) && ch
== wxT('&') )
1121 // skip it, it is used to introduce the accel char (or to quote
1122 // itself in which case it should still be skipped): note that it
1123 // can't be the last character of the string
1126 wxLogDebug(wxT("Invalid menu string '%s'"), in
.c_str());
1130 // use the next char instead
1134 else if ( (flags
& wxStrip_Accel
) && ch
== wxT('\t') )
1136 // everything after TAB is accel string, exit the loop
1146 // ----------------------------------------------------------------------------
1147 // Window search functions
1148 // ----------------------------------------------------------------------------
1151 * If parent is non-NULL, look through children for a label or title
1152 * matching the specified string. If NULL, look through all top-level windows.
1157 wxFindWindowByLabel (const wxString
& title
, wxWindow
* parent
)
1159 return wxWindow::FindWindowByLabel( title
, parent
);
1164 * If parent is non-NULL, look through children for a name
1165 * matching the specified string. If NULL, look through all top-level windows.
1170 wxFindWindowByName (const wxString
& name
, wxWindow
* parent
)
1172 return wxWindow::FindWindowByName( name
, parent
);
1175 // Returns menu item id or wxNOT_FOUND if none.
1177 wxFindMenuItemId(wxFrame
*frame
,
1178 const wxString
& menuString
,
1179 const wxString
& itemString
)
1182 wxMenuBar
*menuBar
= frame
->GetMenuBar ();
1184 return menuBar
->FindMenuItem (menuString
, itemString
);
1185 #else // !wxUSE_MENUS
1187 wxUnusedVar(menuString
);
1188 wxUnusedVar(itemString
);
1189 #endif // wxUSE_MENUS/!wxUSE_MENUS
1194 // Try to find the deepest child that contains 'pt'.
1195 // We go backwards, to try to allow for controls that are spacially
1196 // within other controls, but are still siblings (e.g. buttons within
1197 // static boxes). Static boxes are likely to be created _before_ controls
1198 // that sit inside them.
1199 wxWindow
* wxFindWindowAtPoint(wxWindow
* win
, const wxPoint
& pt
)
1201 if (!win
->IsShown())
1204 // Hack for wxNotebook case: at least in wxGTK, all pages
1205 // claim to be shown, so we must only deal with the selected one.
1207 if (win
->IsKindOf(CLASSINFO(wxNotebook
)))
1209 wxNotebook
* nb
= (wxNotebook
*) win
;
1210 int sel
= nb
->GetSelection();
1213 wxWindow
* child
= nb
->GetPage(sel
);
1214 wxWindow
* foundWin
= wxFindWindowAtPoint(child
, pt
);
1221 wxWindowList::compatibility_iterator node
= win
->GetChildren().GetLast();
1224 wxWindow
* child
= node
->GetData();
1225 wxWindow
* foundWin
= wxFindWindowAtPoint(child
, pt
);
1228 node
= node
->GetPrevious();
1231 wxPoint pos
= win
->GetPosition();
1232 wxSize sz
= win
->GetSize();
1233 if ( !win
->IsTopLevel() && win
->GetParent() )
1235 pos
= win
->GetParent()->ClientToScreen(pos
);
1238 wxRect
rect(pos
, sz
);
1239 if (rect
.Contains(pt
))
1245 wxWindow
* wxGenericFindWindowAtPoint(const wxPoint
& pt
)
1247 // Go backwards through the list since windows
1248 // on top are likely to have been appended most
1250 wxWindowList::compatibility_iterator node
= wxTopLevelWindows
.GetLast();
1253 wxWindow
* win
= node
->GetData();
1254 wxWindow
* found
= wxFindWindowAtPoint(win
, pt
);
1257 node
= node
->GetPrevious();
1262 // ----------------------------------------------------------------------------
1264 // ----------------------------------------------------------------------------
1267 * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
1268 * since otherwise the generic code may be pulled in unnecessarily.
1273 int wxMessageBox(const wxString
& message
, const wxString
& caption
, long style
,
1274 wxWindow
*parent
, int WXUNUSED(x
), int WXUNUSED(y
) )
1276 // add the appropriate icon unless this was explicitly disabled by use of
1278 if ( !(style
& wxICON_NONE
) && !(style
& wxICON_MASK
) )
1280 style
|= style
& wxYES
? wxICON_QUESTION
: wxICON_INFORMATION
;
1283 wxMessageDialog
dialog(parent
, message
, caption
, style
);
1285 int ans
= dialog
.ShowModal();
1298 wxFAIL_MSG( wxT("unexpected return code from wxMessageDialog") );
1303 void wxInfoMessageBox(wxWindow
* parent
)
1305 // don't translate these strings, they're for diagnostics purposes only
1307 msg
.Printf(wxS("wxWidgets Library (%s port)\n")
1308 wxS("Version %d.%d.%d (Unicode: %s, debug level: %d),\n")
1309 wxS("compiled at %s %s\n\n")
1310 wxS("Runtime version of toolkit used is %d.%d.\n"),
1311 wxPlatformInfo::Get().GetPortIdName(),
1315 #if wxUSE_UNICODE_UTF8
1325 wxPlatformInfo::Get().GetToolkitMajorVersion(),
1326 wxPlatformInfo::Get().GetToolkitMinorVersion()
1330 msg
+= wxString::Format("Compile-time GTK+ version is %d.%d.%d.\n",
1336 msg
+= wxS("\nCopyright (c) 1995-2010 wxWidgets team");
1338 wxMessageBox(msg
, wxT("wxWidgets information"),
1339 wxICON_INFORMATION
| wxOK
,
1343 #endif // wxUSE_MSGDLG
1347 wxString
wxGetTextFromUser(const wxString
& message
, const wxString
& caption
,
1348 const wxString
& defaultValue
, wxWindow
*parent
,
1349 wxCoord x
, wxCoord y
, bool centre
)
1352 long style
= wxTextEntryDialogStyle
;
1359 wxTextEntryDialog
dialog(parent
, message
, caption
, defaultValue
, style
, wxPoint(x
, y
));
1361 if (dialog
.ShowModal() == wxID_OK
)
1363 str
= dialog
.GetValue();
1369 wxString
wxGetPasswordFromUser(const wxString
& message
,
1370 const wxString
& caption
,
1371 const wxString
& defaultValue
,
1373 wxCoord x
, wxCoord y
, bool centre
)
1376 long style
= wxTextEntryDialogStyle
;
1383 wxPasswordEntryDialog
dialog(parent
, message
, caption
, defaultValue
,
1384 style
, wxPoint(x
, y
));
1385 if ( dialog
.ShowModal() == wxID_OK
)
1387 str
= dialog
.GetValue();
1393 #endif // wxUSE_TEXTDLG
1397 wxColour
wxGetColourFromUser(wxWindow
*parent
,
1398 const wxColour
& colInit
,
1399 const wxString
& caption
,
1400 wxColourData
*ptrData
)
1402 // contains serialized representation of wxColourData used the last time
1403 // the dialog was shown: we want to reuse it the next time in order to show
1404 // the same custom colours to the user (and we can't just have static
1405 // wxColourData itself because it's a GUI object and so should be destroyed
1406 // before GUI shutdown and doing it during static cleanup is too late)
1407 static wxString s_strColourData
;
1413 if ( !s_strColourData
.empty() )
1415 if ( !data
.FromString(s_strColourData
) )
1417 wxFAIL_MSG( "bug in wxColourData::FromString()?" );
1421 // we don't get back the "choose full" flag value from the native
1422 // dialog and so we can't preserve it between runs, so we decide to
1423 // always use it as it seems better than not using it (user can
1424 // just ignore the extra controls in the dialog but having to click
1425 // a button each time to show them would be very annoying
1426 data
.SetChooseFull(true);
1431 if ( colInit
.IsOk() )
1433 ptrData
->SetColour(colInit
);
1437 wxColourDialog
dialog(parent
, ptrData
);
1438 if (!caption
.empty())
1439 dialog
.SetTitle(caption
);
1440 if ( dialog
.ShowModal() == wxID_OK
)
1442 *ptrData
= dialog
.GetColourData();
1443 colRet
= ptrData
->GetColour();
1444 s_strColourData
= ptrData
->ToString();
1446 //else: leave colRet invalid
1451 #endif // wxUSE_COLOURDLG
1455 wxFont
wxGetFontFromUser(wxWindow
*parent
, const wxFont
& fontInit
, const wxString
& caption
)
1458 if ( fontInit
.Ok() )
1460 data
.SetInitialFont(fontInit
);
1464 wxFontDialog
dialog(parent
, data
);
1465 if (!caption
.empty())
1466 dialog
.SetTitle(caption
);
1467 if ( dialog
.ShowModal() == wxID_OK
)
1469 fontRet
= dialog
.GetFontData().GetChosenFont();
1471 //else: leave it invalid
1476 #endif // wxUSE_FONTDLG
1478 // ----------------------------------------------------------------------------
1479 // wxSafeYield and supporting functions
1480 // ----------------------------------------------------------------------------
1482 void wxEnableTopLevelWindows(bool enable
)
1484 wxWindowList::compatibility_iterator node
;
1485 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1486 node
->GetData()->Enable(enable
);
1489 wxWindowDisabler::wxWindowDisabler(bool disable
)
1491 m_disabled
= disable
;
1496 wxWindowDisabler::wxWindowDisabler(wxWindow
*winToSkip
)
1499 DoDisable(winToSkip
);
1502 void wxWindowDisabler::DoDisable(wxWindow
*winToSkip
)
1504 // remember the top level windows which were already disabled, so that we
1505 // don't reenable them later
1506 m_winDisabled
= NULL
;
1508 wxWindowList::compatibility_iterator node
;
1509 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1511 wxWindow
*winTop
= node
->GetData();
1512 if ( winTop
== winToSkip
)
1515 // we don't need to disable the hidden or already disabled windows
1516 if ( winTop
->IsEnabled() && winTop
->IsShown() )
1522 if ( !m_winDisabled
)
1524 m_winDisabled
= new wxWindowList
;
1527 m_winDisabled
->Append(winTop
);
1532 wxWindowDisabler::~wxWindowDisabler()
1537 wxWindowList::compatibility_iterator node
;
1538 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
1540 wxWindow
*winTop
= node
->GetData();
1541 if ( !m_winDisabled
|| !m_winDisabled
->Find(winTop
) )
1545 //else: had been already disabled, don't reenable
1548 delete m_winDisabled
;
1551 // Yield to other apps/messages and disable user input to all windows except
1553 bool wxSafeYield(wxWindow
*win
, bool onlyIfNeeded
)
1555 wxWindowDisabler
wd(win
);
1559 rc
= wxYieldIfNeeded();
1566 // ----------------------------------------------------------------------------
1567 // wxApp::Yield() wrappers for backwards compatibility
1568 // ----------------------------------------------------------------------------
1572 return wxTheApp
&& wxTheApp
->Yield();
1575 bool wxYieldIfNeeded()
1577 return wxTheApp
&& wxTheApp
->Yield(true);