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