X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/518b5d2ffbaf7422195537a5512e791be4497591..674ac8b919eecbc201b5f23b470a567cd0565e10:/src/common/utilscmn.cpp diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index f15e7f0bbd..ec09523cc7 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -9,69 +9,87 @@ // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __GNUG__ -#pragma implementation "utils.h" + #pragma implementation "utils.h" #endif // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif #ifndef WX_PRECOMP -#include "wx/defs.h" -#include "wx/utils.h" -#include "wx/window.h" -#include "wx/menu.h" -#include "wx/frame.h" -#include "wx/msgdlg.h" -#include "wx/textdlg.h" -#endif - -#include "wx/ioswrap.h" - -#if wxUSE_IOSTREAMH - #include -#else - #include -#endif + #include "wx/defs.h" + #include "wx/string.h" + #include "wx/utils.h" + #include "wx/intl.h" + #include "wx/log.h" + + #if wxUSE_GUI + #include "wx/window.h" + #include "wx/menu.h" + #include "wx/frame.h" + #include "wx/msgdlg.h" + #include "wx/textdlg.h" + #if wxUSE_ACCEL + #include "wx/menuitem.h" + #include "wx/accel.h" + #endif // wxUSE_ACCEL + #endif // wxUSE_GUI +#endif // WX_PRECOMP #include #include #include #include + #if !defined(__WATCOMC__) #if !(defined(_MSC_VER) && (_MSC_VER > 800)) #include #endif #endif + #include + #ifndef __MWERKS__ -#include -#include + #include + #include #endif #ifdef __SALFORDC__ -#include -#endif - -// Pattern matching code. -// Yes, this path is deliberate (for Borland compilation) -#ifdef wx_mac /* MATTHEW: [5] Mac doesn't like paths with "/" */ -#include "glob.inc" -#else -#include "../common/glob.inc" + #include #endif #ifdef __WXMSW__ -#include "windows.h" + #include "windows.h" #endif -#define _MAXPATHLEN 500 +// ---------------------------------------------------------------------------- +// function protoypes +// ---------------------------------------------------------------------------- + +#if wxUSE_GUI + static wxWindow *wxFindWindowByLabel1(const wxString& title, wxWindow *parent); + static wxWindow *wxFindWindowByName1 (const wxString& title, wxWindow *parent); +#endif // wxUSE_GUI + +// ============================================================================ +// implementation +// ============================================================================ -extern char *wxBuffer; +// ---------------------------------------------------------------------------- +// string functions +// ---------------------------------------------------------------------------- #ifdef __WXMAC__ int strcasecmp(const char *str_1, const char *str_2) @@ -102,8 +120,9 @@ int strncasecmp(const char *str_1, const char *str_2, size_t maxchar) return 0 ; } -#endif -#ifdef __VMS__ +#endif // wxMAC + +#if defined( __VMS__ ) && ( __VMS_VER < 70000000 ) // we have no strI functions under VMS, therefore I have implemented // an inefficient but portable version: convert copies of strings to lowercase // and then use the normal comparison @@ -124,7 +143,7 @@ int strcasecmp(const char *str_1, const char *str_2) myLowerString(temp1); myLowerString(temp2); - int result = strcmp(temp1,temp2); + int result = wxStrcmp(temp1,temp2); delete[] temp1; delete[] temp2; @@ -146,7 +165,7 @@ int strncasecmp(const char *str_1, const char *str_2, size_t maxchar) return(result); } -#endif +#endif // __VMS__ #ifdef __WINDOWS__ @@ -161,6 +180,12 @@ int strncasecmp(const char *str_1, const char *str_2, size_t maxchar) #endif #else + +#ifdef __EMX__ +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + // This declaration is missing in SunOS! // (Yes, I know it is NOT ANSI-C but its in BSD libc) #if defined(__xlC) || defined(__AIX__) || defined(__GNUG__) @@ -172,15 +197,19 @@ extern "C" #endif #endif /* __WXMSW__ */ +#ifdef __WXPM__ +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif -char * -copystring (const char *s) +wxChar * +copystring (const wxChar *s) { - if (s == NULL) s = ""; - size_t len = strlen (s) + 1; + if (s == NULL) s = wxT(""); + size_t len = wxStrlen (s) + 1; - char *news = new char[len]; - memcpy (news, s, len); // Should be the fastest + wxChar *news = new wxChar[len]; + memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest return news; } @@ -205,94 +234,93 @@ wxRegisterId (long id) } void -StringToFloat (char *s, float *number) +StringToFloat (wxChar *s, float *number) { if (s && *s && number) - *number = (float) strtod (s, (char **) NULL); + *number = (float) wxStrtod (s, (wxChar **) NULL); } void -StringToDouble (char *s, double *number) +StringToDouble (wxChar *s, double *number) { if (s && *s && number) - *number = strtod (s, (char **) NULL); + *number = wxStrtod (s, (wxChar **) NULL); } -char * -FloatToString (float number, const char *fmt) +wxChar * +FloatToString (float number, const wxChar *fmt) { - static char buf[256]; + static wxChar buf[256]; // sprintf (buf, "%.2f", number); - sprintf (buf, fmt, number); + wxSprintf (buf, fmt, number); return buf; } -char * -DoubleToString (double number, const char *fmt) +wxChar * +DoubleToString (double number, const wxChar *fmt) { - static char buf[256]; + static wxChar buf[256]; - sprintf (buf, fmt, number); + wxSprintf (buf, fmt, number); return buf; } void -StringToInt (char *s, int *number) +StringToInt (wxChar *s, int *number) { if (s && *s && number) - *number = (int) strtol (s, (char **) NULL, 10); + *number = (int) wxStrtol (s, (wxChar **) NULL, 10); } void -StringToLong (char *s, long *number) +StringToLong (wxChar *s, long *number) { if (s && *s && number) - *number = strtol (s, (char **) NULL, 10); + *number = wxStrtol (s, (wxChar **) NULL, 10); } -char * +wxChar * IntToString (int number) { - static char buf[20]; + static wxChar buf[20]; - sprintf (buf, "%d", number); + wxSprintf (buf, wxT("%d"), number); return buf; } -char * +wxChar * LongToString (long number) { - static char buf[20]; + static wxChar buf[20]; - sprintf (buf, "%ld", number); + wxSprintf (buf, wxT("%ld"), number); return buf; } // Array used in DecToHex conversion routine. -static char hexArray[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', - 'C', 'D', 'E', 'F' }; +static wxChar hexArray[] = wxT("0123456789ABCDEF"); // Convert 2-digit hex number to decimal int wxHexToDec(const wxString& buf) { int firstDigit, secondDigit; - if (buf.GetChar(0) >= 'A') - firstDigit = buf.GetChar(0) - 'A' + 10; + if (buf.GetChar(0) >= wxT('A')) + firstDigit = buf.GetChar(0) - wxT('A') + 10; else - firstDigit = buf.GetChar(0) - '0'; + firstDigit = buf.GetChar(0) - wxT('0'); - if (buf.GetChar(1) >= 'A') - secondDigit = buf.GetChar(1) - 'A' + 10; + if (buf.GetChar(1) >= wxT('A')) + secondDigit = buf.GetChar(1) - wxT('A') + 10; else - secondDigit = buf.GetChar(1) - '0'; + secondDigit = buf.GetChar(1) - wxT('0'); return firstDigit * 16 + secondDigit; } // Convert decimal integer to 2-character hex string -void wxDecToHex(int dec, char *buf) +void wxDecToHex(int dec, wxChar *buf) { int firstDigit = (int)(dec/16.0); int secondDigit = (int)(dec - (firstDigit*16.0)); @@ -304,7 +332,7 @@ void wxDecToHex(int dec, char *buf) // Convert decimal integer to 2-character hex string wxString wxDecToHex(int dec) { - char buf[3]; + wxChar buf[3]; wxDecToHex(dec, buf); return wxString(buf); } @@ -351,7 +379,7 @@ StringMatch (char *str1, char *str2, bool subString, bool exact) // Return the current date/time // [volatile] -wxString wxNow( void ) +wxString wxNow() { time_t now = time((time_t *) NULL); char *date = ctime(&now); @@ -359,51 +387,31 @@ wxString wxNow( void ) return wxString(date); } -/* Get Full RFC822 style email address */ -bool -wxGetEmailAddress (char *address, int maxSize) -{ - char host[65]; - char user[65]; - - if (wxGetHostName(host, 64) == FALSE) - return FALSE; - if (wxGetUserId(user, 64) == FALSE) - return FALSE; - - char tmp[130]; - strcpy(tmp, user); - strcat(tmp, "@"); - strcat(tmp, host); +#if wxUSE_GUI - strncpy(address, tmp, maxSize - 1); - address[maxSize-1] = '\0'; - return TRUE; -} - -/* - * Strip out any menu codes - */ +// ---------------------------------------------------------------------------- +// Menu accelerators related functions +// ---------------------------------------------------------------------------- -char *wxStripMenuCodes (char *in, char *out) +wxChar *wxStripMenuCodes (wxChar *in, wxChar *out) { if (!in) - return (char *) NULL; + return (wxChar *) NULL; if (!out) out = copystring(in); - char *tmpOut = out; + wxChar *tmpOut = out; while (*in) { - if (*in == '&') + if (*in == wxT('&')) { // Check && -> &, &x -> x - if (*++in == '&') + if (*++in == wxT('&')) *out++ = *in++; } - else if (*in == '\t') + else if (*in == wxT('\t')) { // Remove all stuff after \t in X mode, and let the stuff as is // in Windows mode. @@ -415,24 +423,108 @@ char *wxStripMenuCodes (char *in, char *out) *out++ = *in++; } // while - *out = '\0'; + *out = wxT('\0'); return tmpOut; } wxString wxStripMenuCodes(const wxString& str) { - char *buf = new char[str.Length() + 1]; - wxStripMenuCodes((char*) (const char*) str, buf); + wxChar *buf = new wxChar[str.Length() + 1]; + wxStripMenuCodes(WXSTRINGCAST str, buf); wxString str1(buf); delete[] buf; return str1; } -/* - * Window search functions - * - */ +#if wxUSE_ACCEL + +// return wxAcceleratorEntry for the given menu string or NULL if none +// specified +wxAcceleratorEntry *wxGetAccelFromString(const wxString& label) +{ + // check for accelerators: they are given after '\t' + int posTab = label.Find(wxT('\t')); + if ( posTab != wxNOT_FOUND ) { + // parse the accelerator string + int keyCode = 0; + int accelFlags = wxACCEL_NORMAL; + wxString current; + for ( size_t n = (size_t)posTab + 1; n < label.Len(); n++ ) { + if ( (label[n] == '+') || (label[n] == '-') ) { + if ( current == _("ctrl") ) + accelFlags |= wxACCEL_CTRL; + else if ( current == _("alt") ) + accelFlags |= wxACCEL_ALT; + else if ( current == _("shift") ) + accelFlags |= wxACCEL_SHIFT; + else { + wxLogDebug(wxT("Unknown accel modifier: '%s'"), + current.c_str()); + } + + current.Empty(); + } + else { + current += wxTolower(label[n]); + } + } + + if ( current.IsEmpty() ) { + wxLogDebug(wxT("No accel key found, accel string ignored.")); + } + else { + if ( current.Len() == 1 ) { + // it's a letter + keyCode = wxToupper(current[0U]); + } + else { + // is it a function key? + if ( current[0U] == 'f' && isdigit(current[1U]) && + (current.Len() == 2 || + (current.Len() == 3 && isdigit(current[2U]))) ) { + int n; + wxSscanf(current.c_str() + 1, wxT("%d"), &n); + + keyCode = WXK_F1 + n - 1; + } + else { +#if 0 // this is not supported by GTK+, apparently + // several special cases + current.MakeUpper(); + if ( current == wxT("DEL") ) { + keyCode = VK_DELETE; + } + else if ( current == wxT("PGUP") ) { + keyCode = VK_PRIOR; + } + else if ( current == wxT("PGDN") ) { + keyCode = VK_NEXT; + } + else +#endif // 0 + { + wxLogDebug(wxT("Unrecognized accel key '%s', accel " + "string ignored."), current.c_str()); + } + } + } + } + + if ( keyCode ) { + // we do have something + return new wxAcceleratorEntry(accelFlags, keyCode); + } + } + + return (wxAcceleratorEntry *)NULL; +} + +#endif // wxUSE_ACCEL + +// ---------------------------------------------------------------------------- +// Window search functions +// ---------------------------------------------------------------------------- /* * If parent is non-NULL, look through children for a label or title @@ -440,53 +532,54 @@ wxString wxStripMenuCodes(const wxString& str) * */ -static wxWindow *wxFindWindowByLabel1 (const wxString& title, wxWindow * parent); - wxWindow * wxFindWindowByLabel (const wxString& title, wxWindow * parent) { - if (parent) + if (parent) { - return wxFindWindowByLabel1 (title, parent); + return wxFindWindowByLabel1(title, parent); } - else + else { - for (wxNode * node = wxTopLevelWindows.First (); node; node = node->Next ()) + for ( wxWindowList::Node * node = wxTopLevelWindows.GetFirst(); + node; + node = node->GetNext() ) { - wxWindow *win = (wxWindow *) node->Data (); - wxWindow *retwin = wxFindWindowByLabel1 (title, win); - if (retwin) - return retwin; + wxWindow *win = node->GetData(); + wxWindow *retwin = wxFindWindowByLabel1 (title, win); + if (retwin) + return retwin; } // for() } - return (wxWindow *) NULL; + return (wxWindow *) NULL; } // Recursive static wxWindow * wxFindWindowByLabel1 (const wxString& title, wxWindow * parent) { - if (parent) + if (parent) { - if (parent->GetLabel() == title) - return parent; + if (parent->GetLabel() == title) + return parent; } - if (parent) + if (parent) { - for (wxNode * node = parent->GetChildren().First (); node; node = node->Next ()) + for ( wxWindowList::Node * node = parent->GetChildren().GetFirst(); + node; + node = node->GetNext() ) { - wxWindow *win = (wxWindow *) node->Data (); - wxWindow *retwin = wxFindWindowByLabel1 (title, win); - if (retwin) - return retwin; - } // for() + wxWindow *win = (wxWindow *)node->GetData(); + wxWindow *retwin = wxFindWindowByLabel1 (title, win); + if (retwin) + return retwin; + } } - return (wxWindow *) NULL; // Not found - + return (wxWindow *) NULL; // Not found } /* @@ -495,28 +588,29 @@ wxFindWindowByLabel1 (const wxString& title, wxWindow * parent) * */ -static wxWindow *wxFindWindowByName1 (const wxString& title, wxWindow * parent); - wxWindow * wxFindWindowByName (const wxString& title, wxWindow * parent) { - if (parent) + if (parent) { - return wxFindWindowByName1 (title, parent); + return wxFindWindowByName1 (title, parent); } - else + else { - for (wxNode * node = wxTopLevelWindows.First (); node; node = node->Next ()) + for ( wxWindowList::Node * node = wxTopLevelWindows.GetFirst(); + node; + node = node->GetNext() ) { - wxWindow *win = (wxWindow *) node->Data (); - wxWindow *retwin = wxFindWindowByName1 (title, win); - if (retwin) - return retwin; - } // for() + wxWindow *win = node->GetData(); + wxWindow *retwin = wxFindWindowByName1 (title, win); + if (retwin) + return retwin; + } } - // Failed? Try by label instead. - return wxFindWindowByLabel(title, parent); + + // Failed? Try by label instead. + return wxFindWindowByLabel(title, parent); } // Recursive @@ -555,6 +649,8 @@ wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& i return menuBar->FindMenuItem (menuString, itemString); } +#endif // wxUSE_GUI + /* On Fri, 21 Jul 1995, Paul Craven wrote: @@ -748,6 +844,12 @@ whereami(name) #endif +#if wxUSE_GUI + +// ---------------------------------------------------------------------------- +// GUI helpers +// ---------------------------------------------------------------------------- + /* * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp * since otherwise the generic code may be pulled in unnecessarily. @@ -763,21 +865,17 @@ int wxMessageBox(const wxString& message, const wxString& caption, long style, { case wxID_OK: return wxOK; - break; case wxID_YES: return wxYES; - break; case wxID_NO: return wxNO; - break; default: case wxID_CANCEL: return wxCANCEL; - break; } - return ans; } +#if wxUSE_TEXTDLG wxString wxGetTextFromUser(const wxString& message, const wxString& caption, const wxString& defaultValue, wxWindow *parent, int x, int y, bool WXUNUSED(centre) ) @@ -788,6 +886,7 @@ wxString wxGetTextFromUser(const wxString& message, const wxString& caption, else return wxString(""); } +#endif // wxUSE_TEXTDLG #ifdef __MWERKS__ char *strdup(const char *s) @@ -799,39 +898,174 @@ int isascii( int c ) { return ( c >= 0 && c < 128 ) ; } -#endif +#endif // __MWERKS__ + +// ---------------------------------------------------------------------------- +// misc functions +// ---------------------------------------------------------------------------- -bool wxGetUserId(wxString& buf) +void wxEnableTopLevelWindows(bool enable) { - bool success = wxGetUserId(wxBuffer, 500); - if (success) - { - buf = wxBuffer; - return TRUE; - } - else + wxWindowList::Node *node; + for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) + node->GetData()->Enable(enable); +} + +// Yield to other apps/messages and disable user input +bool wxSafeYield(wxWindow *win) +{ + wxEnableTopLevelWindows(FALSE); + // always enable ourselves + if ( win ) + win->Enable(TRUE); + bool rc = wxYield(); + wxEnableTopLevelWindows(TRUE); + return rc; +} + +// Don't synthesize KeyUp events holding down a key and producing KeyDown +// events with autorepeat. On by default and always on in wxMSW. wxGTK version +// in utilsgtk.cpp. +#ifndef __WXGTK__ +bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) ) +{ + return TRUE; // detectable auto-repeat is the only mode MSW supports +} +#endif // !wxGTK + +#endif // wxUSE_GUI + +// ---------------------------------------------------------------------------- +// network and user id functions +// ---------------------------------------------------------------------------- + +// Get Full RFC822 style email address +bool wxGetEmailAddress(wxChar *address, int maxSize) +{ + wxString email = wxGetEmailAddress(); + if ( !email ) return FALSE; + + wxStrncpy(address, email, maxSize - 1); + address[maxSize - 1] = wxT('\0'); + + return TRUE; } -bool wxGetUserName(wxString& buf) +wxString wxGetEmailAddress() { - bool success = wxGetUserName(wxBuffer, 500); - if (success) + wxString email; + + wxString host = wxGetHostName(); + if ( !!host ) { - buf = wxBuffer; - return TRUE; + wxString user = wxGetUserId(); + if ( !!user ) + { + wxString email(user); + email << wxT('@') << host; + } } - else - return FALSE; + + return email; +} + +wxString wxGetUserId() +{ + static const int maxLoginLen = 256; // FIXME arbitrary number + + wxString buf; + bool ok = wxGetUserId(buf.GetWriteBuf(maxLoginLen), maxLoginLen); + buf.UngetWriteBuf(); + + if ( !ok ) + buf.Empty(); + + return buf; +} + +wxString wxGetUserName() +{ + static const int maxUserNameLen = 1024; // FIXME arbitrary number + + wxString buf; + bool ok = wxGetUserName(buf.GetWriteBuf(maxUserNameLen), maxUserNameLen); + buf.UngetWriteBuf(); + + if ( !ok ) + buf.Empty(); + + return buf; } -bool wxGetHostName(wxString& buf) +wxString wxGetHostName() { static const size_t hostnameSize = 257; + + wxString buf; bool ok = wxGetHostName(buf.GetWriteBuf(hostnameSize), hostnameSize); buf.UngetWriteBuf(); - return ok; + if ( !ok ) + buf.Empty(); + + return buf; +} + +wxString wxGetFullHostName() +{ + static const size_t hostnameSize = 257; + + wxString buf; + bool ok = wxGetFullHostName(buf.GetWriteBuf(hostnameSize), hostnameSize); + + buf.UngetWriteBuf(); + + if ( !ok ) + buf.Empty(); + + return buf; +} + +wxString wxGetHomeDir() +{ + wxString home; + wxGetHomeDir(&home); + + return home; +} + +#if 0 + +wxString wxGetCurrentDir() +{ + wxString dir; + size_t len = 1024; + bool ok; + do + { + ok = getcwd(dir.GetWriteBuf(len + 1), len) != NULL; + dir.UngetWriteBuf(); + + if ( !ok ) + { + if ( errno != ERANGE ) + { + wxLogSysError(_T("Failed to get current directory")); + + return wxEmptyString; + } + else + { + // buffer was too small, retry with a larger one + len *= 2; + } + } + //else: ok + } while ( !ok ); + + return dir; } +#endif // 0