]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/utilscmn.cpp
Mem leak in new accelerator code.
[wxWidgets.git] / src / common / utilscmn.cpp
index 349d6f04a0755b47f164a4e6b9c80324b2d326ee..a96372e00dc051199f4443f2edc97706e4a1a901 100644 (file)
@@ -6,49 +6,71 @@
 // Created:     29/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) 1998 Julian Smart
 // Created:     29/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) 1998 Julian Smart
-// Licence:    wxWindows license
+// Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
 /////////////////////////////////////////////////////////////////////////////
 
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
 #ifdef __GNUG__
 #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__
 #endif
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
-#pragma hdrstop
+    #pragma hdrstop
 #endif
 
 #ifndef WX_PRECOMP
 #endif
 
 #ifndef WX_PRECOMP
-#include "wx/defs.h"
-#include "wx/utils.h"
-#include "wx/window.h"
-#include "wx/menu.h"
-#include "wx/frame.h"
-#endif
-
-#if USE_IOSTREAMH
-#include <iostream.h>
-#else
-#include <iostream>
-#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 <fstream.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+
 #if !defined(__WATCOMC__)
 #if !defined(__WATCOMC__)
-#if !(defined(_MSC_VER) && (_MSC_VER > 800))
-#include <errno.h>
-#endif
+    #if !(defined(_MSC_VER) && (_MSC_VER > 800))
+        #include <errno.h>
+    #endif
 #endif
 #endif
+
 #include <time.h>
 #include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 
 
-// Pattern matching code.
+#ifndef __MWERKS__
+    #include <sys/types.h>
+    #include <sys/stat.h>
+#endif
+
+#ifdef __SALFORDC__
+    #include <clib.h>
+#endif
+
+// Pattern matching code. (FIXME)
 // Yes, this path is deliberate (for Borland compilation)
 #ifdef wx_mac /* MATTHEW: [5] Mac doesn't like paths with "/" */
 #include "glob.inc"
 // Yes, this path is deliberate (for Borland compilation)
 #ifdef wx_mac /* MATTHEW: [5] Mac doesn't like paths with "/" */
 #include "glob.inc"
 #include "../common/glob.inc"
 #endif
 
 #include "../common/glob.inc"
 #endif
 
-#ifdef __WINDOWS__
-#include "windows.h"
+#ifdef __WXMSW__
+    #include "windows.h"
 #endif
 
 #endif
 
-#define _MAXPATHLEN 500
+// ----------------------------------------------------------------------------
+// function protoypes
+// ----------------------------------------------------------------------------
 
 
-extern char *wxBuffer;
+#if wxUSE_GUI
+    static wxWindow *wxFindWindowByLabel1(const wxString& title, wxWindow *parent);
+    static wxWindow *wxFindWindowByName1 (const wxString& title, wxWindow *parent);
+#endif // wxUSE_GUI
+
+// ============================================================================
+// 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
 
 #ifdef __VMS__
 // we have no strI functions under VMS, therefore I have implemented
 
 #ifdef __VMS__
 // we have no strI functions under VMS, therefore I have implemented
@@ -107,24 +173,27 @@ int strncasecmp(const char *str_1, const char *str_2, size_t maxchar)
 
   return(result);
 }
 
   return(result);
 }
-#endif
+#endif // __VMS__
 
 #ifdef __WINDOWS__
 
 #ifndef __GNUWIN32__
 
 #ifdef __WINDOWS__
 
 #ifndef __GNUWIN32__
+#ifndef __MWERKS__
 #define strcasecmp stricmp
 #define strncasecmp strnicmp
 #define strcasecmp stricmp
 #define strncasecmp strnicmp
+#else
+#define strcasecmp _stricmp
+#define strncasecmp _strnicmp
 #endif
 #endif
-
-#ifdef _MSC_VER
-#pragma warning (disable : 4245)
 #endif
 
 #endif
 
-#ifdef _MSC_VER
-#pragma warning (default : 4245)
+#else
+
+#ifdef __EMX__
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
 #endif
 
 #endif
 
-#else
 // 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__)
 // 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__)
@@ -134,17 +203,21 @@ extern "C"
   int strncasecmp (const char *, const char *, size_t);
 }
 #endif
   int strncasecmp (const char *, const char *, size_t);
 }
 #endif
-#endif                         /* __WINDOWS__ */
+#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;
 }
 
   return news;
 }
