Files
wxWidgets/src/common/utilscmn.cpp
Vadim Zeitlin cd6ce4a90c 1. wxProcess changes to make capturing subprocess output easier (and more
reliable), now works in both sync and async modes
2. wxSafeYieldBug() corrected, wxWindowDisabler which is now used in it
   added and documented
3. exec sample updated to illustrate capturing the subprocess output
4. wxStreamBase::IsOk() added
5. wxInputStream::Eof() added and non-blocking Eof() implementation in
   wxPipeInputStream used by wxExecute


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6400 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2000-03-02 19:06:13 +00:00

1203 lines
30 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: utilscmn.cpp
// Purpose: Miscellaneous utility functions and classes
// Author: Julian Smart
// Modified by:
// Created: 29/01/98
// RCS-ID: $Id$
// Copyright: (c) 1998 Julian Smart
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "utils.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#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 "wx/process.h"
#include "wx/txtstrm.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if !defined(__WATCOMC__)
#if !(defined(_MSC_VER) && (_MSC_VER > 800))
#include <errno.h>
#endif
#endif
#if wxUSE_GUI
#include "wx/colordlg.h"
#endif // wxUSE_GUI
#include <time.h>
#ifndef __MWERKS__
#include <sys/types.h>
#include <sys/stat.h>
#endif
#ifdef __SALFORDC__
#include <clib.h>
#endif
#ifdef __WXMSW__
#include "windows.h"
#endif
// ----------------------------------------------------------------------------
// function protoypes
// ----------------------------------------------------------------------------
#if wxUSE_GUI
static wxWindow *wxFindWindowByLabel1(const wxString& title, wxWindow *parent);
static wxWindow *wxFindWindowByName1 (const wxString& title, wxWindow *parent);
#endif // wxUSE_GUI
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// 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__
#ifdef __WINDOWS__
#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)
{
if (s == NULL) s = wxT("");
size_t len = wxStrlen (s) + 1;
wxChar *news = new wxChar[len];
memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest
return news;
}
// Id generation
static long wxCurrentId = 100;
long
wxNewId (void)
{
return wxCurrentId++;
}
long
wxGetCurrentId(void) { return wxCurrentId; }
void
wxRegisterId (long id)
{
if (id >= wxCurrentId)
wxCurrentId = id + 1;
}
void
StringToFloat (wxChar *s, float *number)
{
if (s && *s && number)
*number = (float) wxStrtod (s, (wxChar **) NULL);
}
void
StringToDouble (wxChar *s, double *number)
{
if (s && *s && number)
*number = wxStrtod (s, (wxChar **) NULL);
}
wxChar *
FloatToString (float number, const wxChar *fmt)
{
static wxChar buf[256];
// sprintf (buf, "%.2f", number);
wxSprintf (buf, fmt, number);
return buf;
}
wxChar *
DoubleToString (double number, const wxChar *fmt)
{
static wxChar buf[256];
wxSprintf (buf, fmt, number);
return buf;
}
void
StringToInt (wxChar *s, int *number)
{
if (s && *s && number)
*number = (int) wxStrtol (s, (wxChar **) NULL, 10);
}
void
StringToLong (wxChar *s, long *number)
{
if (s && *s && number)
*number = wxStrtol (s, (wxChar **) NULL, 10);
}
wxChar *
IntToString (int number)
{
static wxChar buf[20];
wxSprintf (buf, wxT("%d"), number);
return buf;
}
wxChar *
LongToString (long number)
{
static wxChar buf[20];
wxSprintf (buf, wxT("%ld"), number);
return buf;
}
// Array used in DecToHex conversion routine.
static wxChar hexArray[] = wxT("0123456789ABCDEF");
// Convert 2-digit hex number to decimal
int wxHexToDec(const wxString& buf)
{
int firstDigit, secondDigit;
if (buf.GetChar(0) >= wxT('A'))
firstDigit = buf.GetChar(0) - wxT('A') + 10;
else
firstDigit = buf.GetChar(0) - wxT('0');
if (buf.GetChar(1) >= wxT('A'))
secondDigit = buf.GetChar(1) - wxT('A') + 10;
else
secondDigit = buf.GetChar(1) - wxT('0');
return firstDigit * 16 + secondDigit;
}
// Convert decimal integer to 2-character hex string
void wxDecToHex(int dec, wxChar *buf)
{
int firstDigit = (int)(dec/16.0);
int secondDigit = (int)(dec - (firstDigit*16.0));
buf[0] = hexArray[firstDigit];
buf[1] = hexArray[secondDigit];
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
bool
StringMatch (char *str1, char *str2, bool subString, bool exact)
{
if (str1 == NULL || str2 == NULL)
return FALSE;
if (str1 == str2)
return TRUE;
if (subString)
{
int len1 = strlen (str1);
int len2 = strlen (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)
return TRUE;
}
}
else if (exact)
{
if (strcasecmp (str1, str2) == 0)
return TRUE;
}
else
{
int len1 = strlen (str1);
int len2 = strlen (str2);
if (strncasecmp (str1, str2, wxMin (len1, len2)) == 0)
return TRUE;
}
return FALSE;
}
// 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);
}
#if wxUSE_GUI
// ----------------------------------------------------------------------------
// Menu accelerators related functions
// ----------------------------------------------------------------------------
wxChar *wxStripMenuCodes (wxChar *in, wxChar *out)
{
if (!in)
return (wxChar *) NULL;
if (!out)
out = copystring(in);
wxChar *tmpOut = out;
while (*in)
{
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
break;
}
else
*out++ = *in++;
} // while
*out = wxT('\0');
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;
}
#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
* matching the specified string. If NULL, look through all top-level windows.
*
*/
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;
}
// 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
* matching the specified string. If NULL, look through all top-level windows.
*
*/
wxWindow *
wxFindWindowByName (const wxString& title, 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
}
// Returns menu item id or -1 if none.
int
wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
{
wxMenuBar *menuBar = frame->GetMenuBar ();
if (!menuBar)
return -1;
return menuBar->FindMenuItem (menuString, itemString);
}
#endif // wxUSE_GUI
/*
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.
>
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,
||==== Voice: +1 (617)965-9191 Newton Centre,
|| FAX: +1 (617)965-1636 MA 02159 USA
Email: ken@als.com WWW: http://www.als.com
------------------------------------------------------------------------
*/
// This code is commented out but it may be integrated with wxWin at
// a later date, after testing. Thanks Ken!
#if 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
| the current directory.
*--------------------------------------------------------------------*/
static void
whereami(name)
char *name;
{
register char *cutoff = NULL; /* stifle -Wall */
register char *s;
register char *t;
int cc;
char ebuf[4096];
/*
* See if the file is accessible either through the current directory
* or through an absolute path.
*/
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.
*-------------------------------------------------------------*/
t = imagedir;
if (!absolute_pathname(name)) {
#if defined(DOS) || defined(__WIN32__)
int drive;
char *newrbuf;
newrbuf = imagedir;
#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) { /* } */
#else
if (getcwd(newrbuf, 1024) == 0) { /* } */
#endif
#else /* DOS */
#ifdef HAVE_GETWD
if (getwd(imagedir) == 0) { /* } */
#else /* !HAVE_GETWD */
if (getcwd(imagedir, 1024) == 0) {
#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;
}
}
#if (!defined(__MAC__) && !defined(__DJGPP__) && !defined(__GO32__) && !defined(__WIN32__))
else
(*t++ = DIR_SEPARATOR);
#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.
*-------------------------------------------------------------*/
for ((*name == DIR_SEPARATOR ? (s = name+1) : (s = name));;) {
if (*s == DIR_SEPARATOR)
cutoff = t;
if (!(*t++ = *s++))
break;
}
}
else {
/*-------------------------------------------------------------*
* Get the path list from the environment. If the path list is
* inaccessible for any reason, leave with fatal error.
*-------------------------------------------------------------*/
#ifdef __MAC__
if ((s = getenv("Commands")) == (char *) 0)
#else
if ((s = getenv("PATH")) == (char *) 0)
#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);
}
}
/*-------------------------------------------------------------*
| At this point the full pathname should exist in imagedir and
| cutoff should be set to the final slash. We must now determine
| whether the file name is a symbolic link or not and chase it down
| if it is. Note that we reuse ebuf for getting the link.
*-------------------------------------------------------------*/
#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;
}
}
#endif /* HAVE_SYMLINK */
strcpy(imagename, cutoff + 1); /* keep the image name */
*(cutoff + 1) = 0; /* chop off the filename part */
}
#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;
case wxID_YES:
return wxYES;
case wxID_NO:
return wxNO;
default:
case wxID_CANCEL:
return wxCANCEL;
}
}
#if wxUSE_TEXTDLG
wxString wxGetTextFromUser(const wxString& message, const wxString& caption,
const wxString& defaultValue, wxWindow *parent,
int x, int y, bool WXUNUSED(centre) )
{
wxString str;
wxTextEntryDialog dialog(parent, message, caption, defaultValue, wxOK|wxCANCEL, wxPoint(x, y));
if (dialog.ShowModal() == wxID_OK)
{
str = dialog.GetValue();
}
return str;
}
wxString wxGetPasswordFromUser(const wxString& message,
const wxString& caption,
const wxString& defaultValue,
wxWindow *parent)
{
wxString str;
wxTextEntryDialog dialog(parent, message, caption, defaultValue,
wxOK | wxCANCEL | wxTE_PASSWORD);
if ( dialog.ShowModal() == wxID_OK )
{
str = dialog.GetValue();
}
return str;
}
#endif // wxUSE_TEXTDLG
wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit)
{
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
return colRet;
}
// ----------------------------------------------------------------------------
// missing C RTL functions (FIXME shouldn't be here at all)
// ----------------------------------------------------------------------------
#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);
}
static void wxFindDisabledWindows(wxWindowList& winDisabled, wxWindow *win)
{
wxWindowList::Node *node;
for ( node = win->GetChildren().GetFirst(); node; node = node->GetNext() )
{
wxWindow *child = node->GetData();
wxFindDisabledWindows(winDisabled, child);
if ( child->IsEnabled() )
{
winDisabled.Append(child);
child->Disable();
}
}
}
wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip)
{
// remember all windows we're going to (temporarily) disable
m_winDisabled = new wxWindowList;
wxWindowList::Node *node;
for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
{
wxWindow *winTop = node->GetData();
if ( winTop->IsEnabled() )
{
wxFindDisabledWindows(*m_winDisabled, winTop);
m_winDisabled->Append(winTop);
winTop->Disable();
}
}
if ( winToSkip && m_winDisabled->Find(winToSkip) )
{
// always enable ourselves
m_winDisabled->DeleteObject(winToSkip);
winToSkip->Enable();
}
}
wxWindowDisabler::~wxWindowDisabler()
{
wxWindowList::Node *node;
for ( node = m_winDisabled->GetFirst(); node; node = node->GetNext() )
{
node->GetData()->Enable();
}
delete m_winDisabled;
}
// Yield to other apps/messages and disable user input to all windows except
// the given one
bool wxSafeYield(wxWindow *win)
{
wxWindowDisabler wd;
bool rc = wxYield();
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;
}
wxString wxGetHomeDir()
{
wxString home;
wxGetHomeDir(&home);
return home;
}
#if 0
wxString wxGetCurrentDir()
{
wxString dir;
size_t len = 1024;
bool ok;
do
{
ok = getcwd(dir.GetWriteBuf(len + 1), len) != NULL;
dir.UngetWriteBuf();
if ( !ok )
{
if ( errno != ERANGE )
{
wxLogSysError(_T("Failed to get current directory"));
return wxEmptyString;
}
else
{
// buffer was too small, retry with a larger one
len *= 2;
}
}
//else: ok
} while ( !ok );
return dir;
}
#endif // 0
// ----------------------------------------------------------------------------
// wxExecute
// ----------------------------------------------------------------------------
long wxExecute(const wxString& command, wxArrayString& output)
{
// create a wxProcess which will capture the output
wxProcess *process = new wxProcess;
process->Redirect();
long rc = wxExecute(command, TRUE /* sync */, process);
if ( rc != -1 )
{
wxInputStream& is = *process->GetInputStream();
wxTextInputStream tis(is);
while ( !is.Eof() )
{
wxString line = tis.ReadLine();
if ( is.LastError() )
break;
output.Add(line);
}
}
return rc;
}