]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/utilscmn.cpp
same as r57054 in 2.8
[wxWidgets.git] / src / common / utilscmn.cpp
index 2183825135b782f0c0c035dfcc387e4141518aa2..43826ac40f3c51375ed4de09649459cef5e9b187 100644 (file)
     #include "wx/statusbr.h"
 #endif // wxUSE_GUI
 
+#ifndef __WXPALMOS5__
 #ifndef __WXWINCE__
 #include <time.h>
 #else
 #include "wx/msw/wince/time.h"
 #endif
+#endif // ! __WXPALMOS5__
 
 #ifdef __WXMAC__
-#include "wx/mac/private.h"
-#ifndef __DARWIN__
-#include "InternetConfig.h"
-#endif
+#include "wx/osx/private.h"
 #endif
 
+#ifndef __WXPALMOS5__
 #if !defined(__MWERKS__) && !defined(__WXWINCE__)
     #include <sys/types.h>
     #include <sys/stat.h>
 #endif
+#endif // ! __WXPALMOS5__
 
 #if defined(__WXMSW__)
     #include "wx/msw/private.h"
     #include <shellapi.h> // needed for SHELLEXECUTEINFO
 #endif
 
+#if wxUSE_GUI && defined(__WXGTK__)
+    #include <gtk/gtk.h>    // for GTK_XXX_VERSION constants
+#endif
+
 #if wxUSE_BASE
 
 // ----------------------------------------------------------------------------
@@ -431,8 +436,7 @@ bool wxGetEmailAddress(wxChar *address, int maxSize)
     if ( !email )
         return false;
 
-    wxStrncpy(address, email, maxSize - 1);
-    address[maxSize - 1] = wxT('\0');
+    wxStrlcpy(address, email.t_str(), maxSize);
 
     return true;
 }
@@ -928,6 +932,50 @@ void wxQsort(void *const pbase, size_t total_elems,
 
 #if wxUSE_GUI
 
+// ----------------------------------------------------------------------------
+// Launch document with default app
+// ----------------------------------------------------------------------------
+
+bool wxLaunchDefaultApplication(const wxString& document, int flags)
+{
+    wxUnusedVar(flags);
+
+#ifdef __WXMAC__
+    static const char * const OPEN_CMD = "/usr/bin/open";
+    if ( wxFileExists(OPEN_CMD) &&
+            wxExecute(wxString(OPEN_CMD) + " " + document) )
+        return true;
+#elif defined(__UNIX__)
+    // Our best best is to use xdg-open from freedesktop.org cross-desktop
+    // compatibility suite xdg-utils
+    // (see http://portland.freedesktop.org/wiki/) -- this is installed on
+    // most modern distributions and may be tweaked by them to handle
+    // distribution specifics.
+    wxString path, xdg_open;
+    if ( wxGetEnv("PATH", &path) &&
+         wxFindFileInPath(&xdg_open, path, "xdg-open") )
+    {
+        if ( wxExecute(xdg_open + " " + document) )
+            return true;
+    }
+#elif defined(__WXMSW__)
+    WinStruct<SHELLEXECUTEINFO> sei;
+    sei.lpFile = document.wx_str();
+    sei.lpVerb = _T("open");
+    sei.nShow = SW_SHOWDEFAULT;
+
+    // avoid Windows message box in case of error for consistency with
+    // wxLaunchDefaultBrowser() even if don't show the error ourselves in this
+    // function
+    sei.fMask = SEE_MASK_FLAG_NO_UI;
+
+    if ( ::ShellExecuteEx(&sei) )
+        return true;
+#endif
+
+    return false;
+}
+
 // ----------------------------------------------------------------------------
 // Launch default browser
 // ----------------------------------------------------------------------------
@@ -937,7 +985,7 @@ void wxQsort(void *const pbase, size_t total_elems,
 bool wxCocoaLaunchDefaultBrowser(const wxString& url, int flags);
 #endif
 
-bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags)
+static bool DoLaunchDefaultBrowser(const wxString& urlOrig, int flags)
 {
     wxUnusedVar(flags);
 
@@ -973,13 +1021,14 @@ bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags)
             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
+                static const wxChar *TOPIC_OPEN_URL = wxT("WWW_OpenURL");
                 wxString ddeCmd;
-                bool ok = ddeTopic == wxT("WWW_OpenURL");
+                wxRegKey keyTopic(keyDDE, wxT("topic"));
+                bool ok = keyTopic.Exists() &&
+                            keyTopic.QueryDefaultValue() == TOPIC_OPEN_URL;
                 if ( ok )
                 {
                     ddeCmd = keyDDE.QueryDefaultValue();
@@ -992,7 +1041,7 @@ bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags)
                     // 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;
+                                        false /* only first occurrence */) == 1;
                 }
 
                 if ( ok )
