]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/utilscmn.cpp
always NUL-terminate log messages, even if they're longer than buffer size
[wxWidgets.git] / src / common / utilscmn.cpp
index a294d53d5d93220762cfef3c11b234876d671fc3..93aa19f675a6a33f464a84f05922039dae285258 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     29/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) 1998 Julian Smart
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
@@ -36,6 +36,7 @@
     #include "wx/log.h"
 
     #if wxUSE_GUI
+        #include "wx/app.h"
         #include "wx/window.h"
         #include "wx/frame.h"
         #include "wx/menu.h"
 
 #if wxUSE_GUI
     #include "wx/colordlg.h"
+    #include "wx/fontdlg.h"
     #include "wx/notebook.h"
     #include "wx/frame.h"
     #include "wx/statusbr.h"
-    #include "wx/toolbar.h"
 #endif // wxUSE_GUI
 
 #include <time.h>
 #endif
 
 // ----------------------------------------------------------------------------
-// function protoypes
+// common data
 // ----------------------------------------------------------------------------
 
-#if wxUSE_GUI
-    static wxWindow *wxFindWindowByLabel1(const wxString& title, wxWindow *parent);
-    static wxWindow *wxFindWindowByName1 (const wxString& title, wxWindow *parent);
-#endif // wxUSE_GUI
+#if WXWIN_COMPATIBILITY_2_2
+    const wxChar *wxInternalErrorStr = wxT("wxWindows Internal Error");
+    const wxChar *wxFatalErrorStr = wxT("wxWindows Fatal Error");
+#endif // WXWIN_COMPATIBILITY_2_2
 
 // ============================================================================
 // implementation
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// string functions
-// ----------------------------------------------------------------------------
-
-#ifdef __WXMAC__
-int strcasecmp(const char *str_1, const char *str_2)
-{
-  register char c1, c2;
-  do {
-    c1 = tolower(*str_1++);
-    c2 = tolower(*str_2++);
-  } while ( c1 && (c1 == c2) );
-
-  return c1 - c2;
-}
-
-int strncasecmp(const char *str_1, const char *str_2, size_t maxchar)
-{
-
-  register char c1, c2;
-  while( maxchar--)
-  {
-    c1 = tolower(*str_1++);
-    c2 = tolower(*str_2++);
-
-    if ( !c1 || c1!=c2 )
-                  return c1 - c2;
-
-  } ;
-
-  return 0 ;
-
-}
-#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
-static void myLowerString(char *s)
-{
-  while(*s){
-    if(isalpha(*s)) *s = (char)tolower(*s);
-    s++;
-  }
-}
-
-int strcasecmp(const char *str_1, const char *str_2)
-{
-  char *temp1 = new char[strlen(str_1)+1];
-  char *temp2 = new char[strlen(str_2)+1];
-  strcpy(temp1,str_1);
-  strcpy(temp2,str_2);
-  myLowerString(temp1);
-  myLowerString(temp2);
-
-  int result = wxStrcmp(temp1,temp2);
-  delete[] temp1;
-  delete[] temp2;
-
-  return(result);
-}
-
-int strncasecmp(const char *str_1, const char *str_2, size_t maxchar)
-{
-  char *temp1 = new char[strlen(str_1)+1];
-  char *temp2 = new char[strlen(str_2)+1];
-  strcpy(temp1,str_1);
-  strcpy(temp2,str_2);
-  myLowerString(temp1);
-  myLowerString(temp2);
-
-  int result = strncmp(temp1,temp2,maxchar);
-  delete[] temp1;
-  delete[] temp2;
-
-  return(result);
-}
-#endif // __VMS__
-
-#if defined(__WINDOWS__) && !defined(__WXMICROWIN__)
-
-#ifndef __GNUWIN32__
-#ifndef __MWERKS__
-#define strcasecmp stricmp
-#define strncasecmp strnicmp
-#else
-#define strcasecmp _stricmp
-#define strncasecmp _strnicmp
-#endif
-#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__)
-extern "C"
-{
-  int strcasecmp (const char *, const char *);
-  int strncasecmp (const char *, const char *, size_t);
-}
-#endif
-#endif  /* __WXMSW__ */
-
-#ifdef __WXPM__
-#define strcasecmp stricmp
-#define strncasecmp strnicmp
-#endif
-
 wxChar *
 copystring (const wxChar *s)
 {
@@ -247,15 +133,24 @@ wxRegisterId (long id)
     wxCurrentId = id + 1;
 }
 
