]>
git.saurik.com Git - wxWidgets.git/blob - src/common/utilscmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Miscellaneous utility functions and classes
4 // Author: Julian Smart
8 // Copyright: (c) 1998 Julian Smart
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "utils.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
26 #include "wx/window.h"
29 #include "wx/msgdlg.h"
30 #include "wx/textdlg.h"
33 #include "wx/ioswrap.h"
45 #if !defined(__WATCOMC__)
46 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
52 #include <sys/types.h>
60 // Pattern matching code.
61 // Yes, this path is deliberate (for Borland compilation)
62 #ifdef wx_mac /* MATTHEW: [5] Mac doesn't like paths with "/" */
65 #include "../common/glob.inc"
72 #define _MAXPATHLEN 500
74 extern wxChar
*wxBuffer
;
76 // ----------------------------------------------------------------------------
78 // ----------------------------------------------------------------------------
80 static wxWindow
*wxFindWindowByLabel1(const wxString
& title
, wxWindow
* parent
);
81 static wxWindow
*wxFindWindowByName1 (const wxString
& title
, wxWindow
* parent
);
84 int strcasecmp(const char *str_1
, const char *str_2
)
88 c1
= tolower(*str_1
++);
89 c2
= tolower(*str_2
++);
90 } while ( c1
&& (c1
== c2
) );
95 int strncasecmp(const char *str_1
, const char *str_2
, size_t maxchar
)
101 c1
= tolower(*str_1
++);
102 c2
= tolower(*str_2
++);
114 // we have no strI functions under VMS, therefore I have implemented
115 // an inefficient but portable version: convert copies of strings to lowercase
116 // and then use the normal comparison
117 static void myLowerString(char *s
)
120 if(isalpha(*s
)) *s
= (char)tolower(*s
);
125 int strcasecmp(const char *str_1
, const char *str_2
)
127 char *temp1
= new char[strlen(str_1
)+1];
128 char *temp2
= new char[strlen(str_2
)+1];
131 myLowerString(temp1
);
132 myLowerString(temp2
);
134 int result
= strcmp(temp1
,temp2
);
141 int strncasecmp(const char *str_1
, const char *str_2
, size_t maxchar
)
143 char *temp1
= new char[strlen(str_1
)+1];
144 char *temp2
= new char[strlen(str_2
)+1];
147 myLowerString(temp1
);
148 myLowerString(temp2
);
150 int result
= strncmp(temp1
,temp2
,maxchar
);
162 #define strcasecmp stricmp
163 #define strncasecmp strnicmp
165 #define strcasecmp _stricmp
166 #define strncasecmp _strnicmp
173 #define strcasecmp stricmp
174 #define strncasecmp strnicmp
177 // This declaration is missing in SunOS!
178 // (Yes, I know it is NOT ANSI-C but its in BSD libc)
179 #if defined(__xlC) || defined(__AIX__) || defined(__GNUG__)
182 int strcasecmp (const char *, const char *);
183 int strncasecmp (const char *, const char *, size_t);
186 #endif /* __WXMSW__ */
190 copystring (const wxChar
*s
)
192 if (s
== NULL
) s
= _T("");
193 size_t len
= wxStrlen (s
) + 1;
195 wxChar
*news
= new wxChar
[len
];
196 memcpy (news
, s
, len
* sizeof(wxChar
)); // Should be the fastest
202 static long wxCurrentId
= 100;
207 return wxCurrentId
++;
211 wxGetCurrentId(void) { return wxCurrentId
; }
214 wxRegisterId (long id
)
216 if (id
>= wxCurrentId
)
217 wxCurrentId
= id
+ 1;
221 StringToFloat (wxChar
*s
, float *number
)
223 if (s
&& *s
&& number
)
224 *number
= (float) wxStrtod (s
, (wxChar
**) NULL
);
228 StringToDouble (wxChar
*s
, double *number
)
230 if (s
&& *s
&& number
)
231 *number
= wxStrtod (s
, (wxChar
**) NULL
);
235 FloatToString (float number
, const wxChar
*fmt
)
237 static wxChar buf
[256];
239 // sprintf (buf, "%.2f", number);
240 wxSprintf (buf
, fmt
, number
);
245 DoubleToString (double number
, const wxChar
*fmt
)
247 static wxChar buf
[256];
249 wxSprintf (buf
, fmt
, number
);
254 StringToInt (wxChar
*s
, int *number
)
256 if (s
&& *s
&& number
)
257 *number
= (int) wxStrtol (s
, (wxChar
**) NULL
, 10);
261 StringToLong (wxChar
*s
, long *number
)
263 if (s
&& *s
&& number
)
264 *number
= wxStrtol (s
, (wxChar
**) NULL
, 10);
268 IntToString (int number
)
270 static wxChar buf
[20];
272 wxSprintf (buf
, _T("%d"), number
);
277 LongToString (long number
)
279 static wxChar buf
[20];
281 wxSprintf (buf
, _T("%ld"), number
);
285 // Array used in DecToHex conversion routine.
286 static wxChar hexArray
[] = _T("0123456789ABCDEF");
288 // Convert 2-digit hex number to decimal
289 int wxHexToDec(const wxString
& buf
)
291 int firstDigit
, secondDigit
;
293 if (buf
.GetChar(0) >= _T('A'))
294 firstDigit
= buf
.GetChar(0) - _T('A') + 10;
296 firstDigit
= buf
.GetChar(0) - _T('0');
298 if (buf
.GetChar(1) >= _T('A'))
299 secondDigit
= buf
.GetChar(1) - _T('A') + 10;
301 secondDigit
= buf
.GetChar(1) - _T('0');
303 return firstDigit
* 16 + secondDigit
;
306 // Convert decimal integer to 2-character hex string
307 void wxDecToHex(int dec
, wxChar
*buf
)
309 int firstDigit
= (int)(dec
/16.0);
310 int secondDigit
= (int)(dec
- (firstDigit
*16.0));
311 buf
[0] = hexArray
[firstDigit
];
312 buf
[1] = hexArray
[secondDigit
];
316 // Convert decimal integer to 2-character hex string
317 wxString
wxDecToHex(int dec
)
320 wxDecToHex(dec
, buf
);
321 return wxString(buf
);
324 // Match a string INDEPENDENT OF CASE
326 StringMatch (char *str1
, char *str2
, bool subString
, bool exact
)
328 if (str1
== NULL
|| str2
== NULL
)
335 int len1
= strlen (str1
);
336 int len2
= strlen (str2
);
339 // Search for str1 in str2
340 // Slow .... but acceptable for short strings
341 for (i
= 0; i
<= len2
- len1
; i
++)
343 if (strncasecmp (str1
, str2
+ i
, len1
) == 0)
349 if (strcasecmp (str1
, str2
) == 0)
354 int len1
= strlen (str1
);
355 int len2
= strlen (str2
);
357 if (strncasecmp (str1
, str2
, wxMin (len1
, len2
)) == 0)
364 // Don't synthesize KeyUp events holding down a key and producing
365 // KeyDown events with autorepeat. On by default and always on
366 // on in wxMSW. wxGTK version in utilsgtk.cpp.
368 bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag
) )
370 return TRUE
; // detectable auto-repeat is the only mode MSW supports
374 // Return the current date/time
376 wxString
wxNow( void )
378 time_t now
= time((time_t *) NULL
);
379 char *date
= ctime(&now
);
381 return wxString(date
);
385 * Strip out any menu codes
388 wxChar
*wxStripMenuCodes (wxChar
*in
, wxChar
*out
)
391 return (wxChar
*) NULL
;
394 out
= copystring(in
);
396 wxChar
*tmpOut
= out
;
402 // Check && -> &, &x -> x
403 if (*++in
== _T('&'))
406 else if (*in
== _T('\t'))
408 // Remove all stuff after \t in X mode, and let the stuff as is
410 // Accelerators are handled in wx_item.cc for Motif, and are not
411 // YET supported in XView
423 wxString
wxStripMenuCodes(const wxString
& str
)
425 wxChar
*buf
= new wxChar
[str
.Length() + 1];
426 wxStripMenuCodes(WXSTRINGCAST str
, buf
);
433 * Window search functions
438 * If parent is non-NULL, look through children for a label or title
439 * matching the specified string. If NULL, look through all top-level windows.
444 wxFindWindowByLabel (const wxString
& title
, wxWindow
* parent
)
448 return wxFindWindowByLabel1(title
, parent
);
452 for ( wxWindowList::Node
* node
= wxTopLevelWindows
.GetFirst();
454 node
= node
->GetNext() )
456 wxWindow
*win
= node
->GetData();
457 wxWindow
*retwin
= wxFindWindowByLabel1 (title
, win
);
463 return (wxWindow
*) NULL
;
468 wxFindWindowByLabel1 (const wxString
& title
, wxWindow
* parent
)
472 if (parent
->GetLabel() == title
)
478 for ( wxWindowList::Node
* node
= parent
->GetChildren().GetFirst();
480 node
= node
->GetNext() )
482 wxWindow
*win
= (wxWindow
*)node
->GetData();
483 wxWindow
*retwin
= wxFindWindowByLabel1 (title
, win
);
490 return (wxWindow
*) NULL
; // Not found
494 * If parent is non-NULL, look through children for a name
495 * matching the specified string. If NULL, look through all top-level windows.
500 wxFindWindowByName (const wxString
& title
, wxWindow
* parent
)
504 return wxFindWindowByName1 (title
, parent
);
508 for ( wxWindowList::Node
* node
= wxTopLevelWindows
.GetFirst();
510 node
= node
->GetNext() )
512 wxWindow
*win
= node
->GetData();
513 wxWindow
*retwin
= wxFindWindowByName1 (title
, win
);
520 // Failed? Try by label instead.
521 return wxFindWindowByLabel(title
, parent
);
526 wxFindWindowByName1 (const wxString
& title
, wxWindow
* parent
)
530 if ( parent
->GetName() == title
)
536 for (wxNode
* node
= parent
->GetChildren().First (); node
; node
= node
->Next ())
538 wxWindow
*win
= (wxWindow
*) node
->Data ();
539 wxWindow
*retwin
= wxFindWindowByName1 (title
, win
);
546 return (wxWindow
*) NULL
; // Not found
550 // Returns menu item id or -1 if none.
552 wxFindMenuItemId (wxFrame
* frame
, const wxString
& menuString
, const wxString
& itemString
)
554 wxMenuBar
*menuBar
= frame
->GetMenuBar ();
557 return menuBar
->FindMenuItem (menuString
, itemString
);
561 On Fri, 21 Jul 1995, Paul Craven wrote:
563 > Is there a way to find the path of running program's executable? I can get
564 > my home directory, and the current directory, but I don't know how to get the
565 > executable directory.
568 The code below (warty as it is), does what you want on most Unix,
569 DOS, and Mac platforms (it's from the ALS Prolog main).
571 || Ken Bowen Applied Logic Systems, Inc. PO Box 180,
572 ||==== Voice: +1 (617)965-9191 Newton Centre,
573 || FAX: +1 (617)965-1636 MA 02159 USA
574 Email: ken@als.com WWW: http://www.als.com
575 ------------------------------------------------------------------------
578 // This code is commented out but it may be integrated with wxWin at
579 // a later date, after testing. Thanks Ken!
582 /*--------------------------------------------------------------------*
583 | whereami is given a filename f in the form: whereami(argv[0])
584 | It returns the directory in which the executable file (containing
585 | this code [main.c] ) may be found. A dot will be returned to indicate
586 | the current directory.
587 *--------------------------------------------------------------------*/
593 register char *cutoff
= NULL
; /* stifle -Wall */
600 * See if the file is accessible either through the current directory
601 * or through an absolute path.
604 if (access(name
, R_OK
) == 0) {
606 /*-------------------------------------------------------------*
607 * The file was accessible without any other work. But the current
608 * working directory might change on us, so if it was accessible
609 * through the cwd, then we should get it for later accesses.
610 *-------------------------------------------------------------*/
613 if (!absolute_pathname(name
)) {
614 #if defined(DOS) || defined(__WIN32__)
620 if (*(name
+ 1) == ':') {
621 if (*name
>= 'a' && *name
<= 'z')
622 drive
= (int) (*name
- 'a' + 1);
624 drive
= (int) (*name
- 'A' + 1);
626 *newrbuf
++ = *(name
+ 1);
627 *newrbuf
++ = DIR_SEPARATOR
;
631 *newrbuf
++ = DIR_SEPARATOR
;
633 if (getcwd(newrbuf
, drive
) == 0) { /* } */
635 if (getcwd(newrbuf
, 1024) == 0) { /* } */
639 if (getwd(imagedir
) == 0) { /* } */
640 #else /* !HAVE_GETWD */
641 if (getcwd(imagedir
, 1024) == 0) {
642 #endif /* !HAVE_GETWD */
644 fatal_error(FE_GETCWD
, 0);
646 for (; *t
; t
++) /* Set t to end of buffer */
648 if (*(t
- 1) == DIR_SEPARATOR
) /* leave slash if already
653 cutoff
= t
; /* otherwise put one in */
654 *t
++ = DIR_SEPARATOR
;
657 #if (!defined(__MAC__) && !defined(__DJGPP__) && !defined(__GO32__) && !defined(__WIN32__))
659 (*t
++ = DIR_SEPARATOR
);
662 /*-------------------------------------------------------------*
663 * Copy the rest of the string and set the cutoff if it was not
664 * already set. If the first character of name is a slash, cutoff
665 * is not presently set but will be on the first iteration of the
667 *-------------------------------------------------------------*/
669 for ((*name
== DIR_SEPARATOR
? (s
= name
+1) : (s
= name
));;) {
670 if (*s
== DIR_SEPARATOR
)
679 /*-------------------------------------------------------------*
680 * Get the path list from the environment. If the path list is
681 * inaccessible for any reason, leave with fatal error.
682 *-------------------------------------------------------------*/
685 if ((s
= getenv("Commands")) == (char *) 0)
687 if ((s
= getenv("PATH")) == (char *) 0)
689 fatal_error(FE_PATH
, 0);
692 * Copy path list into ebuf and set the source pointer to the
693 * beginning of this buffer.
701 while (*s
&& *s
!= PATH_SEPARATOR
)
703 if (t
> imagedir
&& *(t
- 1) == DIR_SEPARATOR
)
704 ; /* do nothing -- slash already is in place */
706 *t
++ = DIR_SEPARATOR
; /* put in the slash */
707 cutoff
= t
- 1; /* set cutoff */
709 if (access(imagedir
, R_OK
) == 0)
713 s
++; /* advance source pointer */
715 fatal_error(FE_INFND
, 0);
720 /*-------------------------------------------------------------*
721 | At this point the full pathname should exist in imagedir and
722 | cutoff should be set to the final slash. We must now determine
723 | whether the file name is a symbolic link or not and chase it down
724 | if it is. Note that we reuse ebuf for getting the link.
725 *-------------------------------------------------------------*/
728 while ((cc
= readlink(imagedir
, ebuf
, 512)) != -1) {
731 if (*s
== DIR_SEPARATOR
) {
738 if (*s
== DIR_SEPARATOR
)
739 cutoff
= t
; /* mark the last slash seen */
740 if (!(*t
++ = *s
++)) /* copy the character */
745 #endif /* HAVE_SYMLINK */
747 strcpy(imagename
, cutoff
+ 1); /* keep the image name */
748 *(cutoff
+ 1) = 0; /* chop off the filename part */
752 void wxEnableTopLevelWindows(bool enable
)
754 wxWindowList::Node
*node
;
755 for ( node
= wxTopLevelWindows
.GetFirst(); node
; node
= node
->GetNext() )
756 node
->GetData()->Enable(enable
);
759 // Yield to other apps/messages and disable user input
760 bool wxSafeYield(wxWindow
*win
)
762 wxEnableTopLevelWindows(FALSE
);
763 // always enable ourselves
767 wxEnableTopLevelWindows(TRUE
);
772 * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
773 * since otherwise the generic code may be pulled in unnecessarily.
776 int wxMessageBox(const wxString
& message
, const wxString
& caption
, long style
,
777 wxWindow
*parent
, int WXUNUSED(x
), int WXUNUSED(y
) )
779 wxMessageDialog
dialog(parent
, message
, caption
, style
);
781 int ans
= dialog
.ShowModal();
802 wxString
wxGetTextFromUser(const wxString
& message
, const wxString
& caption
,
803 const wxString
& defaultValue
, wxWindow
*parent
,
804 int x
, int y
, bool WXUNUSED(centre
) )
806 wxTextEntryDialog
dialog(parent
, message
, caption
, defaultValue
, wxOK
|wxCANCEL
, wxPoint(x
, y
));
807 if (dialog
.ShowModal() == wxID_OK
)
808 return dialog
.GetValue();
812 #endif // wxUSE_TEXTDLG
815 char *strdup(const char *s
)
817 return strcpy( (char*) malloc( strlen( s
) + 1 ) , s
) ;
822 return ( c
>= 0 && c
< 128 ) ;
826 // ----------------------------------------------------------------------------
827 // network and user id functions
828 // ----------------------------------------------------------------------------
830 // Get Full RFC822 style email address
831 bool wxGetEmailAddress(wxChar
*address
, int maxSize
)
833 wxString email
= wxGetEmailAddress();
837 wxStrncpy(address
, email
, maxSize
- 1);
838 address
[maxSize
- 1] = _T('\0');
843 wxString
wxGetEmailAddress()
847 wxString host
= wxGetHostName();
850 wxString user
= wxGetUserId();
853 wxString
email(user
);
854 email
<< _T('@') << host
;
861 wxString
wxGetUserId()
863 static const int maxLoginLen
= 256; // FIXME arbitrary number
866 bool ok
= wxGetUserId(buf
.GetWriteBuf(maxLoginLen
), maxLoginLen
);
875 wxString
wxGetUserName()
877 static const int maxUserNameLen
= 1024; // FIXME arbitrary number
880 bool ok
= wxGetUserName(buf
.GetWriteBuf(maxUserNameLen
), maxUserNameLen
);
889 wxString
wxGetHostName()
891 static const size_t hostnameSize
= 257;
894 bool ok
= wxGetHostName(buf
.GetWriteBuf(hostnameSize
), hostnameSize
);
904 wxString
wxGetFullHostName()
906 static const size_t hostnameSize
= 257;
909 bool ok
= wxGetFullHostName(buf
.GetWriteBuf(hostnameSize
), hostnameSize
);