@@ -1008,7 +1057,7 @@ bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags)
                     wxLogNull noLog;
 
                     const wxString ddeServer = wxRegKey(keyDDE, wxT("application"));
-                    if ( wxExecuteDDE(ddeServer, ddeTopic, ddeCmd) )
+                    if ( wxExecuteDDE(ddeServer, TOPIC_OPEN_URL, ddeCmd) )
                         return true;
 
                     // this is not necessarily an error: maybe browser is
@@ -1026,53 +1075,26 @@ bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags)
     sei.lpFile = url.c_str();
     sei.lpVerb = _T("open");
     sei.nShow = SW_SHOWNORMAL;
+    sei.fMask = SEE_MASK_FLAG_NO_UI; // we give error message ourselves
 
-    ::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__
+    if ( ::ShellExecuteEx(&sei) )
         return true;
-    }
 #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;
+#elif defined(__WXMAC__) && !defined(__WXOSX_IPHONE__)
+    wxCFRef< CFURLRef > curl( CFURLCreateWithString( kCFAllocatorDefault,
+            wxCFStringRef( url ), NULL ) );
+    OSStatus err = LSOpenCFURLRef( curl , NULL );
 
-    err = ICStart(&inst, 'STKA'); // put your app creator code here
     if (err == noErr)
     {
-#if !TARGET_CARBON
-        err = ICFindConfigFile(inst, 0, NULL);
-#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);
+        wxLogDebug(wxT("Browser Launch error %d"), (int) err);
         return false;
     }
 #else
@@ -1080,6 +1102,20 @@ bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags)
 
 #ifdef __UNIX__
 
+    // Our best best is to use xdg-open from freedesktop.org cross-desktop
+    // compatibility suite xdg-utils
+    // (see http://portland.freedesktop.org/wiki/) -- this is installed on
+    // most modern distributions and may be tweaked by them to handle
+    // distribution specifics. Only if that fails, try to find the right
+    // browser ourselves.
+    wxString path, xdg_open;
+    if ( wxGetEnv("PATH", &path) &&
+         wxFindFileInPath(&xdg_open, path, "xdg-open") )
+    {
+        if ( wxExecute(xdg_open + " " + url) )
+            return true;
+    }
+
     wxString desktop = wxTheApp->GetTraits()->GetDesktopEnvironment();
 
     // GNOME and KDE desktops have some applications which should be always installed
@@ -1136,16 +1172,25 @@ bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags)
         return ok;
 
     // no file type for HTML extension
-    wxLogError(_T("No default application configured for HTML files."));
+    wxLogError(_("No default application configured for HTML files."));
 
 #endif // !wxUSE_MIMETYPE && !__WXMSW__
 
-    wxLogSysError(_T("Failed to open URL \"%s\" in default browser."),
+    wxLogSysError(_("Failed to open URL \"%s\" in default browser."),
                   url.c_str());
 
     return false;
 }
 
+bool wxLaunchDefaultBrowser(const wxString& url, int flags)
+{
+    if ( flags & wxBROWSER_NOBUSYCURSOR )
+        return DoLaunchDefaultBrowser(url, flags);
+
+    wxBusyCursor bc;
+    return DoLaunchDefaultBrowser(url, flags);
+}
+
 // ----------------------------------------------------------------------------
 // Menu accelerators related functions
 // ----------------------------------------------------------------------------
@@ -1242,13 +1287,19 @@ wxFindWindowByName (const wxString& name, wxWindow * parent)
 
 // Returns menu item id or wxNOT_FOUND if none.
 int
-wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
+wxFindMenuItemId(wxFrame *frame,
+                 const wxString& menuString,
+                 const wxString& itemString)
 {
 #if wxUSE_MENUS
     wxMenuBar *menuBar = frame->GetMenuBar ();
     if ( menuBar )
         return menuBar->FindMenuItem (menuString, itemString);
-#endif // wxUSE_MENUS
+#else // !wxUSE_MENUS
+    wxUnusedVar(frame);
+    wxUnusedVar(menuString);
+    wxUnusedVar(itemString);
+#endif // wxUSE_MENUS/!wxUSE_MENUS
 
     return wxNOT_FOUND;
 }
@@ -1362,6 +1413,46 @@ int wxMessageBox(const wxString& message, const wxString& caption, long style,
     return wxCANCEL;
 }
 
