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