]> git.saurik.com Git - wxWidgets.git/blame - src/common/utilscmn.cpp
* Changed char to wxChar in operators.
[wxWidgets.git] / src / common / utilscmn.cpp
CommitLineData
c801d85f
KB
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$
8// Copyright: (c) 1998 Julian Smart
3f4a0c5b 9// Licence: wxWindows license
c801d85f
KB
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
7007fcfc 13#pragma implementation "utils.h"
c801d85f
KB
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx/defs.h"
25#include "wx/utils.h"
26#include "wx/window.h"
27#include "wx/menu.h"
28#include "wx/frame.h"
dfad0599
JS
29#include "wx/msgdlg.h"
30#include "wx/textdlg.h"
c801d85f
KB
31#endif
32
c801d85f
KB
33#include <ctype.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#if !defined(__WATCOMC__)
3f4a0c5b
VZ
38 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
39 #include <errno.h>
40 #endif
c801d85f
KB
41#endif
42#include <time.h>
469e1e5c 43#ifndef __MWERKS__
c801d85f
KB
44#include <sys/types.h>
45#include <sys/stat.h>
469e1e5c 46#endif
c801d85f 47
ce3ed50d
JS
48#ifdef __SALFORDC__
49#include <clib.h>
50#endif
51
c801d85f
KB
52// Pattern matching code.
53// Yes, this path is deliberate (for Borland compilation)
54#ifdef wx_mac /* MATTHEW: [5] Mac doesn't like paths with "/" */
55#include "glob.inc"
56#else
57#include "../common/glob.inc"
58#endif
59
2049ba38 60#ifdef __WXMSW__
c801d85f
KB
61#include "windows.h"
62#endif
63
64#define _MAXPATHLEN 500
65
84fff0b3 66extern wxChar *wxBuffer;
c801d85f 67
e146b8c8
VZ
68// ----------------------------------------------------------------------------
69// private functions
70// ----------------------------------------------------------------------------
71
72static wxWindow *wxFindWindowByLabel1(const wxString& title, wxWindow * parent);
73static wxWindow *wxFindWindowByName1 (const wxString& title, wxWindow * parent);
74
17dff81c
SC
75#ifdef __WXMAC__
76int strcasecmp(const char *str_1, const char *str_2)
77{
78 register char c1, c2;
79 do {
80 c1 = tolower(*str_1++);
81 c2 = tolower(*str_2++);
82 } while ( c1 && (c1 == c2) );
83
84 return c1 - c2;
85}
86
87int strncasecmp(const char *str_1, const char *str_2, size_t maxchar)
88{
89
90 register char c1, c2;
3f4a0c5b 91 while( maxchar--)
17dff81c
SC
92 {
93 c1 = tolower(*str_1++);
94 c2 = tolower(*str_2++);
3f4a0c5b 95
17dff81c 96 if ( !c1 || c1!=c2 )
3f4a0c5b
VZ
97 return c1 - c2;
98
17dff81c
SC
99 } ;
100
101 return 0 ;
102
103}
104#endif
c801d85f
KB
105#ifdef __VMS__
106// we have no strI functions under VMS, therefore I have implemented
107// an inefficient but portable version: convert copies of strings to lowercase
108// and then use the normal comparison
109static void myLowerString(char *s)
110{
111 while(*s){
112 if(isalpha(*s)) *s = (char)tolower(*s);
113 s++;
114 }
115}
116
117int strcasecmp(const char *str_1, const char *str_2)
118{
119 char *temp1 = new char[strlen(str_1)+1];
120 char *temp2 = new char[strlen(str_2)+1];
121 strcpy(temp1,str_1);
122 strcpy(temp2,str_2);
123 myLowerString(temp1);
124 myLowerString(temp2);
125
126 int result = strcmp(temp1,temp2);
127 delete[] temp1;
128 delete[] temp2;
129
130 return(result);
131}
132
133int strncasecmp(const char *str_1, const char *str_2, size_t maxchar)
134{
135 char *temp1 = new char[strlen(str_1)+1];
136 char *temp2 = new char[strlen(str_2)+1];
137 strcpy(temp1,str_1);
138 strcpy(temp2,str_2);
139 myLowerString(temp1);
140 myLowerString(temp2);
141
142 int result = strncmp(temp1,temp2,maxchar);
143 delete[] temp1;
144 delete[] temp2;
145
146 return(result);
147}
148#endif
149
34138703 150#ifdef __WINDOWS__
c801d85f
KB
151
152#ifndef __GNUWIN32__
469e1e5c 153#ifndef __MWERKS__
c801d85f
KB
154#define strcasecmp stricmp
155#define strncasecmp strnicmp
469e1e5c
SC
156#else
157#define strcasecmp _stricmp
158#define strncasecmp _strnicmp
159#endif
c801d85f
KB
160#endif
161
c801d85f 162#else
91b8de8d
RR
163
164#ifdef __EMX__
165#define strcasecmp stricmp
166#define strncasecmp strnicmp
167#endif
168
c801d85f
KB
169// This declaration is missing in SunOS!
170// (Yes, I know it is NOT ANSI-C but its in BSD libc)
171#if defined(__xlC) || defined(__AIX__) || defined(__GNUG__)
172extern "C"
173{
174 int strcasecmp (const char *, const char *);
175 int strncasecmp (const char *, const char *, size_t);
176}
177#endif
3f4a0c5b 178#endif /* __WXMSW__ */
c801d85f
KB
179
180
0080691b
OK
181wxChar *
182copystring (const wxChar *s)
c801d85f 183{
0080691b
OK
184 if (s == NULL) s = _T("");
185 size_t len = wxStrlen (s) + 1;
c801d85f 186
0080691b
OK
187 wxChar *news = new wxChar[len];
188 memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest
c801d85f
KB
189
190 return news;
191}
192
193// Id generation
194static long wxCurrentId = 100;
195
3f4a0c5b 196long
c801d85f
KB
197wxNewId (void)
198{
199 return wxCurrentId++;
200}
201
202long
203wxGetCurrentId(void) { return wxCurrentId; }
204
3f4a0c5b 205void
c801d85f
KB
206wxRegisterId (long id)
207{
208 if (id >= wxCurrentId)
209 wxCurrentId = id + 1;
210}
211
3f4a0c5b 212void
0080691b 213StringToFloat (wxChar *s, float *number)
c801d85f
KB
214{
215 if (s && *s && number)
0080691b 216 *number = (float) wxStrtod (s, (wxChar **) NULL);
c801d85f
KB
217}
218
3f4a0c5b 219void
0080691b 220StringToDouble (wxChar *s, double *number)
c801d85f
KB
221{
222 if (s && *s && number)
0080691b 223 *number = wxStrtod (s, (wxChar **) NULL);
c801d85f
KB
224}
225
0080691b
OK
226wxChar *
227FloatToString (float number, const wxChar *fmt)
c801d85f 228{
0080691b 229 static wxChar buf[256];
c801d85f
KB
230
231// sprintf (buf, "%.2f", number);
0080691b 232 wxSprintf (buf, fmt, number);
c801d85f
KB
233 return buf;
234}
235
0080691b
OK
236wxChar *
237DoubleToString (double number, const wxChar *fmt)
c801d85f 238{
0080691b 239 static wxChar buf[256];
c801d85f 240
0080691b 241 wxSprintf (buf, fmt, number);
c801d85f
KB
242 return buf;
243}
244
3f4a0c5b 245void
0080691b 246StringToInt (wxChar *s, int *number)
c801d85f
KB
247{
248 if (s && *s && number)
0080691b 249 *number = (int) wxStrtol (s, (wxChar **) NULL, 10);
c801d85f
KB
250}
251
3f4a0c5b 252void
0080691b 253StringToLong (wxChar *s, long *number)
c801d85f
KB
254{
255 if (s && *s && number)
0080691b 256 *number = wxStrtol (s, (wxChar **) NULL, 10);
c801d85f
KB
257}
258
84fff0b3 259wxChar *
c801d85f
KB
260IntToString (int number)
261{
84fff0b3 262 static wxChar buf[20];
c801d85f 263
84fff0b3 264 wxSprintf (buf, _T("%d"), number);
c801d85f
KB
265 return buf;
266}
267
84fff0b3 268wxChar *
c801d85f
KB
269LongToString (long number)
270{
84fff0b3 271 static wxChar buf[20];
c801d85f 272
84fff0b3 273 wxSprintf (buf, _T("%ld"), number);
c801d85f
KB
274 return buf;
275}
276
277// Array used in DecToHex conversion routine.
84fff0b3 278static wxChar hexArray[] = _T("0123456789ABCDEF");
c801d85f
KB
279
280// Convert 2-digit hex number to decimal
fd71308f 281int wxHexToDec(const wxString& buf)
c801d85f
KB
282{
283 int firstDigit, secondDigit;
3f4a0c5b 284
84fff0b3
OK
285 if (buf.GetChar(0) >= _T('A'))
286 firstDigit = buf.GetChar(0) - _T('A') + 10;
c801d85f 287 else
84fff0b3 288 firstDigit = buf.GetChar(0) - _T('0');
c801d85f 289
84fff0b3
OK
290 if (buf.GetChar(1) >= _T('A'))
291 secondDigit = buf.GetChar(1) - _T('A') + 10;
c801d85f 292 else
84fff0b3 293 secondDigit = buf.GetChar(1) - _T('0');
3f4a0c5b 294
c801d85f
KB
295 return firstDigit * 16 + secondDigit;
296}
297
298// Convert decimal integer to 2-character hex string
84fff0b3 299void wxDecToHex(int dec, wxChar *buf)
c801d85f
KB
300{
301 int firstDigit = (int)(dec/16.0);
302 int secondDigit = (int)(dec - (firstDigit*16.0));
303 buf[0] = hexArray[firstDigit];
304 buf[1] = hexArray[secondDigit];
305 buf[2] = 0;
306}
307
fd71308f
JS
308// Convert decimal integer to 2-character hex string
309wxString wxDecToHex(int dec)
310{
84fff0b3 311 wxChar buf[3];
fd71308f
JS
312 wxDecToHex(dec, buf);
313 return wxString(buf);
314}
315
c801d85f 316// Match a string INDEPENDENT OF CASE
3f4a0c5b 317bool
c801d85f
KB
318StringMatch (char *str1, char *str2, bool subString, bool exact)
319{
320 if (str1 == NULL || str2 == NULL)
321 return FALSE;
322 if (str1 == str2)
323 return TRUE;
324
325 if (subString)
326 {
327 int len1 = strlen (str1);
328 int len2 = strlen (str2);
329 int i;
330
331 // Search for str1 in str2
332 // Slow .... but acceptable for short strings
333 for (i = 0; i <= len2 - len1; i++)
3f4a0c5b
VZ
334 {
335 if (strncasecmp (str1, str2 + i, len1) == 0)
336 return TRUE;
337 }
c801d85f
KB
338 }
339 else if (exact)
340 {
341 if (strcasecmp (str1, str2) == 0)
3f4a0c5b 342 return TRUE;
c801d85f
KB
343 }
344 else
345 {
346 int len1 = strlen (str1);
347 int len2 = strlen (str2);
348
349 if (strncasecmp (str1, str2, wxMin (len1, len2)) == 0)
3f4a0c5b 350 return TRUE;
c801d85f
KB
351 }
352
353 return FALSE;
354}
355
63cc5d9d
RR
356// Don't synthesize KeyUp events holding down a key and producing
357// KeyDown events with autorepeat. On by default and always on
f0492f7d
RR
358// on in wxMSW. wxGTK version in utilsgtk.cpp.
359#ifndef __WXGTK__
360bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) )
361{
362 return TRUE; // detectable auto-repeat is the only mode MSW supports
363}
364#endif
365
c801d85f
KB
366// Return the current date/time
367// [volatile]
368wxString wxNow( void )
369{
c67daf87 370 time_t now = time((time_t *) NULL);
3f4a0c5b 371 char *date = ctime(&now);
c801d85f
KB
372 date[24] = '\0';
373 return wxString(date);
374}
375
c801d85f
KB
376/*
377 * Strip out any menu codes
378 */
379
0080691b 380wxChar *wxStripMenuCodes (wxChar *in, wxChar *out)
c801d85f
KB
381{
382 if (!in)
0080691b 383 return (wxChar *) NULL;
3f4a0c5b 384
c801d85f
KB
385 if (!out)
386 out = copystring(in);
387
0080691b 388 wxChar *tmpOut = out;
3f4a0c5b 389
c801d85f
KB
390 while (*in)
391 {
0080691b 392 if (*in == _T('&'))
3f4a0c5b
VZ
393 {
394 // Check && -> &, &x -> x
0080691b 395 if (*++in == _T('&'))
3f4a0c5b
VZ
396 *out++ = *in++;
397 }
0080691b 398 else if (*in == _T('\t'))
3f4a0c5b 399 {
c801d85f
KB
400 // Remove all stuff after \t in X mode, and let the stuff as is
401 // in Windows mode.
402 // Accelerators are handled in wx_item.cc for Motif, and are not
403 // YET supported in XView
3f4a0c5b
VZ
404 break;
405 }
c801d85f 406 else
3f4a0c5b
VZ
407 *out++ = *in++;
408 } // while
c801d85f 409
0080691b 410 *out = _T('\0');
c801d85f
KB
411
412 return tmpOut;
413}
414
47bc1060
JS
415wxString wxStripMenuCodes(const wxString& str)
416{
84fff0b3
OK
417 wxChar *buf = new wxChar[str.Length() + 1];
418 wxStripMenuCodes(WXSTRINGCAST str, buf);
47bc1060
JS
419 wxString str1(buf);
420 delete[] buf;
421 return str1;
422}
c801d85f
KB
423
424/*
425 * Window search functions
426 *
427 */
428
429/*
430 * If parent is non-NULL, look through children for a label or title
431 * matching the specified string. If NULL, look through all top-level windows.
432 *
433 */
434
c801d85f
KB
435wxWindow *
436wxFindWindowByLabel (const wxString& title, wxWindow * parent)
437{
e146b8c8 438 if (parent)
c801d85f 439 {
e146b8c8 440 return wxFindWindowByLabel1(title, parent);
c801d85f 441 }
e146b8c8 442 else
c801d85f 443 {
e146b8c8
VZ
444 for ( wxWindowList::Node * node = wxTopLevelWindows.GetFirst();
445 node;
446 node = node->GetNext() )
3f4a0c5b 447 {
e146b8c8
VZ
448 wxWindow *win = node->GetData();
449 wxWindow *retwin = wxFindWindowByLabel1 (title, win);
450 if (retwin)
451 return retwin;
3f4a0c5b 452 } // for()
c801d85f
KB
453
454 }
e146b8c8 455 return (wxWindow *) NULL;
c801d85f
KB
456}
457
458// Recursive
459static wxWindow *
460wxFindWindowByLabel1 (const wxString& title, wxWindow * parent)
461{
e146b8c8 462 if (parent)
c801d85f 463 {
e146b8c8
VZ
464 if (parent->GetLabel() == title)
465 return parent;
c801d85f
KB
466 }
467
e146b8c8 468 if (parent)
c801d85f 469 {
f03fc89f 470 for ( wxWindowList::Node * node = parent->GetChildren().GetFirst();
e146b8c8
VZ
471 node;
472 node = node->GetNext() )
3f4a0c5b 473 {
e146b8c8
VZ
474 wxWindow *win = (wxWindow *)node->GetData();
475 wxWindow *retwin = wxFindWindowByLabel1 (title, win);
476 if (retwin)
477 return retwin;
478 }
c801d85f
KB
479
480 }
481
e146b8c8 482 return (wxWindow *) NULL; // Not found
c801d85f
KB
483}
484
485/*
486 * If parent is non-NULL, look through children for a name
487 * matching the specified string. If NULL, look through all top-level windows.
488 *
489 */
490
c801d85f
KB
491wxWindow *
492wxFindWindowByName (const wxString& title, wxWindow * parent)
493{
e146b8c8 494 if (parent)
c801d85f 495 {
e146b8c8 496 return wxFindWindowByName1 (title, parent);
c801d85f 497 }
e146b8c8 498 else
c801d85f 499 {
e146b8c8
VZ
500 for ( wxWindowList::Node * node = wxTopLevelWindows.GetFirst();
501 node;
502 node = node->GetNext() )
3f4a0c5b 503 {
e146b8c8
VZ
504 wxWindow *win = node->GetData();
505 wxWindow *retwin = wxFindWindowByName1 (title, win);
506 if (retwin)
507 return retwin;
508 }
c801d85f
KB
509
510 }
e146b8c8
VZ
511
512 // Failed? Try by label instead.
513 return wxFindWindowByLabel(title, parent);
c801d85f
KB
514}
515
516// Recursive
517static wxWindow *
518wxFindWindowByName1 (const wxString& title, wxWindow * parent)
519{
520 if (parent)
521 {
3f4a0c5b
VZ
522 if ( parent->GetName() == title )
523 return parent;
c801d85f
KB
524 }
525
526 if (parent)
527 {
c0ed460c 528 for (wxNode * node = parent->GetChildren().First (); node; node = node->Next ())
3f4a0c5b
VZ
529 {
530 wxWindow *win = (wxWindow *) node->Data ();
531 wxWindow *retwin = wxFindWindowByName1 (title, win);
532 if (retwin)
533 return retwin;
534 } // for()
c801d85f
KB
535
536 }
537
3f4a0c5b 538 return (wxWindow *) NULL; // Not found
c801d85f
KB
539
540}
541
542// Returns menu item id or -1 if none.
3f4a0c5b 543int
c801d85f
KB
544wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
545{
546 wxMenuBar *menuBar = frame->GetMenuBar ();
547 if (!menuBar)
548 return -1;
549 return menuBar->FindMenuItem (menuString, itemString);
550}
551
c801d85f
KB
552/*
553On Fri, 21 Jul 1995, Paul Craven wrote:
554
555> Is there a way to find the path of running program's executable? I can get
556> my home directory, and the current directory, but I don't know how to get the
557> executable directory.
3f4a0c5b 558>
c801d85f
KB
559
560The code below (warty as it is), does what you want on most Unix,
561DOS, and Mac platforms (it's from the ALS Prolog main).
562
3f4a0c5b 563|| Ken Bowen Applied Logic Systems, Inc. PO Box 180,
c801d85f
KB
564||==== Voice: +1 (617)965-9191 Newton Centre,
565|| FAX: +1 (617)965-1636 MA 02159 USA
566 Email: ken@als.com WWW: http://www.als.com
567------------------------------------------------------------------------
568*/
569
570// This code is commented out but it may be integrated with wxWin at
571// a later date, after testing. Thanks Ken!
572#if 0
573
574/*--------------------------------------------------------------------*
575 | whereami is given a filename f in the form: whereami(argv[0])
3f4a0c5b
VZ
576 | It returns the directory in which the executable file (containing
577 | this code [main.c] ) may be found. A dot will be returned to indicate
c801d85f
KB
578 | the current directory.
579 *--------------------------------------------------------------------*/
580
581static void
582whereami(name)
583 char *name;
584{
3f4a0c5b 585 register char *cutoff = NULL; /* stifle -Wall */
c801d85f
KB
586 register char *s;
587 register char *t;
588 int cc;
589 char ebuf[4096];
590
591 /*
592 * See if the file is accessible either through the current directory
593 * or through an absolute path.
594 */
595
596 if (access(name, R_OK) == 0) {
597
3f4a0c5b
VZ
598 /*-------------------------------------------------------------*
599 * The file was accessible without any other work. But the current
600 * working directory might change on us, so if it was accessible
601 * through the cwd, then we should get it for later accesses.
602 *-------------------------------------------------------------*/
c801d85f 603
3f4a0c5b
VZ
604 t = imagedir;
605 if (!absolute_pathname(name)) {
c801d85f 606#if defined(DOS) || defined(__WIN32__)
3f4a0c5b
VZ
607 int drive;
608 char *newrbuf;
c801d85f 609
3f4a0c5b 610 newrbuf = imagedir;
c801d85f 611#ifndef __DJGPP__
3f4a0c5b
VZ
612 if (*(name + 1) == ':') {
613 if (*name >= 'a' && *name <= 'z')
614 drive = (int) (*name - 'a' + 1);
615 else
616 drive = (int) (*name - 'A' + 1);
617 *newrbuf++ = *name;
618 *newrbuf++ = *(name + 1);
619 *newrbuf++ = DIR_SEPARATOR;
620 }
621 else {
622 drive = 0;
623 *newrbuf++ = DIR_SEPARATOR;
624 }
625 if (getcwd(newrbuf, drive) == 0) { /* } */
c801d85f 626#else
3f4a0c5b 627 if (getcwd(newrbuf, 1024) == 0) { /* } */
c801d85f
KB
628#endif
629#else /* DOS */
630#ifdef HAVE_GETWD
3f4a0c5b 631 if (getwd(imagedir) == 0) { /* } */
c801d85f 632#else /* !HAVE_GETWD */
3f4a0c5b 633 if (getcwd(imagedir, 1024) == 0) {
c801d85f
KB
634#endif /* !HAVE_GETWD */
635#endif /* DOS */
3f4a0c5b
VZ
636 fatal_error(FE_GETCWD, 0);
637 }
638 for (; *t; t++) /* Set t to end of buffer */
639 ;
640 if (*(t - 1) == DIR_SEPARATOR) /* leave slash if already
641 * last char
642 */
643 cutoff = t - 1;
644 else {
645 cutoff = t; /* otherwise put one in */
646 *t++ = DIR_SEPARATOR;
647 }
648 }
c801d85f 649#if (!defined(__MAC__) && !defined(__DJGPP__) && !defined(__GO32__) && !defined(__WIN32__))
3f4a0c5b
VZ
650 else
651 (*t++ = DIR_SEPARATOR);
c801d85f
KB
652#endif
653
3f4a0c5b
VZ
654 /*-------------------------------------------------------------*
655 * Copy the rest of the string and set the cutoff if it was not
656 * already set. If the first character of name is a slash, cutoff
657 * is not presently set but will be on the first iteration of the
658 * loop below.
659 *-------------------------------------------------------------*/
c801d85f 660
3f4a0c5b
VZ
661 for ((*name == DIR_SEPARATOR ? (s = name+1) : (s = name));;) {
662 if (*s == DIR_SEPARATOR)
663 cutoff = t;
664 if (!(*t++ = *s++))
665 break;
666 }
c801d85f
KB
667
668 }
669 else {
670
3f4a0c5b
VZ
671 /*-------------------------------------------------------------*
672 * Get the path list from the environment. If the path list is
673 * inaccessible for any reason, leave with fatal error.
674 *-------------------------------------------------------------*/
c801d85f
KB
675
676#ifdef __MAC__
3f4a0c5b 677 if ((s = getenv("Commands")) == (char *) 0)
c801d85f 678#else
3f4a0c5b 679 if ((s = getenv("PATH")) == (char *) 0)
c801d85f 680#endif
3f4a0c5b
VZ
681 fatal_error(FE_PATH, 0);
682
683 /*
684 * Copy path list into ebuf and set the source pointer to the
685 * beginning of this buffer.
686 */
687
688 strcpy(ebuf, s);
689 s = ebuf;
690
691 for (;;) {
692 t = imagedir;
693 while (*s && *s != PATH_SEPARATOR)
694 *t++ = *s++;
695 if (t > imagedir && *(t - 1) == DIR_SEPARATOR)
696 ; /* do nothing -- slash already is in place */
697 else
698 *t++ = DIR_SEPARATOR; /* put in the slash */
699 cutoff = t - 1; /* set cutoff */
700 strcpy(t, name);
701 if (access(imagedir, R_OK) == 0)
702 break;
703
704 if (*s)
705 s++; /* advance source pointer */
706 else
707 fatal_error(FE_INFND, 0);
708 }
c801d85f
KB
709
710 }
711
712 /*-------------------------------------------------------------*
713 | At this point the full pathname should exist in imagedir and
714 | cutoff should be set to the final slash. We must now determine
715 | whether the file name is a symbolic link or not and chase it down
716 | if it is. Note that we reuse ebuf for getting the link.
717 *-------------------------------------------------------------*/
718
719#ifdef HAVE_SYMLINK
720 while ((cc = readlink(imagedir, ebuf, 512)) != -1) {
3f4a0c5b
VZ
721 ebuf[cc] = 0;
722 s = ebuf;
723 if (*s == DIR_SEPARATOR) {
724 t = imagedir;
725 }
726 else {
727 t = cutoff + 1;
728 }
729 for (;;) {
730 if (*s == DIR_SEPARATOR)
731 cutoff = t; /* mark the last slash seen */
732 if (!(*t++ = *s++)) /* copy the character */
733 break;
734 }
c801d85f
KB
735 }
736
737#endif /* HAVE_SYMLINK */
738
3f4a0c5b
VZ
739 strcpy(imagename, cutoff + 1); /* keep the image name */
740 *(cutoff + 1) = 0; /* chop off the filename part */
c801d85f
KB
741}
742
743#endif
95dee651
KB
744void wxEnableTopLevelWindows(bool enable)
745{
746 wxWindowList::Node *node;
747 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
748 node->GetData()->Enable(enable);
749}
ead7ce10
KB
750
751// Yield to other apps/messages and disable user input
752bool wxSafeYield(wxWindow *win)
753{
a28d23bb 754 wxEnableTopLevelWindows(FALSE);
95dee651
KB
755 // always enable ourselves
756 if ( win )
757 win->Enable(TRUE);
758 bool rc = wxYield();
a28d23bb 759 wxEnableTopLevelWindows(TRUE);
95dee651 760 return rc;
ead7ce10
KB
761}
762
dfad0599
JS
763/*
764 * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
765 * since otherwise the generic code may be pulled in unnecessarily.
766 */
767
768int wxMessageBox(const wxString& message, const wxString& caption, long style,
769 wxWindow *parent, int WXUNUSED(x), int WXUNUSED(y) )
770{
771 wxMessageDialog dialog(parent, message, caption, style);
772
773 int ans = dialog.ShowModal();
774 switch ( ans )
775 {
776 case wxID_OK:
777 return wxOK;
778 break;
779 case wxID_YES:
780 return wxYES;
781 break;
782 case wxID_NO:
783 return wxNO;
784 break;
785 default:
786 case wxID_CANCEL:
787 return wxCANCEL;
788 break;
789 }
790 return ans;
791}
792
88ac883a 793#if wxUSE_TEXTDLG
dfad0599
JS
794wxString wxGetTextFromUser(const wxString& message, const wxString& caption,
795 const wxString& defaultValue, wxWindow *parent,
796 int x, int y, bool WXUNUSED(centre) )
797{
798 wxTextEntryDialog dialog(parent, message, caption, defaultValue, wxOK|wxCANCEL, wxPoint(x, y));
799 if (dialog.ShowModal() == wxID_OK)
800 return dialog.GetValue();
801 else
802 return wxString("");
803}
88ac883a 804#endif // wxUSE_TEXTDLG
dfad0599 805
469e1e5c 806#ifdef __MWERKS__
3f4a0c5b 807char *strdup(const char *s)
469e1e5c 808{
3f4a0c5b 809 return strcpy( (char*) malloc( strlen( s ) + 1 ) , s ) ;
469e1e5c
SC
810}
811
3f4a0c5b 812int isascii( int c )
469e1e5c 813{
3f4a0c5b 814 return ( c >= 0 && c < 128 ) ;
469e1e5c 815}
f60d0f94 816#endif
e2a6f233 817
0fb67cd1
VZ
818// ----------------------------------------------------------------------------
819// network and user id functions
820// ----------------------------------------------------------------------------
821
822// Get Full RFC822 style email address
84fff0b3 823bool wxGetEmailAddress(wxChar *address, int maxSize)
e2a6f233 824{
0fb67cd1
VZ
825 wxString email = wxGetEmailAddress();
826 if ( !email )
e2a6f233 827 return FALSE;
0fb67cd1 828
84fff0b3
OK
829 wxStrncpy(address, email, maxSize - 1);
830 address[maxSize - 1] = _T('\0');
0fb67cd1
VZ
831
832 return TRUE;
e2a6f233
JS
833}
834
0fb67cd1 835wxString wxGetEmailAddress()
e2a6f233 836{
0fb67cd1
VZ
837 wxString email;
838
839 wxString host = wxGetHostName();
840 if ( !!host )
e2a6f233 841 {
0fb67cd1
VZ
842 wxString user = wxGetUserId();
843 if ( !!user )
844 {
845 wxString email(user);
84fff0b3 846 email << _T('@') << host;
0fb67cd1 847 }
e2a6f233 848 }
0fb67cd1
VZ
849
850 return email;
851}
852
853wxString wxGetUserId()
854{
855 static const int maxLoginLen = 256; // FIXME arbitrary number
856
857 wxString buf;
858 bool ok = wxGetUserId(buf.GetWriteBuf(maxLoginLen), maxLoginLen);
859 buf.UngetWriteBuf();
860
861 if ( !ok )
862 buf.Empty();
863
864 return buf;
865}
866
867wxString wxGetUserName()
868{
869 static const int maxUserNameLen = 1024; // FIXME arbitrary number
870
871 wxString buf;
872 bool ok = wxGetUserName(buf.GetWriteBuf(maxUserNameLen), maxUserNameLen);
873 buf.UngetWriteBuf();
874
875 if ( !ok )
876 buf.Empty();
877
878 return buf;
e2a6f233
JS
879}
880
0fb67cd1 881wxString wxGetHostName()
518b5d2f
VZ
882{
883 static const size_t hostnameSize = 257;
0fb67cd1
VZ
884
885 wxString buf;
518b5d2f
VZ
886 bool ok = wxGetHostName(buf.GetWriteBuf(hostnameSize), hostnameSize);
887
888 buf.UngetWriteBuf();
889
0fb67cd1
VZ
890 if ( !ok )
891 buf.Empty();
892
893 return buf;
518b5d2f
VZ
894}
895
96c5bd7f
KB
896wxString wxGetFullHostName()
897{
898 static const size_t hostnameSize = 257;
899
900 wxString buf;
901 bool ok = wxGetFullHostName(buf.GetWriteBuf(hostnameSize), hostnameSize);
902
903 buf.UngetWriteBuf();
904
905 if ( !ok )
906 buf.Empty();
907
908 return buf;
909}
910