+// ----------------------------------------------------------------------------
+// String <-> Number conversions (deprecated)
+// ----------------------------------------------------------------------------
+
+#if WXWIN_COMPATIBILITY_2_4
+
+WXDLLEXPORT_DATA(const wxChar *) wxFloatToStringStr = wxT("%.2f");
+WXDLLEXPORT_DATA(const wxChar *) wxDoubleToStringStr = wxT("%.2f");
+
 void
-StringToFloat (wxChar *s, float *number)
+StringToFloat (const wxChar *s, float *number)
 {
   if (s && *s && number)
     *number = (float) wxStrtod (s, (wxChar **) NULL);
 }
 
 void
-StringToDouble (wxChar *s, double *number)
+StringToDouble (const wxChar *s, double *number)
 {
   if (s && *s && number)
     *number = wxStrtod (s, (wxChar **) NULL);
@@ -280,14 +175,14 @@ DoubleToString (double number, const wxChar *fmt)
 }
 
 void
-StringToInt (wxChar *s, int *number)
+StringToInt (const wxChar *s, int *number)
 {
   if (s && *s && number)
     *number = (int) wxStrtol (s, (wxChar **) NULL, 10);
 }
 
 void
-StringToLong (wxChar *s, long *number)
+StringToLong (const wxChar *s, long *number)
 {
   if (s && *s && number)
     *number = wxStrtol (s, (wxChar **) NULL, 10);
@@ -311,6 +206,8 @@ LongToString (long number)
   return buf;
 }
 
+#endif // WXWIN_COMPATIBILITY_2_4
+
 // Array used in DecToHex conversion routine.
 static wxChar hexArray[] = wxT("0123456789ABCDEF");
 
@@ -350,9 +247,9 @@ wxString wxDecToHex(int dec)
     return wxString(buf);
 }
 
-// Match a string INDEPENDENT OF CASE
+#if WXWIN_COMPATIBILITY_2
 bool
-StringMatch (char *str1, char *str2, bool subString, bool exact)
+StringMatch (const wxChar *str1, const wxChar *str2, bool subString, bool exact)
 {
   if (str1 == NULL || str2 == NULL)
     return FALSE;
@@ -361,43 +258,44 @@ StringMatch (char *str1, char *str2, bool subString, bool exact)
 
   if (subString)
     {
-      int len1 = strlen (str1);
-      int len2 = strlen (str2);
+      int len1 = wxStrlen (str1);
+      int len2 = wxStrlen (str2);
       int i;
 
       // Search for str1 in str2
       // Slow .... but acceptable for short strings
       for (i = 0; i <= len2 - len1; i++)
         {
-          if (strncasecmp (str1, str2 + i, len1) == 0)
+          if (wxStrnicmp (str1, str2 + i, len1) == 0)
             return TRUE;
         }
     }
   else if (exact)
     {
-      if (strcasecmp (str1, str2) == 0)
+      if (wxStricmp (str1, str2) == 0)
         return TRUE;
     }
   else
     {
-      int len1 = strlen (str1);
-      int len2 = strlen (str2);
+      int len1 = wxStrlen (str1);
+      int len2 = wxStrlen (str2);
 
-      if (strncasecmp (str1, str2, wxMin (len1, len2)) == 0)
+      if (wxStrnicmp (str1, str2, wxMin (len1, len2)) == 0)
         return TRUE;
     }
 
   return FALSE;
 }
+#endif
 
 // Return the current date/time
 // [volatile]
 wxString wxNow()
 {
-  time_t now = time((time_t *) NULL);
-  char *date = ctime(&now);
-  date[24] = '\0';
-  return wxString(date);
+    time_t now = time((time_t *) NULL);
+    char *date = ctime(&now);
+    date[24] = '\0';
+    return wxString::FromAscii(date);
 }
 
 #if wxUSE_GUI
@@ -408,7 +306,7 @@ wxString wxNow()
 // Menu accelerators related functions
 // ----------------------------------------------------------------------------
 
