X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f51723055aa4334a355a19e87bb2b478b4204d15..2028c33ab5a39a12bd410ac953731a56ad6377ba:/src/richtext/richtextctrl.cpp diff --git a/src/richtext/richtextctrl.cpp b/src/richtext/richtextctrl.cpp index c5d22f1600..be2bc269ee 100644 --- a/src/richtext/richtextctrl.cpp +++ b/src/richtext/richtextctrl.cpp @@ -26,6 +26,7 @@ #include "wx/settings.h" #endif +#include "wx/timer.h" #include "wx/textfile.h" #include "wx/ffile.h" #include "wx/filename.h" @@ -67,18 +68,30 @@ wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_BUFFER_RESET, wxRichTextEvent ); * wxRICHTEXT_USE_OWN_CARET is set in richtextbuffer.h. */ +class wxRichTextCaret; +class wxRichTextCaretTimer: public wxTimer +{ + public: + wxRichTextCaretTimer(wxRichTextCaret* caret) + { + m_caret = caret; + } + virtual void Notify(); + wxRichTextCaret* m_caret; +}; + class wxRichTextCaret: public wxCaret { public: // ctors // ----- // default - use Create() - wxRichTextCaret() { Init(); } + wxRichTextCaret(): m_timer(this) { Init(); } // creates a block caret associated with the given window wxRichTextCaret(wxRichTextCtrl *window, int width, int height) - : wxCaret(window, width, height) { Init(); m_richTextCtrl = window; } + : wxCaret(window, width, height), m_timer(this) { Init(); m_richTextCtrl = window; } wxRichTextCaret(wxRichTextCtrl *window, const wxSize& size) - : wxCaret(window, size) { Init(); m_richTextCtrl = window; } + : wxCaret(window, size), m_timer(this) { Init(); m_richTextCtrl = window; } virtual ~wxRichTextCaret(); @@ -99,6 +112,8 @@ public: bool GetNeedsUpdate() const { return m_needsUpdate; } void SetNeedsUpdate(bool needsUpdate = true ) { m_needsUpdate = needsUpdate; } + void Notify(); + protected: virtual void DoShow(); virtual void DoHide(); @@ -115,7 +130,8 @@ private: m_yOld; bool m_hasFocus; // true => our window has focus bool m_needsUpdate; // must be repositioned - + bool m_flashOn; + wxRichTextCaretTimer m_timer; wxRichTextCtrl* m_richTextCtrl; }; #endif @@ -196,6 +212,8 @@ wxRichTextCtrl::wxRichTextCtrl(wxWindow* parent, bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name) { + style |= wxVSCROLL; + if (!wxTextCtrlBase::Create(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, validator, name)) @@ -271,6 +289,17 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va wxAcceleratorTable accel(6, entries); SetAcceleratorTable(accel); + m_contextMenu = new wxMenu; + m_contextMenu->Append(wxID_UNDO, _("&Undo")); + m_contextMenu->Append(wxID_REDO, _("&Redo")); + m_contextMenu->AppendSeparator(); + m_contextMenu->Append(wxID_CUT, _("Cu&t")); + m_contextMenu->Append(wxID_COPY, _("&Copy")); + m_contextMenu->Append(wxID_PASTE, _("&Paste")); + m_contextMenu->Append(wxID_CLEAR, _("&Delete")); + m_contextMenu->AppendSeparator(); + m_contextMenu->Append(wxID_SELECTALL, _("Select &All")); + return true; } @@ -674,23 +703,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) if (event.GetEventType() == wxEVT_KEY_DOWN) { - if (event.GetKeyCode() == WXK_LEFT || - event.GetKeyCode() == WXK_RIGHT || - event.GetKeyCode() == WXK_UP || - event.GetKeyCode() == WXK_DOWN || - event.GetKeyCode() == WXK_HOME || - event.GetKeyCode() == WXK_PAGEUP || - event.GetKeyCode() == WXK_PAGEDOWN || - event.GetKeyCode() == WXK_END || - - event.GetKeyCode() == WXK_NUMPAD_LEFT || - event.GetKeyCode() == WXK_NUMPAD_RIGHT || - event.GetKeyCode() == WXK_NUMPAD_UP || - event.GetKeyCode() == WXK_NUMPAD_DOWN || - event.GetKeyCode() == WXK_NUMPAD_HOME || - event.GetKeyCode() == WXK_NUMPAD_PAGEUP || - event.GetKeyCode() == WXK_NUMPAD_PAGEDOWN || - event.GetKeyCode() == WXK_NUMPAD_END) + if (event.IsKeyInCategory(WXK_CATEGORY_NAVIGATION)) { KeyboardNavigate(event.GetKeyCode(), flags); return; @@ -766,7 +779,6 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) case WXK_NUMPAD_END: case WXK_NUMPAD_BEGIN: case WXK_NUMPAD_INSERT: - case WXK_NUMPAD_DELETE: case WXK_WINDOWS_LEFT: { return; @@ -951,7 +963,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) } } - if (!processed) + if (!processed && newPos < (GetLastPosition()-1)) GetBuffer().DeleteRangeWithUndo(wxRichTextRange(newPos+1, newPos+1), this); } @@ -992,7 +1004,8 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) #ifdef __WXMAC__ if (event.CmdDown()) #else - if (event.CmdDown() || event.AltDown()) + // Fixes AltGr+key with European input languages on Windows + if ((event.CmdDown() && !event.AltDown()) || (event.AltDown() && !event.CmdDown())) #endif { event.Skip(); @@ -1066,7 +1079,15 @@ bool wxRichTextCtrl::DeleteSelectedContent(long* newPos) if (HasSelection()) { long pos = m_selectionRange.GetStart(); - GetBuffer().DeleteRangeWithUndo(m_selectionRange, this); + wxRichTextRange range = m_selectionRange; + + // SelectAll causes more to be selected than doing it interactively, + // and causes a new paragraph to be inserted. So for multiline buffers, + // don't delete the final position. + if (range.GetEnd() == GetLastPosition() && GetNumberOfLines() > 0) + range.SetEnd(range.GetEnd()-1); + + GetBuffer().DeleteRangeWithUndo(range, this); m_selectionRange.SetRange(-2, -2); if (newPos) @@ -2046,7 +2067,7 @@ void wxRichTextCtrl::SetupScrollbars(bool atTop) return; // Don't set scrollbars if there were none before, and there will be none now. - if (oldPPUY != 0 && (oldVirtualSizeY < clientSize.y) && (unitsY*pixelsPerUnit < clientSize.y)) + if (oldPPUY != 0 && (oldVirtualSizeY*oldPPUY < clientSize.y) && (unitsY*pixelsPerUnit < clientSize.y)) return; // Move to previous scroll position if @@ -2161,8 +2182,7 @@ wxRichTextRange wxRichTextCtrl::AddImage(const wxImage& image) void wxRichTextCtrl::SelectAll() { - SetSelection(0, GetLastPosition()+1); - m_selectionAnchor = -1; + SetSelection(-1, -1); } /// Select none @@ -2294,7 +2314,7 @@ wxRichTextCtrl::HitTest(const wxPoint& pt, // set/get the controls text // ---------------------------------------------------------------------------- -wxString wxRichTextCtrl::GetValue() const +wxString wxRichTextCtrl::DoGetValue() const { return GetBuffer().GetText(); } @@ -2502,6 +2522,13 @@ bool wxRichTextCtrl::CanDeleteSelection() const // Accessors // ---------------------------------------------------------------------------- +void wxRichTextCtrl::SetContextMenu(wxMenu* menu) +{ + if (m_contextMenu && m_contextMenu != menu) + delete m_contextMenu; + m_contextMenu = menu; +} + void wxRichTextCtrl::SetEditable(bool editable) { m_editable = editable; @@ -2514,6 +2541,8 @@ void wxRichTextCtrl::SetInsertionPoint(long pos) m_caretPosition = pos - 1; PositionCaret(); + + SetDefaultStyleToCursorStyle(); } void wxRichTextCtrl::SetInsertionPointEnd() @@ -2561,11 +2590,6 @@ void wxRichTextCtrl::SetSelection(long from, long to) to = GetLastPosition()+1; } - DoSetSelection(from, to); -} - -void wxRichTextCtrl::DoSetSelection(long from, long to, bool WXUNUSED(scrollCaret)) -{ if (from == to) { SelectNone(); @@ -2573,10 +2597,10 @@ void wxRichTextCtrl::DoSetSelection(long from, long to, bool WXUNUSED(scrollCare else { wxRichTextRange oldSelection = m_selectionRange; - m_selectionAnchor = from; + m_selectionAnchor = from-1; m_selectionRange.SetRange(from, to-1); - if (from > -2) - m_caretPosition = from-1; + + m_caretPosition = wxMax(-1, to-2); RefreshForSelectionChange(oldSelection, m_selectionRange); PositionCaret(); @@ -2788,7 +2812,8 @@ void wxRichTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event) void wxRichTextCtrl::OnSelectAll(wxCommandEvent& WXUNUSED(event)) { - SelectAll(); + if (GetLastPosition() > 0) + SelectAll(); } void wxRichTextCtrl::OnUpdateSelectAll(wxUpdateUIEvent& event) @@ -2804,20 +2829,8 @@ void wxRichTextCtrl::OnContextMenu(wxContextMenuEvent& event) return; } - if (!m_contextMenu) - { - m_contextMenu = new wxMenu; - m_contextMenu->Append(wxID_UNDO, _("&Undo")); - m_contextMenu->Append(wxID_REDO, _("&Redo")); - m_contextMenu->AppendSeparator(); - m_contextMenu->Append(wxID_CUT, _("Cu&t")); - m_contextMenu->Append(wxID_COPY, _("&Copy")); - m_contextMenu->Append(wxID_PASTE, _("&Paste")); - m_contextMenu->Append(wxID_CLEAR, _("&Delete")); - m_contextMenu->AppendSeparator(); - m_contextMenu->Append(wxID_SELECTALL, _("Select &All")); - } - PopupMenu(m_contextMenu); + if (m_contextMenu) + PopupMenu(m_contextMenu); return; } @@ -3339,13 +3352,7 @@ wxRichTextRange wxRichTextCtrl::GetSelectionRange() const void wxRichTextCtrl::SetSelectionRange(const wxRichTextRange& range) { - wxRichTextRange range1(range); - if (range1 != wxRichTextRange(-2,-2) && range1 != wxRichTextRange(-1,-1) ) - range1.SetEnd(range1.GetEnd() - 1); - - wxASSERT( range1.GetStart() > range1.GetEnd() ); - - SetInternalSelectionRange(range1); + SetSelection(range.GetStart(), range.GetEnd()); } /// Set list style @@ -3482,10 +3489,13 @@ void wxRichTextCaret::Init() m_yOld = -1; m_richTextCtrl = NULL; m_needsUpdate = false; + m_flashOn = true; } wxRichTextCaret::~wxRichTextCaret() { + if (m_timer.IsRunning()) + m_timer.Stop(); } // ---------------------------------------------------------------------------- @@ -3494,11 +3504,19 @@ wxRichTextCaret::~wxRichTextCaret() void wxRichTextCaret::DoShow() { + m_flashOn = true; + + if (!m_timer.IsRunning()) + m_timer.Start(GetBlinkTime()); + Refresh(); } void wxRichTextCaret::DoHide() { + if (m_timer.IsRunning()) + m_timer.Stop(); + Refresh(); } @@ -3575,17 +3593,25 @@ void wxRichTextCaret::DoDraw(wxDC *dc) dc->SetBrush(*(m_hasFocus ? wxBLACK_BRUSH : wxTRANSPARENT_BRUSH)); dc->SetPen(*wxBLACK_PEN); - // VZ: unfortunately, the rectangle comes out a pixel smaller when this is - // done under wxGTK - no idea why - //dc->SetLogicalFunction(wxINVERT); - wxPoint pt(m_x, m_y); if (m_richTextCtrl) { pt = m_richTextCtrl->GetLogicalPoint(pt); } - dc->DrawRectangle(pt.x, pt.y, m_width, m_height); + if (IsVisible() && m_flashOn) + dc->DrawRectangle(pt.x, pt.y, m_width, m_height); +} + +void wxRichTextCaret::Notify() +{ + m_flashOn = !m_flashOn; + Refresh(); +} + +void wxRichTextCaretTimer::Notify() +{ + m_caret->Notify(); } #endif // wxRICHTEXT_USE_OWN_CARET