1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Utility functions and classes
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
10 /////////////////////////////////////////////////////////////////////////////
13 // #pragma implementation
18 #include "wx/notebook.h"
19 #include "wx/splitter.h"
20 #include "wx/wfstream.h"
21 #include "wx/datstrm.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"
35 #include "wx/msw/winundef.h"
40 // Returns the image type, or -1, determined from the extension.
41 int apDetermineImageType(const wxString
& filename
)
43 wxString path
, name
, ext
;
45 wxSplitPath(filename
, & path
, & name
, & ext
);
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
;
64 // Convert a colour to a 6-digit hex string
65 wxString
apColourToHexString(const wxColour
& col
)
69 hex
+= wxDecToHex(col
.Red());
70 hex
+= wxDecToHex(col
.Green());
71 hex
+= wxDecToHex(col
.Blue());
76 // Convert 6-digit hex string to a colour
77 wxColour
apHexStringToColour(const wxString
& hex
)
82 r
= wxHexToDec(hex
.Mid(0, 2));
83 g
= wxHexToDec(hex
.Mid(2, 2));
84 b
= wxHexToDec(hex
.Mid(4, 2));
86 return wxColour(r
, g
, b
);
89 // Convert a wxFont to a string
90 wxString
apFontToString(const wxFont
& font
)
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());
100 // Convert a string to a wxFont
101 wxFont
apStringToFont(const wxString
& str
)
104 int family
= wxSWISS
;
105 int style
= wxNORMAL
;
106 int weight
= wxNORMAL
;
108 wxString
facename(wxT(""));
110 wxStringTokenizer
tkz(str
, wxT(","));
112 while (tkz
.HasMoreTokens())
114 wxString token
= tkz
.GetNextToken();
118 StringToInt(token
, & pointSize
);
119 #if defined(__WXGTK__) || defined(__WXMAC__)
127 StringToInt(token
, & family
);
129 StringToInt(token
, & style
);
131 StringToInt(token
, & weight
);
133 StringToInt(token
, & underlined
);
137 #if defined(__WXGTK__)
138 if (facename
== wxT("Arial"))
139 facename
= wxT("helvetica");
145 return wxFont(pointSize
, family
, style
, weight
, (underlined
!= 0), facename
);
149 // Get the index of the given named wxNotebook page
150 int apFindNotebookPage(wxNotebook
* notebook
, const wxString
& name
)
153 for (i
= 0; i
< notebook
->GetPageCount(); i
++)
154 if (name
== notebook
->GetPageText(i
))
163 void apViewHTMLFile(const wxString
& url
)
167 TCHAR szCmdName
[1024];
168 DWORD dwType
, dw
= sizeof(szCmdName
);
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
)
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
);
182 if(lRes
== ERROR_SUCCESS
)
185 wxFileType
*ft
= wxTheMimeTypesManager
->GetFileTypeFromExtension(wxT("html"));
188 wxLogError(_T("Impossible to determine the file type for extension html. Please edit your MIME types."));
193 bool ok
= ft
->GetOpenCommand(&cmd
,
194 wxFileType::MessageParameters(url
, _T("")));
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
);
205 ok
= (wxExecute(cmd
, FALSE
) != 0);
209 wxString
wxGetTempDir()
212 #if defined(__WXMAC__) && !defined(__DARWIN__)
213 dir
= wxMacFindFolder( (short) kOnSystemDisk
, kTemporaryFolderType
, kCreateFolder
) ;
215 dir
= wxGetenv(_T("TMP"));
218 dir
= wxGetenv(_T("TEMP"));
234 // Invoke app for file type
235 // Eventually we should allow the user to select an app.
236 bool apInvokeAppForFile(const wxString
& filename
)
238 wxString path
, file
, ext
;
239 wxSplitPath(filename
, & path
, & file
, & ext
);
241 wxFileType
*ft
= wxTheMimeTypesManager
->GetFileTypeFromExtension(ext
);
245 msg
.Printf(wxT("Sorry, could not determine what application to invoke for extension %s\nYou may need to edit your MIME types."),
247 wxMessageBox(msg
, wxT("Application Invocation"), wxICON_EXCLAMATION
|wxOK
);
252 bool ok
= ft
->GetOpenCommand(&cmd
,
253 wxFileType::MessageParameters(filename
, _T("")));
256 ok
= (wxExecute(cmd
, FALSE
) != 0);
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.
267 wxString
apFindAppPath(const wxString
& argv0
, const wxString
& cwd
, const wxString
& appVariableName
)
271 // Try appVariableName
272 if (!appVariableName
.IsEmpty())
274 str
= wxGetenv(appVariableName
);
279 if (wxIsAbsolutePath(argv0
))
280 return wxPathOnly(argv0
);
283 // Is it a relative path?
284 wxString
currentDir(cwd
);
285 if (currentDir
.Last() != wxFILE_SEP_PATH
)
286 currentDir
+= wxFILE_SEP_PATH
;
288 str
= currentDir
+ argv0
;
289 if (wxFileExists(str
))
290 return wxPathOnly(str
);
293 // OK, it's neither an absolute path nor a relative path.
297 pathList
.AddEnvList(wxT("PATH"));
298 str
= pathList
.FindAbsoluteValidPath(argv0
);
300 return wxPathOnly(str
);
303 return wxEmptyString
;
306 // Adds a context-sensitive help button, for non-Windows platforms
307 void apAddContextHelpButton(wxWindow
* parent
, wxSizer
* sizer
, int sizerFlags
, int sizerBorder
)
309 #if defined(__WXGTK__) || defined(__WXMAC__)
311 wxSize
buttonSize(20, 20);
313 wxSize
buttonSize(-1, -1);
315 wxButton
*contextButton
= new wxContextHelpButton( parent
, wxID_CONTEXT_HELP
,
316 wxDefaultPosition
, buttonSize
);
317 sizer
->Add( contextButton
, 0, sizerFlags
, sizerBorder
);
319 // Add a bit of space on the right, to allow for the dialog resizing
322 sizer
->Add(0, 0, 0, wxRIGHT
, 10);
325 contextButton
->SetHelpText(_("Invokes context-sensitive help for the clicked-on window."));
327 if (wxGetApp().UsingTooltips())
329 contextButton
->SetToolTip(_("Invokes context-sensitive help for the clicked-on window."));
335 // Get selected wxNotebook page
336 wxWindow
* apNotebookGetSelectedPage(wxNotebook
* notebook
)
338 int sel
= notebook
->GetSelection();
341 return notebook
->GetPage(sel
);
350 wxIconInfo::wxIconInfo(const wxString
& name
)
355 for (i
= 0; i
< wxMAX_ICON_STATES
; i
++)
359 int wxIconInfo::GetIconId(int state
, bool enabled
) const
361 wxASSERT ( state
< (wxMAX_ICON_STATES
* 2) );
362 wxASSERT ( state
< m_maxStates
);
364 return m_states
[state
* 2 + (enabled
? 0 : 1)];
367 void wxIconInfo::SetIconId(int state
, bool enabled
, int iconId
)
369 wxASSERT ( state
< (wxMAX_ICON_STATES
* 2) );
370 if (state
+1 > m_maxStates
)
371 m_maxStates
= state
+1;
373 m_states
[state
* 2 + (enabled
? 0 : 1)] = iconId
;
378 * Contains a list of wxIconInfos
381 wxIconTable::wxIconTable(wxImageList
* imageList
)
383 m_imageList
= imageList
;
384 DeleteContents(TRUE
);
387 void wxIconTable::AppendInfo(wxIconInfo
* info
)
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
)
396 wxASSERT (m_imageList
!= NULL
);
398 wxIconInfo
* info
= FindInfo(name
);
401 info
= new wxIconInfo(name
);
404 info
->SetIconId(state
, enabled
, m_imageList
->Add(icon
));
408 wxIconInfo
* wxIconTable::FindInfo(const wxString
& name
) const
410 wxNode
* node
= GetFirst();
413 wxIconInfo
* info
= (wxIconInfo
*) node
->GetData();
414 if (info
->GetName() == name
)
416 node
= node
->GetNext();
421 int wxIconTable::GetIconId(const wxString
& name
, int state
, bool enabled
) const
423 wxIconInfo
* info
= FindInfo(name
);
426 return info
->GetIconId(state
, enabled
);
429 bool wxIconTable::SetIconId(const wxString
& name
, int state
, bool enabled
, int iconId
)
431 wxIconInfo
* info
= FindInfo(name
);
434 info
->SetIconId(state
, enabled
, iconId
);
438 // Output stream operators
440 wxOutputStream
& operator <<(wxOutputStream
& stream
, const wxString
& s
)
442 stream
.Write(s
, s
.Length());
446 wxOutputStream
& operator <<(wxOutputStream
& stream
, long l
)
449 str
.Printf(_T("%ld"), l
);
450 return stream
<< str
;
453 wxOutputStream
& operator <<(wxOutputStream
& stream
, const char c
)
456 str
.Printf(_T("%c"), c
);
457 return stream
<< str
;
460 // Convert characters to HTML equivalents
461 wxString
ctEscapeHTMLCharacters(const wxString
& str
)
464 size_t len
= str
.Length();
466 for (i
= 0; i
< len
; i
++)
468 wxChar c
= str
.GetChar(i
);
471 else if (c
== _T('>'))
473 else if (c
== _T('&'))
481 // Match 'matchText' against 'matchAgainst', optionally constraining to
483 bool ctMatchString(const wxString
& matchAgainst
, const wxString
& matchText
, bool wholeWordOnly
)
485 // Fast operation if not matching against whole words only
487 return (matchAgainst
.Find(matchText
) != -1);
489 wxString
left(matchAgainst
);
490 bool success
= FALSE
;
492 int matchTextLen
= (int) matchText
.Length();
493 while (!success
&& !matchAgainst
.IsEmpty())
495 pos
= left
.Find(matchText
);
499 bool firstCharOK
= FALSE
;
500 bool lastCharOK
= FALSE
;
501 if (pos
== 0 || !wxIsalnum(left
[(size_t) (pos
-1)]))
504 if (((pos
+ matchTextLen
) == (int) left
.Length()) || !wxIsalnum(left
[(size_t) (pos
+ matchTextLen
)]))
507 if (firstCharOK
&& lastCharOK
)
510 left
= left
.Mid(pos
+1);