X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/14f355c2b5c71fc7c3d680aea366582d2ac60f7b..797e38dde12c5dc2d99070eef25d9b8c2549d621:/src/common/textcmn.cpp diff --git a/src/common/textcmn.cpp b/src/common/textcmn.cpp index 119ffc8c01..8fa4ad28c9 100644 --- a/src/common/textcmn.cpp +++ b/src/common/textcmn.cpp @@ -1,11 +1,11 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: common/textcmn.cpp +// Name: src/common/textcmn.cpp // Purpose: implementation of platform-independent functions of wxTextCtrl // Author: Julian Smart // Modified by: // Created: 13.07.99 // RCS-ID: $Id$ -// Copyright: (c) wxWindows team +// Copyright: (c) wxWidgets team // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// @@ -13,10 +13,6 @@ // declarations // ============================================================================ -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "textctrlbase.h" -#endif - // for compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -24,12 +20,17 @@ #pragma hdrstop #endif +#ifndef WX_PRECOMP + #include "wx/event.h" +#endif // WX_PRECOMP + #if wxUSE_TEXTCTRL +#include "wx/textctrl.h" + #ifndef WX_PRECOMP #include "wx/intl.h" #include "wx/log.h" - #include "wx/textctrl.h" #endif // WX_PRECOMP #include "wx/ffile.h" @@ -53,17 +54,7 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_ENTER) DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_URL) DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_MAXLEN) -// ---------------------------------------------------------------------------- -// ctor -// ---------------------------------------------------------------------------- - -wxTextCtrlBase::wxTextCtrlBase() -{ -} - -wxTextCtrlBase::~wxTextCtrlBase() -{ -} +IMPLEMENT_ABSTRACT_CLASS(wxTextCtrlBase, wxControl) // ---------------------------------------------------------------------------- // style functions - not implemented here @@ -77,6 +68,7 @@ wxTextAttr::wxTextAttr(const wxColour& colText, { m_flags = 0; m_leftIndent = 0; + m_leftSubIndent = 0; m_rightIndent = 0; if (m_colText.Ok()) m_flags |= wxTEXT_ATTR_TEXT_COLOUR; if (m_colBack.Ok()) m_flags |= wxTEXT_ATTR_BACKGROUND_COLOUR; @@ -90,6 +82,7 @@ void wxTextAttr::Init() m_textAlignment = wxTEXT_ALIGNMENT_DEFAULT; m_flags = 0; m_leftIndent = 0; + m_leftSubIndent = 0; m_rightIndent = 0; } @@ -126,27 +119,27 @@ wxTextAttr wxTextAttr::Combine(const wxTextAttr& attr, } wxTextAttr newAttr(colFg, colBg, font); - + if (attr.HasAlignment()) newAttr.SetAlignment(attr.GetAlignment()); else if (attrDef.HasAlignment()) newAttr.SetAlignment(attrDef.GetAlignment()); - + if (attr.HasTabs()) newAttr.SetTabs(attr.GetTabs()); else if (attrDef.HasTabs()) newAttr.SetTabs(attrDef.GetTabs()); - + if (attr.HasLeftIndent()) - newAttr.SetLeftIndent(attr.GetLeftIndent()); + newAttr.SetLeftIndent(attr.GetLeftIndent(), attr.GetLeftSubIndent()); else if (attrDef.HasLeftIndent()) - newAttr.SetLeftIndent(attrDef.GetLeftIndent()); - + newAttr.SetLeftIndent(attrDef.GetLeftIndent(), attr.GetLeftSubIndent()); + if (attr.HasRightIndent()) newAttr.SetRightIndent(attr.GetRightIndent()); else if (attrDef.HasRightIndent()) - newAttr.SetRightIndent(attrDef.GetRightIndent()); - + newAttr.SetRightIndent(attrDef.GetRightIndent()); + return newAttr; } @@ -157,6 +150,7 @@ void wxTextAttr::operator= (const wxTextAttr& attr) m_colBack = attr.m_colBack; m_textAlignment = attr.m_textAlignment; m_leftIndent = attr.m_leftIndent; + m_leftSubIndent = attr.m_leftSubIndent; m_rightIndent = attr.m_rightIndent; m_tabs = attr.m_tabs; m_flags = attr.m_flags; @@ -167,15 +161,15 @@ void wxTextAttr::operator= (const wxTextAttr& attr) bool wxTextCtrlBase::SetStyle(long WXUNUSED(start), long WXUNUSED(end), const wxTextAttr& WXUNUSED(style)) { - // to be implemented in derived TextCtrl classes - return FALSE; + // to be implemented in derived classes + return false; } // get the styling at the given position bool wxTextCtrlBase::GetStyle(long WXUNUSED(position), wxTextAttr& WXUNUSED(style)) { - // to be implemented in derived TextCtrl classes - return FALSE; + // to be implemented in derived classes + return false; } // change default text attributes @@ -189,20 +183,14 @@ bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr& style) else m_defaultStyle = wxTextAttr::Combine(style, m_defaultStyle, this); - return TRUE; -} - -// get default text attributes -const wxTextAttr& wxTextCtrlBase::GetDefaultStyle() const -{ - return m_defaultStyle; + return true; } // ---------------------------------------------------------------------------- // file IO functions // ---------------------------------------------------------------------------- -bool wxTextCtrlBase::LoadFile(const wxString& filename) +bool wxTextCtrlBase::DoLoadFile(const wxString& filename, int WXUNUSED(fileType)) { #if wxUSE_FFILE wxFFile file(filename); @@ -217,43 +205,49 @@ bool wxTextCtrlBase::LoadFile(const wxString& filename) m_filename = filename; - return TRUE; + return true; } } wxLogError(_("File couldn't be loaded.")); #endif // wxUSE_FFILE - return FALSE; + return false; } -bool wxTextCtrlBase::SaveFile(const wxString& filename) +bool wxTextAreaBase::SaveFile(const wxString& filename, int fileType) { - wxString filenameToUse = filename.IsEmpty() ? m_filename : filename; - if ( !filenameToUse ) + wxString filenameToUse = filename.empty() ? m_filename : filename; + if ( filenameToUse.empty() ) { // what kind of message to give? is it an error or a program bug? wxLogDebug(wxT("Can't save textctrl to file without filename.")); - return FALSE; + return false; } + return DoSaveFile(filenameToUse, fileType); +} + +bool wxTextCtrlBase::DoSaveFile(const wxString& filename, int WXUNUSED(fileType)) +{ #if wxUSE_FFILE wxFFile file(filename, _T("w")); if ( file.IsOpened() && file.Write(GetValue()) ) { + // if it worked, save for future calls + m_filename = filename; + // it's not modified any longer DiscardEdits(); - m_filename = filename; - - return TRUE; + return true; } +#endif // wxUSE_FFILE wxLogError(_("The text couldn't be saved.")); -#endif // wxUSE_FFILE - return FALSE; + return false; } // ---------------------------------------------------------------------------- @@ -307,7 +301,7 @@ wxTextCtrl& wxTextCtrlBase::operator<<(const wxChar c) // streambuf methods implementation // ---------------------------------------------------------------------------- -#ifndef NO_TEXT_WINDOW_STREAM +#if wxHAS_TEXT_WINDOW_STREAM int wxTextCtrlBase::overflow(int c) { @@ -317,45 +311,16 @@ int wxTextCtrlBase::overflow(int c) return 0; } -#endif // NO_TEXT_WINDOW_STREAM - -// ---------------------------------------------------------------------------- -// clipboard stuff -// ---------------------------------------------------------------------------- - -bool wxTextCtrlBase::CanCopy() const -{ - // can copy if there's a selection - long from, to; - GetSelection(&from, &to); - return from != to; -} - -bool wxTextCtrlBase::CanCut() const -{ - // can cut if there's a selection and if we're not read only - return CanCopy() && IsEditable(); -} - -bool wxTextCtrlBase::CanPaste() const -{ - // can paste if we are not read only - return IsEditable(); -} +#endif // wxHAS_TEXT_WINDOW_STREAM // ---------------------------------------------------------------------------- // emulating key presses // ---------------------------------------------------------------------------- -#ifdef __WIN32__ -// the generic version is unused in wxMSW -bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& WXUNUSED(event)) -{ - return FALSE; -} -#else // !__WIN32__ bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event) { + // we have a native implementation for Win32 and so don't need this one +#ifndef __WIN32__ wxChar ch = 0; int keycode = event.GetKeyCode(); switch ( keycode ) @@ -370,7 +335,7 @@ bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event) case WXK_NUMPAD7: case WXK_NUMPAD8: case WXK_NUMPAD9: - ch = _T('0') + keycode - WXK_NUMPAD0; + ch = (wxChar)(_T('0') + keycode - WXK_NUMPAD0); break; case WXK_MULTIPLY: @@ -402,9 +367,8 @@ bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event) case WXK_NUMPAD_DELETE: // delete the character at cursor { - const long pos = GetInsertionPoint(), - last = GetLastPosition(); - if ( pos < last ) + const long pos = GetInsertionPoint(); + if ( pos < GetLastPosition() ) Remove(pos, pos + 1); } break; @@ -419,6 +383,13 @@ bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event) break; default: +#if wxUSE_UNICODE + if ( event.GetUnicodeKey() ) + { + ch = event.GetUnicodeKey(); + } + else +#endif if ( keycode < 256 && keycode >= 0 && wxIsprint(keycode) ) { // FIXME this is not going to work for non letters... @@ -439,62 +410,83 @@ bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event) { WriteText(ch); - return TRUE; + return true; } +#else // __WIN32__ + wxUnusedVar(event); +#endif // !__WIN32__/__WIN32__ - return FALSE; + return false; } -#endif // !__WIN32__ -// ---------------------------------------------------------------------------- -// selection and ranges -// ---------------------------------------------------------------------------- - -void wxTextCtrlBase::SelectAll() -{ - SetSelection(0, GetLastPosition()); -} - -wxString wxTextCtrlBase::GetStringSelection() const +// do the window-specific processing after processing the update event +void wxTextCtrlBase::DoUpdateWindowUI(wxUpdateUIEvent& event) { - long from, to; - GetSelection(&from, &to); + // call inherited, but skip the wxControl's version, and call directly the + // wxWindow's one instead, because the only reason why we are overriding this + // function is that we want to use SetValue() instead of wxControl::SetLabel() + wxWindowBase::DoUpdateWindowUI(event); - return GetRange(from, to); + // update text + if ( event.GetSetText() ) + { + if ( event.GetText() != GetValue() ) + SetValue(event.GetText()); + } } -wxString wxTextCtrlBase::GetRange(long from, long to) const +// ---------------------------------------------------------------------------- +// hit testing +// ---------------------------------------------------------------------------- + +wxTextCtrlHitTestResult +wxTextAreaBase::HitTest(const wxPoint& pt, wxTextCoord *x, wxTextCoord *y) const { - wxString sel; - if ( from < to ) + // implement in terms of the other overload as the native ports typically + // can get the position and not (x, y) pair directly (although wxUniv + // directly gets x and y -- and so overrides this method as well) + long pos; + wxTextCtrlHitTestResult rc = HitTest(pt, &pos); + + if ( rc != wxTE_HT_UNKNOWN ) { - sel = GetValue().Mid(from, to - from); + PositionToXY(pos, x, y); } - return sel; + return rc; } -// do the window-specific processing after processing the update event -void wxTextCtrlBase::DoUpdateWindowUI(wxUpdateUIEvent& event) +wxTextCtrlHitTestResult +wxTextAreaBase::HitTest(const wxPoint& WXUNUSED(pt), long * WXUNUSED(pos)) const { - if ( event.GetSetEnabled() ) - Enable(event.GetEnabled()); - - if ( event.GetSetText() ) - { - if ( event.GetText() != GetValue() ) - SetValue(event.GetText()); - } + // not implemented + return wxTE_HT_UNKNOWN; } +// ---------------------------------------------------------------------------- +// events +// ---------------------------------------------------------------------------- + +/* static */ +bool wxTextCtrlBase::SendTextUpdatedEvent(wxWindow *win) +{ + wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, win->GetId()); + + // do not do this as it could be very inefficient if the text control + // contains a lot of text and we're not using ref-counted wxString + // implementation -- instead, event.GetString() will query the control for + // its current text if needed + //event.SetString(win->GetValue()); + + event.SetEventObject(win); + return win->GetEventHandler()->ProcessEvent(event); +} #else // !wxUSE_TEXTCTRL // define this one even if !wxUSE_TEXTCTRL because it is also used by other // controls (wxComboBox and wxSpinCtrl) -#include "wx/event.h" DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED) #endif // wxUSE_TEXTCTRL/!wxUSE_TEXTCTRL -