@@ -152,7 +225,7 @@ copystring (const char *s)
 // Id generation
 static long wxCurrentId = 100;
 
 // Id generation
 static long wxCurrentId = 100;
 
-long 
+long
 wxNewId (void)
 {
   return wxCurrentId++;
 wxNewId (void)
 {
   return wxCurrentId++;
@@ -161,102 +234,101 @@ wxNewId (void)
 long
 wxGetCurrentId(void) { return wxCurrentId; }
 
 long
 wxGetCurrentId(void) { return wxCurrentId; }
 
-void 
+void
 wxRegisterId (long id)
 {
   if (id >= wxCurrentId)
     wxCurrentId = id + 1;
 }
 
 wxRegisterId (long id)
 {
   if (id >= wxCurrentId)
     wxCurrentId = id + 1;
 }
 
-void 
-StringToFloat (char *s, float *number)
+void
+StringToFloat (wxChar *s, float *number)
 {
   if (s && *s && number)
 {
   if (s && *s && number)
-    *number = (float) strtod (s, NULL);
+    *number = (float) wxStrtod (s, (wxChar **) NULL);
 }
 
 }
 
-void 
-StringToDouble (char *s, double *number)
+void
+StringToDouble (wxChar *s, double *number)
 {
   if (s && *s && number)
 {
   if (s && *s && number)
-    *number = strtod (s, 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, "%.2f", number);
-  sprintf (buf, fmt, number);
+  wxSprintf (buf, fmt, number);
   return buf;
 }
 
   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;
 }
 
   return buf;
 }
 
-void 
-StringToInt (char *s, int *number)
+void
+StringToInt (wxChar *s, int *number)
 {
   if (s && *s && number)
 {
   if (s && *s && number)
-    *number = (int) strtol (s, NULL, 10);
+    *number = (int) wxStrtol (s, (wxChar **) NULL, 10);
 }
 
 }
 
-void 
-StringToLong (char *s, long *number)
+void
+StringToLong (wxChar *s, long *number)
 {
   if (s && *s && number)
 {
   if (s && *s && number)
-    *number = strtol (s, NULL, 10);
+    *number = wxStrtol (s, (wxChar **) NULL, 10);
 }
 
 }
 
-char *
+wxChar *
 IntToString (int number)
 {
 IntToString (int number)
 {
-  static char buf[20];
+  static wxChar buf[20];
 
 
-  sprintf (buf, "%d", number);
+  wxSprintf (buf, wxT("%d"), number);
   return buf;
 }
 
   return buf;
 }
 
-char *
+wxChar *
 LongToString (long number)
 {
 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.
   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
 
 // Convert 2-digit hex number to decimal
-int wxHexToDec(char *buf)
+int wxHexToDec(const wxString& buf)
 {
   int firstDigit, secondDigit;
 {
   int firstDigit, secondDigit;
-  
-  if (buf[0] >= 'A')
-    firstDigit = buf[0] - 'A' + 10;
+
+  if (buf.GetChar(0) >= wxT('A'))
+    firstDigit = buf.GetChar(0) - wxT('A') + 10;
   else
   else
-    firstDigit = buf[0] - '0';
+    firstDigit = buf.GetChar(0) - wxT('0');
 
 
-  if (buf[1] >= 'A')
-    secondDigit = buf[1] - 'A' + 10;
+  if (buf.GetChar(1) >= wxT('A'))
+    secondDigit = buf.GetChar(1) - wxT('A') + 10;
   else
   else
-    secondDigit = buf[1] - '0';
-    
+    secondDigit = buf.GetChar(1) - wxT('0');
+
   return firstDigit * 16 + secondDigit;
 }
 
 // Convert decimal integer to 2-character hex string
   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));
 {
   int firstDigit = (int)(dec/16.0);
   int secondDigit = (int)(dec - (firstDigit*16.0));
@@ -265,8 +337,16 @@ void wxDecToHex(int dec, char *buf)
   buf[2] = 0;
 }
 
   buf[2] = 0;
 }
 
+// Convert decimal integer to 2-character hex string
+wxString wxDecToHex(int dec)
+{
+    wxChar buf[3];
+    wxDecToHex(dec, buf);
+    return wxString(buf);
+}
+
 // Match a string INDEPENDENT OF CASE
 // Match a string INDEPENDENT OF CASE
