1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Utility functions and classes
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
10 /////////////////////////////////////////////////////////////////////////////
13 // #pragma implementation
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
27 #include "wx/splitter.h"
28 #include "wx/datstrm.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"
42 #include "wx/wfstream.h"
43 #include "wx/cshelp.h"
45 #include "wx/imaglist.h"
46 #include "wx/tokenzr.h"
47 #include "wx/notebook.h"
48 #include "wx/mimetype.h"
51 // Returns the image type, or -1, determined from the extension.
52 int apDetermineImageType(const wxString
& filename
)
54 wxString path
, name
, ext
;
56 wxSplitPath(filename
, & path
, & name
, & ext
);
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
;
75 // Convert a colour to a 6-digit hex string
76 wxString
apColourToHexString(const wxColour
& col
)
80 hex
+= wxDecToHex(col
.Red());
81 hex
+= wxDecToHex(col
.Green());
82 hex
+= wxDecToHex(col
.Blue());
87 // Convert 6-digit hex string to a colour
88 wxColour
apHexStringToColour(const wxString
& hex
)
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));
94 return wxColour(r
, g
, b
);
97 // Convert a wxFont to a string
98 wxString
apFontToString(const wxFont
& font
)
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());
108 static inline int StringToInt(const wxString
& s
)
116 // Convert a string to a wxFont
117 wxFont
apStringToFont(const wxString
& str
)
120 int family
= wxSWISS
;
121 int style
= wxNORMAL
;
122 int weight
= wxNORMAL
;
126 wxStringTokenizer
tkz(str
, wxT(","));
128 while (tkz
.HasMoreTokens())
130 wxString token
= tkz
.GetNextToken();
134 pointSize
= StringToInt(token
);
135 #if defined(__WXGTK__) || defined(__WXMAC__)
143 family
= StringToInt(token
);
145 style
= StringToInt(token
);
147 weight
= StringToInt(token
);
149 underlined
= StringToInt(token
);
153 #if defined(__WXGTK__)
154 if (facename
== wxT("Arial"))
155 facename
= wxT("helvetica");
161 return wxFont(pointSize
, family
, style
, weight
, (underlined
!= 0), facename
);
165 // Get the index of the given named wxNotebook page
166 int apFindNotebookPage(wxNotebook
* notebook
, const wxString
& name
)
169 for (i
= 0; i
< (int)notebook
->GetPageCount(); i
++)
170 if (name
== notebook
->GetPageText(i
))
175 wxString
wxGetTempDir()
178 #if defined(__WXMAC__) && !defined(__DARWIN__)
179 dir
= wxMacFindFolder( (short) kOnSystemDisk
, kTemporaryFolderType
, kCreateFolder
) ;
181 wxString
dirEnv(wxGetenv(_T("TMP")));
185 wxString
envVar(wxGetenv(_T("TEMP")));
202 // Invoke app for file type
203 // Eventually we should allow the user to select an app.
204 bool apInvokeAppForFile(const wxString
& filename
)
206 wxString path
, file
, ext
;
207 wxSplitPath(filename
, & path
, & file
, & ext
);
209 wxFileType
*ft
= wxTheMimeTypesManager
->GetFileTypeFromExtension(ext
);
213 msg
.Printf(wxT("Sorry, could not determine what application to invoke for extension %s\nYou may need to edit your MIME types."),
215 wxMessageBox(msg
, wxT("Application Invocation"), wxICON_EXCLAMATION
|wxOK
);
220 ft
->GetOpenCommand(&cmd
, wxFileType::MessageParameters(filename
, wxEmptyString
));
223 return (wxExecute(cmd
, false) != 0);
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.
232 wxString
apFindAppPath(const wxString
& argv0
, const wxString
& cwd
, const wxString
& appVariableName
)
234 // Try appVariableName
235 if (!appVariableName
.empty())
237 wxString
strVar(wxGetenv(appVariableName
.c_str()));
242 if (wxIsAbsolutePath(argv0
))
243 return wxPathOnly(argv0
);
246 // Is it a relative path?
247 wxString
currentDir(cwd
);
248 if (currentDir
.Last() != wxFILE_SEP_PATH
)
249 currentDir
+= wxFILE_SEP_PATH
;
252 if (wxFileExists(currentDir
))
253 return wxPathOnly(currentDir
);
256 // OK, it's neither an absolute path nor a relative path.
260 pathList
.AddEnvList(wxT("PATH"));
261 wxString strPath
= pathList
.FindAbsoluteValidPath(argv0
);
262 if (!strPath
.empty())
263 return wxPathOnly(strPath
);
266 return wxEmptyString
;
269 // Adds a context-sensitive help button, for non-Windows platforms
270 void apAddContextHelpButton(wxWindow
*
271 #if defined(__WXGTK__) || defined(__WXMAC__)
277 #if defined(__WXGTK__) || defined(__WXMAC__)
283 #if defined(__WXGTK__) || defined(__WXMAC__)
289 #if defined(__WXGTK__) || defined(__WXMAC__)
292 WXUNUSED(sizerBorder
)
296 #if defined(__WXGTK__) || defined(__WXMAC__)
298 wxSize
buttonSize(20, 20);
300 wxSize buttonSize
= wxDefaultSize
;
302 wxButton
*contextButton
= new wxContextHelpButton( parent
, wxID_CONTEXT_HELP
,
303 wxDefaultPosition
, buttonSize
);
304 sizer
->Add( contextButton
, 0, sizerFlags
, sizerBorder
);
306 // Add a bit of space on the right, to allow for the dialog resizing
309 sizer
->Add(0, 0, 0, wxRIGHT
, 10);
312 contextButton
->SetHelpText(_("Invokes context-sensitive help for the clicked-on window."));
314 if (wxGetApp().UsingTooltips())
316 contextButton
->SetToolTip(_("Invokes context-sensitive help for the clicked-on window."));
322 // Get selected wxNotebook page
323 wxWindow
* apNotebookGetSelectedPage(wxNotebook
* notebook
)
325 int sel
= notebook
->GetSelection();
328 return notebook
->GetPage(sel
);
337 wxIconInfo::wxIconInfo(const wxString
& name
)
342 for (i
= 0; i
< wxMAX_ICON_STATES
; i
++)
346 int wxIconInfo::GetIconId(int state
, bool enabled
) const
348 wxASSERT ( state
< (wxMAX_ICON_STATES
* 2) );
349 wxASSERT ( state
< m_maxStates
);
351 return m_states
[state
* 2 + (enabled
? 0 : 1)];
354 void wxIconInfo::SetIconId(int state
, bool enabled
, int iconId
)
356 wxASSERT ( state
< (wxMAX_ICON_STATES
* 2) );
357 if (state
+1 > m_maxStates
)
358 m_maxStates
= state
+1;
360 m_states
[state
* 2 + (enabled
? 0 : 1)] = iconId
;
365 * Contains a list of wxIconInfos
368 wxIconTable::wxIconTable(wxImageList
* imageList
)
370 m_imageList
= imageList
;
371 WX_CLEAR_LIST(wxIconTable
,*this);
374 void wxIconTable::AppendInfo(wxIconInfo
* info
)
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
)
383 wxASSERT (m_imageList
!= NULL
);
385 wxIconInfo
* info
= FindInfo(name
);
388 info
= new wxIconInfo(name
);
391 info
->SetIconId(state
, enabled
, m_imageList
->Add(icon
));
395 wxIconInfo
* wxIconTable::FindInfo(const wxString
& name
) const
397 wxObjectList::compatibility_iterator node
= GetFirst();
400 wxIconInfo
* info
= (wxIconInfo
*) node
->GetData();
401 if (info
->GetName() == name
)
403 node
= node
->GetNext();
408 int wxIconTable::GetIconId(const wxString
& name
, int state
, bool enabled
) const
410 wxIconInfo
* info
= FindInfo(name
);
413 return info
->GetIconId(state
, enabled
);
416 bool wxIconTable::SetIconId(const wxString
& name
, int state
, bool enabled
, int iconId
)
418 wxIconInfo
* info
= FindInfo(name
);
421 info
->SetIconId(state
, enabled
, iconId
);
425 // Output stream operators
427 wxOutputStream
& operator <<(wxOutputStream
& stream
, const wxString
& s
)
429 stream
.Write(s
, s
.Length());
433 wxOutputStream
& operator <<(wxOutputStream
& stream
, long l
)
436 str
.Printf(_T("%ld"), l
);
437 return stream
<< str
;
440 wxOutputStream
& operator <<(wxOutputStream
& stream
, const wxChar c
)
443 str
.Printf(_T("%c"), c
);
444 return stream
<< str
;
447 // Convert characters to HTML equivalents
448 wxString
ctEscapeHTMLCharacters(const wxString
& str
)
451 size_t len
= str
.Length();
453 for (i
= 0; i
< len
; i
++)
455 wxChar c
= str
.GetChar(i
);
458 else if (c
== _T('>'))
460 else if (c
== _T('&'))
468 // Match 'matchText' against 'matchAgainst', optionally constraining to
470 bool ctMatchString(const wxString
& matchAgainst
, const wxString
& matchText
, bool wholeWordOnly
)
472 // Fast operation if not matching against whole words only
474 return (matchAgainst
.Find(matchText
) != wxNOT_FOUND
);
476 wxString
left(matchAgainst
);
477 bool success
= false;
478 int matchTextLen
= (int) matchText
.Length();
479 while (!success
&& !matchAgainst
.empty())
481 int pos
= left
.Find(matchText
);
482 if (pos
== wxNOT_FOUND
)
485 bool firstCharOK
= false;
486 bool lastCharOK
= false;
487 if (pos
== 0 || !wxIsalnum(left
[(size_t) (pos
-1)]))
490 if (((pos
+ matchTextLen
) == (int) left
.Length()) || !wxIsalnum(left
[(size_t) (pos
+ matchTextLen
)]))
493 if (firstCharOK
&& lastCharOK
)
496 left
= left
.Mid(pos
+1);