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 // for compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  28     #include "wx/textctrl.h" 
  33 // ---------------------------------------------------------------------------- 
  35 // ---------------------------------------------------------------------------- 
  37 // we don't have any objects of type wxTextCtrlBase in the program, only 
  38 // wxTextCtrl, so this cast is safe 
  39 #define TEXTCTRL(ptr)   ((wxTextCtrl *)(ptr)) 
  41 // ============================================================================ 
  43 // ============================================================================ 
  45 IMPLEMENT_DYNAMIC_CLASS(wxTextUrlEvent
, wxCommandEvent
) 
  47 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED
) 
  48 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_ENTER
) 
  49 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_URL
) 
  50 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_MAXLEN
) 
  52 // ---------------------------------------------------------------------------- 
  53 // style functions - not implemented here 
  54 // ---------------------------------------------------------------------------- 
  56 wxTextAttr::wxTextAttr(const wxColour
& colText
, 
  57                const wxColour
& colBack
, 
  59                wxTextAttrAlignment alignment
) 
  60     : m_colText(colText
), m_colBack(colBack
), m_font(font
), m_textAlignment(alignment
) 
  66     if (m_colText
.Ok()) m_flags 
|= wxTEXT_ATTR_TEXT_COLOUR
; 
  67     if (m_colBack
.Ok()) m_flags 
|= wxTEXT_ATTR_BACKGROUND_COLOUR
; 
  68     if (m_font
.Ok()) m_flags 
|= wxTEXT_ATTR_FONT
; 
  69     if (alignment 
!= wxTEXT_ALIGNMENT_DEFAULT
) 
  70         m_flags 
|= wxTEXT_ATTR_ALIGNMENT
; 
  73 void wxTextAttr::Init() 
  75     m_textAlignment 
= wxTEXT_ALIGNMENT_DEFAULT
; 
  83 wxTextAttr 
wxTextAttr::Combine(const wxTextAttr
& attr
, 
  84                                const wxTextAttr
& attrDef
, 
  85                                const wxTextCtrlBase 
*text
) 
  87     wxFont font 
= attr
.GetFont(); 
  90         font 
= attrDef
.GetFont(); 
  92         if ( text 
&& !font
.Ok() ) 
  93             font 
= text
->GetFont(); 
  96     wxColour colFg 
= attr
.GetTextColour(); 
  99         colFg 
= attrDef
.GetTextColour(); 
 101         if ( text 
&& !colFg
.Ok() ) 
 102             colFg 
= text
->GetForegroundColour(); 
 105     wxColour colBg 
= attr
.GetBackgroundColour(); 
 108         colBg 
= attrDef
.GetBackgroundColour(); 
 110         if ( text 
&& !colBg
.Ok() ) 
 111             colBg 
= text
->GetBackgroundColour(); 
 114     wxTextAttr 
newAttr(colFg
, colBg
, font
); 
 116     if (attr
.HasAlignment()) 
 117         newAttr
.SetAlignment(attr
.GetAlignment()); 
 118     else if (attrDef
.HasAlignment()) 
 119         newAttr
.SetAlignment(attrDef
.GetAlignment()); 
 122         newAttr
.SetTabs(attr
.GetTabs()); 
 123     else if (attrDef
.HasTabs()) 
 124         newAttr
.SetTabs(attrDef
.GetTabs()); 
 126     if (attr
.HasLeftIndent()) 
 127         newAttr
.SetLeftIndent(attr
.GetLeftIndent(), attr
.GetLeftSubIndent()); 
 128     else if (attrDef
.HasLeftIndent()) 
 129         newAttr
.SetLeftIndent(attrDef
.GetLeftIndent(), attr
.GetLeftSubIndent()); 
 131     if (attr
.HasRightIndent()) 
 132         newAttr
.SetRightIndent(attr
.GetRightIndent()); 
 133     else if (attrDef
.HasRightIndent()) 
 134         newAttr
.SetRightIndent(attrDef
.GetRightIndent()); 
 139 void wxTextAttr::operator= (const wxTextAttr
& attr
) 
 141     m_font 
= attr
.m_font
; 
 142     m_colText 
= attr
.m_colText
; 
 143     m_colBack 
= attr
.m_colBack
; 
 144     m_textAlignment 
= attr
.m_textAlignment
; 
 145     m_leftIndent 
