1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        common/textcmn.cpp 
   3 // Purpose:     implementation of platform-independent functions of wxTextCtrl 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) wxWidgets team 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  17     #pragma implementation "textctrlbase.h" 
  20 // for compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  32     #include "wx/textctrl.h" 
  37 // ---------------------------------------------------------------------------- 
  39 // ---------------------------------------------------------------------------- 
  41 // we don't have any objects of type wxTextCtrlBase in the program, only 
  42 // wxTextCtrl, so this cast is safe 
  43 #define TEXTCTRL(ptr)   ((wxTextCtrl *)(ptr)) 
  45 // ============================================================================ 
  47 // ============================================================================ 
  49 IMPLEMENT_DYNAMIC_CLASS(wxTextUrlEvent
, wxCommandEvent
) 
  51 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED
) 
  52 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_ENTER
) 
  53 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_URL
) 
  54 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_MAXLEN
) 
  56 // ---------------------------------------------------------------------------- 
  57 // style functions - not implemented here 
  58 // ---------------------------------------------------------------------------- 
  60 wxTextAttr::wxTextAttr(const wxColour
& colText
, 
  61                const wxColour
& colBack
, 
  63                wxTextAttrAlignment alignment
) 
  64     : m_colText(colText
), m_colBack(colBack
), m_font(font
), m_textAlignment(alignment
) 
  70     if (m_colText
.Ok()) m_flags 
|= wxTEXT_ATTR_TEXT_COLOUR
; 
  71     if (m_colBack
.Ok()) m_flags 
|= wxTEXT_ATTR_BACKGROUND_COLOUR
; 
  72     if (m_font
.Ok()) m_flags 
|= wxTEXT_ATTR_FONT
; 
  73     if (alignment 
!= wxTEXT_ALIGNMENT_DEFAULT
) 
  74         m_flags 
|= wxTEXT_ATTR_ALIGNMENT
; 
  77 void wxTextAttr::Init() 
  79     m_textAlignment 
= wxTEXT_ALIGNMENT_DEFAULT
; 
  87 wxTextAttr 
wxTextAttr::Combine(const wxTextAttr
& attr
, 
  88                                const wxTextAttr
& attrDef
, 
  89                                const wxTextCtrlBase 
*text
) 
  91     wxFont font 
= attr
.GetFont(); 
  94         font 
= attrDef
.GetFont(); 
  96         if ( text 
&& !font
.Ok() ) 
  97             font 
= text
->GetFont(); 
 100     wxColour colFg 
= attr
.GetTextColour(); 
 103         colFg 
= attrDef
.GetTextColour(); 
 105         if ( text 
&& !colFg
.Ok() ) 
 106             colFg 
= text
->GetForegroundColour(); 
 109     wxColour colBg 
= attr
.GetBackgroundColour(); 
 112         colBg 
= attrDef
.GetBackgroundColour(); 
 114         if ( text 
&& !colBg
.Ok() ) 
 115             colBg 
= text
->GetBackgroundColour(); 
 118     wxTextAttr 
newAttr(colFg
, colBg
, font
); 
 120     if (attr
.HasAlignment()) 
 121         newAttr
.SetAlignment(attr
.GetAlignment()); 
 122     else if (attrDef
.HasAlignment()) 
 123         newAttr
.SetAlignment(attrDef
.GetAlignment()); 
 126         newAttr
.SetTabs(attr
.GetTabs()); 
 127     else if (attrDef
.HasTabs()) 
 128         newAttr
.SetTabs(attrDef
.GetTabs()); 
 130     if (attr
.HasLeftIndent()) 
 131         newAttr
.SetLeftIndent(attr
.GetLeftIndent(), attr
.GetLeftSubIndent()); 
 132     else if (attrDef
.HasLeftIndent()) 
 133         newAttr
.SetLeftIndent(attrDef
.GetLeftIndent(), attr
.GetLeftSubIndent()); 
 135     if (attr
.HasRightIndent()) 
 136         newAttr
.SetRightIndent(attr
.GetRightIndent()); 
 137     else if (attrDef
.HasRightIndent()) 
 138         newAttr
.SetRightIndent(attrDef
.GetRightIndent()); 
 143 void wxTextAttr::operator= (const wxTextAttr
& attr
) 
 145     m_font 
= attr
.m_font
; 
 146     m_colText 
= attr
.m_colText
; 
 147     m_colBack 