+void wxInfoMessageBox(wxWindow* parent)
+{
+    // don't translate these strings, they're for diagnostics purposes only
+    wxString msg;
+    msg.Printf(_T("wxWidgets Library (%s port)\n")
+               _T("Version %d.%d.%d%s%s, compiled at %s %s\n")
+               _T("Runtime version of toolkit used is %d.%d.%s\n")
+               _T("Copyright (c) 1995-2008 wxWidgets team"),
+               wxPlatformInfo::Get().GetPortIdName().c_str(),
+               wxMAJOR_VERSION,
+               wxMINOR_VERSION,
+               wxRELEASE_NUMBER,
+#if wxUSE_UNICODE
+               L" (Unicode)",
+#else
+               wxEmptyString,
+#endif
+#ifdef __WXDEBUG__
+               _T(" Debug build"),
+#else
+               wxEmptyString,
+#endif
+               __TDATE__,
+               __TTIME__,
+               wxPlatformInfo::Get().GetToolkitMajorVersion(),
+               wxPlatformInfo::Get().GetToolkitMinorVersion(),
+#ifdef __WXGTK__
+               wxString::Format("\nThe compile-time GTK+ version is %d.%d.%d.",
+                                GTK_MAJOR_VERSION,
+                                GTK_MINOR_VERSION,
+                                GTK_MICRO_VERSION).c_str()
+#else
+               wxEmptyString
+#endif
+               );
+    wxMessageBox(msg, _T("wxWidgets information"),
+                 wxICON_INFORMATION | wxOK,
+                 parent);
+}
+
 #endif // wxUSE_MSGDLG
 
 #if wxUSE_TEXTDLG
@@ -1416,24 +1507,56 @@ wxString wxGetPasswordFromUser(const wxString& message,
 
 #if wxUSE_COLOURDLG
 
-wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit, const wxString& caption)
+wxColour wxGetColourFromUser(wxWindow *parent,
+                             const wxColour& colInit,
+                             const wxString& caption,
+                             wxColourData *ptrData)
 {
+    // contains serialized representation of wxColourData used the last time
+    // the dialog was shown: we want to reuse it the next time in order to show
+    // the same custom colours to the user (and we can't just have static
+    // wxColourData itself because it's a GUI object and so should be destroyed
+    // before GUI shutdown and doing it during static cleanup is too late)
+    static wxString s_strColourData;
+
     wxColourData data;
-    data.SetChooseFull(true);
-    if ( colInit.Ok() )
+    if ( !ptrData )
     {
-        data.SetColour((wxColour &)colInit); // const_cast
+        ptrData = &data;
+        if ( !s_strColourData.empty() )
+        {
+            if ( !data.FromString(s_strColourData) )
+            {
+                wxFAIL_MSG( "bug in wxColourData::FromString()?" );
+            }
+
+#ifdef __WXMSW__
+            // we don't get back the "choose full" flag value from the native
+            // dialog and so we can't preserve it between runs, so we decide to
+            // always use it as it seems better than not using it (user can
+            // just ignore the extra controls in the dialog but having to click
+            // a button each time to show them would be very annoying
+            data.SetChooseFull(true);
+#endif // __WXMSW__
+        }
+    }
+
+    if ( colInit.IsOk() )
+    {
+        ptrData->SetColour(colInit);
     }
 
     wxColour colRet;
-    wxColourDialog dialog(parent, &data);
+    wxColourDialog dialog(parent, ptrData);
     if (!caption.empty())
         dialog.SetTitle(caption);
     if ( dialog.ShowModal() == wxID_OK )
     {
-        colRet = dialog.GetColourData().GetColour();
+        *ptrData = dialog.GetColourData();
+        colRet = ptrData->GetColour();
+        s_strColourData = ptrData->ToString();
     }
-    //else: leave it invalid
+    //else: leave colRet invalid
 
     return colRet;
 }
@@ -1476,7 +1599,20 @@ void wxEnableTopLevelWindows(bool enable)
         node->GetData()->Enable(enable);
 }
 
+wxWindowDisabler::wxWindowDisabler(bool disable)
+{
+    m_disabled = disable;
+    if ( disable )
+        DoDisable();
+}
+
 wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip)
+{
+    m_disabled = true;
+    DoDisable(winToSkip);
+}
+
+void wxWindowDisabler::DoDisable(wxWindow *winToSkip)
 {
     // remember the top level windows which were already disabled, so that we
     // don't reenable them later
@@ -1508,6 +1644,9 @@ wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip)
 
 wxWindowDisabler::~wxWindowDisabler()
 {
+    if ( !m_disabled )
+        return;
+
     wxWindowList::compatibility_iterator node;
     for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
     {