home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / common / utilscmn.cpp < prev    next >
C/C++ Source or Header  |  2002-12-17  |  30KB  |  1,174 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        utilscmn.cpp
  3. // Purpose:     Miscellaneous utility functions and classes
  4. // Author:      Julian Smart
  5. // Modified by:
  6. // Created:     29/01/98
  7. // RCS-ID:      $Id: utilscmn.cpp,v 1.93.2.7 2002/12/16 23:08:31 RD Exp $
  8. // Copyright:   (c) 1998 Julian Smart
  9. // Licence:     wxWindows license
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ============================================================================
  13. // declarations
  14. // ============================================================================
  15.  
  16. // ----------------------------------------------------------------------------
  17. // headers
  18. // ----------------------------------------------------------------------------
  19.  
  20. #ifdef __GNUG__
  21.     #pragma implementation "utils.h"
  22. #endif
  23.  
  24. // For compilers that support precompilation, includes "wx.h".
  25. #include "wx/wxprec.h"
  26.  
  27. #ifdef __BORLANDC__
  28.     #pragma hdrstop
  29. #endif
  30.  
  31. #ifndef WX_PRECOMP
  32.     #include "wx/defs.h"
  33.     #include "wx/string.h"
  34.     #include "wx/utils.h"
  35.     #include "wx/intl.h"
  36.     #include "wx/log.h"
  37.  
  38.     #if wxUSE_GUI
  39.         #include "wx/app.h"
  40.         #include "wx/window.h"
  41.         #include "wx/frame.h"
  42.         #include "wx/menu.h"
  43.         #include "wx/msgdlg.h"
  44.         #include "wx/textdlg.h"
  45.         #include "wx/textctrl.h"    // for wxTE_PASSWORD
  46.         #if wxUSE_ACCEL
  47.             #include "wx/menuitem.h"
  48.             #include "wx/accel.h"
  49.         #endif // wxUSE_ACCEL
  50.     #endif // wxUSE_GUI
  51. #endif // WX_PRECOMP
  52.  
  53. #ifndef __WIN16__
  54. #include "wx/process.h"
  55. #include "wx/txtstrm.h"
  56. #endif
  57.  
  58. #include <ctype.h>
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include <string.h>
  62.  
  63. #if !defined(__WATCOMC__)
  64.     #if !(defined(_MSC_VER) && (_MSC_VER > 800))
  65.         #include <errno.h>
  66.     #endif
  67. #endif
  68.  
  69. #if wxUSE_GUI
  70.     #include "wx/colordlg.h"
  71.     #include "wx/fontdlg.h"
  72.     #include "wx/notebook.h"
  73.     #include "wx/frame.h"
  74.     #include "wx/statusbr.h"
  75. #endif // wxUSE_GUI
  76.  
  77. #include <time.h>
  78.  
  79. #ifndef __MWERKS__
  80.     #include <sys/types.h>
  81.     #include <sys/stat.h>
  82. #endif
  83.  
  84. #ifdef __SALFORDC__
  85.     #include <clib.h>
  86. #endif
  87.  
  88. #ifdef __WXMSW__
  89.     #include "wx/msw/private.h"
  90. #endif
  91.  
  92. // ----------------------------------------------------------------------------
  93. // common data
  94. // ----------------------------------------------------------------------------
  95.  
  96. #if WXWIN_COMPATIBILITY_2_2
  97.     const wxChar *wxInternalErrorStr = wxT("wxWindows Internal Error");
  98.     const wxChar *wxFatalErrorStr = wxT("wxWindows Fatal Error");
  99. #endif // WXWIN_COMPATIBILITY_2_2
  100.  
  101. // ============================================================================
  102. // implementation
  103. // ============================================================================
  104.  
  105. wxChar *
  106. copystring (const wxChar *s)
  107. {
  108.   if (s == NULL) s = wxT("");
  109.   size_t len = wxStrlen (s) + 1;
  110.  
  111.   wxChar *news = new wxChar[len];
  112.   memcpy (news, s, len * sizeof(wxChar));    // Should be the fastest
  113.  
  114.   return news;
  115. }
  116.  
  117. // Id generation
  118. static long wxCurrentId = 100;
  119.  
  120. long
  121. wxNewId (void)
  122. {
  123.   return wxCurrentId++;
  124. }
  125.  
  126. long
  127. wxGetCurrentId(void) { return wxCurrentId; }
  128.  
  129. void
  130. wxRegisterId (long id)
  131. {
  132.   if (id >= wxCurrentId)
  133.     wxCurrentId = id + 1;
  134. }
  135.  
  136. void
  137. StringToFloat (const wxChar *s, float *number)
  138. {
  139.   if (s && *s && number)
  140.     *number = (float) wxStrtod (s, (wxChar **) NULL);
  141. }
  142.  
  143. void
  144. StringToDouble (const wxChar *s, double *number)
  145. {
  146.   if (s && *s && number)
  147.     *number = wxStrtod (s, (wxChar **) NULL);
  148. }
  149.  
  150. wxChar *
  151. FloatToString (float number, const wxChar *fmt)
  152. {
  153.   static wxChar buf[256];
  154.  
  155.   wxSprintf (buf, fmt, number);
  156.   return buf;
  157. }
  158.  
  159. wxChar *
  160. DoubleToString (double number, const wxChar *fmt)
  161. {
  162.   static wxChar buf[256];
  163.  
  164.   wxSprintf (buf, fmt, number);
  165.   return buf;
  166. }
  167.  
  168. void
  169. StringToInt (const wxChar *s, int *number)
  170. {
  171.   if (s && *s && number)
  172.     *number = (int) wxStrtol (s, (wxChar **) NULL, 10);
  173. }
  174.  
  175. void
  176. StringToLong (const wxChar *s, long *number)
  177. {
  178.   if (s && *s && number)
  179.     *number = wxStrtol (s, (wxChar **) NULL, 10);
  180. }
  181.  
  182. wxChar *
  183. IntToString (int number)
  184. {
  185.   static wxChar buf[20];
  186.  
  187.   wxSprintf (buf, wxT("%d"), number);
  188.   return buf;
  189. }
  190.  
  191. wxChar *
  192. LongToString (long number)
  193. {
  194.   static wxChar buf[20];
  195.  
  196.   wxSprintf (buf, wxT("%ld"), number);
  197.   return buf;
  198. }
  199.  
  200. // Array used in DecToHex conversion routine.
  201. static wxChar hexArray[] = wxT("0123456789ABCDEF");
  202.  
  203. // Convert 2-digit hex number to decimal
  204. int wxHexToDec(const wxString& buf)
  205. {
  206.   int firstDigit, secondDigit;
  207.  
  208.   if (buf.GetChar(0) >= wxT('A'))
  209.     firstDigit = buf.GetChar(0) - wxT('A') + 10;
  210.   else
  211.     firstDigit = buf.GetChar(0) - wxT('0');
  212.  
  213.   if (buf.GetChar(1) >= wxT('A'))
  214.     secondDigit = buf.GetChar(1) - wxT('A') + 10;
  215.   else
  216.     secondDigit = buf.GetChar(1) - wxT('0');
  217.  
  218.   return (firstDigit & 0xF) * 16 + (secondDigit & 0xF );
  219. }
  220.  
  221. // Convert decimal integer to 2-character hex string
  222. void wxDecToHex(int dec, wxChar *buf)
  223. {
  224.   int firstDigit = (int)(dec/16.0);
  225.   int secondDigit = (int)(dec - (firstDigit*16.0));
  226.   buf[0] = hexArray[firstDigit];
  227.   buf[1] = hexArray[secondDigit];
  228.   buf[2] = 0;
  229. }
  230.  
  231. // Convert decimal integer to 2-character hex string
  232. wxString wxDecToHex(int dec)
  233. {
  234.     wxChar buf[3];
  235.     wxDecToHex(dec, buf);
  236.     return wxString(buf);
  237. }
  238.  
  239. #if WXWIN_COMPATIBILITY_2
  240. bool
  241. StringMatch (const wxChar *str1, const wxChar *str2, bool subString, bool exact)
  242. {
  243.   if (str1 == NULL || str2 == NULL)
  244.     return FALSE;
  245.   if (str1 == str2)
  246.     return TRUE;
  247.  
  248.   if (subString)
  249.     {
  250.       int len1 = wxStrlen (str1);
  251.       int len2 = wxStrlen (str2);
  252.       int i;
  253.  
  254.       // Search for str1 in str2
  255.       // Slow .... but acceptable for short strings
  256.       for (i = 0; i <= len2 - len1; i++)
  257.         {
  258.           if (wxStrnicmp (str1, str2 + i, len1) == 0)
  259.             return TRUE;
  260.         }
  261.     }
  262.   else if (exact)
  263.     {
  264.       if (wxStricmp (str1, str2) == 0)
  265.         return TRUE;
  266.     }
  267.   else
  268.     {
  269.       int len1 = wxStrlen (str1);
  270.       int len2 = wxStrlen (str2);
  271.  
  272.       if (wxStrnicmp (str1, str2, wxMin (len1, len2)) == 0)
  273.         return TRUE;
  274.     }
  275.  
  276.   return FALSE;
  277. }
  278. #endif
  279.  
  280. // Return the current date/time
  281. // [volatile]
  282. wxString wxNow()
  283. {
  284.     time_t now = time((time_t *) NULL);
  285.     char *date = ctime(&now);
  286.     date[24] = '\0';
  287.     return wxString::FromAscii(date);
  288. }
  289.  
  290. #if wxUSE_GUI
  291.  
  292. #if wxUSE_MENUS
  293.  
  294. // ----------------------------------------------------------------------------
  295. // Menu accelerators related functions
  296. // ----------------------------------------------------------------------------
  297.  
  298. wxChar *wxStripMenuCodes(const wxChar *in, wxChar *out)
  299. {
  300.     wxString s = wxMenuItem::GetLabelFromText(in);
  301.     if ( out )
  302.     {
  303.         // go smash their buffer if it's not big enough - I love char * params
  304.         memcpy(out, s.c_str(), s.length() * sizeof(wxChar));
  305.     }
  306.     else
  307.     {
  308.         out = copystring(s);
  309.     }
  310.  
  311.     return out;
  312. }
  313.  
  314. wxString wxStripMenuCodes(const wxString& in)
  315. {
  316.     wxString out;
  317.  
  318.     size_t len = in.length();
  319.     out.reserve(len);
  320.  
  321.     for ( size_t n = 0; n < len; n++ )
  322.     {
  323.         wxChar ch = in[n];
  324.         if ( ch == _T('&') )
  325.         {
  326.             // skip it, it is used to introduce the accel char (or to quote
  327.             // itself in which case it should still be skipped): note that it
  328.             // can't be the last character of the string
  329.             if ( ++n == len )
  330.             {
  331.                 wxLogDebug(_T("Invalid menu string '%s'"), in.c_str());
  332.             }
  333.             else
  334.             {
  335.                 // use the next char instead
  336.                 ch = in[n];
  337.             }
  338.         }
  339.         else if ( ch == _T('\t') )
  340.         {
  341.             // everything after TAB is accel string, exit the loop
  342.             break;
  343.         }
  344.  
  345.         out += ch;
  346.     }
  347.  
  348.     return out;
  349. }
  350.  
  351. #endif // wxUSE_MENUS
  352.  
  353. // ----------------------------------------------------------------------------
  354. // Window search functions
  355. // ----------------------------------------------------------------------------
  356.  
  357. /*
  358.  * If parent is non-NULL, look through children for a label or title
  359.  * matching the specified string. If NULL, look through all top-level windows.
  360.  *
  361.  */
  362.  
  363. wxWindow *
  364. wxFindWindowByLabel (const wxString& title, wxWindow * parent)
  365. {
  366.     return wxWindow::FindWindowByLabel( title, parent );
  367. }
  368.  
  369.  
  370. /*
  371.  * If parent is non-NULL, look through children for a name
  372.  * matching the specified string. If NULL, look through all top-level windows.
  373.  *
  374.  */
  375.  
  376. wxWindow *
  377. wxFindWindowByName (const wxString& name, wxWindow * parent)
  378. {
  379.     return wxWindow::FindWindowByName( name, parent );
  380. }
  381.  
  382. // Returns menu item id or -1 if none.
  383. int
  384. wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
  385. {
  386. #if wxUSE_MENUS
  387.   wxMenuBar *menuBar = frame->GetMenuBar ();
  388.   if ( menuBar )
  389.       return menuBar->FindMenuItem (menuString, itemString);
  390. #endif // wxUSE_MENUS
  391.  
  392.   return -1;
  393. }
  394.  
  395. // Try to find the deepest child that contains 'pt'.
  396. // We go backwards, to try to allow for controls that are spacially
  397. // within other controls, but are still siblings (e.g. buttons within
  398. // static boxes). Static boxes are likely to be created _before_ controls
  399. // that sit inside them.
  400. wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt)
  401. {
  402.     if (!win->IsShown())
  403.         return NULL;
  404.  
  405.     // Hack for wxNotebook case: at least in wxGTK, all pages
  406.     // claim to be shown, so we must only deal with the selected one.
  407. #if wxUSE_NOTEBOOK
  408.     if (win->IsKindOf(CLASSINFO(wxNotebook)))
  409.     {
  410.       wxNotebook* nb = (wxNotebook*) win;
  411.       int sel = nb->GetSelection();
  412.       if (sel >= 0)
  413.       {
  414.         wxWindow* child = nb->GetPage(sel);
  415.         wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
  416.         if (foundWin)
  417.            return foundWin;
  418.       }
  419.     }
  420. #endif
  421.  
  422.     /* Doesn't work
  423.     // Frame case
  424.     else if (win->IsKindOf(CLASSINFO(wxFrame)))
  425.     {
  426.       // Pseudo-children that may not be mentioned in the child list
  427.       wxWindowList extraChildren;
  428.       wxFrame* frame = (wxFrame*) win;
  429.       if (frame->GetStatusBar())
  430.         extraChildren.Append(frame->GetStatusBar());
  431.       if (frame->GetToolBar())
  432.         extraChildren.Append(frame->GetToolBar());
  433.  
  434.       wxNode* node = extraChildren.First();
  435.       while (node)
  436.       {
  437.           wxWindow* child = (wxWindow*) node->Data();
  438.           wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
  439.           if (foundWin)
  440.             return foundWin;
  441.           node = node->Next();
  442.       }
  443.     }
  444.     */
  445.  
  446.     wxNode* node = win->GetChildren().Last();
  447.     while (node)
  448.     {
  449.         wxWindow* child = (wxWindow*) node->Data();
  450.         wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
  451.         if (foundWin)
  452.           return foundWin;
  453.         node = node->Previous();
  454.     }
  455.  
  456.     wxPoint pos = win->GetPosition();
  457.     wxSize sz = win->GetSize();
  458.     if (win->GetParent())
  459.     {
  460.         pos = win->GetParent()->ClientToScreen(pos);
  461.     }
  462.  
  463.     wxRect rect(pos, sz);
  464.     if (rect.Inside(pt))
  465.         return win;
  466.     else
  467.         return NULL;
  468. }
  469.  
  470. wxWindow* wxGenericFindWindowAtPoint(const wxPoint& pt)
  471. {
  472.     // Go backwards through the list since windows
  473.     // on top are likely to have been appended most
  474.     // recently.
  475.     wxNode* node = wxTopLevelWindows.Last();
  476.     while (node)
  477.     {
  478.         wxWindow* win = (wxWindow*) node->Data();
  479.         wxWindow* found = wxFindWindowAtPoint(win, pt);
  480.         if (found)
  481.             return found;
  482.         node = node->Previous();
  483.     }
  484.     return NULL;
  485. }
  486.  
  487. #endif // wxUSE_GUI
  488.  
  489. /*
  490. On Fri, 21 Jul 1995, Paul Craven wrote:
  491.  
  492. > Is there a way to find the path of running program's executable? I can get
  493. > my home directory, and the current directory, but I don't know how to get the
  494. > executable directory.
  495. >
  496.  
  497. The code below (warty as it is), does what you want on most Unix,
  498. DOS, and Mac platforms (it's from the ALS Prolog main).
  499.  
  500. || Ken Bowen      Applied Logic Systems, Inc.         PO Box 180,
  501. ||====            Voice:  +1 (617)965-9191            Newton Centre,
  502. ||                FAX:    +1 (617)965-1636            MA  02159  USA
  503.                   Email:  ken@als.com        WWW: http://www.als.com
  504. ------------------------------------------------------------------------
  505. */
  506.  
  507. // This code is commented out but it may be integrated with wxWin at
  508. // a later date, after testing. Thanks Ken!
  509. #if 0
  510.  
  511. /*--------------------------------------------------------------------*
  512.  | whereami is given a filename f in the form:  whereami(argv[0])
  513.  | It returns the directory in which the executable file (containing
  514.  | this code [main.c] ) may be found.  A dot will be returned to indicate
  515.  | the current directory.
  516.  *--------------------------------------------------------------------*/
  517.  
  518. static void
  519. whereami(name)
  520.     char *name;
  521. {
  522.     register char *cutoff = NULL;        /* stifle -Wall */
  523.     register char *s;
  524.     register char *t;
  525.     int   cc;
  526.     char  ebuf[4096];
  527.  
  528.     /*
  529.      * See if the file is accessible either through the current directory
  530.      * or through an absolute path.
  531.      */
  532.  
  533.     if (access(name, R_OK) == 0) {
  534.  
  535.         /*-------------------------------------------------------------*
  536.          * The file was accessible without any other work.  But the current
  537.          * working directory might change on us, so if it was accessible
  538.          * through the cwd, then we should get it for later accesses.
  539.          *-------------------------------------------------------------*/
  540.  
  541.         t = imagedir;
  542.         if (!absolute_pathname(name)) {
  543. #if defined(__DOS__) || defined(__WIN32__)
  544.             int   drive;
  545.             char *newrbuf;
  546.  
  547.             newrbuf = imagedir;
  548. #ifndef __DJGPP__
  549.             if (*(name + 1) == ':') {
  550.                 if (*name >= 'a' && *name <= 'z')
  551.                     drive = (int) (*name - 'a' + 1);
  552.                 else
  553.                     drive = (int) (*name - 'A' + 1);
  554.                 *newrbuf++ = *name;
  555.                 *newrbuf++ = *(name + 1);
  556.                 *newrbuf++ = DIR_SEPARATOR;
  557.             }
  558.             else {
  559.                 drive = 0;
  560.                 *newrbuf++ = DIR_SEPARATOR;
  561.             }
  562.             if (getcwd(newrbuf, drive) == 0) {        /* } */
  563. #else
  564.             if (getcwd(newrbuf, 1024) == 0) {        /* } */
  565. #endif
  566. #else  /* DOS */
  567. #ifdef HAVE_GETWD
  568.             if (getwd(imagedir) == 0) {                /* } */
  569. #else  /* !HAVE_GETWD */
  570.             if (getcwd(imagedir, 1024) == 0) {
  571. #endif /* !HAVE_GETWD */
  572. #endif /* DOS */
  573.                 fatal_error(FE_GETCWD, 0);
  574.             }
  575.             for (; *t; t++)        /* Set t to end of buffer */
  576.                 ;
  577.             if (*(t - 1) == DIR_SEPARATOR)        /* leave slash if already
  578.                                                  * last char
  579.                                                  */
  580.                 cutoff = t - 1;
  581.             else {
  582.                 cutoff = t;        /* otherwise put one in */
  583.                 *t++ = DIR_SEPARATOR;
  584.             }
  585.         }
  586. #if (!defined(__MAC__) && !defined(__DJGPP__) && !defined(__GO32__) && !defined(__WIN32__))
  587.         else
  588.                 (*t++ = DIR_SEPARATOR);
  589. #endif
  590.  
  591.         /*-------------------------------------------------------------*
  592.          * Copy the rest of the string and set the cutoff if it was not
  593.          * already set.  If the first character of name is a slash, cutoff
  594.          * is not presently set but will be on the first iteration of the
  595.          * loop below.
  596.          *-------------------------------------------------------------*/
  597.  
  598.         for ((*name == DIR_SEPARATOR ? (s = name+1) : (s = name));;) {
  599.             if (*s == DIR_SEPARATOR)
  600.                         cutoff = t;
  601.             if (!(*t++ = *s++))
  602.                         break;
  603.         }
  604.  
  605.     }
  606.     else {
  607.  
  608.         /*-------------------------------------------------------------*
  609.          * Get the path list from the environment.  If the path list is
  610.          * inaccessible for any reason, leave with fatal error.
  611.          *-------------------------------------------------------------*/
  612.  
  613. #ifdef __MAC__
  614.         if ((s = getenv("Commands")) == (char *) 0)
  615. #else
  616.         if ((s = getenv("PATH")) == (char *) 0)
  617. #endif
  618.             fatal_error(FE_PATH, 0);
  619.  
  620.         /*
  621.          * Copy path list into ebuf and set the source pointer to the
  622.          * beginning of this buffer.
  623.          */
  624.  
  625.         strcpy(ebuf, s);
  626.         s = ebuf;
  627.  
  628.         for (;;) {
  629.             t = imagedir;
  630.             while (*s && *s != PATH_SEPARATOR)
  631.                 *t++ = *s++;
  632.             if (t > imagedir && *(t - 1) == DIR_SEPARATOR)
  633.                 ;                /* do nothing -- slash already is in place */
  634.             else
  635.                 *t++ = DIR_SEPARATOR;        /* put in the slash */
  636.             cutoff = t - 1;        /* set cutoff */
  637.             strcpy(t, name);
  638.             if (access(imagedir, R_OK) == 0)
  639.                 break;
  640.  
  641.             if (*s)
  642.                 s++;                /* advance source pointer */
  643.             else
  644.                 fatal_error(FE_INFND, 0);
  645.         }
  646.  
  647.     }
  648.  
  649.     /*-------------------------------------------------------------*
  650.      | At this point the full pathname should exist in imagedir and
  651.      | cutoff should be set to the final slash.  We must now determine
  652.      | whether the file name is a symbolic link or not and chase it down
  653.      | if it is.  Note that we reuse ebuf for getting the link.
  654.      *-------------------------------------------------------------*/
  655.  
  656. #ifdef HAVE_SYMLINK
  657.     while ((cc = readlink(imagedir, ebuf, 512)) != -1) {
  658.         ebuf[cc] = 0;
  659.         s = ebuf;
  660.         if (*s == DIR_SEPARATOR) {
  661.             t = imagedir;
  662.         }
  663.         else {
  664.             t = cutoff + 1;
  665.         }
  666.         for (;;) {
  667.             if (*s == DIR_SEPARATOR)
  668.                 cutoff = t;        /* mark the last slash seen */
  669.             if (!(*t++ = *s++))        /* copy the character */
  670.                 break;
  671.         }
  672.     }
  673.  
  674. #endif /* HAVE_SYMLINK */
  675.  
  676.     strcpy(imagename, cutoff + 1);        /* keep the image name */
  677.     *(cutoff + 1) = 0;                /* chop off the filename part */
  678. }
  679.  
  680. #endif
  681.  
  682. #if wxUSE_GUI
  683.  
  684. // ----------------------------------------------------------------------------
  685. // GUI helpers
  686. // ----------------------------------------------------------------------------
  687.  
  688. /*
  689.  * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
  690.  * since otherwise the generic code may be pulled in unnecessarily.
  691.  */
  692.  
  693. #if wxUSE_MSGDLG
  694.  
  695. int wxMessageBox(const wxString& message, const wxString& caption, long style,
  696.                  wxWindow *parent, int WXUNUSED(x), int WXUNUSED(y) )
  697. {
  698.     wxMessageDialog dialog(parent, message, caption, style);
  699.  
  700.     int ans = dialog.ShowModal();
  701.     switch ( ans )
  702.     {
  703.         case wxID_OK:
  704.             return wxOK;
  705.         case wxID_YES:
  706.             return wxYES;
  707.         case wxID_NO:
  708.             return wxNO;
  709.         case wxID_CANCEL:
  710.             return wxCANCEL;
  711.     }
  712.  
  713.     wxFAIL_MSG( _T("unexpected return code from wxMessageDialog") );
  714.  
  715.     return wxCANCEL;
  716. }
  717.  
  718. #endif // wxUSE_MSGDLG
  719.  
  720. #if wxUSE_TEXTDLG
  721.  
  722. wxString wxGetTextFromUser(const wxString& message, const wxString& caption,
  723.                         const wxString& defaultValue, wxWindow *parent,
  724.                         int x, int y, bool WXUNUSED(centre) )
  725. {
  726.     wxString str;
  727.     wxTextEntryDialog dialog(parent, message, caption, defaultValue, wxOK|wxCANCEL, wxPoint(x, y));
  728.     if (dialog.ShowModal() == wxID_OK)
  729.     {
  730.         str = dialog.GetValue();
  731.     }
  732.  
  733.     return str;
  734. }
  735.  
  736. wxString wxGetPasswordFromUser(const wxString& message,
  737.                                const wxString& caption,
  738.                                const wxString& defaultValue,
  739.                                wxWindow *parent)
  740. {
  741.     wxString str;
  742.     wxTextEntryDialog dialog(parent, message, caption, defaultValue,
  743.                              wxOK | wxCANCEL | wxTE_PASSWORD);
  744.     if ( dialog.ShowModal() == wxID_OK )
  745.     {
  746.         str = dialog.GetValue();
  747.     }
  748.  
  749.     return str;
  750. }
  751.  
  752. #endif // wxUSE_TEXTDLG
  753.  
  754. #if wxUSE_COLOURDLG
  755.  
  756. wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit)
  757. {
  758.     wxColourData data;
  759.     data.SetChooseFull(TRUE);
  760.     if ( colInit.Ok() )
  761.     {
  762.         data.SetColour((wxColour &)colInit); // const_cast
  763.     }
  764.  
  765.     wxColour colRet;
  766.     wxColourDialog dialog(parent, &data);
  767.     if ( dialog.ShowModal() == wxID_OK )
  768.     {
  769.         colRet = dialog.GetColourData().GetColour();
  770.     }
  771.     //else: leave it invalid
  772.  
  773.     return colRet;
  774. }
  775.  
  776. #endif // wxUSE_COLOURDLG
  777.  
  778. #if wxUSE_FONTDLG
  779.  
  780. wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit)
  781. {
  782.     wxFontData data;
  783.     if ( fontInit.Ok() )
  784.     {
  785.         data.SetInitialFont(fontInit);
  786.     }
  787.  
  788.     wxFont fontRet;
  789.     wxFontDialog dialog(parent, data);
  790.     if ( dialog.ShowModal() == wxID_OK )
  791.     {
  792.         fontRet = dialog.GetFontData().GetChosenFont();
  793.     }
  794.     //else: leave it invalid
  795.  
  796.     return fontRet;
  797. }
  798.  
  799. #endif // wxUSE_FONTDLG
  800. // ----------------------------------------------------------------------------
  801. // missing C RTL functions (FIXME shouldn't be here at all)
  802. // ----------------------------------------------------------------------------
  803.  
  804. #ifdef __MWERKS__
  805. #if __MSL__ < 0x7000
  806. char *strdup(const char *s)
  807. {
  808.         return strcpy( (char*) malloc( strlen( s ) + 1 ) , s ) ;
  809. }
  810. #endif
  811. int isascii( int c )
  812. {
  813.         return ( c >= 0 && c < 128 ) ;
  814. }
  815. #endif // __MWERKS__
  816.  
  817. // ----------------------------------------------------------------------------
  818. // wxSafeYield and supporting functions
  819. // ----------------------------------------------------------------------------
  820.  
  821. void wxEnableTopLevelWindows(bool enable)
  822. {
  823.     wxWindowList::Node *node;
  824.     for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
  825.         node->GetData()->Enable(enable);
  826. }
  827.  
  828. wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip)
  829. {
  830.     // remember the top level windows which were already disabled, so that we
  831.     // don't reenable them later
  832.     m_winDisabled = NULL;
  833.  
  834.     wxWindowList::Node *node;
  835.     for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
  836.     {
  837.         wxWindow *winTop = node->GetData();
  838.         if ( winTop == winToSkip )
  839.             continue;
  840.  
  841.         if ( winTop->IsEnabled() )
  842.         {
  843.             winTop->Disable();
  844.         }
  845.         else
  846.         {
  847.             if ( !m_winDisabled )
  848.             {
  849.                 m_winDisabled = new wxWindowList;
  850.             }
  851.  
  852.             m_winDisabled->Append(winTop);
  853.         }
  854.     }
  855. }
  856.  
  857. wxWindowDisabler::~wxWindowDisabler()
  858. {
  859.     wxWindowList::Node *node;
  860.     for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
  861.     {
  862.         wxWindow *winTop = node->GetData();
  863.         if ( !m_winDisabled || !m_winDisabled->Find(winTop) )
  864.         {
  865.             winTop->Enable();
  866.         }
  867.         //else: had been already disabled, don't reenable
  868.     }
  869.  
  870.     delete m_winDisabled;
  871. }
  872.  
  873. // Yield to other apps/messages and disable user input to all windows except
  874. // the given one
  875. bool wxSafeYield(wxWindow *win, bool onlyIfNeeded)
  876. {
  877.     wxWindowDisabler wd(win);
  878.  
  879.     bool rc;
  880.     if (onlyIfNeeded)
  881.         rc = wxYieldIfNeeded();
  882.     else
  883.         rc = wxYield();
  884.  
  885.     return rc;
  886. }
  887.  
  888. // ----------------------------------------------------------------------------
  889. // misc functions
  890. // ----------------------------------------------------------------------------
  891.  
  892. // Don't synthesize KeyUp events holding down a key and producing KeyDown
  893. // events with autorepeat. On by default and always on in wxMSW. wxGTK version
  894. // in utilsgtk.cpp.
  895. #ifndef __WXGTK__
  896. bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) )
  897. {
  898.     return TRUE;    // detectable auto-repeat is the only mode MSW supports
  899. }
  900. #endif // !wxGTK
  901.  
  902. #endif // wxUSE_GUI
  903.  
  904. const wxChar *wxGetInstallPrefix()
  905. {
  906.     wxString prefix;
  907.  
  908.     if ( wxGetEnv(wxT("WXPREFIX"), &prefix) )
  909.         return prefix.c_str();
  910.  
  911. #ifdef wxINSTALL_PREFIX
  912.     return wxT(wxINSTALL_PREFIX);
  913. #else
  914.     return wxT("");
  915. #endif
  916. }
  917.  
  918. wxString wxGetDataDir()
  919. {
  920.     wxString format = wxGetInstallPrefix();
  921.     format <<  wxFILE_SEP_PATH
  922.            << wxT("share") << wxFILE_SEP_PATH
  923.            << wxT("wx") << wxFILE_SEP_PATH
  924.            << wxT("%i.%i");
  925.     wxString dir;
  926.     dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
  927.     return dir;
  928. }
  929.  
  930.  
  931. // ----------------------------------------------------------------------------
  932. // network and user id functions
  933. // ----------------------------------------------------------------------------
  934.  
  935. // Get Full RFC822 style email address
  936. bool wxGetEmailAddress(wxChar *address, int maxSize)
  937. {
  938.     wxString email = wxGetEmailAddress();
  939.     if ( !email )
  940.         return FALSE;
  941.  
  942.     wxStrncpy(address, email, maxSize - 1);
  943.     address[maxSize - 1] = wxT('\0');
  944.  
  945.     return TRUE;
  946. }
  947.  
  948. wxString wxGetEmailAddress()
  949. {
  950.     wxString email;
  951.  
  952.     wxString host = wxGetFullHostName();
  953.     if ( !!host )
  954.     {
  955.         wxString user = wxGetUserId();
  956.         if ( !!user )
  957.         {
  958.             email << user << wxT('@') << host;
  959.         }
  960.     }
  961.  
  962.     return email;
  963. }
  964.  
  965. wxString wxGetUserId()
  966. {
  967.     static const int maxLoginLen = 256; // FIXME arbitrary number
  968.  
  969.     wxString buf;
  970.     bool ok = wxGetUserId(buf.GetWriteBuf(maxLoginLen), maxLoginLen);
  971.     buf.UngetWriteBuf();
  972.  
  973.     if ( !ok )
  974.         buf.Empty();
  975.  
  976.     return buf;
  977. }
  978.  
  979. wxString wxGetUserName()
  980. {
  981.     static const int maxUserNameLen = 1024; // FIXME arbitrary number
  982.  
  983.     wxString buf;
  984.     bool ok = wxGetUserName(buf.GetWriteBuf(maxUserNameLen), maxUserNameLen);
  985.     buf.UngetWriteBuf();
  986.  
  987.     if ( !ok )
  988.         buf.Empty();
  989.  
  990.     return buf;
  991. }
  992.  
  993. wxString wxGetHostName()
  994. {
  995.     static const size_t hostnameSize = 257;
  996.  
  997.     wxString buf;
  998.     bool ok = wxGetHostName(buf.GetWriteBuf(hostnameSize), hostnameSize);
  999.  
  1000.     buf.UngetWriteBuf();
  1001.  
  1002.     if ( !ok )
  1003.         buf.Empty();
  1004.  
  1005.     return buf;
  1006. }
  1007.  
  1008. wxString wxGetFullHostName()
  1009. {
  1010.     static const size_t hostnameSize = 257;
  1011.  
  1012.     wxString buf;
  1013.     bool ok = wxGetFullHostName(buf.GetWriteBuf(hostnameSize), hostnameSize);
  1014.  
  1015.     buf.UngetWriteBuf();
  1016.  
  1017.     if ( !ok )
  1018.         buf.Empty();
  1019.  
  1020.     return buf;
  1021. }
  1022.  
  1023. wxString wxGetHomeDir()
  1024. {
  1025.     wxString home;
  1026.     wxGetHomeDir(&home);
  1027.  
  1028.     return home;
  1029. }
  1030.  
  1031. #if 0
  1032.  
  1033. wxString wxGetCurrentDir()
  1034. {
  1035.     wxString dir;
  1036.     size_t len = 1024;
  1037.     bool ok;
  1038.     do
  1039.     {
  1040.         ok = getcwd(dir.GetWriteBuf(len + 1), len) != NULL;
  1041.         dir.UngetWriteBuf();
  1042.  
  1043.         if ( !ok )
  1044.         {
  1045.             if ( errno != ERANGE )
  1046.             {
  1047.                 wxLogSysError(_T("Failed to get current directory"));
  1048.  
  1049.                 return wxEmptyString;
  1050.             }
  1051.             else
  1052.             {
  1053.                 // buffer was too small, retry with a larger one
  1054.                 len *= 2;
  1055.             }
  1056.         }
  1057.         //else: ok
  1058.     } while ( !ok );
  1059.  
  1060.     return dir;
  1061. }
  1062.  
  1063. #endif // 0
  1064.  
  1065. // ----------------------------------------------------------------------------
  1066. // wxExecute
  1067. // ----------------------------------------------------------------------------
  1068.  
  1069. // wxDoExecuteWithCapture() helper: reads an entire stream into one array
  1070. //
  1071. // returns TRUE if ok, FALSE if error
  1072. static bool ReadAll(wxInputStream *is, wxArrayString& output)
  1073. {
  1074.     wxCHECK_MSG( is, FALSE, _T("NULL stream in wxExecute()?") );
  1075.  
  1076.     // the stream could be already at EOF or in wxSTREAM_BROKEN_PIPE state
  1077.     is->Reset();
  1078.  
  1079.     wxTextInputStream tis(*is);
  1080.  
  1081.     bool cont = TRUE;
  1082.     while ( cont )
  1083.     {
  1084.         wxString line = tis.ReadLine();
  1085.         if ( is->Eof() )
  1086.             break;
  1087.  
  1088.         if ( !*is )
  1089.         {
  1090.             cont = FALSE;
  1091.         }
  1092.         else
  1093.         {
  1094.             output.Add(line);
  1095.         }
  1096.     }
  1097.  
  1098.     return cont;
  1099. }
  1100.  
  1101. // this is a private function because it hasn't a clean interface: the first
  1102. // array is passed by reference, the second by pointer - instead we have 2
  1103. // public versions of wxExecute() below
  1104. static long wxDoExecuteWithCapture(const wxString& command,
  1105.                                    wxArrayString& output,
  1106.                                    wxArrayString* error)
  1107. {
  1108. #ifdef __WIN16__
  1109.     wxFAIL_MSG("Sorry, this version of wxExecute not implemented on WIN16.");
  1110.  
  1111.     return 0;
  1112. #else // !Win16
  1113.     // create a wxProcess which will capture the output
  1114.     wxProcess *process = new wxProcess;
  1115.     process->Redirect();
  1116.  
  1117.     long rc = wxExecute(command, wxEXEC_SYNC, process);
  1118.  
  1119. #if wxUSE_STREAMS
  1120.     if ( rc != -1 )
  1121.     {
  1122.         if ( !ReadAll(process->GetInputStream(), output) )
  1123.             rc = -1;
  1124.  
  1125.         if ( error )
  1126.         {
  1127.             if ( !ReadAll(process->GetErrorStream(), *error) )
  1128.                 rc = -1;
  1129.         }
  1130.  
  1131.     }
  1132. #endif // wxUSE_STREAMS
  1133.  
  1134.     delete process;
  1135.  
  1136.     return rc;
  1137. #endif // IO redirection supoprted
  1138. }
  1139.  
  1140. long wxExecute(const wxString& command, wxArrayString& output)
  1141. {
  1142.     return wxDoExecuteWithCapture(command, output, NULL);
  1143. }
  1144.  
  1145. long wxExecute(const wxString& command,
  1146.                wxArrayString& output,
  1147.                wxArrayString& error)
  1148. {
  1149.     return wxDoExecuteWithCapture(command, output, &error);
  1150. }
  1151.  
  1152. // ----------------------------------------------------------------------------
  1153. // wxApp::Yield() wrappers for backwards compatibility
  1154. // ----------------------------------------------------------------------------
  1155.  
  1156. bool wxYield()
  1157. {
  1158. #if wxUSE_GUI
  1159.     return wxTheApp && wxTheApp->Yield();
  1160. #else
  1161.     return FALSE;
  1162. #endif
  1163. }
  1164.  
  1165. bool wxYieldIfNeeded()
  1166. {
  1167. #if wxUSE_GUI
  1168.     return wxTheApp && wxTheApp->Yield(TRUE);
  1169. #else
  1170.     return FALSE;
  1171. #endif
  1172. }
  1173.  
  1174.