-bool 
+bool
 StringMatch (char *str1, char *str2, bool subString, bool exact)
 {
   if (str1 == NULL || str2 == NULL)
 StringMatch (char *str1, char *str2, bool subString, bool exact)
 {
   if (str1 == NULL || str2 == NULL)
@@ -283,15 +363,15 @@ StringMatch (char *str1, char *str2, bool subString, bool exact)
       // Search for str1 in str2
       // Slow .... but acceptable for short strings
       for (i = 0; i <= len2 - len1; 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)
-           return TRUE;
-       }
+        {
+          if (strncasecmp (str1, str2 + i, len1) == 0)
+            return TRUE;
+        }
     }
   else if (exact)
     {
       if (strcasecmp (str1, str2) == 0)
     }
   else if (exact)
     {
       if (strcasecmp (str1, str2) == 0)
-       return TRUE;
+        return TRUE;
     }
   else
     {
     }
   else
     {
@@ -299,7 +379,7 @@ StringMatch (char *str1, char *str2, bool subString, bool exact)
       int len2 = strlen (str2);
 
       if (strncasecmp (str1, str2, wxMin (len1, len2)) == 0)
       int len2 = strlen (str2);
 
       if (strncasecmp (str1, str2, wxMin (len1, len2)) == 0)
-       return TRUE;
+        return TRUE;
     }
 
   return FALSE;
     }
 
   return FALSE;
@@ -307,80 +387,152 @@ StringMatch (char *str1, char *str2, bool subString, bool exact)
 
 // Return the current date/time
 // [volatile]
 
 // Return the current date/time
 // [volatile]
-wxString wxNow( void )
+wxString wxNow()
 {
 {
-  time_t now = time(NULL);
-  char *date = ctime(&now); 
+  time_t now = time((time_t *) NULL);
+  char *date = ctime(&now);
   date[24] = '\0';
   return wxString(date);
 }
 
   date[24] = '\0';
   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);
-
-  strncpy(address, tmp, maxSize - 1);
-  address[maxSize-1] = '\0';
-  return TRUE;
-}
+#if wxUSE_GUI
 
 
-/*
- * Strip out any menu codes
- */
+// ----------------------------------------------------------------------------
+// Menu accelerators related functions
+// ----------------------------------------------------------------------------
 
 
-char *wxStripMenuCodes (char *in, char *out)
+wxChar *wxStripMenuCodes (wxChar *in, wxChar *out)
 {
   if (!in)
 {
   if (!in)
-    return NULL;
-    
+    return (wxChar *) NULL;
+
   if (!out)
     out = copystring(in);
 
   if (!out)
     out = copystring(in);
 
-  char *tmpOut = out;
-  
+  wxChar *tmpOut = out;
+
   while (*in)
     {
   while (*in)
     {
-      if (*in == '&')
-       {
-         // Check && -> &, &x -> x
-         if (*++in == '&')
-           *out++ = *in++;
-       }
-      else if (*in == '\t')
-       {
+      if (*in == wxT('&'))
+        {
+          // Check && -> &, &x -> x
+          if (*++in == wxT('&'))
+            *out++ = *in++;
+        }
+      else if (*in == wxT('\t'))
+        {
           // Remove all stuff after \t in X mode, and let the stuff as is
           // in Windows mode.
           // Accelerators are handled in wx_item.cc for Motif, and are not
           // YET supported in XView
           // Remove all stuff after \t in X mode, and let the stuff as is
           // in Windows mode.
           // Accelerators are handled in wx_item.cc for Motif, and are not
           // YET supported in XView
-         break;
-       }
+          break;
+        }
       else
       else
-       *out++ = *in++;
-    }                          // while
+        *out++ = *in++;
+    }                                // while
 
 
-  *out = '\0';
+  *out = wxT('\0');
 
   return tmpOut;
 }
 
 
   return tmpOut;
 }
 
+wxString wxStripMenuCodes(const wxString& str)
+{
+    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
 
 /*
  * If parent is non-NULL, look through children for a label or title
@@ -388,53 +540,54 @@ char *wxStripMenuCodes (char *in, char *out)
  *
  */
 
  *
  */
 
-static wxWindow *wxFindWindowByLabel1 (const wxString& title, wxWindow * parent);
-
 wxWindow *
 wxFindWindowByLabel (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 ())
-       {
-         wxWindow *win = (wxWindow *) node->Data ();
-         wxWindow *retwin = wxFindWindowByLabel1 (title, win);
-         if (retwin)
-           return retwin;
-       }                       // for()
+        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 NULL;
+    return (wxWindow *) NULL;
 }
 
 // Recursive
 static wxWindow *
 wxFindWindowByLabel1 (const wxString& title, wxWindow * parent)
 {
 }
 
 // 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 ())