-wxChar *wxStripMenuCodes(wxChar *in, wxChar *out)
+wxChar *wxStripMenuCodes(const wxChar *in, wxChar *out)
 {
     wxString s = wxMenuItem::GetLabelFromText(in);
     if ( out )
@@ -476,52 +374,9 @@ wxString wxStripMenuCodes(const wxString& in)
 wxWindow *
 wxFindWindowByLabel (const wxString& title, wxWindow * parent)
 {
-    if (parent)
-    {
-        return wxFindWindowByLabel1(title, parent);
-    }
-    else
-    {
-        for ( wxWindowList::Node * node = wxTopLevelWindows.GetFirst();
-              node;
-              node = node->GetNext() )
-        {
-            wxWindow *win = node->GetData();
-            wxWindow *retwin = wxFindWindowByLabel1 (title, win);
-            if (retwin)
-                return retwin;
-        }                        // for()
-
-    }
-    return (wxWindow *) NULL;
+    return wxWindow::FindWindowByLabel( title, parent );
 }
 
-// Recursive
-static wxWindow *
-wxFindWindowByLabel1 (const wxString& title, wxWindow * parent)
-{
-    if (parent)
-    {
-        if (parent->GetLabel() == title)
-            return parent;
-    }
-
-    if (parent)
-    {
-        for ( wxWindowList::Node * node = parent->GetChildren().GetFirst();
-              node;
-              node = node->GetNext() )
-        {
-            wxWindow *win = (wxWindow *)node->GetData();
-            wxWindow *retwin = wxFindWindowByLabel1 (title, win);
-            if (retwin)
-                return retwin;
-        }
-
-    }
-
-    return (wxWindow *) NULL;                        // Not found
-}
 
 /*
  * If parent is non-NULL, look through children for a name
@@ -530,54 +385,9 @@ wxFindWindowByLabel1 (const wxString& title, wxWindow * parent)
  */
 
 wxWindow *
-wxFindWindowByName (const wxString& title, wxWindow * parent)
+wxFindWindowByName (const wxString& name, wxWindow * parent)
 {
-    if (parent)
-    {
-        return wxFindWindowByName1 (title, parent);
-    }
-    else
-    {
-        for ( wxWindowList::Node * node = wxTopLevelWindows.GetFirst();
-              node;
-              node = node->GetNext() )
-        {
-            wxWindow *win = node->GetData();
-            wxWindow *retwin = wxFindWindowByName1 (title, win);
-            if (retwin)
-                return retwin;
-        }
-
-    }
-
-    // Failed? Try by label instead.
-    return wxFindWindowByLabel(title, parent);
-}
-
-// Recursive
-static wxWindow *
-wxFindWindowByName1 (const wxString& title, wxWindow * parent)
-{
-  if (parent)
-    {
-            if ( parent->GetName() == title )
-                        return parent;
-    }
-
-  if (parent)
-    {
-      for (wxNode * node = parent->GetChildren().First (); node; node = node->Next ())
-        {
-          wxWindow *win = (wxWindow *) node->Data ();
-          wxWindow *retwin = wxFindWindowByName1 (title, win);
-          if (retwin)
-            return retwin;
-        }                        // for()
-
-    }
-
-  return (wxWindow *) NULL;                        // Not found
-
+    return wxWindow::FindWindowByName( name, parent );
 }
 
 // Returns menu item id or -1 if none.
@@ -605,6 +415,7 @@ wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt)
 
     // Hack for wxNotebook case: at least in wxGTK, all pages
     // claim to be shown, so we must only deal with the selected one.
+#if wxUSE_NOTEBOOK
     if (win->IsKindOf(CLASSINFO(wxNotebook)))
     {
       wxNotebook* nb = (wxNotebook*) win;
@@ -617,6 +428,8 @@ wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt)
            return foundWin;
       }
     }
+#endif
+
     /* Doesn't work
     // Frame case
     else if (win->IsKindOf(CLASSINFO(wxFrame)))
@@ -629,10 +442,10 @@ wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt)
       if (frame->GetToolBar())
         extraChildren.Append(frame->GetToolBar());
 
-      wxNode* node = extraChildren.First();
+      wxNode* node = extraChildren.GetFirst();
       while (node)
       {
-          wxWindow* child = (wxWindow*) node->Data();
+          wxWindow* child = (wxWindow*) node->GetData();
           wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
           if (foundWin)
             return foundWin;
@@ -641,14 +454,14 @@ wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt)
     }
     */
 
