]> git.saurik.com Git - wxWidgets.git/blame - src/common/utilscmn.cpp
Improved selection mode handling in wxGrid::SelectBlock
[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
e90c1d2a
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
c801d85f 20#ifdef __GNUG__
e90c1d2a 21 #pragma implementation "utils.h"
c801d85f
KB
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
e90c1d2a 28 #pragma hdrstop
c801d85f
KB
29#endif
30
31#ifndef WX_PRECOMP
e90c1d2a
VZ
32 #include "wx/defs.h"
33 #include "wx/string.h"
34 #include "wx/utils.h"
974e8d94
VZ
35 #include "wx/intl.h"
36 #include "wx/log.h"
e90c1d2a
VZ
37
38 #if wxUSE_GUI
39 #include "wx/window.h"
40 #include "wx/menu.h"
41 #include "wx/frame.h"
42 #include "wx/msgdlg.h"
43 #include "wx/textdlg.h"
974e8d94
VZ
44 #if wxUSE_ACCEL
45 #include "wx/menuitem.h"
46 #include "wx/accel.h"
47 #endif // wxUSE_ACCEL
e90c1d2a
VZ
48 #endif // wxUSE_GUI
49#endif // WX_PRECOMP
c801d85f 50
cd6ce4a9
VZ
51#include "wx/process.h"
52#include "wx/txtstrm.h"
53
c801d85f
KB
54#include <ctype.h>
55#include <stdio.h>
56#include <stdlib.h>
57#include <string.h>
e90c1d2a 58
c801d85f 59#if !defined(__WATCOMC__)
3f4a0c5b
VZ
60 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
61 #include <errno.h>
62 #endif
c801d85f 63#endif
e90c1d2a 64
91b4c08d
VZ
65#if wxUSE_GUI
66 #include "wx/colordlg.h"
67#endif // wxUSE_GUI
68
c801d85f 69#include <time.h>
e90c1d2a 70
469e1e5c 71#ifndef __MWERKS__
e90c1d2a
VZ
72 #include <sys/types.h>
73 #include <sys/stat.h>
469e1e5c 74#endif
c801d85f 75
ce3ed50d 76#ifdef __SALFORDC__
e90c1d2a 77 #include <clib.h>
ce3ed50d
JS
78#endif
79
2049ba38 80#ifdef __WXMSW__
5e1febfa 81 #include "wx/msw/private.h"
c801d85f
KB
82#endif
83
e90c1d2a
VZ
84// ----------------------------------------------------------------------------
85// function protoypes
86// ----------------------------------------------------------------------------
87
88#if wxUSE_GUI
89 static wxWindow *wxFindWindowByLabel1(const wxString& title, wxWindow *parent);
90 static wxWindow *wxFindWindowByName1 (const wxString& title, wxWindow *parent);
91#endif // wxUSE_GUI
c801d85f 92
e90c1d2a
VZ
93// ============================================================================
94// implementation
95// ============================================================================
c801d85f 96
e146b8c8 97// ----------------------------------------------------------------------------
e90c1d2a 98// string functions
e146b8c8
VZ
99// ----------------------------------------------------------------------------
100
17dff81c
SC
101#ifdef __WXMAC__
102int strcasecmp(const char *str_1, const char *str_2)
103{
104 register char c1, c2;
105 do {
106 c1 = tolower(*str_1++);
107 c2 = tolower(*str_2++);
108 } while ( c1 && (c1 == c2) );
109
110 return c1 - c2;
111}
112
113int strncasecmp(const char *str_1, const char *str_2, size_t maxchar)
114{
115
116 register char c1, c2;
3f4a0c5b 117 while( maxchar--)
17dff81c
SC
118 {
119 c1 = tolower(*str_1++);
120 c2 = tolower(*str_2++);
3f4a0c5b 121
17dff81c 122 if ( !c1 || c1!=c2 )
3f4a0c5b
VZ
123 return c1 - c2;
124
17dff81c
SC
125 } ;
126
127 return 0 ;
128
129}
e90c1d2a
VZ
130#endif // wxMAC
131
7e72d7aa 132#if defined( __VMS__ ) && ( __VMS_VER < 70000000 )
c801d85f
KB
133// we have no strI functions under VMS, therefore I have implemented
134// an inefficient but portable version: convert copies of strings to lowercase
135// and then use the normal comparison
136static void myLowerString(char *s)
137{
138 while(*s){
139 if(isalpha(*s)) *s = (char)tolower(*s);
140 s++;
141 }
142}
143
144int strcasecmp(const char *str_1, const char *str_2)
145{
146 char *temp1 = new char[strlen(str_1)+1];
147 char *temp2 = new char[strlen(str_2)+1];
148 strcpy(temp1,str_1);
149 strcpy(temp2,str_2);
150 myLowerString(temp1);
151 myLowerString(temp2);
152
81c67e27 153 int result = wxStrcmp(temp1,temp2);
c801d85f
KB
154 delete[] temp1;
155 delete[] temp2;
156
157 return(result);
158}
159
160int strncasecmp(const char *str_1, const char *str_2, size_t maxchar)
161{
162 char *temp1 = new char[strlen(str_1)+1];
163 char *temp2 = new char[strlen(str_2)+1];
164 strcpy(temp1,str_1);
165 strcpy(temp2,str_2);
166 myLowerString(temp1);
167 myLowerString(temp2);
168
169 int result = strncmp(temp1,temp2,maxchar);
170 delete[] temp1;
171 delete[] temp2;
172
173 return(result);
174}
e90c1d2a 175#endif // __VMS__
c801d85f 176
34138703 177#ifdef __WINDOWS__
c801d85f
KB
178
179#ifndef __GNUWIN32__
469e1e5c 180#ifndef __MWERKS__
c801d85f
KB
181#define strcasecmp stricmp
182#define strncasecmp strnicmp
469e1e5c
SC
183#else
184#define strcasecmp _stricmp
185#define strncasecmp _strnicmp
186#endif
c801d85f
KB
187#endif
188
c801d85f 189#else
91b8de8d
RR
190
191#ifdef __EMX__
192#define strcasecmp stricmp
193#define strncasecmp strnicmp
194#endif
195
c801d85f
KB
196// This declaration is missing in SunOS!
197// (Yes, I know it is NOT ANSI-C but its in BSD libc)
198#if defined(__xlC) || defined(__AIX__) || defined(__GNUG__)
199extern "C"
200{
201 int strcasecmp (const char *, const char *);
202 int strncasecmp (const char *, const char *, size_t);
203}
204#endif
3f4a0c5b 205#endif /* __WXMSW__ */
c801d85f 206
717b9bf2
DW
207#ifdef __WXPM__
208#define strcasecmp stricmp
209#define strncasecmp strnicmp
210#endif
c801d85f 211
0080691b
OK
212wxChar *
213copystring (const wxChar *s)
c801d85f 214{
223d09f6 215 if (s == NULL) s = wxT("");
0080691b 216 size_t len = wxStrlen (s) + 1;
c801d85f 217
0080691b
OK
218 wxChar *news = new wxChar[len];
219 memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest
c801d85f
KB
220
221 return news;
222}
223
224// Id generation
225static long wxCurrentId = 100;
226
3f4a0c5b 227long
c801d85f
KB
228wxNewId (void)
229{
230 return wxCurrentId++;
231}
232
233long
234wxGetCurrentId(void) { return wxCurrentId; }
235
3f4a0c5b 236void
c801d85f
KB
237wxRegisterId (long id)
238{
239 if (id >= wxCurrentId)
240 wxCurrentId = id + 1;
241}
242
3f4a0c5b 243void
0080691b 244StringToFloat (wxChar *s, float *number)
c801d85f
KB
245{
246 if (s && *s && number)
0080691b 247 *number = (float) wxStrtod (s, (wxChar **) NULL);
c801d85f
KB
248}
249
3f4a0c5b 250void
0080691b 251StringToDouble (wxChar *s, double *number)
c801d85f
KB
252{
253 if (s && *s && number)
0080691b 254 *number = wxStrtod (s, (wxChar **) NULL);
c801d85f
KB
255}
256
0080691b
OK
257wxChar *
258FloatToString (float number, const wxChar *fmt)
c801d85f 259{
0080691b 260 static wxChar buf[256];
c801d85f
KB
261
262// sprintf (buf, "%.2f", number);
0080691b 263 wxSprintf (buf, fmt, number);
c801d85f
KB
264 return buf;
265}
266
0080691b
OK
267wxChar *
268DoubleToString (double number, const wxChar *fmt)
c801d85f 269{
0080691b 270 static wxChar buf[256];
c801d85f 271
0080691b 272 wxSprintf (buf, fmt, number);
c801d85f
KB
273 return buf;
274}
275
3f4a0c5b 276void
0080691b 277StringToInt (wxChar *s, int *number)
c801d85f
KB
278{
279 if (s && *s && number)
0080691b 280 *number = (int) wxStrtol (s, (wxChar **) NULL, 10);
c801d85f
KB
281}
282
3f4a0c5b 283void
0080691b 284StringToLong (wxChar *s, long *number)
c801d85f
KB
285{
286 if (s && *s && number)
0080691b 287 *number = wxStrtol (s, (wxChar **) NULL, 10);
c801d85f
KB
288}
289
84fff0b3 290wxChar *
c801d85f
KB
291IntToString (int number)
292{
84fff0b3 293 static wxChar buf[20];
c801d85f 294
223d09f6 295 wxSprintf (buf, wxT("%d"), number);
c801d85f
KB
296 return buf;
297}
298
84fff0b3 299wxChar *
c801d85f
KB
300LongToString (long number)
301{
84fff0b3 302 static wxChar buf[20];
c801d85f 303
223d09f6 304 wxSprintf (buf, wxT("%ld"), number);
c801d85f
KB
305 return buf;
306}
307
308// Array used in DecToHex conversion routine.
223d09f6 309static wxChar hexArray[] = wxT("0123456789ABCDEF");
c801d85f
KB
310
311// Convert 2-digit hex number to decimal
fd71308f 312int wxHexToDec(const wxString& buf)
c801d85f
KB
313{
314 int firstDigit, secondDigit;
3f4a0c5b 315
223d09f6
KB
316 if (buf.GetChar(0) >= wxT('A'))
317 firstDigit = buf.GetChar(0) - wxT('A') + 10;
c801d85f 318 else
223d09f6 319 firstDigit = buf.GetChar(0) - wxT('0');
c801d85f 320
223d09f6
KB
321 if (buf.GetChar(1) >= wxT('A'))
322 secondDigit = buf.GetChar(1) - wxT('A') + 10;
c801d85f 323 else
223d09f6 324 secondDigit = buf.GetChar(1) - wxT('0');
3f4a0c5b 325
c801d85f
KB
326 return firstDigit * 16 + secondDigit;
327}
328
329// Convert decimal integer to 2-character hex string
84fff0b3 330void wxDecToHex(int dec, wxChar *buf)
c801d85f
KB
331{
332 int firstDigit = (int)(dec/16.0);
333 int secondDigit = (int)(dec - (firstDigit*16.0));
334 buf[0] = hexArray[firstDigit];
335 buf[1] = hexArray[secondDigit];
336 buf[2] = 0;
337}
338
fd71308f
JS
339// Convert decimal integer to 2-character hex string
340wxString wxDecToHex(int dec)
341{
84fff0b3 342 wxChar buf[3];
fd71308f
JS
343 wxDecToHex(dec, buf);
344 return wxString(buf);
345}
346
c801d85f 347// Match a string INDEPENDENT OF CASE
3f4a0c5b 348bool
c801d85f
KB
349StringMatch (char *str1, char *str2, bool subString, bool exact)
350{
351 if (str1 == NULL || str2 == NULL)
352 return FALSE;
353 if (str1 == str2)
354 return TRUE;
355
356 if (subString)
357 {
358 int len1 = strlen (str1);
359 int len2 = strlen (str2);
360 int i;
361
362 // Search for str1 in str2
363 // Slow .... but acceptable for short strings
364 for (i = 0; i <= len2 - len1; i++)
3f4a0c5b
VZ
365 {
366 if (strncasecmp (str1, str2 + i, len1) == 0)
367 return TRUE;
368 }
c801d85f
KB
369 }
370 else if (exact)
371 {
372 if (strcasecmp (str1, str2) == 0)
3f4a0c5b 373 return TRUE;
c801d85f
KB
374 }
375 else
376 {
377 int len1 = strlen (str1);
378 int len2 = strlen (str2);
379
380 if (strncasecmp (str1, str2, wxMin (len1, len2)) == 0)
3f4a0c5b 381 return TRUE;
c801d85f
KB
382 }
383
384 return FALSE;
385}
386
387// Return the current date/time
388// [volatile]
e90c1d2a 389wxString wxNow()
c801d85f 390{
c67daf87 391 time_t now = time((time_t *) NULL);
3f4a0c5b 392 char *date = ctime(&now);
c801d85f
KB
393 date[24] = '\0';
394 return wxString(date);
395}
396
e90c1d2a
VZ
397#if wxUSE_GUI
398
399// ----------------------------------------------------------------------------
974e8d94 400// Menu accelerators related functions
e90c1d2a 401// ----------------------------------------------------------------------------
c801d85f 402
0080691b 403wxChar *wxStripMenuCodes (wxChar *in, wxChar *out)
c801d85f
KB
404{
405 if (!in)
0080691b 406 return (wxChar *) NULL;
3f4a0c5b 407
c801d85f
KB
408 if (!out)
409 out = copystring(in);
410
0080691b 411 wxChar *tmpOut = out;
3f4a0c5b 412
c801d85f
KB
413 while (*in)
414 {
223d09f6 415 if (*in == wxT('&'))
3f4a0c5b
VZ
416 {
417 // Check && -> &, &x -> x
223d09f6 418 if (*++in == wxT('&'))
3f4a0c5b
VZ
419 *out++ = *in++;
420 }
223d09f6 421 else if (*in == wxT('\t'))
3f4a0c5b 422 {
c801d85f
KB
423 // Remove all stuff after \t in X mode, and let the stuff as is
424 // in Windows mode.
425 // Accelerators are handled in wx_item.cc for Motif, and are not
426 // YET supported in XView
3f4a0c5b
VZ
427 break;
428 }
c801d85f 429 else
3f4a0c5b
VZ
430 *out++ = *in++;
431 } // while
c801d85f 432
223d09f6 433 *out = wxT('\0');
c801d85f
KB
434
435 return tmpOut;
436}
437
47bc1060
JS
438wxString wxStripMenuCodes(const wxString& str)
439{
84fff0b3
OK
440 wxChar *buf = new wxChar[str.Length() + 1];
441 wxStripMenuCodes(WXSTRINGCAST str, buf);
47bc1060
JS
442 wxString str1(buf);
443 delete[] buf;
444 return str1;
445}
c801d85f 446
974e8d94
VZ
447#if wxUSE_ACCEL
448
449// return wxAcceleratorEntry for the given menu string or NULL if none
450// specified
451wxAcceleratorEntry *wxGetAccelFromString(const wxString& label)
452{
453 // check for accelerators: they are given after '\t'
454 int posTab = label.Find(wxT('\t'));
455 if ( posTab != wxNOT_FOUND ) {
456 // parse the accelerator string
457 int keyCode = 0;
458 int accelFlags = wxACCEL_NORMAL;
459 wxString current;
460 for ( size_t n = (size_t)posTab + 1; n < label.Len(); n++ ) {
461 if ( (label[n] == '+') || (label[n] == '-') ) {
462 if ( current == _("ctrl") )
463 accelFlags |= wxACCEL_CTRL;
464 else if ( current == _("alt") )
465 accelFlags |= wxACCEL_ALT;
466 else if ( current == _("shift") )
467 accelFlags |= wxACCEL_SHIFT;
468 else {
469 wxLogDebug(wxT("Unknown accel modifier: '%s'"),
470 current.c_str());
471 }
472
473 current.Empty();
474 }
475 else {
476 current += wxTolower(label[n]);
477 }
478 }
479
480 if ( current.IsEmpty() ) {
481 wxLogDebug(wxT("No accel key found, accel string ignored."));
482 }
483 else {
484 if ( current.Len() == 1 ) {
485 // it's a letter
486 keyCode = wxToupper(current[0U]);
487 }
488 else {
489 // is it a function key?
490 if ( current[0U] == 'f' && isdigit(current[1U]) &&
491 (current.Len() == 2 ||
492 (current.Len() == 3 && isdigit(current[2U]))) ) {
493 int n;
494 wxSscanf(current.c_str() + 1, wxT("%d"), &n);
495
496 keyCode = WXK_F1 + n - 1;
497 }
498 else {
499#if 0 // this is not supported by GTK+, apparently
500 // several special cases
501 current.MakeUpper();
502 if ( current == wxT("DEL") ) {
503 keyCode = VK_DELETE;
504 }
505 else if ( current == wxT("PGUP") ) {
506 keyCode = VK_PRIOR;
507 }
508 else if ( current == wxT("PGDN") ) {
509 keyCode = VK_NEXT;
510 }
511 else
512#endif // 0
513 {
514 wxLogDebug(wxT("Unrecognized accel key '%s', accel "
515 "string ignored."), current.c_str());
516 }
517 }
518 }
519 }
520
521 if ( keyCode ) {
522 // we do have something
523 return new wxAcceleratorEntry(accelFlags, keyCode);
524 }
525 }
526
bbeb6c2b 527 return (wxAcceleratorEntry *)NULL;
974e8d94
VZ
528}
529
530#endif // wxUSE_ACCEL
531
e90c1d2a
VZ
532// ----------------------------------------------------------------------------
533// Window search functions
534// ----------------------------------------------------------------------------
c801d85f
KB
535
536/*
537 * If parent is non-NULL, look through children for a label or title
538 * matching the specified string. If NULL, look through all top-level windows.
539 *
540 */
541
c801d85f
KB
542wxWindow *
543wxFindWindowByLabel (const wxString& title, wxWindow * parent)
544{
e146b8c8 545 if (parent)
c801d85f 546 {
e146b8c8 547 return wxFindWindowByLabel1(title, parent);
c801d85f 548 }
e146b8c8 549 else
c801d85f 550 {
e146b8c8
VZ
551 for ( wxWindowList::Node * node = wxTopLevelWindows.GetFirst();
552 node;
553 node = node->GetNext() )
3f4a0c5b 554 {
e146b8c8
VZ
555 wxWindow *win = node->GetData();
556 wxWindow *retwin = wxFindWindowByLabel1 (title, win);
557 if (retwin)
558 return retwin;
3f4a0c5b 559 } // for()
c801d85f
KB
560
561 }
e146b8c8 562 return (wxWindow *) NULL;
c801d85f
KB
563}
564
565// Recursive
566static wxWindow *
567wxFindWindowByLabel1 (const wxString& title, wxWindow * parent)
568{
e146b8c8 569 if (parent)
c801d85f 570 {
e146b8c8
VZ
571 if (parent->GetLabel() == title)
572 return parent;
c801d85f
KB
573 }
574
e146b8c8 575 if (parent)
c801d85f 576 {
f03fc89f 577 for ( wxWindowList::Node * node = parent->GetChildren().GetFirst();
e146b8c8
VZ
578 node;
579 node = node->GetNext() )
3f4a0c5b 580 {
e146b8c8
VZ
581 wxWindow *win = (wxWindow *)node->GetData();
582 wxWindow *retwin = wxFindWindowByLabel1 (title, win);
583 if (retwin)
584 return retwin;
585 }
c801d85f
KB
586
587 }
588
e146b8c8 589 return (wxWindow *) NULL; // Not found
c801d85f
KB
590}
591
592/*
593 * If parent is non-NULL, look through children for a name
594 * matching the specified string. If NULL, look through all top-level windows.
595 *
596 */
597
c801d85f
KB
598wxWindow *
599wxFindWindowByName (const wxString& title, wxWindow * parent)
600{
e146b8c8 601 if (parent)
c801d85f 602 {
e146b8c8 603 return wxFindWindowByName1 (title, parent);
c801d85f 604 }
e146b8c8 605 else
c801d85f 606 {
e146b8c8
VZ
607 for ( wxWindowList::Node * node = wxTopLevelWindows.GetFirst();
608 node;
609 node = node->GetNext() )
3f4a0c5b 610 {
e146b8c8
VZ
611 wxWindow *win = node->GetData();
612 wxWindow *retwin = wxFindWindowByName1 (title, win);
613 if (retwin)
614 return retwin;
615 }
c801d85f
KB
616
617 }
e146b8c8
VZ
618
619 // Failed? Try by label instead.
620 return wxFindWindowByLabel(title, parent);
c801d85f
KB
621}
622
623// Recursive
624static wxWindow *
625wxFindWindowByName1 (const wxString& title, wxWindow * parent)
626{
627 if (parent)
628 {
3f4a0c5b
VZ
629 if ( parent->GetName() == title )
630 return parent;
c801d85f
KB
631 }
632
633 if (parent)
634 {
c0ed460c 635 for (wxNode * node = parent->GetChildren().First (); node; node = node->Next ())
3f4a0c5b
VZ
636 {
637 wxWindow *win = (wxWindow *) node->Data ();
638 wxWindow *retwin = wxFindWindowByName1 (title, win);
639 if (retwin)
640 return retwin;
641 } // for()
c801d85f
KB
642
643 }
644
3f4a0c5b 645 return (wxWindow *) NULL; // Not found
c801d85f
KB
646
647}
648
649// Returns menu item id or -1 if none.
3f4a0c5b 650int
c801d85f
KB
651wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
652{
653 wxMenuBar *menuBar = frame->GetMenuBar ();
654 if (!menuBar)
655 return -1;
656 return menuBar->FindMenuItem (menuString, itemString);
657}
658
e90c1d2a
VZ
659#endif // wxUSE_GUI
660
c801d85f
KB
661/*
662On Fri, 21 Jul 1995, Paul Craven wrote:
663
664> Is there a way to find the path of running program's executable? I can get
665> my home directory, and the current directory, but I don't know how to get the
666> executable directory.
3f4a0c5b 667>
c801d85f
KB
668
669The code below (warty as it is), does what you want on most Unix,
670DOS, and Mac platforms (it's from the ALS Prolog main).
671
3f4a0c5b 672|| Ken Bowen Applied Logic Systems, Inc. PO Box 180,
c801d85f
KB
673||==== Voice: +1 (617)965-9191 Newton Centre,
674|| FAX: +1 (617)965-1636 MA 02159 USA
675 Email: ken@als.com WWW: http://www.als.com
676------------------------------------------------------------------------
677*/
678
679// This code is commented out but it may be integrated with wxWin at
680// a later date, after testing. Thanks Ken!
681#if 0
682
683/*--------------------------------------------------------------------*
684 | whereami is given a filename f in the form: whereami(argv[0])
3f4a0c5b
VZ
685 | It returns the directory in which the executable file (containing
686 | this code [main.c] ) may be found. A dot will be returned to indicate
c801d85f
KB
687 | the current directory.
688 *--------------------------------------------------------------------*/
689
690static void
691whereami(name)
692 char *name;
693{
3f4a0c5b 694 register char *cutoff = NULL; /* stifle -Wall */
c801d85f
KB
695 register char *s;
696 register char *t;
697 int cc;
698 char ebuf[4096];
699
700 /*
701 * See if the file is accessible either through the current directory
702 * or through an absolute path.
703 */
704
705 if (access(name, R_OK) == 0) {
706
3f4a0c5b
VZ
707 /*-------------------------------------------------------------*
708 * The file was accessible without any other work. But the current
709 * working directory might change on us, so if it was accessible
710 * through the cwd, then we should get it for later accesses.
711 *-------------------------------------------------------------*/
c801d85f 712
3f4a0c5b
VZ
713 t = imagedir;
714 if (!absolute_pathname(name)) {
c801d85f 715#if defined(DOS) || defined(__WIN32__)
3f4a0c5b
VZ
716 int drive;
717 char *newrbuf;
c801d85f 718
3f4a0c5b 719 newrbuf = imagedir;
c801d85f 720#ifndef __DJGPP__
3f4a0c5b
VZ
721 if (*(name + 1) == ':') {
722 if (*name >= 'a' && *name <= 'z')
723 drive = (int) (*name - 'a' + 1);
724 else
725 drive = (int) (*name - 'A' + 1);
726 *newrbuf++ = *name;
727 *newrbuf++ = *(name + 1);
728 *newrbuf++ = DIR_SEPARATOR;
729 }
730 else {
731 drive = 0;
732 *newrbuf++ = DIR_SEPARATOR;
733 }
734 if (getcwd(newrbuf, drive) == 0) { /* } */
c801d85f 735#else
3f4a0c5b 736 if (getcwd(newrbuf, 1024) == 0) { /* } */
c801d85f
KB
737#endif
738#else /* DOS */
739#ifdef HAVE_GETWD
3f4a0c5b 740 if (getwd(imagedir) == 0) { /* } */
c801d85f 741#else /* !HAVE_GETWD */
3f4a0c5b 742 if (getcwd(imagedir, 1024) == 0) {
c801d85f
KB
743#endif /* !HAVE_GETWD */
744#endif /* DOS */
3f4a0c5b
VZ
745 fatal_error(FE_GETCWD, 0);
746 }
747 for (; *t; t++) /* Set t to end of buffer */
748 ;
749 if (*(t - 1) == DIR_SEPARATOR) /* leave slash if already
750 * last char
751 */
752 cutoff = t - 1;
753 else {
754 cutoff = t; /* otherwise put one in */
755 *t++ = DIR_SEPARATOR;
756 }
757 }
c801d85f 758#if (!defined(__MAC__) && !defined(__DJGPP__) && !defined(__GO32__) && !defined(__WIN32__))
3f4a0c5b
VZ
759 else
760 (*t++ = DIR_SEPARATOR);
c801d85f
KB
761#endif
762
3f4a0c5b
VZ
763 /*-------------------------------------------------------------*
764 * Copy the rest of the string and set the cutoff if it was not
765 * already set. If the first character of name is a slash, cutoff
766 * is not presently set but will be on the first iteration of the
767 * loop below.
768 *-------------------------------------------------------------*/
c801d85f 769
3f4a0c5b
VZ
770 for ((*name == DIR_SEPARATOR ? (s = name+1) : (s = name));;) {
771 if (*s == DIR_SEPARATOR)
772 cutoff = t;
773 if (!(*t++ = *s++))
774 break;
775 }
c801d85f
KB
776
777 }
778 else {
779
3f4a0c5b
VZ
780 /*-------------------------------------------------------------*
781 * Get the path list from the environment. If the path list is
782 * inaccessible for any reason, leave with fatal error.
783 *-------------------------------------------------------------*/
c801d85f
KB
784
785#ifdef __MAC__
3f4a0c5b 786 if ((s = getenv("Commands")) == (char *) 0)
c801d85f 787#else
3f4a0c5b 788 if ((s = getenv("PATH")) == (char *) 0)
c801d85f 789#endif
3f4a0c5b
VZ
790 fatal_error(FE_PATH, 0);
791
792 /*
793 * Copy path list into ebuf and set the source pointer to the
794 * beginning of this buffer.
795 */
796
797 strcpy(ebuf, s);
798 s = ebuf;
799
800 for (;;) {
801 t = imagedir;
802 while (*s && *s != PATH_SEPARATOR)
803 *t++ = *s++;
804 if (t > imagedir && *(t - 1) == DIR_SEPARATOR)
805 ; /* do nothing -- slash already is in place */
806 else
807 *t++ = DIR_SEPARATOR; /* put in the slash */
808 cutoff = t - 1; /* set cutoff */
809 strcpy(t, name);
810 if (access(imagedir, R_OK) == 0)
811 break;
812
813 if (*s)
814 s++; /* advance source pointer */
815 else
816 fatal_error(FE_INFND, 0);
817 }
c801d85f
KB
818
819 }
820
821 /*-------------------------------------------------------------*
822 | At this point the full pathname should exist in imagedir and
823 | cutoff should be set to the final slash. We must now determine
824 | whether the file name is a symbolic link or not and chase it down
825 | if it is. Note that we reuse ebuf for getting the link.
826 *-------------------------------------------------------------*/
827
828#ifdef HAVE_SYMLINK
829 while ((cc = readlink(imagedir, ebuf, 512)) != -1) {
3f4a0c5b
VZ
830 ebuf[cc] = 0;
831 s = ebuf;
832 if (*s == DIR_SEPARATOR) {
833 t = imagedir;
834 }
835 else {
836 t = cutoff + 1;
837 }
838 for (;;) {
839 if (*s == DIR_SEPARATOR)
840 cutoff = t; /* mark the last slash seen */
841 if (!(*t++ = *s++)) /* copy the character */
842 break;
843 }
c801d85f
KB
844 }
845
846#endif /* HAVE_SYMLINK */
847
3f4a0c5b
VZ
848 strcpy(imagename, cutoff + 1); /* keep the image name */
849 *(cutoff + 1) = 0; /* chop off the filename part */
c801d85f
KB
850}
851
852#endif
ead7ce10 853
e90c1d2a
VZ
854#if wxUSE_GUI
855
856// ----------------------------------------------------------------------------
857// GUI helpers
858// ----------------------------------------------------------------------------
ead7ce10 859
dfad0599
JS
860/*
861 * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
862 * since otherwise the generic code may be pulled in unnecessarily.
863 */
864
865int wxMessageBox(const wxString& message, const wxString& caption, long style,
866 wxWindow *parent, int WXUNUSED(x), int WXUNUSED(y) )
867{
868 wxMessageDialog dialog(parent, message, caption, style);
869
870 int ans = dialog.ShowModal();
871 switch ( ans )
872 {
873 case wxID_OK:
874 return wxOK;
dfad0599
JS
875 case wxID_YES:
876 return wxYES;
dfad0599
JS
877 case wxID_NO:
878 return wxNO;
dfad0599
JS
879 default:
880 case wxID_CANCEL:
881 return wxCANCEL;
dfad0599 882 }
dfad0599
JS
883}
884
88ac883a 885#if wxUSE_TEXTDLG
dfad0599
JS
886wxString wxGetTextFromUser(const wxString& message, const wxString& caption,
887 const wxString& defaultValue, wxWindow *parent,
888 int x, int y, bool WXUNUSED(centre) )
889{
d2f50933 890 wxString str;
dfad0599
JS
891 wxTextEntryDialog dialog(parent, message, caption, defaultValue, wxOK|wxCANCEL, wxPoint(x, y));
892 if (dialog.ShowModal() == wxID_OK)
d2f50933
VZ
893 {
894 str = dialog.GetValue();
895 }
896
897 return str;
dfad0599 898}
d2f50933
VZ
899
900wxString wxGetPasswordFromUser(const wxString& message,
901 const wxString& caption,
902 const wxString& defaultValue,
903 wxWindow *parent)
904{
905 wxString str;
906 wxTextEntryDialog dialog(parent, message, caption, defaultValue,
907 wxOK | wxCANCEL | wxTE_PASSWORD);
908 if ( dialog.ShowModal() == wxID_OK )
909 {
910 str = dialog.GetValue();
911 }
912
913 return str;
914}
915
88ac883a 916#endif // wxUSE_TEXTDLG
dfad0599 917
91b4c08d
VZ
918wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit)
919{
920 wxColourData data;
921 data.SetChooseFull(TRUE);
922 if ( colInit.Ok() )
923 {
924 data.SetColour((wxColour &)colInit); // const_cast
925 }
926
927 wxColour colRet;
928 wxColourDialog dialog(parent, &data);
929 if ( dialog.ShowModal() == wxID_OK )
930 {
931 colRet = dialog.GetColourData().GetColour();
932 }
933 //else: leave it invalid
934
935 return colRet;
936}
937
938// ----------------------------------------------------------------------------
939// missing C RTL functions (FIXME shouldn't be here at all)
940// ----------------------------------------------------------------------------
941
469e1e5c 942#ifdef __MWERKS__
3f4a0c5b 943char *strdup(const char *s)
469e1e5c 944{
3f4a0c5b 945 return strcpy( (char*) malloc( strlen( s ) + 1 ) , s ) ;
469e1e5c
SC
946}
947
3f4a0c5b 948int isascii( int c )
469e1e5c 949{
3f4a0c5b 950 return ( c >= 0 && c < 128 ) ;
469e1e5c 951}
e90c1d2a
VZ
952#endif // __MWERKS__
953
954// ----------------------------------------------------------------------------
cbc66a27 955// wxSafeYield and supporting functions
e90c1d2a
VZ
956// ----------------------------------------------------------------------------
957
958void wxEnableTopLevelWindows(bool enable)
959{
225fe9d6
VZ
960 wxWindowList::Node *node;
961 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
962 node->GetData()->Enable(enable);
e90c1d2a
VZ
963}
964
cd6ce4a9 965wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip)
e90c1d2a 966{
5e1febfa 967#ifdef __WXMSW__
62ea79f3 968#ifdef __WIN32__
5e1febfa
VZ
969 // and the top level window too
970 HWND hwndFG = ::GetForegroundWindow();
971 m_winTop = hwndFG ? wxFindWinFromHandle((WXHWND)hwndFG) : (wxWindow *)NULL;
62ea79f3
JS
972#else
973 HWND hwndFG = ::GetTopWindow();
974 m_winTop = hwndFG ? wxFindWinFromHandle((WXHWND)hwndFG) : (wxWindow *)NULL;
975#endif
5e1febfa
VZ
976#endif // MSW
977
79f585d9
VZ
978 // remember the top level windows which were already disabled, so that we
979 // don't reenable them later
980 m_winDisabled = NULL;
981
225fe9d6
VZ
982 wxWindowList::Node *node;
983 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
984 {
985 wxWindow *winTop = node->GetData();
79f585d9
VZ
986 if ( winTop == winToSkip )
987 continue;
988
989 if ( winTop->IsEnabled() )
990 {
991 winTop->Disable();
992 }
993 else
cd6ce4a9 994 {
79f585d9
VZ
995 if ( !m_winDisabled )
996 {
997 m_winDisabled = new wxWindowList;
998 }
225fe9d6 999
cd6ce4a9 1000 m_winDisabled->Append(winTop);
cd6ce4a9 1001 }
225fe9d6 1002 }
cd6ce4a9 1003}
225fe9d6 1004
cd6ce4a9
VZ
1005wxWindowDisabler::~wxWindowDisabler()
1006{
1007 wxWindowList::Node *node;
79f585d9 1008 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
225fe9d6 1009 {
79f585d9
VZ
1010 wxWindow *winTop = node->GetData();
1011 if ( !m_winDisabled || !m_winDisabled->Find(winTop) )
1012 {
1013 winTop->Enable();
1014 }
1015 //else: had been already disabled, don't reenable
225fe9d6
VZ
1016 }
1017
cd6ce4a9 1018 delete m_winDisabled;
5e1febfa
VZ
1019
1020#ifdef __WXMSW__
62ea79f3 1021#ifdef __WIN32__
5e1febfa
VZ
1022 if ( m_winTop )
1023 {
1024 if ( !::SetForegroundWindow(GetHwndOf(m_winTop)) )
1025 {
1026 wxLogLastError("SetForegroundWindow");
1027 }
1028 }
62ea79f3
JS
1029#else
1030 if ( m_winTop )
1031 {
1032 // 16-bit SetForegroundWindow() replacement
1033 RECT reWin;
1034 GetWindowRect(m_winTop, &reWin);
1035 SetWindowPos (m_winTop, HWND_TOP,
1036 reWin.left, reWin.top,
1037 reWin.right - reWin.left, reWin.bottom,
1038 SWP_SHOWWINDOW);
1039 }
1040#endif
5e1febfa 1041#endif // MSW
cd6ce4a9
VZ
1042}
1043
1044// Yield to other apps/messages and disable user input to all windows except
1045// the given one
1046bool wxSafeYield(wxWindow *win)
1047{
1048 wxWindowDisabler wd;
1049
1050 bool rc = wxYield();
1051
225fe9d6 1052 return rc;
e90c1d2a
VZ
1053}
1054
cbc66a27
VZ
1055// ----------------------------------------------------------------------------
1056// misc functions
1057// ----------------------------------------------------------------------------
1058
e90c1d2a
VZ
1059// Don't synthesize KeyUp events holding down a key and producing KeyDown
1060// events with autorepeat. On by default and always on in wxMSW. wxGTK version
1061// in utilsgtk.cpp.
1062#ifndef __WXGTK__
1063bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) )
1064{
225fe9d6 1065 return TRUE; // detectable auto-repeat is the only mode MSW supports
e90c1d2a
VZ
1066}
1067#endif // !wxGTK
1068
1069#endif // wxUSE_GUI
e2a6f233 1070
0fb67cd1
VZ
1071// ----------------------------------------------------------------------------
1072// network and user id functions
1073// ----------------------------------------------------------------------------
1074
1075// Get Full RFC822 style email address
84fff0b3 1076bool wxGetEmailAddress(wxChar *address, int maxSize)
e2a6f233 1077{
0fb67cd1
VZ
1078 wxString email = wxGetEmailAddress();
1079 if ( !email )
e2a6f233 1080 return FALSE;
0fb67cd1 1081
84fff0b3 1082 wxStrncpy(address, email, maxSize - 1);
223d09f6 1083 address[maxSize - 1] = wxT('\0');
0fb67cd1
VZ
1084
1085 return TRUE;
e2a6f233
JS
1086}
1087
0fb67cd1 1088wxString wxGetEmailAddress()
e2a6f233 1089{
0fb67cd1
VZ
1090 wxString email;
1091
1092 wxString host = wxGetHostName();
1093 if ( !!host )
e2a6f233 1094 {
0fb67cd1
VZ
1095 wxString user = wxGetUserId();
1096 if ( !!user )
1097 {
1098 wxString email(user);
223d09f6 1099 email << wxT('@') << host;
0fb67cd1 1100 }
e2a6f233 1101 }
0fb67cd1
VZ
1102
1103 return email;
1104}
1105
1106wxString wxGetUserId()
1107{
1108 static const int maxLoginLen = 256; // FIXME arbitrary number
1109
1110 wxString buf;
1111 bool ok = wxGetUserId(buf.GetWriteBuf(maxLoginLen), maxLoginLen);
1112 buf.UngetWriteBuf();
1113
1114 if ( !ok )
1115 buf.Empty();
1116
1117 return buf;
1118}
1119
1120wxString wxGetUserName()
1121{
1122 static const int maxUserNameLen = 1024; // FIXME arbitrary number
1123
1124 wxString buf;
1125 bool ok = wxGetUserName(buf.GetWriteBuf(maxUserNameLen), maxUserNameLen);
1126 buf.UngetWriteBuf();
1127
1128 if ( !ok )
1129 buf.Empty();
1130
1131 return buf;
e2a6f233
JS
1132}
1133
0fb67cd1 1134wxString wxGetHostName()
518b5d2f
VZ
1135{
1136 static const size_t hostnameSize = 257;
0fb67cd1
VZ
1137
1138 wxString buf;
518b5d2f
VZ
1139 bool ok = wxGetHostName(buf.GetWriteBuf(hostnameSize), hostnameSize);
1140
1141 buf.UngetWriteBuf();
1142
0fb67cd1
VZ
1143 if ( !ok )
1144 buf.Empty();
1145
1146 return buf;
518b5d2f
VZ
1147}
1148
96c5bd7f
KB
1149wxString wxGetFullHostName()
1150{
1151 static const size_t hostnameSize = 257;
1152
1153 wxString buf;
1154 bool ok = wxGetFullHostName(buf.GetWriteBuf(hostnameSize), hostnameSize);
1155
1156 buf.UngetWriteBuf();
1157
1158 if ( !ok )
1159 buf.Empty();
1160
1161 return buf;
1162}
1163
c51deffc
VZ
1164wxString wxGetHomeDir()
1165{
1166 wxString home;
1167 wxGetHomeDir(&home);
1168
1169 return home;
1170}
bc385ba9
VZ
1171
1172#if 0
1173
1174wxString wxGetCurrentDir()
1175{
1176 wxString dir;
1177 size_t len = 1024;
1178 bool ok;
1179 do
1180 {
1181 ok = getcwd(dir.GetWriteBuf(len + 1), len) != NULL;
1182 dir.UngetWriteBuf();
1183
1184 if ( !ok )
1185 {
1186 if ( errno != ERANGE )
1187 {
1188 wxLogSysError(_T("Failed to get current directory"));
1189
1190 return wxEmptyString;
1191 }
1192 else
1193 {
1194 // buffer was too small, retry with a larger one
1195 len *= 2;
1196 }
1197 }
1198 //else: ok
1199 } while ( !ok );
1200
1201 return dir;
1202}
1203
1204#endif // 0
cd6ce4a9
VZ
1205
1206// ----------------------------------------------------------------------------
1207// wxExecute
1208// ----------------------------------------------------------------------------
1209
1210long wxExecute(const wxString& command, wxArrayString& output)
1211{
1212 // create a wxProcess which will capture the output
1213 wxProcess *process = new wxProcess;
1214 process->Redirect();
1215
1216 long rc = wxExecute(command, TRUE /* sync */, process);
1217 if ( rc != -1 )
1218 {
1219 wxInputStream& is = *process->GetInputStream();
1220 wxTextInputStream tis(is);
5e1febfa 1221 while ( !is.Eof() && is.IsOk() )
cd6ce4a9
VZ
1222 {
1223 wxString line = tis.ReadLine();
1224 if ( is.LastError() )
1225 break;
1226
1227 output.Add(line);
1228 }
1229 }
1230
1231 return rc;
1232}