X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dee1a63ff52bfe4da396187f8438aa1a29796737..69659fd770f615210efac4b4fa741b3ad6223616:/src/common/utilscmn.cpp?ds=sidebyside diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index 0831170f37..21895181cb 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -62,7 +62,7 @@ #include #include -#if !defined(__WATCOMC__) +#if !wxONLY_WATCOM_EARLIER_THAN(1,4) #if !(defined(_MSC_VER) && (_MSC_VER > 800)) #include #endif @@ -72,7 +72,6 @@ #include "wx/colordlg.h" #include "wx/fontdlg.h" #include "wx/notebook.h" - #include "wx/frame.h" #include "wx/statusbr.h" #endif // wxUSE_GUI @@ -82,6 +81,13 @@ #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 @@ -90,6 +96,7 @@ #if defined(__WXMSW__) #include "wx/msw/private.h" #include "wx/msw/registry.h" + #include // needed for SHELLEXECUTEINFO #endif #if wxUSE_BASE @@ -102,97 +109,6 @@ // implementation // ============================================================================ -#if WXWIN_COMPATIBILITY_2_4 - -wxChar * -copystring (const wxChar *s) -{ - 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 - - return news; -} - -#endif // WXWIN_COMPATIBILITY_2_4 - -// ---------------------------------------------------------------------------- -// String <-> Number conversions (deprecated) -// ---------------------------------------------------------------------------- - -#if WXWIN_COMPATIBILITY_2_4 - -WXDLLIMPEXP_DATA_BASE(const wxChar *) wxFloatToStringStr = wxT("%.2f"); -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); -} - -void -StringToDouble (const wxChar *s, double *number) -{ - if (s && *s && number) - *number = wxStrtod (s, (wxChar **) NULL); -} - -wxChar * -FloatToString (float number, const wxChar *fmt) -{ - static wxChar buf[256]; - - wxSprintf (buf, fmt, number); - return buf; -} - -wxChar * -DoubleToString (double number, const wxChar *fmt) -{ - static wxChar buf[256]; - - wxSprintf (buf, fmt, number); - return buf; -} - -void -StringToInt (const wxChar *s, int *number) -{ - 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); -} - -wxChar * -IntToString (int number) -{ - static wxChar buf[20]; - - wxSprintf (buf, wxT("%d"), number); - return buf; -} - -wxChar * -LongToString (long number) -{ - static wxChar buf[20]; - - wxSprintf (buf, wxT("%ld"), number); - return buf; -} - -#endif // WXWIN_COMPATIBILITY_2_4 - // Array used in DecToHex conversion routine. static wxChar hexArray[] = wxT("0123456789ABCDEF"); @@ -224,6 +140,15 @@ void wxDecToHex(int dec, wxChar *buf) buf[2] = 0; } +// Convert decimal integer to 2 characters +void wxDecToHex(int dec, char* ch1, char* ch2) +{ + int firstDigit = (int)(dec/16.0); + int secondDigit = (int)(dec - (firstDigit*16.0)); + (*ch1) = (char) hexArray[firstDigit]; + (*ch2) = (char) hexArray[secondDigit]; +} + // Convert decimal integer to 2-character hex string wxString wxDecToHex(int dec) { @@ -280,20 +205,219 @@ wxString wxGetDataDir() return dir; } -int wxGetOsVersion(int *verMaj, int *verMin) +bool wxIsPlatformLittleEndian() +{ + // Are we little or big endian? This method is from Harbison & Steele. + union + { + long l; + char c[sizeof(long)]; + } u; + u.l = 1; + + return u.c[0] == 1; +} + + +/* + * Class to make it easier to specify platform-dependent values + */ + +wxArrayInt* wxPlatform::sm_customPlatforms = NULL; + +void wxPlatform::Copy(const wxPlatform& platform) +{ + m_longValue = platform.m_longValue; + m_doubleValue = platform.m_doubleValue; + m_stringValue = platform.m_stringValue; +} + +wxPlatform wxPlatform::If(int platform, long value) +{ + if (Is(platform)) + return wxPlatform(value); + else + return wxPlatform(); +} + +wxPlatform wxPlatform::IfNot(int platform, long value) +{ + if (!Is(platform)) + return wxPlatform(value); + else + return wxPlatform(); +} + +wxPlatform& wxPlatform::ElseIf(int platform, long value) { - // we want this function to work even if there is no wxApp - wxConsoleAppTraits traitsConsole; - wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL; - if ( ! traits ) - traits = &traitsConsole; - - wxToolkitInfo& info = traits->GetToolkitInfo(); - if ( verMaj ) - *verMaj = info.versionMajor; - if ( verMin ) - *verMin = info.versionMinor; - return info.os; + if (Is(platform)) + m_longValue = value; + return *this; +} + +wxPlatform& wxPlatform::ElseIfNot(int platform, long value) +{ + if (!Is(platform)) + m_longValue = value; + return *this; +} + +wxPlatform wxPlatform::If(int platform, double value) +{ + if (Is(platform)) + return wxPlatform(value); + else + return wxPlatform(); +} + +wxPlatform wxPlatform::IfNot(int platform, double value) +{ + if (!Is(platform)) + return wxPlatform(value); + else + return wxPlatform(); +} + +wxPlatform& wxPlatform::ElseIf(int platform, double value) +{ + if (Is(platform)) + m_doubleValue = value; + return *this; +} + +wxPlatform& wxPlatform::ElseIfNot(int platform, double value) +{ + if (!Is(platform)) + m_doubleValue = value; + return *this; +} + +wxPlatform wxPlatform::If(int platform, const wxString& value) +{ + if (Is(platform)) + return wxPlatform(value); + else + return wxPlatform(); +} + +wxPlatform wxPlatform::IfNot(int platform, const wxString& value) +{ + if (!Is(platform)) + return wxPlatform(value); + else + return wxPlatform(); +} + +wxPlatform& wxPlatform::ElseIf(int platform, const wxString& value) +{ + if (Is(platform)) + m_stringValue = value; + return *this; +} + +wxPlatform& wxPlatform::ElseIfNot(int platform, const wxString& value) +{ + if (!Is(platform)) + m_stringValue = value; + return *this; +} + +wxPlatform& wxPlatform::Else(long value) +{ + m_longValue = value; + return *this; +} + +wxPlatform& wxPlatform::Else(double value) +{ + m_doubleValue = value; + return *this; +} + +wxPlatform& wxPlatform::Else(const wxString& value) +{ + m_stringValue = value; + return *this; +} + +void wxPlatform::AddPlatform(int platform) +{ + if (!sm_customPlatforms) + sm_customPlatforms = new wxArrayInt; + sm_customPlatforms->Add(platform); +} + +void wxPlatform::ClearPlatforms() +{ + delete sm_customPlatforms; + sm_customPlatforms = NULL; +} + +/// Function for testing current platform + +bool wxPlatform::Is(int platform) +{ +#ifdef __WXMSW__ + if (platform == wxOS_WINDOWS) + return true; +#endif +#ifdef __WXWINCE__ + if (platform == wxOS_WINDOWS_CE) + return true; +#endif + +#if 0 + +// FIXME: wxWinPocketPC and wxWinSmartPhone are unknown symbols + +#if defined(__WXWINCE__) && defined(__POCKETPC__) + if (platform == wxWinPocketPC) + return true; +#endif +#if defined(__WXWINCE__) && defined(__SMARTPHONE__) + if (platform == wxWinSmartPhone) + return true; +#endif + +#endif + +#ifdef __WXGTK__ + if (platform == wxPORT_GTK) + return true; +#endif +#ifdef __WXMAC__ + if (platform == wxPORT_MAC) + return true; +#endif +#ifdef __WXX11__ + if (platform == wxPORT_X11) + return true; +#endif +#ifdef __UNIX__ + if (platform == wxOS_UNIX) + return true; +#endif +#ifdef __WXMGL__ + if (platform == wxPORT_MGL) + return true; +#endif +#ifdef __OS2__ + if (platform == wxOS_OS2) + return true; +#endif +#ifdef __WXPM__ + if (platform == wxPORT_PM) + return true; +#endif +#ifdef __WXCOCOA__ + if (platform == wxPORT_MAC) + return true; +#endif + + if (sm_customPlatforms && sm_customPlatforms->Index(platform) != wxNOT_FOUND) + return true; + + return false; } // ---------------------------------------------------------------------------- @@ -441,24 +565,27 @@ static bool ReadAll(wxInputStream *is, wxArrayString& output) wxTextInputStream tis(*is); - bool cont = true; - while ( cont ) + for ( ;; ) { wxString line = tis.ReadLine(); + + // check for EOF before other errors as it's not really an error if ( is->Eof() ) + { + // add the last, possibly incomplete, line + if ( !line.empty() ) + output.Add(line); break; + } + // any other error is fatal if ( !*is ) - { - cont = false; - } - else - { - output.Add(line); - } + return false; + + output.Add(line); } - return cont; + return true; } #endif // wxUSE_STREAMS @@ -512,25 +639,90 @@ long wxExecute(const wxString& command, return wxDoExecuteWithCapture(command, output, &error, flags); } +// ---------------------------------------------------------------------------- +// wxApp::Yield() wrappers for backwards compatibility +// ---------------------------------------------------------------------------- + +bool wxYield() +{ + return wxTheApp && wxTheApp->Yield(); +} + +bool wxYieldIfNeeded() +{ + return wxTheApp && wxTheApp->Yield(true); +} + +// Id generation +static long wxCurrentId = 100; + +long wxNewId() +{ + // skip the part of IDs space that contains hard-coded values: + if (wxCurrentId == wxID_LOWEST) + wxCurrentId = wxID_HIGHEST + 1; + + return wxCurrentId++; +} + +long +wxGetCurrentId(void) { return wxCurrentId; } + +void +wxRegisterId (long id) +{ + if (id >= wxCurrentId) + wxCurrentId = id + 1; +} + +#endif // wxUSE_BASE + +// ============================================================================ +// GUI-only functions from now on +// ============================================================================ + +#if wxUSE_GUI + // ---------------------------------------------------------------------------- // Launch default browser // ---------------------------------------------------------------------------- +#ifdef __WXCOCOA__ +// Private method in Objective-C++ source file. +bool wxCocoaLaunchDefaultBrowser(const wxString& url, int flags); +#endif + bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags) { wxUnusedVar(flags); // set the scheme of url to http if it does not have one + // RR: This doesn't work if the url is just a local path wxString url(urlOrig); - if ( !wxURI(url).HasScheme() ) - url.Prepend(wxT("http://")); + wxURI uri(url); + if ( !uri.HasScheme() ) + { + if (wxFileExists(urlOrig)) + url.Prepend( wxT("file://") ); + else + 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")); + wxRegKey key(wxRegKey::HKCR, uri.GetScheme() + _T("\\shell\\open")); + if ( !key.Exists() ) + { + // try default browser, it must be registered at least for http URLs + key.SetName(wxRegKey::HKCR, _T("http\\shell\\open")); + } + if ( key.Exists() ) { wxRegKey keyDDE(key, wxT("DDEExec")); @@ -583,6 +775,7 @@ bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags) } } } +#endif // wxUSE_IPC WinStruct sei; sei.lpFile = url.c_str(); @@ -604,94 +797,122 @@ bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags) #endif // __WXDEBUG__ return true; } -#elif wxUSE_MIMETYPE - // Non-windows way - wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension (_T("html")); - if ( ft ) +#elif defined(__WXCOCOA__) + // NOTE: We need to call the real implementation from src/cocoa/utils.mm + // because the code must use Objective-C features. + return wxCocoaLaunchDefaultBrowser(url, flags); +#elif defined(__WXMAC__) + OSStatus err; + ICInstance inst; + long int startSel; + long int endSel; + + err = ICStart(&inst, 'STKA'); // put your app creator code here + if (err == noErr) { - wxString mt; - ft->GetMimeType(&mt); - - wxString cmd; - bool ok = ft->GetOpenCommand(&cmd, wxFileType::MessageParameters(url)); - delete ft; - - if ( !ok || cmd.empty() ) +#if !TARGET_CARBON + err = ICFindConfigFile(inst, 0, NULL); +#endif + if (err == noErr) { - // fallback to checking for the BROWSER environment variable - cmd = wxGetenv(wxT("BROWSER")); - if ( !cmd.empty() ) - cmd << _T(' ') << url; + 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); } - - if ( !cmd.empty() && wxExecute(cmd) ) - return true; + ICStop(inst); + return true; } - else // no file type for html extension + else { - wxLogError(_T("No default application configured for HTML files.")); + wxLogDebug(wxT("ICStart error %d"), (int) err); + return false; } -#endif // !wxUSE_MIMETYPE && !__WXMSW__ +#else + // (non-Mac, non-MSW) - wxLogSysError(_T("Failed to open URL \"%s\" in default browser."), - url.c_str()); +#ifdef __UNIX__ - return false; -} + wxString desktop = wxTheApp->GetTraits()->GetDesktopEnvironment(); -// ---------------------------------------------------------------------------- -// wxApp::Yield() wrappers for backwards compatibility -// ---------------------------------------------------------------------------- + // GNOME and KDE desktops have some applications which should be always installed + // together with their main parts, which give us the + if (desktop == wxT("GNOME")) + { + wxArrayString errors; + wxArrayString output; -bool wxYield() -{ - return wxTheApp && wxTheApp->Yield(); -} + // gconf will tell us the path of the application to use as browser + long res = wxExecute( wxT("gconftool-2 --get /desktop/gnome/applications/browser/exec"), + output, errors, wxEXEC_NODISABLE ); + if (res >= 0 && errors.GetCount() == 0) + { + wxString cmd = output[0]; + cmd << _T(' ') << url; + if (wxExecute(cmd)) + return true; + } + } + else if (desktop == wxT("KDE")) + { + // kfmclient directly opens the given URL + if (wxExecute(wxT("kfmclient openURL ") + url)) + return true; + } +#endif -bool wxYieldIfNeeded() -{ - return wxTheApp && wxTheApp->Yield(true); -} + bool ok = false; + wxString cmd; -#endif // wxUSE_BASE +#if wxUSE_MIMETYPE + wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(_T("html")); + if ( ft ) + { + wxString mt; + ft->GetMimeType(&mt); -// ============================================================================ -// GUI-only functions from now on -// ============================================================================ + ok = ft->GetOpenCommand(&cmd, wxFileType::MessageParameters(url)); + delete ft; + } +#endif // wxUSE_MIMETYPE -#if wxUSE_GUI + if ( !ok || cmd.empty() ) + { + // fallback to checking for the BROWSER environment variable + cmd = wxGetenv(wxT("BROWSER")); + if ( !cmd.empty() ) + cmd << _T(' ') << url; + } -// Id generation -static long wxCurrentId = 100; + ok = ( !cmd.empty() && wxExecute(cmd) ); + if (ok) + return ok; -long wxNewId() -{ - // skip the part of IDs space that contains hard-coded values: - if (wxCurrentId == wxID_LOWEST) - wxCurrentId = wxID_HIGHEST + 1; + // no file type for HTML extension + wxLogError(_T("No default application configured for HTML files.")); - return wxCurrentId++; -} +#endif // !wxUSE_MIMETYPE && !__WXMSW__ -long -wxGetCurrentId(void) { return wxCurrentId; } + wxLogSysError(_T("Failed to open URL \"%s\" in default browser."), + url.c_str()); -void -wxRegisterId (long id) -{ - if (id >= wxCurrentId) - wxCurrentId = id + 1; + return false; } -#if wxUSE_MENUS - // ---------------------------------------------------------------------------- // Menu accelerators related functions // ---------------------------------------------------------------------------- wxChar *wxStripMenuCodes(const wxChar *in, wxChar *out) { +#if wxUSE_MENUS wxString s = wxMenuItem::GetLabelFromText(in); +#else + wxString str(in); + wxString s = wxStripMenuCodes(str); +#endif // wxUSE_MENUS if ( out ) { // go smash their buffer if it's not big enough - I love char * params @@ -699,7 +920,6 @@ wxChar *wxStripMenuCodes(const wxChar *in, wxChar *out) } else { - // MYcopystring - for easier search... out = new wxChar[s.length() + 1]; wxStrcpy(out, s.c_str()); } @@ -707,8 +927,10 @@ wxChar *wxStripMenuCodes(const wxChar *in, wxChar *out) return out; } -wxString wxStripMenuCodes(const wxString& in) +wxString wxStripMenuCodes(const wxString& in, int flags) { + wxASSERT_MSG( flags, _T("this is useless to call without any flags") ); + wxString out; size_t len = in.length(); @@ -717,7 +939,7 @@ wxString wxStripMenuCodes(const wxString& in) for ( size_t n = 0; n < len; n++ ) { wxChar ch = in[n]; - if ( ch == _T('&') ) + if ( (flags & wxStrip_Mnemonics) && ch == _T('&') ) { // skip it, it is used to introduce the accel char (or to quote // itself in which case it should still be skipped): note that it @@ -732,7 +954,7 @@ wxString wxStripMenuCodes(const wxString& in) ch = in[n]; } } - else if ( ch == _T('\t') ) + else if ( (flags & wxStrip_Accel) && ch == _T('\t') ) { // everything after TAB is accel string, exit the loop break; @@ -744,8 +966,6 @@ wxString wxStripMenuCodes(const wxString& in) return out; } -#endif // wxUSE_MENUS - // ---------------------------------------------------------------------------- // Window search functions // ---------------------------------------------------------------------------- @@ -780,12 +1000,12 @@ int wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString) { #if wxUSE_MENUS - wxMenuBar *menuBar = frame->GetMenuBar (); - if ( menuBar ) - return menuBar->FindMenuItem (menuString, itemString); + wxMenuBar *menuBar = frame->GetMenuBar (); + if ( menuBar ) + return menuBar->FindMenuItem (menuString, itemString); #endif // wxUSE_MENUS - return wxNOT_FOUND; + return wxNOT_FOUND; } // Try to find the deepest child that contains 'pt'. @@ -827,16 +1047,16 @@ wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt) wxPoint pos = win->GetPosition(); wxSize sz = win->GetSize(); - if (win->GetParent()) + if ( !win->IsTopLevel() && win->GetParent() ) { pos = win->GetParent()->ClientToScreen(pos); } wxRect rect(pos, sz); - if (rect.Inside(pt)) + if (rect.Contains(pt)) return win; - else - return NULL; + + return NULL; } wxWindow* wxGenericFindWindowAtPoint(const wxPoint& pt) @@ -951,7 +1171,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); @@ -962,6 +1182,8 @@ wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit) wxColour colRet; wxColourDialog dialog(parent, &data); + if (!caption.empty()) + dialog.SetTitle(caption); if ( dialog.ShowModal() == wxID_OK ) { colRet = dialog.GetColourData().GetColour(); @@ -975,7 +1197,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() ) @@ -985,6 +1207,8 @@ wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit) wxFont fontRet; wxFontDialog dialog(parent, data); + if (!caption.empty()) + dialog.SetTitle(caption); if ( dialog.ShowModal() == wxID_OK ) { fontRet = dialog.GetFontData().GetChosenFont();