= attr
.m_leftIndent
; 
 146     m_leftSubIndent 
= attr
.m_leftSubIndent
; 
 147     m_rightIndent 
= attr
.m_rightIndent
; 
 148     m_tabs 
= attr
.m_tabs
; 
 149     m_flags 
= attr
.m_flags
; 
 153 // apply styling to text range 
 154 bool wxTextCtrlBase::SetStyle(long WXUNUSED(start
), long WXUNUSED(end
), 
 155                               const wxTextAttr
& WXUNUSED(style
)) 
 157     // to be implemented in derived TextCtrl classes 
 161 // get the styling at the given position 
 162 bool wxTextCtrlBase::GetStyle(long WXUNUSED(position
), wxTextAttr
& WXUNUSED(style
)) 
 164     // to be implemented in derived TextCtrl classes 
 168 // change default text attributes 
 169 bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr
& style
) 
 171     // keep the old attributes if the new style doesn't specify them unless the 
 172     // new style is empty - then reset m_defaultStyle (as there is no other way 
 174     if ( style
.IsDefault() ) 
 175         m_defaultStyle 
= style
; 
 177         m_defaultStyle 
= wxTextAttr::Combine(style
, m_defaultStyle
, this); 
 182 // get default text attributes 
 183 const wxTextAttr
& wxTextCtrlBase::GetDefaultStyle() const 
 185     return m_defaultStyle
; 
 188 // ---------------------------------------------------------------------------- 
 190 // ---------------------------------------------------------------------------- 
 192 bool wxTextCtrlBase::LoadFile(const wxString
& filename
) 
 195     wxFFile 
file(filename
); 
 196     if ( file
.IsOpened() ) 
 199         if ( file
.ReadAll(&text
) ) 
 205             m_filename 
= filename
; 
 211     wxLogError(_("File couldn't be loaded.")); 
 212 #endif // wxUSE_FFILE 
 217 bool wxTextCtrlBase::SaveFile(const wxString
& filename
) 
 219     wxString filenameToUse 
= filename
.empty() ? m_filename 
: filename
; 
 220     if ( filenameToUse
.empty() ) 
 222         // what kind of message to give? is it an error or a program bug? 
 223         wxLogDebug(wxT("Can't save textctrl to file without filename.")); 
 229     wxFFile 
file(filenameToUse
, _T("w")); 
 230     if ( file
.IsOpened() && file
.Write(GetValue()) ) 
 232         // it's not modified any longer 
 235         // if it worked, save for future calls 
 236         m_filename 
= filenameToUse
; 
 240 #endif // wxUSE_FFILE 
 242     wxLogError(_("The text couldn't be saved.")); 
 247 // ---------------------------------------------------------------------------- 
 248 // stream-like insertion operator 
 249 // ---------------------------------------------------------------------------- 
 251 wxTextCtrl
& wxTextCtrlBase::operator<<(const wxString
& s
) 
 254     return *TEXTCTRL(this); 
 257 wxTextCtrl
& wxTextCtrlBase::operator<<(float f
) 
 260     str
.Printf(wxT("%.2f"), f
); 
 262     return *TEXTCTRL(this); 
 265 wxTextCtrl
& wxTextCtrlBase::operator<<(double d
) 
 268     str
.Printf(wxT("%.2f"), d
); 
 270     return *TEXTCTRL(this); 
 273 wxTextCtrl
& wxTextCtrlBase::operator<<(int i
) 
 276     str
.Printf(wxT("%d"), i
); 
 278     return *TEXTCTRL(this); 
 281 wxTextCtrl
& wxTextCtrlBase::operator<<(long i
) 
 284     str
.Printf(wxT("%ld"), i
); 
 286     return *TEXTCTRL(this); 
 289 wxTextCtrl
& wxTextCtrlBase::operator<<(const wxChar c
) 
 291     return operator<<(wxString(c
)); 
 294 // ---------------------------------------------------------------------------- 
 295 // streambuf methods implementation 
 296 // ---------------------------------------------------------------------------- 
 298 #if wxHAS_TEXT_WINDOW_STREAM 
 300 int wxTextCtrlBase::overflow(int c
) 
 302     AppendText((wxChar
)c
); 
 304     // return something different from EOF 
 308 #endif // wxHAS_TEXT_WINDOW_STREAM 
 310 // ---------------------------------------------------------------------------- 
 312 // ---------------------------------------------------------------------------- 
 314 bool wxTextCtrlBase::CanCopy() const 
 316     // can copy if there's a selection 
 318     GetSelection(&from
, &to
); 
 322 bool wxTextCtrlBase::CanCut() const 
 324     // can cut if there's a selection and if we're not read only 
 325     return CanCopy() && IsEditable(); 
 328 bool wxTextCtrlBase::CanPaste() const 
 330     // can paste if we are not read only 
 334 // ---------------------------------------------------------------------------- 
 335 // emulating key presses 
 336 // ---------------------------------------------------------------------------- 
 339 // the generic version is unused in wxMSW 
 340 bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent
