]> git.saurik.com Git - wxWidgets.git/blob - utils/configtool/src/utils.cpp
use WX_DEFINE_ARRAY_PTR for anarray of pointers (fixes Sun CC warning)
[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 wxString wxGetTempDir()
176 {
177 wxString dir;
178 #if defined(__WXMAC__) && !defined(__DARWIN__)
179 dir = wxMacFindFolder( (short) kOnSystemDisk, kTemporaryFolderType, kCreateFolder ) ;
180 #else // !Mac
181 wxString dirEnv(wxGetenv(_T("TMP")));
182 dir = dirEnv;
183 if ( dir.empty() )
184 {
185 wxString envVar(wxGetenv(_T("TEMP")));
186 dir = envVar;
187 }
188
189 if ( dir.empty() )
190 {
191 // default
192 #ifdef __DOS__
193 dir = _T(".");
194 #else
195 dir = _T("/tmp");
196 #endif
197 }
198 #endif // Mac/!Mac
199 return dir;
200 }
201
202 // Invoke app for file type
203 // Eventually we should allow the user to select an app.
204 bool apInvokeAppForFile(const wxString& filename)
205 {
206 wxString path, file, ext;
207 wxSplitPath(filename, & path, & file, & ext);
208
209 wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
210 if ( !ft )
211 {
212 wxString msg;
213 msg.Printf(wxT("Sorry, could not determine what application to invoke for extension %s\nYou may need to edit your MIME types."),
214 ext.c_str());
215 wxMessageBox(msg, wxT("Application Invocation"), wxICON_EXCLAMATION|wxOK);
216 return false;
217 }
218
219 wxString cmd;
220 ft->GetOpenCommand(&cmd, wxFileType::MessageParameters(filename, wxEmptyString));
221 delete ft;
222
223 return (wxExecute(cmd, false) != 0);
224 }
225
226 // Find the absolute path where this application has been run from.
227 // argv0 is wxTheApp->argv[0]
228 // cwd is the current working directory (at startup)
229 // appVariableName is the name of a variable containing the directory for this app, e.g.
230 // MYAPPDIR. This is checked first.
231
232 wxString apFindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName)
233 {
234 // Try appVariableName
235 if (!appVariableName.empty())
236 {
237 wxString strVar(wxGetenv(appVariableName.c_str()));
238 if (!strVar.empty())
239 return strVar;
240 }
241
242 if (wxIsAbsolutePath(argv0))
243 return wxPathOnly(argv0);
244 else
245 {
246 // Is it a relative path?
247 wxString currentDir(cwd);
248 if (currentDir.Last() != wxFILE_SEP_PATH)
249 currentDir += wxFILE_SEP_PATH;
250
251 currentDir += argv0;
252 if (wxFileExists(currentDir))
253 return wxPathOnly(currentDir);
254 }
255
256 // OK, it's neither an absolute path nor a relative path.
257 // Search PATH.
258
259 wxPathList pathList;
260 pathList.AddEnvList(wxT("PATH"));
261 wxString strPath = pathList.FindAbsoluteValidPath(argv0);
262 if (!strPath.empty())
263 return wxPathOnly(strPath);
264
265 // Failed
266 return wxEmptyString;
267 }
268
269 // Adds a context-sensitive help button, for non-Windows platforms
270 void apAddContextHelpButton(wxWindow*
271 #if defined(__WXGTK__) || defined(__WXMAC__)
272 parent
273 #else
274 WXUNUSED(parent)
275 #endif
276 , wxSizer*
277 #if defined(__WXGTK__) || defined(__WXMAC__)
278 sizer
279 #else
280 WXUNUSED(sizer)
281 #endif
282 , int
283 #if defined(__WXGTK__) || defined(__WXMAC__)
284 sizerFlags
285 #else
286 WXUNUSED(sizerFlags)
287 #endif
288 , int
289 #if defined(__WXGTK__) || defined(__WXMAC__)
290 sizerBorder
291 #else
292 WXUNUSED(sizerBorder)
293 #endif
294 )
295 {
296 #if defined(__WXGTK__) || defined(__WXMAC__)
297 #ifdef __WXMAC__
298 wxSize buttonSize(20, 20);
299 #else
300 wxSize buttonSize = wxDefaultSize;
301 #endif
302 wxButton *contextButton = new wxContextHelpButton( parent, wxID_CONTEXT_HELP,
303 wxDefaultPosition, buttonSize);
304 sizer->Add( contextButton, 0, sizerFlags, sizerBorder );
305
306 // Add a bit of space on the right, to allow for the dialog resizing
307 // handle
308 #ifdef __WXMAC__
309 sizer->Add(0, 0, 0, wxRIGHT, 10);
310 #endif
311
312 contextButton->SetHelpText(_("Invokes context-sensitive help for the clicked-on window."));
313 #if 0
314 if (wxGetApp().UsingTooltips())
315 {
316 contextButton->SetToolTip(_("Invokes context-sensitive help for the clicked-on window."));
317 }
318 #endif
319 #endif
320 }
321
322 // Get selected wxNotebook page
323 wxWindow* apNotebookGetSelectedPage(wxNotebook* notebook)
324 {
325 int sel = notebook->GetSelection();
326 if (sel > -1)
327 {
328 return notebook->GetPage(sel);
329 }
330 return NULL;
331 }
332
333 /*
334 * wxIconInfo
335 */
336
337 wxIconInfo::wxIconInfo(const wxString& name)
338 {
339 m_maxStates = 0;
340 m_name = name;
341 int i;
342 for (i = 0; i < wxMAX_ICON_STATES; i++)
343 m_states[i] = 0;
344 }
345
346 int wxIconInfo::GetIconId(int state, bool enabled) const
347 {
348 wxASSERT ( state < (wxMAX_ICON_STATES * 2) );
349 wxASSERT ( state < m_maxStates );
350
351 return m_states[state * 2 + (enabled ? 0 : 1)];
352 }
353
354 void wxIconInfo::SetIconId(int state, bool enabled, int iconId)
355 {
356 wxASSERT ( state < (wxMAX_ICON_STATES * 2) );
357 if (state+1 > m_maxStates)
358 m_maxStates = state+1;
359
360 m_states[state * 2 + (enabled ? 0 : 1)] = iconId;
361 }
362
363 /*
364 * wxIconTable
365 * Contains a list of wxIconInfos
366 */
367
368 wxIconTable::wxIconTable(wxImageList* imageList)
369 {
370 m_imageList = imageList;
371 WX_CLEAR_LIST(wxIconTable,*this);
372 }
373
374 void wxIconTable::AppendInfo(wxIconInfo* info)
375 {
376 Append(info);
377 }
378
379 // Easy way of initialising both the image list and the
380 // table. It will generate image ids itself while appending the icon.
381 bool wxIconTable::AddInfo(const wxString& name, const wxIcon& icon, int state, bool enabled)
382 {
383 wxASSERT (m_imageList != NULL);
384
385 wxIconInfo* info = FindInfo(name);
386 if (!info)
387 {
388 info = new wxIconInfo(name);
389 Append(info);
390 }
391 info->SetIconId(state, enabled, m_imageList->Add(icon));
392 return true;
393 }
394
395 wxIconInfo* wxIconTable::FindInfo(const wxString& name) const
396 {
397 wxObjectList::compatibility_iterator node = GetFirst();
398 while (node)
399 {
400 wxIconInfo* info = (wxIconInfo*) node->GetData();
401 if (info->GetName() == name)
402 return info;
403 node = node->GetNext();
404 }
405 return NULL;
406 }
407
408 int wxIconTable::GetIconId(const wxString& name, int state, bool enabled) const
409 {
410 wxIconInfo* info = FindInfo(name);
411 if (!info)
412 return -1;
413 return info->GetIconId(state, enabled);
414 }
415
416 bool wxIconTable::SetIconId(const wxString& name, int state, bool enabled, int iconId)
417 {
418 wxIconInfo* info = FindInfo(name);
419 if (!info)
420 return false;
421 info->SetIconId(state, enabled, iconId);
422 return true;
423 }
424
425 // Output stream operators
426
427 wxOutputStream& operator <<(wxOutputStream& stream, const wxString& s)
428 {
429 stream.Write(s, s.Length());
430 return stream;
431 }
432
433 wxOutputStream& operator <<(wxOutputStream& stream, long l)
434 {
435 wxString str;
436 str.Printf(_T("%ld"), l);
437 return stream << str;
438 }
439
440 wxOutputStream& operator <<(wxOutputStream& stream, const wxChar c)
441 {
442 wxString str;
443 str.Printf(_T("%c"), c);
444 return stream << str;
445 }
446
447 // Convert characters to HTML equivalents
448 wxString ctEscapeHTMLCharacters(const wxString& str)
449 {
450 wxString s;
451 size_t len = str.Length();
452 size_t i;
453 for (i = 0; i < len; i++)
454 {
455 wxChar c = str.GetChar(i);
456 if (c == _T('<'))
457 s += _T("&lt;");
458 else if (c == _T('>'))
459 s += _T("&gt;");
460 else if (c == _T('&'))
461 s += _T("&amp;");
462 else
463 s += c;
464 }
465 return s;
466 }
467
468 // Match 'matchText' against 'matchAgainst', optionally constraining to
469 // whole-word only.
470 bool ctMatchString(const wxString& matchAgainst, const wxString& matchText, bool wholeWordOnly)
471 {
472 // Fast operation if not matching against whole words only
473 if (!wholeWordOnly)
474 return (matchAgainst.Find(matchText) != wxNOT_FOUND);
475
476 wxString left(matchAgainst);
477 bool success = false;
478 int matchTextLen = (int) matchText.Length();
479 while (!success && !matchAgainst.empty())
480 {
481 int pos = left.Find(matchText);
482 if (pos == wxNOT_FOUND)
483 return false;
484
485 bool firstCharOK = false;
486 bool lastCharOK = false;
487 if (pos == 0 || !wxIsalnum(left[(size_t) (pos-1)]))
488 firstCharOK = true;
489
490 if (((pos + matchTextLen) == (int) left.Length()) || !wxIsalnum(left[(size_t) (pos + matchTextLen)]))
491 lastCharOK = true;
492
493 if (firstCharOK && lastCharOK)
494 success = true;
495
496 left = left.Mid(pos+1);
497 }
498 return success;
499 }