= attr
.m_colBack
; 
 148     m_textAlignment 
= attr
.m_textAlignment
; 
 149     m_leftIndent 
= attr
.m_leftIndent
; 
 150     m_leftSubIndent 
= attr
.m_leftSubIndent
; 
 151     m_rightIndent 
= attr
.m_rightIndent
; 
 152     m_tabs 
= attr
.m_tabs
; 
 153     m_flags 
= attr
.m_flags
; 
 157 // apply styling to text range 
 158 bool wxTextCtrlBase::SetStyle(long WXUNUSED(start
), long WXUNUSED(end
), 
 159                               const wxTextAttr
& WXUNUSED(style
)) 
 161     // to be implemented in derived TextCtrl classes 
 165 // get the styling at the given position 
 166 bool wxTextCtrlBase::GetStyle(long WXUNUSED(position
), wxTextAttr
& WXUNUSED(style
)) 
 168     // to be implemented in derived TextCtrl classes 
 172 // change default text attributes 
 173 bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr
& style
) 
 175     // keep the old attributes if the new style doesn't specify them unless the 
 176     // new style is empty - then reset m_defaultStyle (as there is no other way 
 178     if ( style
.IsDefault() ) 
 179         m_defaultStyle 
= style
; 
 181         m_defaultStyle 
= wxTextAttr::Combine(style
, m_defaultStyle
, this); 
 186 // get default text attributes 
 187 const wxTextAttr
& wxTextCtrlBase::GetDefaultStyle() const 
 189     return m_defaultStyle
; 
 192 // ---------------------------------------------------------------------------- 
 194 // ---------------------------------------------------------------------------- 
 196 bool wxTextCtrlBase::LoadFile(const wxString
& filename
) 
 199     wxFFile 
file(filename
); 
 200     if ( file
.IsOpened() ) 
 203         if ( file
.ReadAll(&text
) ) 
 209             m_filename 
= filename
; 
 215     wxLogError(_("File couldn't be loaded.")); 
 216 #endif // wxUSE_FFILE 
 221 bool wxTextCtrlBase::SaveFile(const wxString
& filename
) 
 223     wxString filenameToUse 
= filename
.empty() ? m_filename 
: filename
; 
 224     if ( filenameToUse
.empty() ) 
 226         // what kind of message to give? is it an error or a program bug? 
 227         wxLogDebug(wxT("Can't save textctrl to file without filename.")); 
 233     wxFFile 
file(filenameToUse
, _T("w")); 
 234     if ( file
.IsOpened() && file
.Write(GetValue()) ) 
 236         // it's not modified any longer 
 239         // if it worked, save for future calls 
 240         m_filename 
= filenameToUse
; 
 244 #endif // wxUSE_FFILE 
 246     wxLogError(_("The text couldn't be saved.")); 
 251 // ---------------------------------------------------------------------------- 
 252 // stream-like insertion operator 
 253 // ---------------------------------------------------------------------------- 
 255 wxTextCtrl
& wxTextCtrlBase::operator<<(const wxString
& s
) 
 258     return *TEXTCTRL(this); 
 261 wxTextCtrl
& wxTextCtrlBase::operator<<(float f
) 
 264     str
.Printf(wxT("%.2f"), f
); 
 266     return *TEXTCTRL(this); 
 269 wxTextCtrl
& wxTextCtrlBase::operator<<(double d
) 
 272     str
.Printf(wxT("%.2f"), d
); 
 274     return *TEXTCTRL(this); 
 277 wxTextCtrl
& wxTextCtrlBase::operator<<(int i
) 
 280     str
.Printf(wxT("%d"), i
); 
 282     return *TEXTCTRL(this); 
 285 wxTextCtrl
& wxTextCtrlBase::operator<<(long i
) 
 288     str
.Printf(wxT("%ld"), i
); 
 290     return *TEXTCTRL(this); 
 293 wxTextCtrl
