X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7e72d7aaa20a10f80e3b8f906826c5e40584a607..6342bd1ab36c1957684c00d408d09fba65d33db6:/src/common/utilscmn.cpp?ds=sidebyside diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index bab380b7a8..49c15f3284 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -48,6 +48,11 @@ #endif // wxUSE_GUI #endif // WX_PRECOMP +#ifndef __WIN16__ +#include "wx/process.h" +#include "wx/txtstrm.h" +#endif + #include #include #include @@ -59,6 +64,10 @@ #endif #endif +#if wxUSE_GUI + #include "wx/colordlg.h" +#endif // wxUSE_GUI + #include #ifndef __MWERKS__ @@ -70,16 +79,8 @@ #include #endif -// Pattern matching code. (FIXME) -// Yes, this path is deliberate (for Borland compilation) -#ifdef wx_mac /* MATTHEW: [5] Mac doesn't like paths with "/" */ -#include "glob.inc" -#else -#include "../common/glob.inc" -#endif - #ifdef __WXMSW__ - #include "windows.h" + #include "wx/msw/private.h" #endif // ---------------------------------------------------------------------------- @@ -497,23 +498,32 @@ wxAcceleratorEntry *wxGetAccelFromString(const wxString& label) keyCode = WXK_F1 + n - 1; } else { -#if 0 // this is not supported by GTK+, apparently // several special cases current.MakeUpper(); if ( current == wxT("DEL") ) { - keyCode = VK_DELETE; + keyCode = WXK_DELETE; + } + else if ( current == wxT("DELETE") ) { + keyCode = WXK_DELETE; } + else if ( current == wxT("INS") ) { + keyCode = WXK_INSERT; + } + else if ( current == wxT("INSERT") ) { + keyCode = WXK_INSERT; + } +#if 0 else if ( current == wxT("PGUP") ) { keyCode = VK_PRIOR; } else if ( current == wxT("PGDN") ) { keyCode = VK_NEXT; } +#endif else -#endif // 0 { - wxLogDebug(wxT("Unrecognized accel key '%s', accel " - "string ignored."), current.c_str()); + wxLogDebug(wxT("Unrecognized accel key '%s', accel string ignored."), + current.c_str()); } } } @@ -873,19 +883,17 @@ int wxMessageBox(const wxString& message, const wxString& caption, long style, { case wxID_OK: return wxOK; - break; case wxID_YES: return wxYES; - break; case wxID_NO: return wxNO; - break; - default: case wxID_CANCEL: return wxCANCEL; - break; } - return ans; + + wxFAIL_MSG( _T("unexpected return code from wxMessageDialog") ); + + return wxCANCEL; } #if wxUSE_TEXTDLG @@ -893,14 +901,58 @@ wxString wxGetTextFromUser(const wxString& message, const wxString& caption, const wxString& defaultValue, wxWindow *parent, int x, int y, bool WXUNUSED(centre) ) { + wxString str; wxTextEntryDialog dialog(parent, message, caption, defaultValue, wxOK|wxCANCEL, wxPoint(x, y)); if (dialog.ShowModal() == wxID_OK) - return dialog.GetValue(); - else - return wxString(""); + { + str = dialog.GetValue(); + } + + return str; +} + +wxString wxGetPasswordFromUser(const wxString& message, + const wxString& caption, + const wxString& defaultValue, + wxWindow *parent) +{ + wxString str; + wxTextEntryDialog dialog(parent, message, caption, defaultValue, + wxOK | wxCANCEL | wxTE_PASSWORD); + if ( dialog.ShowModal() == wxID_OK ) + { + str = dialog.GetValue(); + } + + return str; } + #endif // wxUSE_TEXTDLG +wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit) +{ + wxColourData data; + data.SetChooseFull(TRUE); + if ( colInit.Ok() ) + { + data.SetColour((wxColour &)colInit); // const_cast + } + + wxColour colRet; + wxColourDialog dialog(parent, &data); + if ( dialog.ShowModal() == wxID_OK ) + { + colRet = dialog.GetColourData().GetColour(); + } + //else: leave it invalid + + return colRet; +} + +// ---------------------------------------------------------------------------- +// missing C RTL functions (FIXME shouldn't be here at all) +// ---------------------------------------------------------------------------- + #ifdef __MWERKS__ char *strdup(const char *s) { @@ -914,35 +966,117 @@ int isascii( int c ) #endif // __MWERKS__ // ---------------------------------------------------------------------------- -// misc functions +// wxSafeYield and supporting functions // ---------------------------------------------------------------------------- void wxEnableTopLevelWindows(bool enable) { - wxWindowList::Node *node; - for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) - node->GetData()->Enable(enable); + wxWindowList::Node *node; + for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) + node->GetData()->Enable(enable); } -// Yield to other apps/messages and disable user input +wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip) +{ +#ifdef __WXMSW__ +#ifdef __WIN32__ + // and the top level window too + HWND hwndFG = ::GetForegroundWindow(); + m_winTop = hwndFG ? wxFindWinFromHandle((WXHWND)hwndFG) : (wxWindow *)NULL; +#else + HWND hwndFG = ::GetTopWindow(0); + m_winTop = hwndFG ? wxFindWinFromHandle((WXHWND)hwndFG) : (wxWindow *)NULL; +#endif +#endif // MSW + + // remember the top level windows which were already disabled, so that we + // don't reenable them later + m_winDisabled = NULL; + + wxWindowList::Node *node; + for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) + { + wxWindow *winTop = node->GetData(); + if ( winTop == winToSkip ) + continue; + + if ( winTop->IsEnabled() ) + { + winTop->Disable(); + } + else + { + if ( !m_winDisabled ) + { + m_winDisabled = new wxWindowList; + } + + m_winDisabled->Append(winTop); + } + } +} + +wxWindowDisabler::~wxWindowDisabler() +{ + wxWindowList::Node *node; + for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) + { + wxWindow *winTop = node->GetData(); + if ( !m_winDisabled || !m_winDisabled->Find(winTop) ) + { + winTop->Enable(); + } + //else: had been already disabled, don't reenable + } + + delete m_winDisabled; + +#ifdef __WXMSW__ +#ifdef __WIN32__ + if ( m_winTop ) + { + if ( !::SetForegroundWindow(GetHwndOf(m_winTop)) ) + { + wxLogLastError(wxT("SetForegroundWindow")); + } + } +#else + if ( m_winTop ) + { + // 16-bit SetForegroundWindow() replacement + RECT reWin; + GetWindowRect((HWND) m_winTop, &reWin); + SetWindowPos ((HWND) m_winTop, HWND_TOP, + reWin.left, reWin.top, + reWin.right - reWin.left, reWin.bottom, + SWP_SHOWWINDOW); + } +#endif +#endif // MSW +} + +// Yield to other apps/messages and disable user input to all windows except +// the given one bool wxSafeYield(wxWindow *win) { - wxEnableTopLevelWindows(FALSE); - // always enable ourselves - if ( win ) - win->Enable(TRUE); - bool rc = wxYield(); - wxEnableTopLevelWindows(TRUE); - return rc; + wxWindowDisabler wd(win); + + bool rc = wxYield(); + + return rc; } +// ---------------------------------------------------------------------------- +// misc functions +// ---------------------------------------------------------------------------- + // Don't synthesize KeyUp events holding down a key and producing KeyDown // events with autorepeat. On by default and always on in wxMSW. wxGTK version // in utilsgtk.cpp. #ifndef __WXGTK__ bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) ) { - return TRUE; // detectable auto-repeat is the only mode MSW supports + return TRUE; // detectable auto-repeat is the only mode MSW supports } #endif // !wxGTK @@ -969,14 +1103,13 @@ wxString wxGetEmailAddress() { wxString email; - wxString host = wxGetHostName(); + wxString host = wxGetFullHostName(); if ( !!host ) { wxString user = wxGetUserId(); if ( !!user ) { - wxString email(user); - email << wxT('@') << host; + email << user << wxT('@') << host; } } @@ -1041,3 +1174,135 @@ wxString wxGetFullHostName() return buf; } +wxString wxGetHomeDir() +{ + wxString home; + wxGetHomeDir(&home); + + return home; +} + +#if 0 + +wxString wxGetCurrentDir() +{ + wxString dir; + size_t len = 1024; + bool ok; + do + { + ok = getcwd(dir.GetWriteBuf(len + 1), len) != NULL; + dir.UngetWriteBuf(); + + if ( !ok ) + { + if ( errno != ERANGE ) + { + wxLogSysError(_T("Failed to get current directory")); + + return wxEmptyString; + } + else + { + // buffer was too small, retry with a larger one + len *= 2; + } + } + //else: ok + } while ( !ok ); + + return dir; +} + +#endif // 0 + +// ---------------------------------------------------------------------------- +// wxExecute +// ---------------------------------------------------------------------------- + +// this is a private function because it hasn't a clean interface: the first +// array is passed by reference, the second by pointer - instead we have 2 +// public versions of wxExecute() below +static long wxDoExecuteWithCapture(const wxString& command, + wxArrayString& output, + wxArrayString* error) +{ +#ifdef __WIN16__ + wxFAIL_MSG("Sorry, this version of wxExecute not implemented on WIN16."); + + return 0; +#else // !Win16 + // create a wxProcess which will capture the output + wxProcess *process = new wxProcess; + process->Redirect(); + + long rc = wxExecute(command, TRUE /* sync */, process); + +#if wxUSE_STREAMS + if ( rc != -1 ) + { + wxInputStream* is = process->GetInputStream(); + wxCHECK_MSG( is, -1, _T("if wxExecute() succeded, stream can't be NULL") ); + wxTextInputStream tis(*is); + + wxTextInputStream *tes = NULL; + wxInputStream *es = NULL; + if ( error ) + { + es = process->GetErrorStream(); + + wxCHECK_MSG( es, -1, _T("stderr can't be NULL") ); + + tes = new wxTextInputStream(*es); + } + + bool cont; + do + { + cont = FALSE; + + if ( !is->Eof() && is->IsOk() ) + { + wxString line = tis.ReadLine(); + if ( is->LastError() ) + break; + + cont = TRUE; + + output.Add(line); + } + + if ( error && !es->Eof() && es->IsOk() ) + { + wxString line = tes->ReadLine(); + if ( es->LastError() ) + break; + + cont = TRUE; + + error->Add(line); + } + } + while ( cont ); + + delete tes; + } +#endif // wxUSE_STREAMS + + delete process; + + return rc; +#endif // IO redirection supoprted +} + +long wxExecute(const wxString& command, wxArrayString& output) +{ + return wxDoExecuteWithCapture(command, output, NULL); +} + +long wxExecute(const wxString& command, + wxArrayString& output, + wxArrayString& error) +{ + return wxDoExecuteWithCapture(command, output, &error); +}