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