-       {
-         wxWindow *win = (wxWindow *) node->Data ();
-         wxWindow *retwin = wxFindWindowByLabel1 (title, win);
-         if (retwin)
-           return retwin;
-       }                       // for()
+        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 NULL;                 // Not found
-
+    return (wxWindow *) NULL;                        // Not found
 }
 
 /*
 }
 
 /*
@@ -443,28 +596,29 @@ wxFindWindowByLabel1 (const wxString& title, wxWindow * parent)
  *
  */
 
  *
  */
 
-static wxWindow *wxFindWindowByName1 (const wxString& title, wxWindow * parent);
-
 wxWindow *
 wxFindWindowByName (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 ())
-       {
-         wxWindow *win = (wxWindow *) node->Data ();
-         wxWindow *retwin = wxFindWindowByName1 (title, win);
-         if (retwin)
-           return retwin;
-       }                       // for()
+        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);
+
+    // Failed? Try by label instead.
+    return wxFindWindowByLabel(title, parent);
 }
 
 // Recursive
 }
 
 // Recursive
@@ -473,28 +627,28 @@ wxFindWindowByName1 (const wxString& title, wxWindow * parent)
 {
   if (parent)
     {
 {
   if (parent)
     {
-       if ( parent->GetName() == title )
-                       return parent;
+            if ( parent->GetName() == title )
+                        return parent;
     }
 
   if (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()
+      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 NULL;                 // Not found
+  return (wxWindow *) NULL;                        // Not found
 
 }
 
 // Returns menu item id or -1 if none.
 
 }
 
 // Returns menu item id or -1 if none.
-int 
+int
 wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
 {
   wxMenuBar *menuBar = frame->GetMenuBar ();
 wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
 {
   wxMenuBar *menuBar = frame->GetMenuBar ();
@@ -503,49 +657,7 @@ wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& i
   return menuBar->FindMenuItem (menuString, itemString);
 }
 
   return menuBar->FindMenuItem (menuString, itemString);
 }
 
-/*
- * wxDebugStreamBuf
- */
-#if !defined(_WINDLL)
-wxDebugStreamBuf::wxDebugStreamBuf(void)
-{
-  if (allocate()) setp(base(),ebuf());
-}
-
-int wxDebugStreamBuf::overflow(int WXUNUSED(i))
-{
-  int len = pptr() - pbase();
-  char *txt = new char[len+1];
-  strncpy(txt, pbase(), len);
-  txt[len] = '\0';
-#ifdef __WINDOWS__
-  OutputDebugString((LPCSTR)txt);
-#else
-  fprintf(stderr, txt);
-#endif
-  setp(pbase(), epptr());
-  delete[] txt;
-  return EOF;
-}
-
-int wxDebugStreamBuf::sync(void)
-{
-  int len = pptr() - pbase();
-  char *txt = new char[len+1];
-  strncpy(txt, pbase(), len);
-  txt[len] = '\0';
-#ifdef __WINDOWS__
-  OutputDebugString((LPCSTR)txt);
-#else
-  fprintf(stderr, txt);
-#endif
-  setp(pbase(), epptr());
-  delete[] txt;
-  return 0;
-}
-
-#endif
+#endif // wxUSE_GUI
 
 /*
 On Fri, 21 Jul 1995, Paul Craven wrote:
 
 /*
 On Fri, 21 Jul 1995, Paul Craven wrote:
@@ -553,12 +665,12 @@ On Fri, 21 Jul 1995, Paul Craven wrote:
 > Is there a way to find the path of running program's executable? I can get
 > my home directory, and the current directory, but I don't know how to get the
 > executable directory.
 > Is there a way to find the path of running program's executable? I can get
 > my home directory, and the current directory, but I don't know how to get the
 > executable directory.
-> 
+>
 
 The code below (warty as it is), does what you want on most Unix,
 DOS, and Mac platforms (it's from the ALS Prolog main).
 
 
 The code below (warty as it is), does what you want on most Unix,
 DOS, and Mac platforms (it's from the ALS Prolog main).
 
-|| Ken Bowen      Applied Logic Systems, Inc.         PO Box 180,     
+|| Ken Bowen      Applied Logic Systems, Inc.         PO Box 180,
 ||====            Voice:  +1 (617)965-9191            Newton Centre,
 ||                FAX:    +1 (617)965-1636            MA  02159  USA
                   Email:  ken@als.com        WWW: http://www.als.com
 ||====            Voice:  +1 (617)965-9191            Newton Centre,
 ||                FAX:    +1 (617)965-1636            MA  02159  USA
                   Email:  ken@als.com        WWW: http://www.als.com
@@ -571,8 +683,8 @@ DOS, and Mac platforms (it's from the ALS Prolog main).
 
 /*--------------------------------------------------------------------*
  | whereami is given a filename f in the form:  whereami(argv[0])
 
 /*--------------------------------------------------------------------*
  | whereami is given a filename f in the form:  whereami(argv[0])
- | It returns the directory in which the executable file (containing 
- | this code [main.c] ) may be found.  A dot will be returned to indicate 
+ | It returns the directory in which the executable file (containing
+ | this code [main.c] ) may be found.  A dot will be returned to indicate
  | the current directory.
  *--------------------------------------------------------------------*/
 
  | the current directory.
  *--------------------------------------------------------------------*/
 
@@ -580,7 +692,7 @@ static void
 whereami(name)
     char *name;
 {
 whereami(name)
     char *name;
 {
-    register char *cutoff = NULL;      /* stifle -Wall */
+    register char *cutoff = NULL;        /* stifle -Wall */
     register char *s;
     register char *t;
     int   cc;
     register char *s;
     register char *t;
     int   cc;
@@ -593,117 +705,117 @@ whereami(name)
 
     if (access(name, R_OK) == 0) {
 
 
     if (access(name, R_OK) == 0) {
 
-       /*-------------------------------------------------------------*
-        * The file was accessible without any other work.  But the current
-        * working directory might change on us, so if it was accessible
-        * through the cwd, then we should get it for later accesses.
-        *-------------------------------------------------------------*/
+        /*-------------------------------------------------------------*
+         * The file was accessible without any other work.  But the current
+         * working directory might change on us, so if it was accessible
+         * through the cwd, then we should get it for later accesses.
+         *-------------------------------------------------------------*/
 
 
-       t = imagedir;
-       if (!absolute_pathname(name)) {
+        t = imagedir;
+        if (!absolute_pathname(name)) {
 #if defined(DOS) || defined(__WIN32__)
 #if defined(DOS) || defined(__WIN32__)
-           int   drive;
-           char *newrbuf;
+            int   drive;
+            char *newrbuf;
 
 
-           newrbuf = imagedir;
+            newrbuf = imagedir;
 #ifndef __DJGPP__
 #ifndef __DJGPP__
-           if (*(name + 1) == ':') {
-               if (*name >= 'a' && *name <= 'z')
-                   drive = (int) (*name - 'a' + 1);
-               else
-                   drive = (int) (*name - 'A' + 1);
-               *newrbuf++ = *name;
-               *newrbuf++ = *(name + 1);
-               *newrbuf++ = DIR_SEPARATOR;
-           }
-           else {
-               drive = 0;
-               *newrbuf++ = DIR_SEPARATOR;
-           }
-           if (getcwd(newrbuf, drive) == 0) {  /* } */
+            if (*(name + 1) == ':') {
+                if (*name >= 'a' && *name <= 'z')
+                    drive = (int) (*name - 'a' + 1);
+                else
+                    drive = (int) (*name - 'A' + 1);
+                *newrbuf++ = *name;
+                *newrbuf++ = *(name + 1);
+                *newrbuf++ = DIR_SEPARATOR;
+            }
+            else {
+                drive = 0;
+                *newrbuf++ = DIR_SEPARATOR;
+            }
+            if (getcwd(newrbuf, drive) == 0) {        /* } */
 #else
 #else
-           if (getcwd(newrbuf, 1024) == 0) {   /* } */
+            if (getcwd(newrbuf, 1024) == 0) {        /* } */
 #endif
 #else  /* DOS */
 #ifdef HAVE_GETWD
 #endif
 #else  /* DOS */
 #ifdef HAVE_GETWD
-           if (getwd(imagedir) == 0) {         /* } */
+            if (getwd(imagedir) == 0) {                /* } */
 #else  /* !HAVE_GETWD */
 #else  /* !HAVE_GETWD */
-           if (getcwd(imagedir, 1024) == 0) {
+            if (getcwd(imagedir, 1024) == 0) {
 #endif /* !HAVE_GETWD */
 #endif /* DOS */
 #endif /* !HAVE_GETWD */
 #endif /* DOS */
-               fatal_error(FE_GETCWD, 0);
-           }
-           for (; *t; t++)     /* Set t to end of buffer */
-               ;
-           if (*(t - 1) == DIR_SEPARATOR)      /* leave slash if already
-                                                * last char
-                                                */
-               cutoff = t - 1;
-           else {
-               cutoff = t;     /* otherwise put one in */
-               *t++ = DIR_SEPARATOR;
-           }
-       }
+                fatal_error(FE_GETCWD, 0);
+            }
+            for (; *t; t++)        /* Set t to end of buffer */
+                ;
+            if (*(t - 1) == DIR_SEPARATOR)        /* leave slash if already
+                                                 * last char
+                                                 */
+                cutoff = t - 1;
+            else {
+                cutoff = t;        /* otherwise put one in */
+                *t++ = DIR_SEPARATOR;
+            }
+        }
 #if (!defined(__MAC__) && !defined(__DJGPP__) && !defined(__GO32__) && !defined(__WIN32__))
 #if (!defined(__MAC__) && !defined(__DJGPP__) && !defined(__GO32__) && !defined(__WIN32__))
-       else
-               (*t++ = DIR_SEPARATOR);
+        else
+                (*t++ = DIR_SEPARATOR);
 #endif
 
 #endif
 
-       /*-------------------------------------------------------------*
-        * Copy the rest of the string and set the cutoff if it was not
-        * already set.  If the first character of name is a slash, cutoff
-        * is not presently set but will be on the first iteration of the
-        * loop below.
-        *-------------------------------------------------------------*/
+        /*-------------------------------------------------------------*
+         * Copy the rest of the string and set the cutoff if it was not
+         * already set.  If the first character of name is a slash, cutoff
+         * is not presently set but will be on the first iteration of the
+         * loop below.
+         *-------------------------------------------------------------*/
 
 
-       for ((*name == DIR_SEPARATOR ? (s = name+1) : (s = name));;) {
-           if (*s == DIR_SEPARATOR)
-                       cutoff = t;
-           if (!(*t++ = *s++))
-                       break;
-       }
+        for ((*name == DIR_SEPARATOR ? (s = name+1) : (s = name));;) {
+            if (*s == DIR_SEPARATOR)
+                        cutoff = t;
+            if (!(*t++ = *s++))
+                        break;
+        }
 
     }
     else {
 
 
     }
     else {
 
-       /*-------------------------------------------------------------*
-        * Get the path list from the environment.  If the path list is
-        * inaccessible for any reason, leave with fatal error.
-        *-------------------------------------------------------------*/
+        /*-------------------------------------------------------------*
+         * Get the path list from the environment.  If the path list is
+         * inaccessible for any reason, leave with fatal error.
+         *-------------------------------------------------------------*/
 
 #ifdef __MAC__
 
 #ifdef __MAC__
-       if ((s = getenv("Commands")) == (char *) 0)
+        if ((s = getenv("Commands")) == (char *) 0)
 #else
 #else
-       if ((s = getenv("PATH")) == (char *) 0)
+        if ((s = getenv("PATH")) == (char *) 0)
 #endif
 #endif
-           fatal_error(FE_PATH, 0);
-
-       /*
-        * Copy path list into ebuf and set the source pointer to the
-        * beginning of this buffer.
-        */
-
-       strcpy(ebuf, s);
-       s = ebuf;
-
-       for (;;) {
-           t = imagedir;
-           while (*s && *s != PATH_SEPARATOR)
-               *t++ = *s++;
-           if (t > imagedir && *(t - 1) == DIR_SEPARATOR) 
-               ;               /* do nothing -- slash already is in place */
-           else
-               *t++ = DIR_SEPARATOR;   /* put in the slash */
-           cutoff = t - 1;     /* set cutoff */
-           strcpy(t, name);
-           if (access(imagedir, R_OK) == 0)
-               break;
-
-           if (*s)
-               s++;            /* advance source pointer */
-           else
-               fatal_error(FE_INFND, 0);
-       }
+            fatal_error(FE_PATH, 0);
+
+        /*
+         * Copy path list into ebuf and set the source pointer to the
+         * beginning of this buffer.
+         */
+
+        strcpy(ebuf, s);
+        s = ebuf;
+
+        for (;;) {
+            t = imagedir;
+            while (*s && *s != PATH_SEPARATOR)
+                *t++ = *s++;
+            if (t > imagedir && *(t - 1) == DIR_SEPARATOR)
+                ;                /* do nothing -- slash already is in place */
+            else
+                *t++ = DIR_SEPARATOR;        /* put in the slash */
+            cutoff = t - 1;        /* set cutoff */
+            strcpy(t, name);
+            if (access(imagedir, R_OK) == 0)
+                break;
+
+            if (*s)
+                s++;                /* advance source pointer */
+            else
+                fatal_error(FE_INFND, 0);
+        }
 
     }
 
 
     }
 
@@ -716,27 +828,216 @@ whereami(name)
 
 #ifdef HAVE_SYMLINK
     while ((cc = readlink(imagedir, ebuf, 512)) != -1) {
 
 #ifdef HAVE_SYMLINK
     while ((cc = readlink(imagedir, ebuf, 512)) != -1) {
-       ebuf[cc] = 0;
-       s = ebuf;
-       if (*s == DIR_SEPARATOR) {
-           t = imagedir;
-       }
-       else {
-           t = cutoff + 1;
-       }
-       for (;;) {
-           if (*s == DIR_SEPARATOR)
-               cutoff = t;     /* mark the last slash seen */
-           if (!(*t++ = *s++)) /* copy the character */
-               break;
-       }
+        ebuf[cc] = 0;
+        s = ebuf;
+        if (*s == DIR_SEPARATOR) {
+            t = imagedir;
+        }
+        else {
+            t = cutoff + 1;
+        }
+        for (;;) {
+            if (*s == DIR_SEPARATOR)
+                cutoff = t;        /* mark the last slash seen */
+            if (!(*t++ = *s++))        /* copy the character */
+                break;
+        }
     }
 
 #endif /* HAVE_SYMLINK */
 
     }
 
 #endif /* HAVE_SYMLINK */
 
-    strcpy(imagename, cutoff + 1);     /* keep the image name */
-    *(cutoff + 1) = 0;         /* chop off the filename part */
+    strcpy(imagename, cutoff + 1);        /* keep the image name */
+    *(cutoff + 1) = 0;                /* chop off the filename part */
 }
 
 #endif
 
 }
 
 #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.
+ */
+
+int wxMessageBox(const wxString& message, const wxString& caption, long style,
+                 wxWindow *parent, int WXUNUSED(x), int WXUNUSED(y) )
+{
+    wxMessageDialog dialog(parent, message, caption, style);
+
+    int ans = dialog.ShowModal();
+    switch ( ans )
+    {
+        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) )
+{
+    wxTextEntryDialog dialog(parent, message, caption, defaultValue, wxOK|wxCANCEL, wxPoint(x, y));
+    if (dialog.ShowModal() == wxID_OK)
+        return dialog.GetValue();
+    else
+        return wxString("");
+}
+#endif // wxUSE_TEXTDLG
+
+#ifdef __MWERKS__
+char *strdup(const char *s)
+{
+        return strcpy( (char*) malloc( strlen( s ) + 1 ) , s ) ;
+}
+
+int isascii( int c )
+{
+        return ( c >= 0 && c < 128 ) ;
+}
+#endif // __MWERKS__
+
+// ----------------------------------------------------------------------------
+// misc functions
+// ----------------------------------------------------------------------------
+
+void wxEnableTopLevelWindows(bool enable)
+{
+   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;
+}
+
+wxString wxGetEmailAddress()
+{
+    wxString email;
+
+    wxString host = wxGetHostName();
+    if ( !!host )
+    {
+        wxString user = wxGetUserId();
+        if ( !!user )
+        {
+            wxString email(user);
+            email << wxT('@') << host;
+        }
+    }
+
+    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;
+}
+
+wxString wxGetHostName()
+{
+    static const size_t hostnameSize = 257;
+
+    wxString buf;
+    bool ok = wxGetHostName(buf.GetWriteBuf(hostnameSize), hostnameSize);
+
+    buf.UngetWriteBuf();
+
+    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;
+}
+