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