]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/textctrl.cpp
pretend that we support all encodings instead of not supporting any of them under...
[wxWidgets.git] / src / univ / textctrl.cpp
index b6a4b8810db6edced8395b39b0a4b47d4054f570..3b15ef1070fea12489dd660c028822a9589f8d76 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     15.09.00
 // RCS-ID:      $Id$
 // Copyright:   (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
 // Created:     15.09.00
 // RCS-ID:      $Id$
 // Copyright:   (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 /*
 /////////////////////////////////////////////////////////////////////////////
 
 /*
 // headers
 // ----------------------------------------------------------------------------
 
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "univtextctrl.h"
 #endif
 
     #pragma implementation "univtextctrl.h"
 #endif
 
 
 #if wxUSE_TEXTCTRL
 
 
 #if wxUSE_TEXTCTRL
 
+#include <ctype.h>
+
 #ifndef WX_PRECOMP
     #include "wx/log.h"
 
 #ifndef WX_PRECOMP
     #include "wx/log.h"
 
 
 #include "wx/cmdproc.h"
 
 
 #include "wx/cmdproc.h"
 
+#if wxUSE_CLIPBOARD
+#include "wx/dataobj.h"
+#endif
+
 // turn extra wxTextCtrl-specific debugging on/off
 #define WXDEBUG_TEXT
 
 // turn extra wxTextCtrl-specific debugging on/off
 #define WXDEBUG_TEXT
 
@@ -481,7 +487,7 @@ struct WXDLLEXPORT wxTextWrappedData : public wxTextMultiLineData
 // ----------------------------------------------------------------------------
 
 /*
 // ----------------------------------------------------------------------------
 
 /*
-   We use custom versions of wxWindows command processor to implement undo/redo
+   We use custom versions of wxWidgets command processor to implement undo/redo
    as we want to avoid storing the backpointer to wxTextCtrl in wxCommand
    itself: this is a waste of memory as all commands in the given command
    processor always have the same associated wxTextCtrl and so it makes sense
    as we want to avoid storing the backpointer to wxTextCtrl in wxCommand
    itself: this is a waste of memory as all commands in the given command
    processor always have the same associated wxTextCtrl and so it makes sense
@@ -522,6 +528,8 @@ public:
 
     virtual bool CanUndo() const;
     virtual bool Do(wxTextCtrl *text);
 
     virtual bool CanUndo() const;
     virtual bool Do(wxTextCtrl *text);
+    virtual bool Do() { return wxTextCtrlCommand::Do(); }
+    virtual bool Undo() { return wxTextCtrlCommand::Undo(); }
     virtual bool Undo(wxTextCtrl *text);
 
 private:
     virtual bool Undo(wxTextCtrl *text);
 
 private:
@@ -545,6 +553,8 @@ public:
 
     virtual bool CanUndo() const;
     virtual bool Do(wxTextCtrl *text);
 
     virtual bool CanUndo() const;
     virtual bool Do(wxTextCtrl *text);
+    virtual bool Do() { return wxTextCtrlCommand::Do(); }
+    virtual bool Undo() { return wxTextCtrlCommand::Undo(); }
     virtual bool Undo(wxTextCtrl *text);
 
 private:
     virtual bool Undo(wxTextCtrl *text);
 
 private:
@@ -604,8 +614,6 @@ BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
     EVT_CHAR(wxTextCtrl::OnChar)
 
     EVT_SIZE(wxTextCtrl::OnSize)
     EVT_CHAR(wxTextCtrl::OnChar)
 
     EVT_SIZE(wxTextCtrl::OnSize)
-
-    EVT_IDLE(wxTextCtrl::OnIdle)
 END_EVENT_TABLE()
 
 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
 END_EVENT_TABLE()
 
 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
@@ -661,11 +669,14 @@ bool wxTextCtrl::Create(wxWindow *parent,
             style |= wxALWAYS_SHOW_SB;
         }
 
             style |= wxALWAYS_SHOW_SB;
         }
 
+        // wxTE_WORDWRAP is 0 for now so we don't need the code below
+#if 0
         if ( style & wxTE_WORDWRAP )
         {
             // wrapping words means wrapping, hence no horz scrollbar
             style &= ~wxHSCROLL;
         }
         if ( style & wxTE_WORDWRAP )
         {
             // wrapping words means wrapping, hence no horz scrollbar
             style &= ~wxHSCROLL;
         }
+#endif // 0
 
         // TODO: support wxTE_NO_VSCROLL (?)
 
 
         // TODO: support wxTE_NO_VSCROLL (?)
 
@@ -684,6 +695,11 @@ bool wxTextCtrl::Create(wxWindow *parent,
         // create data object for single line controls
         m_data.sdata = new wxTextSingleLineData;
     }
         // create data object for single line controls
         m_data.sdata = new wxTextSingleLineData;
     }
+    
+#if wxUSE_TWO_WINDOWS
+    if ((style & wxBORDER_MASK) == 0)
+        style |= wxBORDER_SUNKEN;
+#endif
 
     if ( !wxControl::Create(parent, id, pos, size, style,
                             validator, name) )
 
     if ( !wxControl::Create(parent, id, pos, size, style,
                             validator, name) )
@@ -725,6 +741,9 @@ bool wxTextCtrl::Create(wxWindow *parent,
 
     CreateInputHandler(wxINP_HANDLER_TEXTCTRL);
 
 
     CreateInputHandler(wxINP_HANDLER_TEXTCTRL);
 
+    wxSizeEvent sizeEvent(GetSize(), GetId());
+    GetEventHandler()->ProcessEvent(sizeEvent);
+
     return TRUE;
 }
 
     return TRUE;
 }
 
@@ -1413,6 +1432,10 @@ void wxTextCtrl::SetSelection(wxTextPos from, wxTextPos to)
     }
     else // valid sel range
     {
     }
     else // valid sel range
     {
+        // remember the 'to' position as the current position, used to move the
+        // caret there later
+        wxTextPos toOrig = to;
+
         OrderPositions(from, to);
 
         wxCHECK_RET( to <= GetLastPosition(),
         OrderPositions(from, to);
 
         wxCHECK_RET( to <= GetLastPosition(),
@@ -1458,8 +1481,8 @@ void wxTextCtrl::SetSelection(wxTextPos from, wxTextPos to)
         }
         //else: nothing to do
 
         }
         //else: nothing to do
 
-        // the insertion point is put at the end of selection
-        DoSetInsertionPoint(to);
+        // the insertion point is put at the location where the caret was moved
+        DoSetInsertionPoint(toOrig);
     }
 }
 
     }
 }
 
@@ -1562,6 +1585,11 @@ bool wxTextCtrl::IsEditable() const
     return m_isEditable && IsEnabled();
 }
 
     return m_isEditable && IsEnabled();
 }
 
+void wxTextCtrl::MarkDirty()
+{
+    m_isModified = TRUE;
+}
+
 void wxTextCtrl::DiscardEdits()
 {
     m_isModified = FALSE;
 void wxTextCtrl::DiscardEdits()
 {
     m_isModified = FALSE;
@@ -1620,6 +1648,9 @@ wxString wxTextCtrl::GetLineText(wxTextCoord line) const
     }
     else // multiline
     {
     }
     else // multiline
     {
+        //this is called during DoGetBestSize
+        if (line == 0 && GetLineCount() == 0) return wxEmptyString ;
+       
         wxCHECK_MSG( (size_t)line < GetLineCount(), _T(""),
                      _T("line index out of range") );
 
         wxCHECK_MSG( (size_t)line < GetLineCount(), _T(""),
                      _T("line index out of range") );
 
@@ -1850,7 +1881,9 @@ wxPoint wxTextCtrl::GetCaretPosition() const
 // pos may be -1 to show the current position
 void wxTextCtrl::ShowPosition(wxTextPos pos)
 {
 // pos may be -1 to show the current position
 void wxTextCtrl::ShowPosition(wxTextPos pos)
 {
-    HideCaret();
+    bool showCaret = GetCaret() && GetCaret()->IsVisible();
+    if (showCaret)
+        HideCaret();
 
     if ( IsSingleLine() )
     {
 
     if ( IsSingleLine() )
     {
@@ -1970,7 +2003,8 @@ void wxTextCtrl::ShowPosition(wxTextPos pos)
     }
     //else: multiline but no scrollbars, hence nothing to do
 
     }
     //else: multiline but no scrollbars, hence nothing to do
 
-    ShowCaret();
+    if (showCaret)
+        ShowCaret();
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -2314,7 +2348,7 @@ wxSize wxTextCtrl::DoGetBestClientSize() const
             lines = 5;
         else if ( lines > 10 )
             lines = 10;
             lines = 5;
         else if ( lines > 10 )
             lines = 10;
-        h *= 10;
+        h *= lines;
     }
 
     wxRect rectText;
     }
 
     wxRect rectText;
@@ -2429,7 +2463,7 @@ void wxTextCtrl::UpdateLastVisible()
     SData().m_colLastVisible += SData().m_colStart;
 
     wxLogTrace(_T("text"), _T("Last visible column/position is %d/%ld"),
     SData().m_colLastVisible += SData().m_colStart;
 
     wxLogTrace(_T("text"), _T("Last visible column/position is %d/%ld"),
-               SData().m_colLastVisible, SData().m_posLastVisible);
+               (int) SData().m_colLastVisible, (long) SData().m_posLastVisible);
 }
 
 void wxTextCtrl::OnSize(wxSizeEvent& event)
 }
 
 void wxTextCtrl::OnSize(wxSizeEvent& event)
@@ -3555,7 +3589,7 @@ void wxTextCtrl::UpdateScrollbars()
     MData().m_updateScrollbarY = FALSE;
 }
 
     MData().m_updateScrollbarY = FALSE;
 }
 
-void wxTextCtrl::OnIdle(wxIdleEvent& event)
+void wxTextCtrl::OnInternalIdle()
 {
     // notice that single line text control never has scrollbars
     if ( !IsSingleLine() &&
 {
     // notice that single line text control never has scrollbars
     if ( !IsSingleLine() &&
@@ -3563,8 +3597,7 @@ void wxTextCtrl::OnIdle(wxIdleEvent& event)
     {
         UpdateScrollbars();
     }
     {
         UpdateScrollbars();
     }
-
-    event.Skip();
+    wxControl::OnInternalIdle();
 }
 
 bool wxTextCtrl::SendAutoScrollEvents(wxScrollWinEvent& event) const
 }
 
 bool wxTextCtrl::SendAutoScrollEvents(wxScrollWinEvent& event) const
@@ -4101,6 +4134,7 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer)
     // the update region is in window coords and text area is in the client
     // ones, so it must be shifted before computing intersection
     wxRegion rgnUpdate = GetUpdateRegion();
     // the update region is in window coords and text area is in the client
     // ones, so it must be shifted before computing intersection
     wxRegion rgnUpdate = GetUpdateRegion();
+    
     wxRect rectTextArea = GetRealTextArea();
     wxPoint pt = GetClientAreaOrigin();
     wxRect rectTextAreaAdjusted = rectTextArea;
     wxRect rectTextArea = GetRealTextArea();
     wxPoint pt = GetClientAreaOrigin();
     wxRect rectTextAreaAdjusted = rectTextArea;
@@ -4165,7 +4199,7 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer)
 
     // show caret first time only: we must show it after drawing the text or
     // the display can be corrupted when it's hidden
 
     // show caret first time only: we must show it after drawing the text or
     // the display can be corrupted when it's hidden
-    if ( !m_hasCaret && GetCaret() )
+    if ( !m_hasCaret && GetCaret() && (FindFocus() == this) )
     {
         ShowCaret();
 
     {
         ShowCaret();
 
@@ -4208,7 +4242,10 @@ bool wxTextCtrl::Enable(bool enable)
     if ( !wxTextCtrlBase::Enable(enable) )
         return FALSE;
 
     if ( !wxTextCtrlBase::Enable(enable) )
         return FALSE;
 
-    ShowCaret(enable);
+    if (FindFocus() == this && GetCaret() &&
+        ((enable && !GetCaret()->IsVisible()) ||
+         (!enable && GetCaret()->IsVisible())))
+        ShowCaret(enable);
 
     return TRUE;
 }
 
     return TRUE;
 }
@@ -4244,7 +4281,9 @@ void wxTextCtrl::ShowCaret(bool show)
         caret->Move(GetCaretPosition());
 
         // and show it there
         caret->Move(GetCaretPosition());
 
         // and show it there
-        caret->Show(show);
+        if ((show && !caret->IsVisible()) ||
+            (!show && caret->IsVisible()))
+            caret->Show(show);
     }
 }
 
     }
 }
 
@@ -4705,7 +4744,7 @@ wxTextPos wxStdTextCtrlInputHandler::HitTest(const wxTextCtrl *text,
     return pos;
 }
 
     return pos;
 }
 
-bool wxStdTextCtrlInputHandler::HandleKey(wxControl *control,
+bool wxStdTextCtrlInputHandler::HandleKey(wxInputConsumer *consumer,
                                           const wxKeyEvent& event,
                                           bool pressed)
 {
                                           const wxKeyEvent& event,
                                           bool pressed)
 {
@@ -4822,22 +4861,22 @@ bool wxStdTextCtrlInputHandler::HandleKey(wxControl *control,
 
     if ( (action != wxACTION_NONE) && (action != wxACTION_TEXT_PREFIX_SEL) )
     {
 
     if ( (action != wxACTION_NONE) && (action != wxACTION_TEXT_PREFIX_SEL) )
     {
-        control->PerformAction(action, -1, str);
+        consumer->PerformAction(action, -1, str);
 
         return TRUE;
     }
 
 
         return TRUE;
     }
 
-    return wxStdInputHandler::HandleKey(control, event, pressed);
+    return wxStdInputHandler::HandleKey(consumer, event, pressed);
 }
 
 }
 
-bool wxStdTextCtrlInputHandler::HandleMouse(wxControl *control,
+bool wxStdTextCtrlInputHandler::HandleMouse(wxInputConsumer *consumer,
                                             const wxMouseEvent& event)
 {
     if ( event.LeftDown() )
     {
         wxASSERT_MSG( !m_winCapture, _T("left button going down twice?") );
 
                                             const wxMouseEvent& event)
 {
     if ( event.LeftDown() )
     {
         wxASSERT_MSG( !m_winCapture, _T("left button going down twice?") );
 
-        wxTextCtrl *text = wxStaticCast(control, wxTextCtrl);
+        wxTextCtrl *text = wxStaticCast(consumer->GetInputWindow(), wxTextCtrl);
 
         m_winCapture = text;
         m_winCapture->CaptureMouse();
 
         m_winCapture = text;
         m_winCapture->CaptureMouse();
@@ -4853,7 +4892,7 @@ bool wxStdTextCtrlInputHandler::HandleMouse(wxControl *control,
     else if ( event.LeftDClick() )
     {
         // select the word the cursor is on
     else if ( event.LeftDClick() )
     {
         // select the word the cursor is on
-        control->PerformAction(wxACTION_TEXT_SEL_WORD);
+        consumer->PerformAction(wxACTION_TEXT_SEL_WORD);
     }
     else if ( event.LeftUp() )
     {
     }
     else if ( event.LeftUp() )
     {
@@ -4866,10 +4905,10 @@ bool wxStdTextCtrlInputHandler::HandleMouse(wxControl *control,
         }
     }
 
         }
     }
 
-    return wxStdInputHandler::HandleMouse(control, event);
+    return wxStdInputHandler::HandleMouse(consumer, event);
 }
 
 }
 
-bool wxStdTextCtrlInputHandler::HandleMouseMove(wxControl *control,
+bool wxStdTextCtrlInputHandler::HandleMouseMove(wxInputConsumer *consumer,
                                                 const wxMouseEvent& event)
 {
     if ( m_winCapture )
                                                 const wxMouseEvent& event)
 {
     if ( m_winCapture )
@@ -4883,17 +4922,29 @@ bool wxStdTextCtrlInputHandler::HandleMouseMove(wxControl *control,
         }
     }
 
         }
     }
 
-    return wxStdInputHandler::HandleMouseMove(control, event);
+    return wxStdInputHandler::HandleMouseMove(consumer, event);
 }
 
 }
 
-bool wxStdTextCtrlInputHandler::HandleFocus(wxControl *control,
-                                            const wxFocusEvent& event)
+bool
+wxStdTextCtrlInputHandler::HandleFocus(wxInputConsumer *consumer,
+                                       const wxFocusEvent& event)
 {
 {
-    wxTextCtrl *text = wxStaticCast(control, wxTextCtrl);
+    wxTextCtrl *text = wxStaticCast(consumer->GetInputWindow(), wxTextCtrl);
 
     // the selection appearance changes depending on whether we have the focus
     text->RefreshSelection();
 
 
     // the selection appearance changes depending on whether we have the focus
     text->RefreshSelection();
 
+    if (event.GetEventType() == wxEVT_SET_FOCUS)
+    {
+        if (text->GetCaret() && !text->GetCaret()->IsVisible())
+            text->ShowCaret();
+    }
+    else
+    {
+        if (text->GetCaret() && text->GetCaret()->IsVisible())
+            text->HideCaret();
+    }
+
     // never refresh entirely
     return FALSE;
 }
     // never refresh entirely
     return FALSE;
 }