-    wxNode* node = win->GetChildren().Last();
+    wxWindowList::Node  *node = win->GetChildren().GetLast();
     while (node)
     {
-        wxWindow* child = (wxWindow*) node->Data();
+        wxWindow* child = node->GetData();
         wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
         if (foundWin)
           return foundWin;
-        node = node->Previous();
+        node = node->GetPrevious();
     }
 
     wxPoint pos = win->GetPosition();
@@ -670,14 +483,14 @@ wxWindow* wxGenericFindWindowAtPoint(const wxPoint& pt)
     // Go backwards through the list since windows
     // on top are likely to have been appended most
     // recently.
-    wxNode* node = wxTopLevelWindows.Last();
+    wxWindowList::Node  *node = wxTopLevelWindows.GetLast();
     while (node)
     {
-        wxWindow* win = (wxWindow*) node->Data();
+        wxWindow* win = node->GetData();
         wxWindow* found = wxFindWindowAtPoint(win, pt);
         if (found)
             return found;
-        node = node->Previous();
+        node = node->GetPrevious();
     }
     return NULL;
 }
@@ -738,7 +551,7 @@ whereami(name)
 
         t = imagedir;
         if (!absolute_pathname(name)) {
-#if defined(DOS) || defined(__WIN32__)
+#if defined(__DOS__) || defined(__WIN32__)
             int   drive;
             char *newrbuf;
 
@@ -953,36 +766,57 @@ wxString wxGetPasswordFromUser(const wxString& message,
 
 wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit)
 {
-      wxColourData data;
-      data.SetChooseFull(TRUE);
-      if ( colInit.Ok() )
-      {
-          data.SetColour((wxColour &)colInit); // const_cast
-      }
+    wxColourData data;
+    data.SetChooseFull(TRUE);
+    if ( colInit.Ok() )
+    {
+        data.SetColour((wxColour &)colInit); // const_cast
+    }
 
-      wxColour colRet;
-      wxColourDialog dialog(parent, &data);
-      if ( dialog.ShowModal() == wxID_OK )
-      {
-          colRet = dialog.GetColourData().GetColour();
-      }
-      //else: leave it invalid
+    wxColour colRet;
+    wxColourDialog dialog(parent, &data);
+    if ( dialog.ShowModal() == wxID_OK )
+    {
+        colRet = dialog.GetColourData().GetColour();
+    }
+    //else: leave it invalid
 
-      return colRet;
+    return colRet;
 }
 
 #endif // wxUSE_COLOURDLG
 
+#if wxUSE_FONTDLG
+
+wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit)
+{
+    wxFontData data;
+    if ( fontInit.Ok() )
+    {
+        data.SetInitialFont(fontInit);
+    }
+
+    wxFont fontRet;
+    wxFontDialog dialog(parent, data);
+    if ( dialog.ShowModal() == wxID_OK )
+    {
+        fontRet = dialog.GetFontData().GetChosenFont();
+    }
+    //else: leave it invalid
+
+    return fontRet;
+}
+
+#endif // wxUSE_FONTDLG
 // ----------------------------------------------------------------------------
 // missing C RTL functions (FIXME shouldn't be here at all)
 // ----------------------------------------------------------------------------
 
-#ifdef __MWERKS__
+#if defined( __MWERKS__ ) && !defined(__MACH__)
 char *strdup(const char *s)
 {
         return strcpy( (char*) malloc( strlen( s ) + 1 ) , s ) ;
 }
-
 int isascii( int c )
 {
         return ( c >= 0 && c < 128 ) ;
@@ -1047,11 +881,15 @@ wxWindowDisabler::~wxWindowDisabler()
 
 // Yield to other apps/messages and disable user input to all windows except
 // the given one
-bool wxSafeYield(wxWindow *win)
+bool wxSafeYield(wxWindow *win, bool onlyIfNeeded)
 {
     wxWindowDisabler wd(win);
 
-    bool rc = wxYield();
+    bool rc;
+    if (onlyIfNeeded)
+        rc = wxYieldIfNeeded();
+    else
+        rc = wxYield();
 
     return rc;
 }
@@ -1075,17 +913,29 @@ bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) )
 const wxChar *wxGetInstallPrefix()
 {
     wxString prefix;
-    
-    if ( wxGetEnv(wxT("WX_PREFIX"), &prefix) )
+
+    if ( wxGetEnv(wxT("WXPREFIX"), &prefix) )
         return prefix.c_str();
-    
+
 #ifdef wxINSTALL_PREFIX
     return wxT(wxINSTALL_PREFIX);
-#else 
+#else
     return wxT("");
 #endif
 }
 
