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