]> git.saurik.com Git - wxWidgets.git/blame - utils/configtool/src/utils.cpp
Regenerated makefiles for 3rd-party lib change
[wxWidgets.git] / utils / configtool / src / utils.cpp
CommitLineData
d7463f75
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: utils.cpp
3// Purpose: Utility functions and classes
4// Author: Julian Smart
5// Modified by:
6// Created: 2002-09-04
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
4fe30bce 9// Licence:
d7463f75
JS
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13// #pragma implementation
14#endif
15
d9ab621e
WS
16// For compilers that support precompilation, includes "wx/wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#include <math.h>
24
25#ifndef WX_PRECOMP
26
d7463f75 27#include "wx/splitter.h"
d7463f75
JS
28#include "wx/datstrm.h"
29#include "wx/file.h"
30#include "wx/listctrl.h"
d7463f75 31#include "wx/process.h"
d7463f75 32#include "wx/variant.h"
d7463f75
JS
33#include "wx/cmdline.h"
34
d7463f75
JS
35#endif
36
d9ab621e
WS
37#include "wx/wfstream.h"
38#include "wx/cshelp.h"
39#include "wx/image.h"
40#include "wx/imaglist.h"
41#include "wx/tokenzr.h"
42#include "wx/notebook.h"
43#include "wx/mimetype.h"
d7463f75
JS
44#include "utils.h"
45
46// Returns the image type, or -1, determined from the extension.
47int apDetermineImageType(const wxString& filename)
48{
49 wxString path, name, ext;
50
51 wxSplitPath(filename, & path, & name, & ext);
52
53 ext.MakeLower();
69da0d99 54 if (ext == _T("jpg") || ext == _T("jpeg"))
d7463f75 55 return wxBITMAP_TYPE_JPEG;
69da0d99 56 else if (ext == _T("gif"))
d7463f75 57 return wxBITMAP_TYPE_GIF;
69da0d99 58 else if (ext == _T("bmp"))
d7463f75 59 return wxBITMAP_TYPE_BMP;
69da0d99 60 else if (ext == _T("png"))
d7463f75 61 return wxBITMAP_TYPE_PNG;
69da0d99 62 else if (ext == _T("pcx"))
d7463f75 63 return wxBITMAP_TYPE_PCX;
69da0d99 64 else if (ext == _T("tif") || ext == _T("tiff"))
d7463f75
JS
65 return wxBITMAP_TYPE_TIF;
66 else
67 return -1;
68}
69
70// Convert a colour to a 6-digit hex string
71wxString apColourToHexString(const wxColour& col)
72{
73 wxString hex;
74
75 hex += wxDecToHex(col.Red());
76 hex += wxDecToHex(col.Green());
77 hex += wxDecToHex(col.Blue());
78
79 return hex;
80}
81
82// Convert 6-digit hex string to a colour
83wxColour apHexStringToColour(const wxString& hex)
84{
254a2129
WS
85 unsigned char r = (unsigned char)wxHexToDec(hex.Mid(0, 2));
86 unsigned char g = (unsigned char)wxHexToDec(hex.Mid(2, 2));
87 unsigned char b = (unsigned char)wxHexToDec(hex.Mid(4, 2));
d7463f75
JS
88
89 return wxColour(r, g, b);
90}
91
92// Convert a wxFont to a string
93wxString apFontToString(const wxFont& font)
94{
95 wxString str;
96 str.Printf(wxT("%d,%d,%d,%d,%d,%s"), (int) font.GetPointSize(),
97 (int) font.GetFamily(), (int) font.GetStyle(), (int) font.GetWeight(),
98 (int) font.GetUnderlined(), font.GetFaceName().c_str());
99
100 return str;
101}
102
3ac35b57
MB
103static inline int StringToInt(const wxString& s)
104{
105 long tmp;
106 s.ToLong(&tmp);
107
108 return int(tmp);
109}
110
d7463f75
JS
111// Convert a string to a wxFont
112wxFont apStringToFont(const wxString& str)
113{
114 int pointSize = 12;
115 int family = wxSWISS;
116 int style = wxNORMAL;
117 int weight = wxNORMAL;
118 int underlined = 0;
119 wxString facename(wxT(""));
120
121 wxStringTokenizer tkz(str, wxT(","));
122 int i = 0;
123 while (tkz.HasMoreTokens())
124 {
125 wxString token = tkz.GetNextToken();
126
127 if (i == 0)
128 {
3ac35b57 129 pointSize = StringToInt(token);
d7463f75
JS
130#if defined(__WXGTK__) || defined(__WXMAC__)
131 if (pointSize < 8)
132 pointSize = 8;
133 if (pointSize == 9)
134 pointSize = 10;
254a2129 135#endif
d7463f75
JS
136 }
137 else if (i == 1)
3ac35b57 138 family = StringToInt(token);
d7463f75 139 else if (i == 2)
3ac35b57 140 style = StringToInt(token);
d7463f75 141 else if (i == 3)
3ac35b57 142 weight = StringToInt(token);
d7463f75 143 else if (i == 4)
3ac35b57 144 underlined = StringToInt(token);
d7463f75
JS
145 else if (i == 5)
146 {
147 facename = token;
148#if defined(__WXGTK__)
149 if (facename == wxT("Arial"))
150 facename = wxT("helvetica");
151#endif
152 }
153 i ++;
154
155 }
156 return wxFont(pointSize, family, style, weight, (underlined != 0), facename);
157}
158
159
160// Get the index of the given named wxNotebook page
161int apFindNotebookPage(wxNotebook* notebook, const wxString& name)
162{
163 int i;
69da0d99 164 for (i = 0; i < (int)notebook->GetPageCount(); i++)
d7463f75
JS
165 if (name == notebook->GetPageText(i))
166 return i;
167 return -1;
168}
169
170/*
171 * View an HTML file
172 */
173
174void apViewHTMLFile(const wxString& url)
175{
176#ifdef __WXMSW__
177 HKEY hKey;
178 TCHAR szCmdName[1024];
179 DWORD dwType, dw = sizeof(szCmdName);
180 LONG lRes;
69da0d99 181 lRes = RegOpenKey(HKEY_CLASSES_ROOT, _T("htmlfile\\shell\\open\\command"), &hKey);
d7463f75
JS
182 if(lRes == ERROR_SUCCESS && RegQueryValueEx(hKey,(LPTSTR)NULL, NULL,
183 &dwType, (LPBYTE)szCmdName, &dw) == ERROR_SUCCESS)
184 {
69da0d99 185 wxStrcat(szCmdName, (const wxChar*) url);
d7463f75
JS
186 PROCESS_INFORMATION piProcInfo;
187 STARTUPINFO siStartInfo;
188 memset(&siStartInfo, 0, sizeof(STARTUPINFO));
189 siStartInfo.cb = sizeof(STARTUPINFO);
4fe30bce 190 CreateProcess(NULL, szCmdName, NULL, NULL, false, 0, NULL,
d7463f75
JS
191 NULL, &siStartInfo, &piProcInfo );
192 }
193 if(lRes == ERROR_SUCCESS)
194 RegCloseKey(hKey);
195#else
196 wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(wxT("html"));
197 if ( !ft )
198 {
199 wxLogError(_T("Impossible to determine the file type for extension html. Please edit your MIME types."));
200 return ;
201 }
202
203 wxString cmd;
204 bool ok = ft->GetOpenCommand(&cmd,
205 wxFileType::MessageParameters(url, _T("")));
206 delete ft;
207
208 if (!ok)
209 {
210 // TODO: some kind of configuration dialog here.
211 wxMessageBox(_("Could not determine the command for running the browser."),
4fe30bce 212 wxT("Browsing problem"), wxOK|wxICON_EXCLAMATION);
d7463f75
JS
213 return ;
214 }
215
4fe30bce 216 ok = (wxExecute(cmd, false) != 0);
d7463f75
JS
217#endif
218}
219
220wxString wxGetTempDir()
221{
222 wxString dir;
223#if defined(__WXMAC__) && !defined(__DARWIN__)
224 dir = wxMacFindFolder( (short) kOnSystemDisk, kTemporaryFolderType, kCreateFolder ) ;
225#else // !Mac
d9ab621e
WS
226 wxString dirEnv(wxGetenv(_T("TMP")));
227 dir = dirEnv;
d7463f75
JS
228 if ( dir.empty() )
229 {
d9ab621e
WS
230 wxString envVar(wxGetenv(_T("TEMP")));
231 dir = envVar;
d7463f75 232 }
254a2129 233
d7463f75
JS
234 if ( dir.empty() )
235 {
236 // default
237#ifdef __DOS__
238 dir = _T(".");
239#else
240 dir = _T("/tmp");
241#endif
242 }
243#endif // Mac/!Mac
244 return dir;
245}
246
247// Invoke app for file type
248// Eventually we should allow the user to select an app.
249bool apInvokeAppForFile(const wxString& filename)
250{
251 wxString path, file, ext;
252 wxSplitPath(filename, & path, & file, & ext);
253
254 wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
255 if ( !ft )
256 {
257 wxString msg;
258 msg.Printf(wxT("Sorry, could not determine what application to invoke for extension %s\nYou may need to edit your MIME types."),
259 ext.c_str());
260 wxMessageBox(msg, wxT("Application Invocation"), wxICON_EXCLAMATION|wxOK);
4fe30bce 261 return false;
d7463f75
JS
262 }
263
264 wxString cmd;
79830320 265 ft->GetOpenCommand(&cmd, wxFileType::MessageParameters(filename, _T("")));
d7463f75
JS
266 delete ft;
267
4fe30bce 268 return (wxExecute(cmd, false) != 0);
d7463f75
JS
269}
270
271// Find the absolute path where this application has been run from.
272// argv0 is wxTheApp->argv[0]
273// cwd is the current working directory (at startup)
274// appVariableName is the name of a variable containing the directory for this app, e.g.
275// MYAPPDIR. This is checked first.
276
277wxString apFindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName)
278{
d7463f75
JS
279 // Try appVariableName
280 if (!appVariableName.IsEmpty())
281 {
d9ab621e
WS
282 wxString strVar(wxGetenv(appVariableName.c_str()));
283 if (!strVar.IsEmpty())
284 return strVar;
d7463f75
JS
285 }
286
287 if (wxIsAbsolutePath(argv0))
288 return wxPathOnly(argv0);
289 else
290 {
291 // Is it a relative path?
292 wxString currentDir(cwd);
293 if (currentDir.Last() != wxFILE_SEP_PATH)
294 currentDir += wxFILE_SEP_PATH;
295
d9ab621e
WS
296 currentDir += argv0;
297 if (wxFileExists(currentDir))
298 return wxPathOnly(currentDir);
d7463f75
JS
299 }
300
301 // OK, it's neither an absolute path nor a relative path.
302 // Search PATH.
303
304 wxPathList pathList;
305 pathList.AddEnvList(wxT("PATH"));
d9ab621e
WS
306 wxString strPath = pathList.FindAbsoluteValidPath(argv0);
307 if (!strPath.IsEmpty())
308 return wxPathOnly(strPath);
d7463f75
JS
309
310 // Failed
311 return wxEmptyString;
312}
313
314// Adds a context-sensitive help button, for non-Windows platforms
254a2129 315void apAddContextHelpButton(wxWindow*
69da0d99
JS
316 #if defined(__WXGTK__) || defined(__WXMAC__)
317 parent
318 #else
319 WXUNUSED(parent)
320 #endif
254a2129 321 , wxSizer*
69da0d99
JS
322 #if defined(__WXGTK__) || defined(__WXMAC__)
323 sizer
324 #else
325 WXUNUSED(sizer)
326 #endif
254a2129 327 , int
69da0d99
JS
328 #if defined(__WXGTK__) || defined(__WXMAC__)
329 sizerFlags
330 #else
331 WXUNUSED(sizerFlags)
332 #endif
254a2129 333 , int
69da0d99
JS
334 #if defined(__WXGTK__) || defined(__WXMAC__)
335 sizerBorder
336 #else
337 WXUNUSED(sizerBorder)
338 #endif
339 )
d7463f75
JS
340{
341#if defined(__WXGTK__) || defined(__WXMAC__)
342#ifdef __WXMAC__
343 wxSize buttonSize(20, 20);
344#else
4fe30bce 345 wxSize buttonSize = wxDefaultSize;
d7463f75
JS
346#endif
347 wxButton *contextButton = new wxContextHelpButton( parent, wxID_CONTEXT_HELP,
348 wxDefaultPosition, buttonSize);
349 sizer->Add( contextButton, 0, sizerFlags, sizerBorder );
350
351 // Add a bit of space on the right, to allow for the dialog resizing
352 // handle
353#ifdef __WXMAC__
354 sizer->Add(0, 0, 0, wxRIGHT, 10);
355#endif
356
357 contextButton->SetHelpText(_("Invokes context-sensitive help for the clicked-on window."));
02ae000a 358#if 0
d7463f75
JS
359 if (wxGetApp().UsingTooltips())
360 {
361 contextButton->SetToolTip(_("Invokes context-sensitive help for the clicked-on window."));
362 }
363#endif
02ae000a 364#endif
d7463f75
JS
365}
366
367// Get selected wxNotebook page
368wxWindow* apNotebookGetSelectedPage(wxNotebook* notebook)
369{
370 int sel = notebook->GetSelection();
371 if (sel > -1)
372 {
373 return notebook->GetPage(sel);
374 }
375 return NULL;
376}
377
378/*
379* wxIconInfo
380*/
381
382wxIconInfo::wxIconInfo(const wxString& name)
383{
384 m_maxStates = 0;
385 m_name = name;
386 int i;
387 for (i = 0; i < wxMAX_ICON_STATES; i++)
388 m_states[i] = 0;
389}
390
391int wxIconInfo::GetIconId(int state, bool enabled) const
392{
393 wxASSERT ( state < (wxMAX_ICON_STATES * 2) );
394 wxASSERT ( state < m_maxStates );
254a2129 395
d7463f75
JS
396 return m_states[state * 2 + (enabled ? 0 : 1)];
397}
398
399void wxIconInfo::SetIconId(int state, bool enabled, int iconId)
400{
401 wxASSERT ( state < (wxMAX_ICON_STATES * 2) );
402 if (state+1 > m_maxStates)
403 m_maxStates = state+1;
254a2129 404
d7463f75
JS
405 m_states[state * 2 + (enabled ? 0 : 1)] = iconId;
406}
407
408/*
409* wxIconTable
410* Contains a list of wxIconInfos
411*/
412
413wxIconTable::wxIconTable(wxImageList* imageList)
414{
415 m_imageList = imageList;
d9ab621e 416 WX_CLEAR_LIST(wxIconTable,*this);
d7463f75
JS
417}
418
419void wxIconTable::AppendInfo(wxIconInfo* info)
420{
421 Append(info);
422}
423
424// Easy way of initialising both the image list and the
425// table. It will generate image ids itself while appending the icon.
426bool wxIconTable::AddInfo(const wxString& name, const wxIcon& icon, int state, bool enabled)
427{
428 wxASSERT (m_imageList != NULL);
254a2129 429
d7463f75
JS
430 wxIconInfo* info = FindInfo(name);
431 if (!info)
432 {
433 info = new wxIconInfo(name);
434 Append(info);
435 }
436 info->SetIconId(state, enabled, m_imageList->Add(icon));
4fe30bce 437 return true;
d7463f75
JS
438}
439
440wxIconInfo* wxIconTable::FindInfo(const wxString& name) const
441{
d9ab621e 442 wxObjectList::compatibility_iterator node = GetFirst();
d7463f75
JS
443 while (node)
444 {
f8105809 445 wxIconInfo* info = (wxIconInfo*) node->GetData();
d7463f75
JS
446 if (info->GetName() == name)
447 return info;
f8105809 448 node = node->GetNext();
d7463f75
JS
449 }
450 return NULL;
451}
452
453int wxIconTable::GetIconId(const wxString& name, int state, bool enabled) const
454{
455 wxIconInfo* info = FindInfo(name);
456 if (!info)
457 return -1;
458 return info->GetIconId(state, enabled);
459}
460
461bool wxIconTable::SetIconId(const wxString& name, int state, bool enabled, int iconId)
462{
463 wxIconInfo* info = FindInfo(name);
464 if (!info)
4fe30bce 465 return false;
d7463f75 466 info->SetIconId(state, enabled, iconId);
4fe30bce 467 return true;
d7463f75
JS
468}
469
470// Output stream operators
471
472wxOutputStream& operator <<(wxOutputStream& stream, const wxString& s)
473{
474 stream.Write(s, s.Length());
475 return stream;
476}
477
478wxOutputStream& operator <<(wxOutputStream& stream, long l)
479{
480 wxString str;
481 str.Printf(_T("%ld"), l);
482 return stream << str;
483}
484
69da0d99 485wxOutputStream& operator <<(wxOutputStream& stream, const wxChar c)
d7463f75
JS
486{
487 wxString str;
488 str.Printf(_T("%c"), c);
489 return stream << str;
490}
491
492// Convert characters to HTML equivalents
493wxString ctEscapeHTMLCharacters(const wxString& str)
494{
495 wxString s;
496 size_t len = str.Length();
497 size_t i;
498 for (i = 0; i < len; i++)
499 {
500 wxChar c = str.GetChar(i);
501 if (c == _T('<'))
502 s += _T("&lt;");
503 else if (c == _T('>'))
504 s += _T("&gt;");
505 else if (c == _T('&'))
506 s += _T("&amp;");
507 else
508 s += c;
509 }
510 return s;
f8105809 511}
e7767867
JS
512
513// Match 'matchText' against 'matchAgainst', optionally constraining to
514// whole-word only.
515bool ctMatchString(const wxString& matchAgainst, const wxString& matchText, bool wholeWordOnly)
516{
517 // Fast operation if not matching against whole words only
518 if (!wholeWordOnly)
4fe30bce 519 return (matchAgainst.Find(matchText) != wxNOT_FOUND);
e7767867
JS
520
521 wxString left(matchAgainst);
4fe30bce 522 bool success = false;
e7767867
JS
523 int matchTextLen = (int) matchText.Length();
524 while (!success && !matchAgainst.IsEmpty())
525 {
79830320 526 int pos = left.Find(matchText);
4fe30bce
WS
527 if (pos == wxNOT_FOUND)
528 return false;
e7767867 529
4fe30bce
WS
530 bool firstCharOK = false;
531 bool lastCharOK = false;
e7767867 532 if (pos == 0 || !wxIsalnum(left[(size_t) (pos-1)]))
4fe30bce 533 firstCharOK = true;
e7767867
JS
534
535 if (((pos + matchTextLen) == (int) left.Length()) || !wxIsalnum(left[(size_t) (pos + matchTextLen)]))
4fe30bce 536 lastCharOK = true;
e7767867
JS
537
538 if (firstCharOK && lastCharOK)
4fe30bce 539 success = true;
e7767867
JS
540
541 left = left.Mid(pos+1);
542 }
543 return success;
544}