]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/textctrl.cpp
wxMenu::Append (and similar) now return a pointer to the wxMenuItem
[wxWidgets.git] / src / univ / textctrl.cpp
index 98b53bda8a47bc6118e19f94746a0ddc3699620d..3111cdf4bdfb74ad8209f0f2023e3fe0d04e79b1 100644 (file)
@@ -5,8 +5,8 @@
 // Modified by:
 // Created:     15.09.00
 // RCS-ID:      $Id$
 // Modified by:
 // Created:     15.09.00
 // RCS-ID:      $Id$
-// Copyright:   (c) 2000 Vadim Zeitlin
-// Licence:     wxWindows license
+// Copyright:   (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
+// 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"
 
 #endif
 
 #include "wx/clipbrd.h"
 #endif
 
 #include "wx/clipbrd.h"
+
 #include "wx/textfile.h"
 
 #include "wx/caret.h"
 #include "wx/textfile.h"
 
 #include "wx/caret.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
 
@@ -521,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:
@@ -544,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:
@@ -603,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)
@@ -660,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 (?)
 
@@ -683,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) )
@@ -724,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;
 }
 
@@ -1412,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(),
@@ -1457,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);
     }
 }
 
     }
 }
 
@@ -1561,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;
@@ -1735,6 +1764,8 @@ wxTextCoord wxTextCtrl::GetRowsPerLine(wxTextCoord line) const
 wxTextCoord wxTextCtrl::GetRowCount() const
 {
     wxTextCoord count = GetLineCount();
 wxTextCoord wxTextCtrl::GetRowCount() const
 {
     wxTextCoord count = GetLineCount();
+    if (count == 0)
+        return 0;
     if ( WrapLines() )
     {
         count = GetFirstRowOfLine(count - 1) +
     if ( WrapLines() )
     {
         count = GetFirstRowOfLine(count - 1) +
@@ -1847,7 +1878,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() )
     {
@@ -1967,7 +2000,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();
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -2311,7 +2345,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;
@@ -2426,7 +2460,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)
@@ -3552,7 +3586,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() &&
@@ -3560,8 +3594,7 @@ void wxTextCtrl::OnIdle(wxIdleEvent& event)
     {
         UpdateScrollbars();
     }
     {
         UpdateScrollbars();
     }
-
-    event.Skip();
+    wxControl::OnInternalIdle();
 }
 
 bool wxTextCtrl::SendAutoScrollEvents(wxScrollWinEvent& event) const
 }
 
 bool wxTextCtrl::SendAutoScrollEvents(wxScrollWinEvent& event) const
@@ -4098,6 +4131,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;
@@ -4162,7 +4196,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();
 
@@ -4205,7 +4239,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;
 }
@@ -4241,7 +4278,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);
     }
 }
 
     }
 }
 
@@ -4702,7 +4741,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)
 {
@@ -4819,22 +4858,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();
@@ -4850,7 +4889,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() )
     {
@@ -4863,10 +4902,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 )
@@ -4880,17 +4919,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;
 }