& wxTextCtrlBase::operator<<(const wxChar c
) 
 295     return operator<<(wxString(c
)); 
 298 // ---------------------------------------------------------------------------- 
 299 // streambuf methods implementation 
 300 // ---------------------------------------------------------------------------- 
 302 #ifndef NO_TEXT_WINDOW_STREAM 
 304 int wxTextCtrlBase::overflow(int c
) 
 306     AppendText((wxChar
)c
); 
 308     // return something different from EOF 
 312 #endif // NO_TEXT_WINDOW_STREAM 
 314 // ---------------------------------------------------------------------------- 
 316 // ---------------------------------------------------------------------------- 
 318 bool wxTextCtrlBase::CanCopy() const 
 320     // can copy if there's a selection 
 322     GetSelection(&from
, &to
); 
 326 bool wxTextCtrlBase::CanCut() const 
 328     // can cut if there's a selection and if we're not read only 
 329     return CanCopy() && IsEditable(); 
 332 bool wxTextCtrlBase::CanPaste() const 
 334     // can paste if we are not read only 
 338 // ---------------------------------------------------------------------------- 
 339 // emulating key presses 
 340 // ---------------------------------------------------------------------------- 
 343 // the generic version is unused in wxMSW 
 344 bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent
& WXUNUSED(event
)) 
 349 bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent
& event
) 
 352     int keycode 
= event
.GetKeyCode(); 
 365             ch 
= _T('0') + keycode 
- WXK_NUMPAD0
; 
 369         case WXK_NUMPAD_MULTIPLY
: 
 379         case WXK_NUMPAD_SUBTRACT
: 
 384         case WXK_NUMPAD_DECIMAL
: 
 389         case WXK_NUMPAD_DIVIDE
: 
 394         case WXK_NUMPAD_DELETE
: 
 395             // delete the character at cursor 
 397                 const long pos 
= GetInsertionPoint(); 
 398                 if ( pos 
< GetLastPosition() ) 
 399                     Remove(pos
, pos 
+ 1); 
 404             // delete the character before the cursor 
 406                 const long pos 
= GetInsertionPoint(); 
 408                     Remove(pos 
- 1, pos
); 
 414             if ( event
.GetUnicodeKey() ) 
 416                 ch 
= event
.GetUnicodeKey(); 
 420             if ( keycode 
< 256 && keycode 
>= 0 && wxIsprint(keycode
) ) 
 422                 // FIXME this is not going to work for non letters... 
 423                 if ( !event
.ShiftDown() ) 
 425                     keycode 
= wxTolower(keycode
); 
 428                 ch 
= (wxChar
)keycode
; 
 447 // ---------------------------------------------------------------------------- 
 448 // selection and ranges 
 449 // ---------------------------------------------------------------------------- 
 451 void wxTextCtrlBase::SelectAll() 
 453     SetSelection(0, GetLastPosition()); 
 456 wxString 
wxTextCtrlBase::GetStringSelection() const 
 459     GetSelection(&from
, &to
); 
 461     return GetRange(from
, to
); 
 464 wxString 
wxTextCtrlBase::GetRange(long from
, long to
) const 
 469         sel 
= GetValue().Mid(from
, to 
- from
); 
 475 // do the window-specific processing after processing the update event 
 476 void wxTextCtrlBase::DoUpdateWindowUI(wxUpdateUIEvent
& event
) 
 478     if ( event
.GetSetEnabled() ) 
 479         Enable(event
.GetEnabled()); 
 481     if ( event
.GetSetText() ) 
 483         if ( event
.GetText() != GetValue() ) 
 484             SetValue(event
.GetText()); 
 488 // ---------------------------------------------------------------------------- 
 490 // ---------------------------------------------------------------------------- 
 492 wxTextCtrlHitTestResult
 
 493 wxTextCtrlBase::HitTest(const wxPoint
& pt
, wxTextCoord 
*x
, wxTextCoord 
*y
) const 
 495     // implement in terms of the other overload as the native ports typically 
 496     // can get the position and not (x, y) pair directly (although wxUniv 
 497     // directly gets x and y -- and so overrides this method as well) 
 499     wxTextCtrlHitTestResult rc 
= HitTest(pt
, &pos
); 
 501     if ( rc 
!= wxTE_HT_UNKNOWN 
) 
 503         PositionToXY(pos
, x
, y
); 
 509 wxTextCtrlHitTestResult
 
 510 wxTextCtrlBase::HitTest(const wxPoint
& WXUNUSED(pt
), 
 511                         long * WXUNUSED(pos
)) const 
 514     return wxTE_HT_UNKNOWN
; 
 517 #else // !wxUSE_TEXTCTRL 
 519 // define this one even if !wxUSE_TEXTCTRL because it is also used by other 
 520 // controls (wxComboBox and wxSpinCtrl) 
 521 #include "wx/event.h" 
 523 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED
) 
 525 #endif // wxUSE_TEXTCTRL/!wxUSE_TEXTCTRL