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