X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c838b68e832831f6032fc5ad57f5d0ba9aba7b8c..b93328d84228c097e125b0082b486da2aa0d1c22:/src/common/utilscmn.cpp diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index 5e25ae4024..c0d7e529c8 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: utilscmn.cpp +// Name: src/common/utilscmn.cpp // Purpose: Miscellaneous utility functions and classes // Author: Julian Smart // Modified by: @@ -17,17 +17,6 @@ // headers // ---------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) && !defined(__EMX__) -// Some older compilers (such as EMX) cannot handle -// #pragma interface/implementation correctly, iff -// #pragma implementation is used in _two_ translation -// units (as created by e.g. event.cpp compiled for -// libwx_base and event.cpp compiled for libwx_gui_core). -// So we must not use those pragmas for those compilers in -// such files. - #pragma implementation "utils.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -60,6 +49,9 @@ #include "wx/process.h" #include "wx/txtstrm.h" +#include "wx/uri.h" +#include "wx/mimetype.h" +#include "wx/config.h" #if defined(__WXWINCE__) && wxUSE_DATETIME #include "wx/datetime.h" @@ -90,13 +82,21 @@ #include "wx/msw/wince/time.h" #endif +#ifdef __WXMAC__ +#include "wx/mac/private.h" +#ifndef __DARWIN__ +#include "InternetConfig.h" +#endif +#endif + #if !defined(__MWERKS__) && !defined(__WXWINCE__) #include #include #endif -#if defined(__WXMSW__) && !defined(__PALMOS__) +#if defined(__WXMSW__) #include "wx/msw/private.h" + #include "wx/msw/registry.h" #endif #if wxUSE_BASE @@ -105,11 +105,6 @@ // common data // ---------------------------------------------------------------------------- -#if WXWIN_COMPATIBILITY_2_2 - const wxChar *wxInternalErrorStr = wxT("wxWidgets Internal Error"); - const wxChar *wxFatalErrorStr = wxT("wxWidgets Fatal Error"); -#endif // WXWIN_COMPATIBILITY_2_2 - // ============================================================================ // implementation // ============================================================================ @@ -119,13 +114,13 @@ wxChar * copystring (const wxChar *s) { - if (s == NULL) s = wxT(""); - size_t len = wxStrlen (s) + 1; + if (s == NULL) s = wxEmptyString; + size_t len = wxStrlen (s) + 1; - wxChar *news = new wxChar[len]; - memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest + wxChar *news = new wxChar[len]; + memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest - return news; + return news; } #endif // WXWIN_COMPATIBILITY_2_4 @@ -142,65 +137,65 @@ WXDLLIMPEXP_DATA_BASE(const wxChar *) wxDoubleToStringStr = wxT("%.2f"); void StringToFloat (const wxChar *s, float *number) { - if (s && *s && number) - *number = (float) wxStrtod (s, (wxChar **) NULL); + if (s && *s && number) + *number = (float) wxStrtod (s, (wxChar **) NULL); } void StringToDouble (const wxChar *s, double *number) { - if (s && *s && number) - *number = wxStrtod (s, (wxChar **) NULL); + if (s && *s && number) + *number = wxStrtod (s, (wxChar **) NULL); } wxChar * FloatToString (float number, const wxChar *fmt) { - static wxChar buf[256]; + static wxChar buf[256]; - wxSprintf (buf, fmt, number); - return buf; + wxSprintf (buf, fmt, number); + return buf; } wxChar * DoubleToString (double number, const wxChar *fmt) { - static wxChar buf[256]; + static wxChar buf[256]; - wxSprintf (buf, fmt, number); - return buf; + wxSprintf (buf, fmt, number); + return buf; } void StringToInt (const wxChar *s, int *number) { - if (s && *s && number) - *number = (int) wxStrtol (s, (wxChar **) NULL, 10); + if (s && *s && number) + *number = (int) wxStrtol (s, (wxChar **) NULL, 10); } void StringToLong (const wxChar *s, long *number) { - if (s && *s && number) - *number = wxStrtol (s, (wxChar **) NULL, 10); + if (s && *s && number) + *number = wxStrtol (s, (wxChar **) NULL, 10); } wxChar * IntToString (int number) { - static wxChar buf[20]; + static wxChar buf[20]; - wxSprintf (buf, wxT("%d"), number); - return buf; + wxSprintf (buf, wxT("%d"), number); + return buf; } wxChar * LongToString (long number) { - static wxChar buf[20]; + static wxChar buf[20]; - wxSprintf (buf, wxT("%ld"), number); - return buf; + wxSprintf (buf, wxT("%ld"), number); + return buf; } #endif // WXWIN_COMPATIBILITY_2_4 @@ -211,29 +206,29 @@ static wxChar hexArray[] = wxT("0123456789ABCDEF"); // Convert 2-digit hex number to decimal int wxHexToDec(const wxString& buf) { - int firstDigit, secondDigit; + int firstDigit, secondDigit; - if (buf.GetChar(0) >= wxT('A')) - firstDigit = buf.GetChar(0) - wxT('A') + 10; - else - firstDigit = buf.GetChar(0) - wxT('0'); + if (buf.GetChar(0) >= wxT('A')) + firstDigit = buf.GetChar(0) - wxT('A') + 10; + else + firstDigit = buf.GetChar(0) - wxT('0'); - if (buf.GetChar(1) >= wxT('A')) - secondDigit = buf.GetChar(1) - wxT('A') + 10; - else - secondDigit = buf.GetChar(1) - wxT('0'); + if (buf.GetChar(1) >= wxT('A')) + secondDigit = buf.GetChar(1) - wxT('A') + 10; + else + secondDigit = buf.GetChar(1) - wxT('0'); - return (firstDigit & 0xF) * 16 + (secondDigit & 0xF ); + return (firstDigit & 0xF) * 16 + (secondDigit & 0xF ); } // Convert decimal integer to 2-character hex string void wxDecToHex(int dec, wxChar *buf) { - int firstDigit = (int)(dec/16.0); - int secondDigit = (int)(dec - (firstDigit*16.0)); - buf[0] = hexArray[firstDigit]; - buf[1] = hexArray[secondDigit]; - buf[2] = 0; + int firstDigit = (int)(dec/16.0); + int secondDigit = (int)(dec - (firstDigit*16.0)); + buf[0] = hexArray[firstDigit]; + buf[1] = hexArray[secondDigit]; + buf[2] = 0; } // Convert decimal integer to 2-character hex string @@ -281,7 +276,7 @@ const wxChar *wxGetInstallPrefix() #ifdef wxINSTALL_PREFIX return wxT(wxINSTALL_PREFIX); #else - return wxT(""); + return wxEmptyString; #endif } @@ -330,10 +325,10 @@ wxString wxGetEmailAddress() wxString email; wxString host = wxGetFullHostName(); - if ( !host.IsEmpty() ) + if ( !host.empty() ) { wxString user = wxGetUserId(); - if ( !user.IsEmpty() ) + if ( !user.empty() ) { email << user << wxT('@') << host; } @@ -479,13 +474,14 @@ static bool ReadAll(wxInputStream *is, wxArrayString& output) // public versions of wxExecute() below static long wxDoExecuteWithCapture(const wxString& command, wxArrayString& output, - wxArrayString* error) + wxArrayString* error, + int flags) { // create a wxProcess which will capture the output wxProcess *process = new wxProcess; process->Redirect(); - long rc = wxExecute(command, wxEXEC_SYNC, process); + long rc = wxExecute(command, wxEXEC_SYNC | flags, process); #if wxUSE_STREAMS if ( rc != -1 ) @@ -510,16 +506,175 @@ static long wxDoExecuteWithCapture(const wxString& command, return rc; } -long wxExecute(const wxString& command, wxArrayString& output) +long wxExecute(const wxString& command, wxArrayString& output, int flags) { - return wxDoExecuteWithCapture(command, output, NULL); + return wxDoExecuteWithCapture(command, output, NULL, flags); } long wxExecute(const wxString& command, wxArrayString& output, - wxArrayString& error) + wxArrayString& error, + int flags) { - return wxDoExecuteWithCapture(command, output, &error); + return wxDoExecuteWithCapture(command, output, &error, flags); +} + +// ---------------------------------------------------------------------------- +// Launch default browser +// ---------------------------------------------------------------------------- + +bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags) +{ + wxUnusedVar(flags); + + // set the scheme of url to http if it does not have one + wxString url(urlOrig); + if ( !wxURI(url).HasScheme() ) + url.Prepend(wxT("http://")); + +#if defined(__WXMSW__) + +#if wxUSE_IPC + if ( flags & wxBROWSER_NEW_WINDOW ) + { + // ShellExecuteEx() opens the URL in an existing window by default so + // we can't use it if we need a new window + wxRegKey key(wxRegKey::HKCR, url.BeforeFirst(':') + _T("\\shell\\open")); + if ( key.Exists() ) + { + wxRegKey keyDDE(key, wxT("DDEExec")); + if ( keyDDE.Exists() ) + { + const wxString ddeTopic = wxRegKey(keyDDE, wxT("topic")); + + // we only know the syntax of WWW_OpenURL DDE request for IE, + // optimistically assume that all other browsers are compatible + // with it + wxString ddeCmd; + bool ok = ddeTopic == wxT("WWW_OpenURL"); + if ( ok ) + { + ddeCmd = keyDDE.QueryDefaultValue(); + ok = !ddeCmd.empty(); + } + + if ( ok ) + { + // for WWW_OpenURL, the index of the window to open the URL + // in is -1 (meaning "current") by default, replace it with + // 0 which means "new" (see KB article 160957) + ok = ddeCmd.Replace(wxT("-1"), wxT("0"), + false /* only first occurence */) == 1; + } + + if ( ok ) + { + // and also replace the parameters: the topic should + // contain a placeholder for the URL + ok = ddeCmd.Replace(wxT("%1"), url, false) == 1; + } + + if ( ok ) + { + // try to send it the DDE request now but ignore the errors + wxLogNull noLog; + + const wxString ddeServer = wxRegKey(keyDDE, wxT("application")); + if ( wxExecuteDDE(ddeServer, ddeTopic, ddeCmd) ) + return true; + + // this is not necessarily an error: maybe browser is + // simply not running, but no matter, in any case we're + // going to launch it using ShellExecuteEx() below now and + // we shouldn't try to open a new window if we open a new + // browser anyhow + } + } + } + } +#endif // wxUSE_IPC + + WinStruct sei; + sei.lpFile = url.c_str(); + sei.lpVerb = _T("open"); + sei.nShow = SW_SHOWNORMAL; + + ::ShellExecuteEx(&sei); + + const int nResult = (int) sei.hInstApp; + + // Firefox returns file not found for some reason, so make an exception + // for it + if ( nResult > 32 || nResult == SE_ERR_FNF ) + { +#ifdef __WXDEBUG__ + // Log something if SE_ERR_FNF happens + if ( nResult == SE_ERR_FNF ) + wxLogDebug(wxT("SE_ERR_FNF from ShellExecute -- maybe FireFox?")); +#endif // __WXDEBUG__ + return true; + } +#elif defined(__WXMAC__) + OSStatus err; + ICInstance inst; + SInt32 startSel; + SInt32 endSel; + + err = ICStart(&inst, 'STKA'); // put your app creator code here + if (err == noErr) { +#if !TARGET_CARBON + err = ICFindConfigFile(inst, 0, nil); +#endif + if (err == noErr) + { + ConstStr255Param hint = 0; + startSel = 0; + endSel = url.Length(); + err = ICLaunchURL(inst, hint, url.fn_str(), endSel, &startSel, &endSel); + if (err != noErr) + wxLogDebug(wxT("ICLaunchURL error %d"), (int) err); + } + ICStop(inst); + return true; + } + else + { + wxLogDebug(wxT("ICStart error %d"), (int) err); + return false; + } +#elif wxUSE_MIMETYPE + // Non-windows way + wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension (_T("html")); + if ( ft ) + { + wxString mt; + ft->GetMimeType(&mt); + + wxString cmd; + bool ok = ft->GetOpenCommand(&cmd, wxFileType::MessageParameters(url)); + delete ft; + + if ( !ok || cmd.empty() ) + { + // fallback to checking for the BROWSER environment variable + cmd = wxGetenv(wxT("BROWSER")); + if ( !cmd.empty() ) + cmd << _T(' ') << url; + } + + if ( !cmd.empty() && wxExecute(cmd) ) + return true; + } + else // no file type for html extension + { + wxLogError(_T("No default application configured for HTML files.")); + } +#endif // !wxUSE_MIMETYPE && !__WXMSW__ + + wxLogSysError(_T("Failed to open URL \"%s\" in default browser."), + url.c_str()); + + return false; } // ---------------------------------------------------------------------------- @@ -809,11 +964,19 @@ wxString wxGetTextFromUser(const wxString& message, const wxString& caption, wxString wxGetPasswordFromUser(const wxString& message, const wxString& caption, const wxString& defaultValue, - wxWindow *parent) + wxWindow *parent, + wxCoord x, wxCoord y, bool centre ) { wxString str; - wxTextEntryDialog dialog(parent, message, caption, defaultValue, - wxOK | wxCANCEL | wxTE_PASSWORD); + long style = wxTextEntryDialogStyle; + + if (centre) + style |= wxCENTRE; + else + style &= ~wxCENTRE; + + wxPasswordEntryDialog dialog(parent, message, caption, defaultValue, + style, wxPoint(x, y)); if ( dialog.ShowModal() == wxID_OK ) { str = dialog.GetValue(); @@ -826,7 +989,7 @@ wxString wxGetPasswordFromUser(const wxString& message, #if wxUSE_COLOURDLG -wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit) +wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit, const wxString& caption) { wxColourData data; data.SetChooseFull(true); @@ -837,6 +1000,8 @@ wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit) wxColour colRet; wxColourDialog dialog(parent, &data); + if (!caption.IsEmpty()) + dialog.SetTitle(caption); if ( dialog.ShowModal() == wxID_OK ) { colRet = dialog.GetColourData().GetColour(); @@ -850,7 +1015,7 @@ wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit) #if wxUSE_FONTDLG -wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit) +wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit, const wxString& caption) { wxFontData data; if ( fontInit.Ok() ) @@ -860,6 +1025,8 @@ wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit) wxFont fontRet; wxFontDialog dialog(parent, data); + if (!caption.IsEmpty()) + dialog.SetTitle(caption); if ( dialog.ShowModal() == wxID_OK ) { fontRet = dialog.GetFontData().GetChosenFont(); @@ -954,4 +1121,3 @@ bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) ) #endif // !wxGTK #endif // wxUSE_GUI -