& WXUNUSED(event
)) 
 345 bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent
& event
) 
 348     int keycode 
= event
.GetKeyCode(); 
 361             ch 
= (wxChar
)(_T('0') + keycode 
- WXK_NUMPAD0
); 
 365         case WXK_NUMPAD_MULTIPLY
: 
 375         case WXK_NUMPAD_SUBTRACT
: 
 380         case WXK_NUMPAD_DECIMAL
: 
 385         case WXK_NUMPAD_DIVIDE
: 
 390         case WXK_NUMPAD_DELETE
: 
 391             // delete the character at cursor 
 393                 const long pos 
= GetInsertionPoint(); 
 394                 if ( pos 
< GetLastPosition() ) 
 395                     Remove(pos
, pos 
+ 1); 
 400             // delete the character before the cursor 
 402                 const long pos 
= GetInsertionPoint(); 
 404                     Remove(pos 
- 1, pos
); 
 410             if ( event
.GetUnicodeKey() ) 
 412                 ch 
= event
.GetUnicodeKey(); 
 416             if ( keycode 
< 256 && keycode 
>= 0 && wxIsprint(keycode
) ) 
 418                 // FIXME this is not going to work for non letters... 
 419                 if ( !event
.ShiftDown() ) 
 421                     keycode 
= wxTolower(keycode
); 
 424                 ch 
= (wxChar
)keycode
; 
 443 // ---------------------------------------------------------------------------- 
 444 // selection and ranges 
 445 // ---------------------------------------------------------------------------- 
 447 void wxTextCtrlBase::SelectAll() 
 449     SetSelection(0, GetLastPosition()); 
 452 wxString 
wxTextCtrlBase::GetStringSelection() const 
 455     GetSelection(&from
, &to
); 
 457     return GetRange(from
, to
); 
 460 wxString 
wxTextCtrlBase::GetRange(long from
, long to
) const 
 465         sel 
= GetValue().Mid(from
, to 
- from
); 
 471 // do the window-specific processing after processing the update event 
 472 void wxTextCtrlBase::DoUpdateWindowUI(wxUpdateUIEvent
& event
) 
 474     if ( event
.GetSetEnabled() ) 
 475         Enable(event
.GetEnabled()); 
 477     if ( event
.GetSetText() ) 
 479         if ( event
.GetText() != GetValue() ) 
 480             SetValue(event
.GetText()); 
 484 // ---------------------------------------------------------------------------- 
 486 // ---------------------------------------------------------------------------- 
 488 wxTextCtrlHitTestResult
 
 489 wxTextCtrlBase::HitTest(const wxPoint
& pt
, wxTextCoord 
*x
, wxTextCoord 
*y
) const 
 491     // implement in terms of the other overload as the native ports typically 
 492     // can get the position and not (x, y) pair directly (although wxUniv 
 493     // directly gets x and y -- and so overrides this method as well) 
 495     wxTextCtrlHitTestResult rc 
= HitTest(pt
, &pos
); 
 497     if ( rc 
!= wxTE_HT_UNKNOWN 
) 
 499         PositionToXY(pos
, x
, y
); 
 505 wxTextCtrlHitTestResult
 
 506 wxTextCtrlBase::HitTest(const wxPoint
& WXUNUSED(pt
), 
 507                         long * WXUNUSED(pos
)) const 
 510     return wxTE_HT_UNKNOWN
; 
 513 #else // !wxUSE_TEXTCTRL 
 515 // define this one even if !wxUSE_TEXTCTRL because it is also used by other 
 516 // controls (wxComboBox and wxSpinCtrl) 
 517 #include "wx/event.h" 
 519 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED
) 
 521 #endif // wxUSE_TEXTCTRL/!wxUSE_TEXTCTRL