X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fe5f448f431631c6963e52926e24dfe2901fa71a..6c2cd2a2116c5eff1646e0acb7cad2c887300300:/src/common/utilscmn.cpp diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index c48cd24201..2e8c64bfe6 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -75,11 +75,13 @@ #include "wx/statusbr.h" #endif // wxUSE_GUI +#ifndef __WXPALMOS5__ #ifndef __WXWINCE__ #include #else #include "wx/msw/wince/time.h" #endif +#endif // ! __WXPALMOS5__ #ifdef __WXMAC__ #include "wx/mac/private.h" @@ -88,10 +90,12 @@ #endif #endif +#ifndef __WXPALMOS5__ #if !defined(__MWERKS__) && !defined(__WXWINCE__) #include #include #endif +#endif // ! __WXPALMOS5__ #if defined(__WXMSW__) #include "wx/msw/private.h" @@ -99,6 +103,10 @@ #include // needed for SHELLEXECUTEINFO #endif +#if wxUSE_GUI && defined(__WXGTK__) + #include // for GTK_XXX_VERSION constants +#endif + #if wxUSE_BASE // ---------------------------------------------------------------------------- @@ -681,13 +689,13 @@ wxRegisterId (long id) /* This file is part of the GNU C Library. Written by Douglas C. Schmidt (schmidt@ics.uci.edu). - + Douglas Schmidt kindly gave permission to relicence the code under the wxWindows licence: - + From: "Douglas C. Schmidt" To: Robert Roebling -Subject: Re: qsort licence +Subject: Re: qsort licence Date: Mon, 23 Jul 2007 03:44:25 -0500 Sender: schmidt@dre.vanderbilt.edu Message-Id: <20070723084426.64F511000A8@tango.dre.vanderbilt.edu> @@ -705,17 +713,17 @@ Thanks, /* Byte-wise swap two items of size SIZE. */ -#define SWAP(a, b, size) \ - do \ - { \ - register size_t __size = (size); \ - register char *__a = (a), *__b = (b); \ - do \ - { \ - char __tmp = *__a; \ - *__a++ = *__b; \ - *__b++ = __tmp; \ - } while (--__size > 0); \ +#define SWAP(a, b, size) \ + do \ + { \ + register size_t __size = (size); \ + register char *__a = (a), *__b = (b); \ + do \ + { \ + char __tmp = *__a; \ + *__a++ = *__b; \ + *__b++ = __tmp; \ + } while (--__size > 0); \ } while (0) /* Discontinue quicksort algorithm when partition gets below this size. @@ -730,10 +738,10 @@ typedef struct } stack_node; /* The next 4 #defines implement a very fast in-line stack abstraction. */ -#define STACK_SIZE (8 * sizeof(unsigned long int)) -#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) -#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) -#define STACK_NOT_EMPTY (stack < top) +#define STACK_SIZE (8 * sizeof(unsigned long int)) +#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) +#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) +#define STACK_NOT_EMPTY (stack < top) /* Order size using quicksort. This implementation incorporates @@ -760,7 +768,7 @@ typedef struct stack size is needed (actually O(1) in this case)! */ void wxQsort(void *const pbase, size_t total_elems, - size_t size, CMPFUNCDATA cmp, const void* user_data) + size_t size, CMPFUNCDATA cmp, const void* user_data) { register char *base_ptr = (char *) pbase; const size_t max_thresh = MAX_THRESH * size; @@ -783,54 +791,54 @@ void wxQsort(void *const pbase, size_t total_elems, char *left_ptr; char *right_ptr; - /* Select median value from among LO, MID, and HI. Rearrange - LO and HI so the three values are sorted. This lowers the - probability of picking a pathological pivot value and - skips a comparison for both the LEFT_PTR and RIGHT_PTR. */ - - char *mid = lo + size * ((hi - lo) / size >> 1); - - if ((*cmp) ((void *) mid, (void *) lo, user_data) < 0) - SWAP (mid, lo, size); - if ((*cmp) ((void *) hi, (void *) mid, user_data) < 0) - SWAP (mid, hi, size); - else - goto jump_over; - if ((*cmp) ((void *) mid, (void *) lo, user_data) < 0) - SWAP (mid, lo, size); - jump_over:; - left_ptr = lo + size; - right_ptr = hi - size; - - /* Here's the famous ``collapse the walls'' section of quicksort. - Gotta like those tight inner loops! They are the main reason - that this algorithm runs much faster than others. */ - do - { - while ((*cmp) ((void *) left_ptr, (void *) mid, user_data) < 0) - left_ptr += size; - - while ((*cmp) ((void *) mid, (void *) right_ptr, user_data) < 0) - right_ptr -= size; - - if (left_ptr < right_ptr) - { - SWAP (left_ptr, right_ptr, size); - if (mid == left_ptr) - mid = right_ptr; - else if (mid == right_ptr) - mid = left_ptr; - left_ptr += size; - right_ptr -= size; - } - else if (left_ptr == right_ptr) - { - left_ptr += size; - right_ptr -= size; - break; - } - } - while (left_ptr <= right_ptr); + /* Select median value from among LO, MID, and HI. Rearrange + LO and HI so the three values are sorted. This lowers the + probability of picking a pathological pivot value and + skips a comparison for both the LEFT_PTR and RIGHT_PTR. */ + + char *mid = lo + size * ((hi - lo) / size >> 1); + + if ((*cmp) ((void *) mid, (void *) lo, user_data) < 0) + SWAP (mid, lo, size); + if ((*cmp) ((void *) hi, (void *) mid, user_data) < 0) + SWAP (mid, hi, size); + else + goto jump_over; + if ((*cmp) ((void *) mid, (void *) lo, user_data) < 0) + SWAP (mid, lo, size); + jump_over:; + left_ptr = lo + size; + right_ptr = hi - size; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do + { + while ((*cmp) ((void *) left_ptr, (void *) mid, user_data) < 0) + left_ptr += size; + + while ((*cmp) ((void *) mid, (void *) right_ptr, user_data) < 0) + right_ptr -= size; + + if (left_ptr < right_ptr) + { + SWAP (left_ptr, right_ptr, size); + if (mid == left_ptr) + mid = right_ptr; + else if (mid == right_ptr) + mid = left_ptr; + left_ptr += size; + right_ptr -= size; + } + else if (left_ptr == right_ptr) + { + left_ptr += size; + right_ptr -= size; + break; + } + } + while (left_ptr <= right_ptr); /* Set up pointers for next iteration. First determine whether left and right partitions are below the threshold size. If so, @@ -840,24 +848,24 @@ void wxQsort(void *const pbase, size_t total_elems, if ((size_t) (right_ptr - lo) <= max_thresh) { if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore both small partitions. */ + /* Ignore both small partitions. */ POP (lo, hi); else - /* Ignore small left partition. */ + /* Ignore small left partition. */ lo = left_ptr; } else if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore small right partition. */ + /* Ignore small right partition. */ hi = right_ptr; else if ((right_ptr - lo) > (hi - left_ptr)) { - /* Push larger left partition indices. */ + /* Push larger left partition indices. */ PUSH (lo, right_ptr); lo = left_ptr; } else { - /* Push larger right partition indices. */ + /* Push larger right partition indices. */ PUSH (left_ptr, hi); hi = right_ptr; } @@ -870,12 +878,12 @@ void wxQsort(void *const pbase, size_t total_elems, of the array to sort, and END_PTR points at the very last element in the array (*not* one beyond it!). */ -#define min(x, y) ((x) < (y) ? (x) : (y)) - { char *const end_ptr = &base_ptr[size * (total_elems - 1)]; char *tmp_ptr = base_ptr; - char *thresh = min(end_ptr, base_ptr + max_thresh); + char *thresh = base_ptr + max_thresh; + if ( thresh > end_ptr ) + thresh = end_ptr; register char *run_ptr; /* Find smallest element in first threshold and place it at the @@ -894,17 +902,17 @@ void wxQsort(void *const pbase, size_t total_elems, run_ptr = base_ptr + size; while ((run_ptr += size) <= end_ptr) { - tmp_ptr = run_ptr - size; - while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, user_data) < 0) - tmp_ptr -= size; + tmp_ptr = run_ptr - size; + while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, user_data) < 0) + tmp_ptr -= size; - tmp_ptr += size; + tmp_ptr += size; if (tmp_ptr != run_ptr) { char *trav; - trav = run_ptr + size; - while (--trav >= run_ptr) + trav = run_ptr + size; + while (--trav >= run_ptr) { char c = *trav; char *hi, *lo; @@ -1029,7 +1037,7 @@ bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags) ::ShellExecuteEx(&sei); - const int nResult = (int) sei.hInstApp; + const INT_PTR nResult = (INT_PTR)sei.hInstApp; // Firefox returns file not found for some reason, so make an exception // for it @@ -1047,32 +1055,17 @@ bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags) // 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; + 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 +1073,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,11 +1143,11 @@ 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; @@ -1153,7 +1160,7 @@ bool wxLaunchDefaultBrowser(const wxString& urlOrig, int flags) wxChar *wxStripMenuCodes(const wxChar *in, wxChar *out) { #if wxUSE_MENUS - wxString s = wxMenuItem::GetLabelFromText(in); + wxString s = wxMenuItem::GetLabelText(in); #else wxString str(in); wxString s = wxStripMenuCodes(str); @@ -1242,13 +1249,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 +1375,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-2007 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 +1469,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 ) + { + 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() ) { - data.SetColour((wxColour &)colInit); // const_cast + 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 +1561,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 +1606,9 @@ wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip) wxWindowDisabler::~wxWindowDisabler() { + if ( !m_disabled ) + return; + wxWindowList::compatibility_iterator node; for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) {