+wxString wxGetDataDir()
+{
+    wxString format = wxGetInstallPrefix();
+    format <<  wxFILE_SEP_PATH
+           << wxT("share") << wxFILE_SEP_PATH
+           << wxT("wx") << wxFILE_SEP_PATH
+           << wxT("%i.%i");
+    wxString dir;
+    dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
+    return dir;
+}
+
 
 // ----------------------------------------------------------------------------
 // network and user id functions
@@ -1225,6 +1075,40 @@ wxString wxGetCurrentDir()
 // wxExecute
 // ----------------------------------------------------------------------------
 
+// wxDoExecuteWithCapture() helper: reads an entire stream into one array
+//
+// returns TRUE if ok, FALSE if error
+#if wxUSE_STREAMS
+static bool ReadAll(wxInputStream *is, wxArrayString& output)
+{
+    wxCHECK_MSG( is, FALSE, _T("NULL stream in wxExecute()?") );
+
+    // the stream could be already at EOF or in wxSTREAM_BROKEN_PIPE state
+    is->Reset();
+
+    wxTextInputStream tis(*is);
+
+    bool cont = TRUE;
+    while ( cont )
+    {
+        wxString line = tis.ReadLine();
+        if ( is->Eof() )
+            break;
+
+        if ( !*is )
+        {
+            cont = FALSE;
+        }
+        else
+        {
+            output.Add(line);
+        }
+    }
+
+    return cont;
+}
+#endif // wxUSE_STREAMS
+
 // this is a private function because it hasn't a clean interface: the first
 // array is passed by reference, the second by pointer - instead we have 2
 // public versions of wxExecute() below
@@ -1241,56 +1125,20 @@ static long wxDoExecuteWithCapture(const wxString& command,
     wxProcess *process = new wxProcess;
     process->Redirect();
 
-    long rc = wxExecute(command, TRUE /* sync */, process);
+    long rc = wxExecute(command, wxEXEC_SYNC, process);
 
 #if wxUSE_STREAMS
     if ( rc != -1 )
     {
-        wxInputStream* is = process->GetInputStream();
-        wxCHECK_MSG( is, -1, _T("if wxExecute() succeded, stream can't be NULL") );
-        wxTextInputStream tis(*is);
+        if ( !ReadAll(process->GetInputStream(), output) )
+            rc = -1;
 
-        wxTextInputStream *tes = NULL;
-        wxInputStream *es = NULL;
         if ( error )
         {
-            es = process->GetErrorStream();
-
-            wxCHECK_MSG( es, -1, _T("stderr can't be NULL") );
-
-            tes = new wxTextInputStream(*es);
-        }
-
-        bool cont;
-        do
-        {
-            cont = FALSE;
-
-            if ( !is->Eof() && is->IsOk() )
-            {
-                wxString line = tis.ReadLine();
-                if ( is->LastError() )
-                    break;
-
-                cont = TRUE;
-
-                output.Add(line);
-            }
-
-            if ( error && !es->Eof() && es->IsOk() )
-            {
-                wxString line = tes->ReadLine();
-                if ( es->LastError() )
-                    break;
-
-                cont = TRUE;
-
-                error->Add(line);
-            }
+            if ( !ReadAll(process->GetErrorStream(), *error) )
+                rc = -1;
         }
-        while ( cont );
 
-        delete tes;
     }
 #endif // wxUSE_STREAMS
 
@@ -1312,4 +1160,25 @@ long wxExecute(const wxString& command,
     return wxDoExecuteWithCapture(command, output, &error);
 }
 
+// ----------------------------------------------------------------------------
+// wxApp::Yield() wrappers for backwards compatibility
+// ----------------------------------------------------------------------------
+
+bool wxYield()
+{
+#if wxUSE_GUI
+    return wxTheApp && wxTheApp->Yield();
+#else
+    return FALSE;
+#endif
+}
+
+bool wxYieldIfNeeded()
+{
+#if wxUSE_GUI
+    return wxTheApp && wxTheApp->Yield(TRUE);
+#else
+    return FALSE;
+#endif
+}