]> git.saurik.com Git - wxWidgets.git/blob - utils/configtool/src/utils.cpp
Finally whole configtool works regardless of wxUSE_STL value (at least with Borland...
[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
35 #endif
36
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"
44 #include "utils.h"
45
46 // Returns the image type, or -1, determined from the extension.
47 int apDetermineImageType(const wxString& filename)
48 {
49 wxString path, name, ext;
50
51 wxSplitPath(filename, & path, & name, & ext);
52
53 ext.MakeLower();
54 if (ext == _T("jpg") || ext == _T("jpeg"))
55 return wxBITMAP_TYPE_JPEG;
56 else if (ext == _T("gif"))
57 return wxBITMAP_TYPE_GIF;
58 else if (ext == _T("bmp"))
59 return wxBITMAP_TYPE_BMP;
60 else if (ext == _T("png"))
61 return wxBITMAP_TYPE_PNG;
62 else if (ext == _T("pcx"))
63 return wxBITMAP_TYPE_PCX;
64 else if (ext == _T("tif") || ext == _T("tiff"))
65 return wxBITMAP_TYPE_TIF;
66 else
67 return -1;
68 }
69
70 // Convert a colour to a 6-digit hex string
71 wxString 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
83 wxColour apHexStringToColour(const wxString& hex)
84 {
85 unsigned int r = wxHexToDec(hex.Mid(0, 2));
86 unsigned int g = wxHexToDec(hex.Mid(2, 2));
87 unsigned int b = wxHexToDec(hex.Mid(4, 2));
88
89 return wxColour(r, g, b);
90 }
91
92 // Convert a wxFont to a string
93 wxString 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
103 static inline int StringToInt(const wxString& s)
104 {
105 long tmp;
106 s.ToLong(&tmp);
107
108 return int(tmp);
109 }
110
111 // Convert a string to a wxFont
112 wxFont 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 {
129 pointSize = StringToInt(token);
130 #if defined(__WXGTK__) || defined(__WXMAC__)
131 if (pointSize < 8)
132 pointSize = 8;
133 if (pointSize == 9)
134 pointSize = 10;
135 #endif
136 }
137 else if (i == 1)
138 family = StringToInt(token);
139 else if (i == 2)
140 style = StringToInt(token);
141 else if (i == 3)
142 weight = StringToInt(token);
143 else if (i == 4)
144 underlined = StringToInt(token);
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
161 int apFindNotebookPage(wxNotebook* notebook, const wxString& name)
162 {
163 int i;
164 for (i = 0; i < (int)notebook->GetPageCount(); i++)
165 if (name == notebook->GetPageText(i))
166 return i;
167 return -1;
168 }
169
170 /*
171 * View an HTML file
172 */
173
174 void apViewHTMLFile(const wxString& url)
175 {
176 #ifdef __WXMSW__
177 HKEY hKey;
178 TCHAR szCmdName[1024];
179 DWORD dwType, dw = sizeof(szCmdName);
180 LONG lRes;
181 lRes = RegOpenKey(HKEY_CLASSES_ROOT, _T("htmlfile\\shell\\open\\command"), &hKey);
182 if(lRes == ERROR_SUCCESS && RegQueryValueEx(hKey,(LPTSTR)NULL, NULL,
183 &dwType, (LPBYTE)szCmdName, &dw) == ERROR_SUCCESS)
184 {
185 wxStrcat(szCmdName, (const wxChar*) url);
186 PROCESS_INFORMATION piProcInfo;
187 STARTUPINFO siStartInfo;
188 memset(&siStartInfo, 0, sizeof(STARTUPINFO));
189 siStartInfo.cb = sizeof(STARTUPINFO);
190 CreateProcess(NULL, szCmdName, NULL, NULL, false, 0, NULL,
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."),
212 wxT("Browsing problem"), wxOK|wxICON_EXCLAMATION);
213 return ;
214 }
215
216 ok = (wxExecute(cmd, false) != 0);
217 #endif
218 }
219
220 wxString wxGetTempDir()
221 {
222 wxString dir;
223 #if defined(__WXMAC__) && !defined(__DARWIN__)
224 dir = wxMacFindFolder( (short) kOnSystemDisk, kTemporaryFolderType, kCreateFolder ) ;
225 #else // !Mac
226 wxString dirEnv(wxGetenv(_T("TMP")));
227 dir = dirEnv;
228 if ( dir.empty() )
229 {
230 wxString envVar(wxGetenv(_T("TEMP")));
231 dir = envVar;
232 }
233
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.
249 bool 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);
261 return false;
262 }
263
264 wxString cmd;
265 ft->GetOpenCommand(&cmd, wxFileType::MessageParameters(filename, _T("")));
266 delete ft;
267
268 return (wxExecute(cmd, false) != 0);
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
277 wxString apFindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName)
278 {
279 // Try appVariableName
280 if (!appVariableName.IsEmpty())
281 {
282 wxString strVar(wxGetenv(appVariableName.c_str()));
283 if (!strVar.IsEmpty())
284 return strVar;
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
296 currentDir += argv0;
297 if (wxFileExists(currentDir))
298 return wxPathOnly(currentDir);
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"));
306 wxString strPath = pathList.FindAbsoluteValidPath(argv0);
307 if (!strPath.IsEmpty())
308 return wxPathOnly(strPath);
309
310 // Failed
311 return wxEmptyString;
312 }
313
314 // Adds a context-sensitive help button, for non-Windows platforms
315 void apAddContextHelpButton(wxWindow*
316 #if defined(__WXGTK__) || defined(__WXMAC__)
317 parent
318 #else
319 WXUNUSED(parent)
320 #endif
321 , wxSizer*
322 #if defined(__WXGTK__) || defined(__WXMAC__)
323 sizer
324 #else
325 WXUNUSED(sizer)
326 #endif
327 , int
328 #if defined(__WXGTK__) || defined(__WXMAC__)
329 sizerFlags
330 #else
331 WXUNUSED(sizerFlags)
332 #endif
333 , int
334 #if defined(__WXGTK__) || defined(__WXMAC__)
335 sizerBorder
336 #else
337 WXUNUSED(sizerBorder)
338 #endif
339 )
340 {
341 #if defined(__WXGTK__) || defined(__WXMAC__)
342 #ifdef __WXMAC__
343 wxSize buttonSize(20, 20);
344 #else
345 wxSize buttonSize = wxDefaultSize;
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."));
358 #if 0
359 if (wxGetApp().UsingTooltips())
360 {
361 contextButton->SetToolTip(_("Invokes context-sensitive help for the clicked-on window."));
362 }
363 #endif
364 #endif
365 }
366
367 // Get selected wxNotebook page
368 wxWindow* 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
382 wxIconInfo::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
391 int wxIconInfo::GetIconId(int state, bool enabled) const
392 {
393 wxASSERT ( state < (wxMAX_ICON_STATES * 2) );
394 wxASSERT ( state < m_maxStates );
395
396 return m_states[state * 2 + (enabled ? 0 : 1)];
397 }
398
399 void 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;
404
405 m_states[state * 2 + (enabled ? 0 : 1)] = iconId;
406 }
407
408 /*
409 * wxIconTable
410 * Contains a list of wxIconInfos
411 */
412
413 wxIconTable::wxIconTable(wxImageList* imageList)
414 {
415 m_imageList = imageList;
416 WX_CLEAR_LIST(wxIconTable,*this);
417 }
418
419 void 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.
426 bool wxIconTable::AddInfo(const wxString& name, const wxIcon& icon, int state, bool enabled)
427 {
428 wxASSERT (m_imageList != NULL);
429
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));
437 return true;
438 }
439
440 wxIconInfo* wxIconTable::FindInfo(const wxString& name) const
441 {
442 wxObjectList::compatibility_iterator node = GetFirst();
443 while (node)
444 {
445 wxIconInfo* info = (wxIconInfo*) node->GetData();
446 if (info->GetName() == name)
447 return info;
448 node = node->GetNext();
449 }
450 return NULL;
451 }
452
453 int 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
461 bool wxIconTable::SetIconId(const wxString& name, int state, bool enabled, int iconId)
462 {
463 wxIconInfo* info = FindInfo(name);
464 if (!info)
465 return false;
466 info->SetIconId(state, enabled, iconId);
467 return true;
468 }
469
470 // Output stream operators
471
472 wxOutputStream& operator <<(wxOutputStream& stream, const wxString& s)
473 {
474 stream.Write(s, s.Length());
475 return stream;
476 }
477
478 wxOutputStream& operator <<(wxOutputStream& stream, long l)
479 {
480 wxString str;
481 str.Printf(_T("%ld"), l);
482 return stream << str;
483 }
484
485 wxOutputStream& operator <<(wxOutputStream& stream, const wxChar c)
486 {
487 wxString str;
488 str.Printf(_T("%c"), c);
489 return stream << str;
490 }
491
492 // Convert characters to HTML equivalents
493 wxString 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;
511 }
512
513 // Match 'matchText' against 'matchAgainst', optionally constraining to
514 // whole-word only.
515 bool ctMatchString(const wxString& matchAgainst, const wxString& matchText, bool wholeWordOnly)
516 {
517 // Fast operation if not matching against whole words only
518 if (!wholeWordOnly)
519 return (matchAgainst.Find(matchText) != wxNOT_FOUND);
520
521 wxString left(matchAgainst);
522 bool success = false;
523 int matchTextLen = (int) matchText.Length();
524 while (!success && !matchAgainst.IsEmpty())
525 {
526 int pos = left.Find(matchText);
527 if (pos == wxNOT_FOUND)
528 return false;
529
530 bool firstCharOK = false;
531 bool lastCharOK = false;
532 if (pos == 0 || !wxIsalnum(left[(size_t) (pos-1)]))
533 firstCharOK = true;
534
535 if (((pos + matchTextLen) == (int) left.Length()) || !wxIsalnum(left[(size_t) (pos + matchTextLen)]))
536 lastCharOK = true;
537
538 if (firstCharOK && lastCharOK)
539 success = true;
540
541 left = left.Mid(pos+1);
542 }
543 return success;
544 }