#include "wx/settings.h"
#endif
+#include "wx/timer.h"
#include "wx/textfile.h"
#include "wx/ffile.h"
#include "wx/filename.h"
#include "wx/dcbuffer.h"
#include "wx/arrimpl.cpp"
#include "wx/fontenum.h"
+#include "wx/accel.h"
// DLL options compatibility check:
#include "wx/app.h"
WX_CHECK_BUILD_OPTIONS("wxRichTextCtrl")
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_LEFT_CLICK)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_MIDDLE_CLICK)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_RIGHT_CLICK)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_LEFT_DCLICK)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_RETURN)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_CHARACTER)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_DELETE)
-
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACING)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACED)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_STYLESHEET_CHANGING)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_STYLESHEET_CHANGED)
-
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_CONTENT_INSERTED)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_SELECTION_CHANGED)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_BUFFER_RESET)
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_LEFT_CLICK, wxRichTextEvent );
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_MIDDLE_CLICK, wxRichTextEvent );
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_RIGHT_CLICK, wxRichTextEvent );
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_LEFT_DCLICK, wxRichTextEvent );
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_RETURN, wxRichTextEvent );
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_CHARACTER, wxRichTextEvent );
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_DELETE, wxRichTextEvent );
+
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACING, wxRichTextEvent );
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACED, wxRichTextEvent );
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_STYLESHEET_CHANGING, wxRichTextEvent );
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_STYLESHEET_CHANGED, wxRichTextEvent );
+
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_CONTENT_INSERTED, wxRichTextEvent );
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED, wxRichTextEvent );
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED, wxRichTextEvent );
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_SELECTION_CHANGED, wxRichTextEvent );
+wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_BUFFER_RESET, wxRichTextEvent );
#if wxRICHTEXT_USE_OWN_CARET
* 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();
bool GetNeedsUpdate() const { return m_needsUpdate; }
void SetNeedsUpdate(bool needsUpdate = true ) { m_needsUpdate = needsUpdate; }
+ void Notify();
+
protected:
virtual void DoShow();
virtual void DoHide();
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
-IMPLEMENT_CLASS( wxRichTextCtrl, wxControl )
+IMPLEMENT_DYNAMIC_CLASS( wxRichTextCtrl, wxTextCtrlBase )
-IMPLEMENT_CLASS( wxRichTextEvent, wxNotifyEvent )
+IMPLEMENT_DYNAMIC_CLASS( wxRichTextEvent, wxNotifyEvent )
-BEGIN_EVENT_TABLE( wxRichTextCtrl, wxControl )
+BEGIN_EVENT_TABLE( wxRichTextCtrl, wxTextCtrlBase )
EVT_PAINT(wxRichTextCtrl::OnPaint)
EVT_ERASE_BACKGROUND(wxRichTextCtrl::OnEraseBackground)
EVT_IDLE(wxRichTextCtrl::OnIdle)
EVT_MIDDLE_DOWN(wxRichTextCtrl::OnMiddleClick)
EVT_LEFT_DCLICK(wxRichTextCtrl::OnLeftDClick)
EVT_CHAR(wxRichTextCtrl::OnChar)
+ EVT_KEY_DOWN(wxRichTextCtrl::OnChar)
EVT_SIZE(wxRichTextCtrl::OnSize)
EVT_SET_FOCUS(wxRichTextCtrl::OnSetFocus)
EVT_KILL_FOCUS(wxRichTextCtrl::OnKillFocus)
bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style,
const wxValidator& validator, const wxString& name)
{
- if (!wxControl::Create(parent, id, pos, size,
+ style |= wxVSCROLL;
+
+ if (!wxTextCtrlBase::Create(parent, id, pos, size,
style|wxFULL_REPAINT_ON_RESIZE,
validator, name))
return false;
SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
}
+ // No physical scrolling, so we can preserve margins
+ EnableScrolling(false, false);
+
if (style & wxTE_READONLY)
SetEditable(false);
attributes.SetLineSpacing(10);
attributes.SetParagraphSpacingAfter(10);
attributes.SetParagraphSpacingBefore(0);
- attributes.SetTextEffects(0);
- attributes.SetTextEffectFlags(wxTEXT_ATTR_EFFECT_STRIKETHROUGH|wxTEXT_ATTR_EFFECT_CAPITALS);
SetBasicStyle(attributes);
GetBuffer().AddEventHandler(this);
+ // Accelerators
+ wxAcceleratorEntry entries[6];
+
+ entries[0].Set(wxACCEL_CMD, (int) 'C', wxID_COPY);
+ entries[1].Set(wxACCEL_CMD, (int) 'X', wxID_CUT);
+ entries[2].Set(wxACCEL_CMD, (int) 'V', wxID_PASTE);
+ entries[3].Set(wxACCEL_CMD, (int) 'A', wxID_SELECTALL);
+ entries[4].Set(wxACCEL_CMD, (int) 'Z', wxID_UNDO);
+ entries[5].Set(wxACCEL_CMD, (int) 'Y', wxID_REDO);
+
+ 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;
}
LayoutContent();
else
SetupScrollbars();
- Refresh(false);
+
+ wxWindow::DoThaw();
}
/// Clear all text
SetupScrollbars();
}
+ wxRect clipRect(availableSpace);
+ clipRect.x += GetBuffer().GetLeftMargin();
+ clipRect.y += GetBuffer().GetTopMargin();
+ clipRect.width -= (GetBuffer().GetLeftMargin() + GetBuffer().GetRightMargin());
+ clipRect.height -= (GetBuffer().GetTopMargin() + GetBuffer().GetBottomMargin());
+ clipRect.SetPosition(GetLogicalPoint(clipRect.GetPosition()));
+ dc.SetClippingRegion(clipRect);
+
GetBuffer().Draw(dc, GetBuffer().GetRange(), GetInternalSelectionRange(), drawingArea, 0 /* descent */, 0 /* flags */);
+
+ dc.DestroyClippingRegion();
+
+ // Other user defined painting after everything else (i.e. all text) is painted
+ PaintAboveContent(dc);
+
#if wxRICHTEXT_USE_OWN_CARET
if (GetCaret()->IsVisible())
{
if (event.AltDown())
flags |= wxRICHTEXT_ALT_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)
- {
- KeyboardNavigate(event.GetKeyCode(), flags);
+ if (event.GetEventType() == wxEVT_KEY_DOWN)
+ {
+ if (event.IsKeyInCategory(WXK_CATEGORY_NAVIGATION))
+ {
+ KeyboardNavigate(event.GetKeyCode(), flags);
+ return;
+ }
+
+ long keycode = event.GetKeyCode();
+ switch ( keycode )
+ {
+ case WXK_ESCAPE:
+ case WXK_START:
+ case WXK_LBUTTON:
+ case WXK_RBUTTON:
+ case WXK_CANCEL:
+ case WXK_MBUTTON:
+ case WXK_CLEAR:
+ case WXK_SHIFT:
+ case WXK_ALT:
+ case WXK_CONTROL:
+ case WXK_MENU:
+ case WXK_PAUSE:
+ case WXK_CAPITAL:
+ case WXK_END:
+ case WXK_HOME:
+ case WXK_LEFT:
+ case WXK_UP:
+ case WXK_RIGHT:
+ case WXK_DOWN:
+ case WXK_SELECT:
+ case WXK_PRINT:
+ case WXK_EXECUTE:
+ case WXK_SNAPSHOT:
+ case WXK_INSERT:
+ case WXK_HELP:
+ case WXK_F1:
+ case WXK_F2:
+ case WXK_F3:
+ case WXK_F4:
+ case WXK_F5:
+ case WXK_F6:
+ case WXK_F7:
+ case WXK_F8:
+ case WXK_F9:
+ case WXK_F10:
+ case WXK_F11:
+ case WXK_F12:
+ case WXK_F13:
+ case WXK_F14:
+ case WXK_F15:
+ case WXK_F16:
+ case WXK_F17:
+ case WXK_F18:
+ case WXK_F19:
+ case WXK_F20:
+ case WXK_F21:
+ case WXK_F22:
+ case WXK_F23:
+ case WXK_F24:
+ case WXK_NUMLOCK:
+ case WXK_SCROLL:
+ case WXK_PAGEUP:
+ case WXK_PAGEDOWN:
+ case WXK_NUMPAD_F1:
+ case WXK_NUMPAD_F2:
+ case WXK_NUMPAD_F3:
+ case WXK_NUMPAD_F4:
+ case WXK_NUMPAD_HOME:
+ case WXK_NUMPAD_LEFT:
+ case WXK_NUMPAD_UP:
+ case WXK_NUMPAD_RIGHT:
+ case WXK_NUMPAD_DOWN:
+ case WXK_NUMPAD_PAGEUP:
+ case WXK_NUMPAD_PAGEDOWN:
+ case WXK_NUMPAD_END:
+ case WXK_NUMPAD_BEGIN:
+ case WXK_NUMPAD_INSERT:
+ case WXK_WINDOWS_LEFT:
+ {
+ return;
+ }
+ default:
+ {
+ }
+ }
+
+ // Must process this before translation, otherwise it's translated into a WXK_DELETE event.
+ if (event.CmdDown() && event.GetKeyCode() == WXK_BACK)
+ {
+ BeginBatchUndo(_("Delete Text"));
+
+ long newPos = m_caretPosition;
+
+ bool processed = DeleteSelectedContent(& newPos);
+
+ // Submit range in character positions, which are greater than caret positions,
+ // so subtract 1 for deleted character and add 1 for conversion to character position.
+ if (newPos > -1)
+ {
+ if (event.CmdDown())
+ {
+ long pos = wxRichTextCtrl::FindNextWordPosition(-1);
+ if (pos < newPos)
+ {
+ GetBuffer().DeleteRangeWithUndo(wxRichTextRange(pos+1, newPos), this);
+ processed = true;
+ }
+ }
+
+ if (!processed)
+ GetBuffer().DeleteRangeWithUndo(wxRichTextRange(newPos, newPos), this);
+ }
+
+ EndBatchUndo();
+
+ if (GetLastPosition() == -1)
+ {
+ GetBuffer().Reset();
+
+ m_caretPosition = -1;
+ PositionCaret();
+ SetDefaultStyleToCursorStyle();
+ }
+
+ ScrollIntoView(m_caretPosition, WXK_LEFT);
+
+ wxRichTextEvent cmdEvent(
+ wxEVT_COMMAND_RICHTEXT_DELETE,
+ GetId());
+ cmdEvent.SetEventObject(this);
+ cmdEvent.SetFlags(flags);
+ cmdEvent.SetPosition(m_caretPosition+1);
+ GetEventHandler()->ProcessEvent(cmdEvent);
+
+ Update();
+ }
+ else
+ event.Skip();
+
return;
}
wxString text;
text = wxRichTextLineBreakChar;
GetBuffer().InsertTextWithUndo(newPos+1, text, this);
+ m_caretAtLineStart = true;
+ PositionCaret();
}
else
GetBuffer().InsertNewlineWithUndo(newPos+1, this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE|wxRICHTEXT_INSERT_INTERACTIVE);
{
BeginBatchUndo(_("Delete Text"));
+ long newPos = m_caretPosition;
+
+ bool processed = DeleteSelectedContent(& newPos);
+
// Submit range in character positions, which are greater than caret positions,
// so subtract 1 for deleted character and add 1 for conversion to character position.
- if (m_caretPosition > -1 && !HasSelection())
+ if (newPos > -1)
{
- bool processed = false;
if (event.CmdDown())
{
long pos = wxRichTextCtrl::FindNextWordPosition(-1);
- if (pos != -1 && (pos < m_caretPosition))
+ if (pos < newPos)
{
- GetBuffer().DeleteRangeWithUndo(wxRichTextRange(pos+1, m_caretPosition), this);
+ GetBuffer().DeleteRangeWithUndo(wxRichTextRange(pos+1, newPos), this);
processed = true;
}
}
if (!processed)
- GetBuffer().DeleteRangeWithUndo(wxRichTextRange(m_caretPosition, m_caretPosition), this);
+ GetBuffer().DeleteRangeWithUndo(wxRichTextRange(newPos, newPos), this);
}
- else
- DeleteSelectedContent();
EndBatchUndo();
{
BeginBatchUndo(_("Delete Text"));
+ long newPos = m_caretPosition;
+
+ bool processed = DeleteSelectedContent(& newPos);
+
// Submit range in character positions, which are greater than caret positions,
- if (m_caretPosition < GetBuffer().GetRange().GetEnd()+1 && !HasSelection())
+ if (newPos < GetBuffer().GetRange().GetEnd()+1)
{
- GetBuffer().DeleteRangeWithUndo(wxRichTextRange(m_caretPosition+1, m_caretPosition+1), this);
+ if (event.CmdDown())
+ {
+ long pos = wxRichTextCtrl::FindNextWordPosition(1);
+ if (pos != -1 && (pos > newPos))
+ {
+ GetBuffer().DeleteRangeWithUndo(wxRichTextRange(newPos+1, pos), this);
+ processed = true;
+ }
+ }
+
+ if (!processed && newPos < (GetLastPosition()-1))
+ GetBuffer().DeleteRangeWithUndo(wxRichTextRange(newPos+1, newPos+1), this);
}
- else
- DeleteSelectedContent();
EndBatchUndo();
switch ( keycode )
{
case WXK_ESCAPE:
- case WXK_DELETE:
- case WXK_START:
- case WXK_LBUTTON:
- case WXK_RBUTTON:
- case WXK_CANCEL:
- case WXK_MBUTTON:
- case WXK_CLEAR:
- case WXK_SHIFT:
- case WXK_ALT:
- case WXK_CONTROL:
- case WXK_MENU:
- case WXK_PAUSE:
- case WXK_CAPITAL:
- case WXK_END:
- case WXK_HOME:
- case WXK_LEFT:
- case WXK_UP:
- case WXK_RIGHT:
- case WXK_DOWN:
- case WXK_SELECT:
- case WXK_PRINT:
- case WXK_EXECUTE:
- case WXK_SNAPSHOT:
- case WXK_INSERT:
- case WXK_HELP:
- case WXK_NUMPAD0:
- case WXK_NUMPAD1:
- case WXK_NUMPAD2:
- case WXK_NUMPAD3:
- case WXK_NUMPAD4:
- case WXK_NUMPAD5:
- case WXK_NUMPAD6:
- case WXK_NUMPAD7:
- case WXK_NUMPAD8:
- case WXK_NUMPAD9:
- case WXK_MULTIPLY:
- case WXK_ADD:
- case WXK_SEPARATOR:
- case WXK_SUBTRACT:
- case WXK_DECIMAL:
- case WXK_DIVIDE:
- case WXK_F1:
- case WXK_F2:
- case WXK_F3:
- case WXK_F4:
- case WXK_F5:
- case WXK_F6:
- case WXK_F7:
- case WXK_F8:
- case WXK_F9:
- case WXK_F10:
- case WXK_F11:
- case WXK_F12:
- case WXK_F13:
- case WXK_F14:
- case WXK_F15:
- case WXK_F16:
- case WXK_F17:
- case WXK_F18:
- case WXK_F19:
- case WXK_F20:
- case WXK_F21:
- case WXK_F22:
- case WXK_F23:
- case WXK_F24:
- case WXK_NUMLOCK:
- case WXK_SCROLL:
- case WXK_PAGEUP:
- case WXK_PAGEDOWN:
- case WXK_NUMPAD_SPACE:
- case WXK_NUMPAD_TAB:
- case WXK_NUMPAD_ENTER:
- case WXK_NUMPAD_F1:
- case WXK_NUMPAD_F2:
- case WXK_NUMPAD_F3:
- case WXK_NUMPAD_F4:
- case WXK_NUMPAD_HOME:
- case WXK_NUMPAD_LEFT:
- case WXK_NUMPAD_UP:
- case WXK_NUMPAD_RIGHT:
- case WXK_NUMPAD_DOWN:
- case WXK_NUMPAD_PAGEUP:
- case WXK_NUMPAD_PAGEDOWN:
- case WXK_NUMPAD_END:
- case WXK_NUMPAD_BEGIN:
- case WXK_NUMPAD_INSERT:
- case WXK_NUMPAD_DELETE:
- case WXK_NUMPAD_EQUAL:
- case WXK_NUMPAD_MULTIPLY:
- case WXK_NUMPAD_ADD:
- case WXK_NUMPAD_SEPARATOR:
- case WXK_NUMPAD_SUBTRACT:
- case WXK_NUMPAD_DECIMAL:
- case WXK_WINDOWS_LEFT:
{
event.Skip();
return;
default:
{
- if (event.CmdDown() || event.AltDown())
+#ifdef __WXMAC__
+ if (event.CmdDown())
+#else
+ // Fixes AltGr+key with European input languages on Windows
+ if ((event.CmdDown() && !event.AltDown()) || (event.AltDown() && !event.CmdDown()))
+#endif
{
event.Skip();
return;
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)
{
if (flags & wxRICHTEXT_SHIFT_DOWN)
{
+ if (oldPos == newPos)
+ return false;
+
wxRichTextRange oldSelection = m_selectionRange;
// If not currently selecting, start selecting
// the end.
if (newPos > m_selectionAnchor)
m_selectionRange.SetRange(m_selectionAnchor+1, newPos);
+ else if (newPos == m_selectionAnchor)
+ m_selectionRange = wxRichTextRange(-2, -2);
else
m_selectionRange.SetRange(newPos+1, m_selectionAnchor);
}
bool scrolled = false;
wxSize clientSize = GetClientSize();
+ clientSize.y -= GetBuffer().GetBottomMargin();
+
+ if (GetWindowStyle() & wxRE_CENTRE_CARET)
+ {
+ int y = rect.y - GetClientSize().y/2;
+ int yUnits = (int) (0.5 + ((float) y)/(float) ppuY);
+ if (y >= 0 && (y + clientSize.y) < GetBuffer().GetCachedSize().y)
+ {
+ if (startYUnits != yUnits)
+ {
+ SetScrollbars(ppuX, ppuY, sxUnits, syUnits, 0, yUnits);
+ scrolled = true;
+ }
+#if !wxRICHTEXT_USE_OWN_CARET
+ if (scrolled)
+#endif
+ PositionCaret();
+
+ return scrolled;
+ }
+ }
// Going down
if (keyCode == WXK_DOWN || keyCode == WXK_NUMPAD_DOWN ||
scrolled = true;
}
}
- else if (rect.y < startY)
+ else if (rect.y < (startY + GetBuffer().GetTopMargin()))
{
// Make it scroll so this item is at the top
// of the window
- int y = rect.y ;
+ int y = rect.y - GetBuffer().GetTopMargin();
int yUnits = (int) (0.5 + ((float) y)/(float) ppuY);
if (startYUnits != yUnits)
keyCode == WXK_HOME || keyCode == WXK_NUMPAD_HOME ||
keyCode == WXK_PAGEUP || keyCode == WXK_NUMPAD_PAGEUP )
{
- if (rect.y < startY)
+ if (rect.y < (startY + GetBuffer().GetBottomMargin()))
{
// Make it scroll so this item is at the top
// of the window
- int y = rect.y ;
+ int y = rect.y - GetBuffer().GetTopMargin();
int yUnits = (int) (0.5 + ((float) y)/(float) ppuY);
if (startYUnits != yUnits)
wxRect rect = line->GetRect();
wxSize clientSize = GetClientSize();
+ clientSize.y -= GetBuffer().GetBottomMargin();
- return (rect.GetBottom() > startY) && (rect.GetTop() < (startY + clientSize.y));
+ return (rect.GetBottom() > (startY + GetBuffer().GetTopMargin())) && (rect.GetTop() < (startY + clientSize.y));
}
void wxRichTextCtrl::SetCaretPosition(long position, bool showAtLineStart)
int pixelsPerUnit = 5;
wxSize clientSize = GetClientSize();
- int maxHeight = GetBuffer().GetCachedSize().y;
+ int maxHeight = GetBuffer().GetCachedSize().y + GetBuffer().GetTopMargin();
// Round up so we have at least maxHeight pixels
int unitsY = (int) (((float)maxHeight/(float)pixelsPerUnit) + 0.5);
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
bool wxRichTextCtrl::DoLoadFile(const wxString& filename, int fileType)
{
- bool success = GetBuffer().LoadFile(filename, fileType);
+ bool success = GetBuffer().LoadFile(filename, (wxRichTextFileType)fileType);
if (success)
m_filename = filename;
bool wxRichTextCtrl::DoSaveFile(const wxString& filename, int fileType)
{
- if (GetBuffer().SaveFile(filename, fileType))
+ if (GetBuffer().SaveFile(filename, (wxRichTextFileType)fileType))
{
m_filename = filename;
void wxRichTextCtrl::SelectAll()
{
- SetSelection(0, GetLastPosition()+1);
- m_selectionAnchor = -1;
+ SetSelection(-1, -1);
}
/// Select none
// set/get the controls text
// ----------------------------------------------------------------------------
-wxString wxRichTextCtrl::GetValue() const
+wxString wxRichTextCtrl::DoGetValue() const
{
return GetBuffer().GetText();
}
}
/// Write an image at the current insertion point
-bool wxRichTextCtrl::WriteImage(const wxImage& image, int bitmapType)
+bool wxRichTextCtrl::WriteImage(const wxImage& image, wxBitmapType bitmapType)
{
wxRichTextImageBlock imageBlock;
return false;
}
-bool wxRichTextCtrl::WriteImage(const wxString& filename, int bitmapType)
+bool wxRichTextCtrl::WriteImage(const wxString& filename, wxBitmapType bitmapType)
{
wxRichTextImageBlock imageBlock;
return GetBuffer().InsertImageWithUndo(m_caretPosition+1, imageBlock, this);
}
-bool wxRichTextCtrl::WriteImage(const wxBitmap& bitmap, int bitmapType)
+bool wxRichTextCtrl::WriteImage(const wxBitmap& bitmap, wxBitmapType bitmapType)
{
if (bitmap.Ok())
{
/// Insert a newline (actually paragraph) at the current insertion point.
bool wxRichTextCtrl::Newline()
{
- return GetBuffer().InsertNewlineWithUndo(m_caretPosition+1, this);
+ return GetBuffer().InsertNewlineWithUndo(m_caretPosition+1, this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE);
}
/// Insert a line break at the current insertion point.
// 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;
m_caretPosition = pos - 1;
PositionCaret();
+
+ SetDefaultStyleToCursorStyle();
}
void wxRichTextCtrl::SetInsertionPointEnd()
to = GetLastPosition()+1;
}
- DoSetSelection(from, to);
- SetDefaultStyleToCursorStyle();
-}
-
-void wxRichTextCtrl::DoSetSelection(long from, long to, bool WXUNUSED(scrollCaret))
-{
if (from == to)
{
SelectNone();
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-1);
RefreshForSelectionChange(oldSelection, m_selectionRange);
PositionCaret();
void wxRichTextCtrl::OnSelectAll(wxCommandEvent& WXUNUSED(event))
{
- SelectAll();
+ if (GetLastPosition() > 0)
+ SelectAll();
}
void wxRichTextCtrl::OnUpdateSelectAll(wxUpdateUIEvent& 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;
}
/// Set font, and also the buffer attributes
bool wxRichTextCtrl::SetFont(const wxFont& font)
{
- wxControl::SetFont(font);
+ wxTextCtrlBase::SetFont(font);
wxTextAttr attr = GetBuffer().GetAttributes();
attr.SetFont(font);
GetCaret()->Hide();
if (GetCaret()->GetSize() != newSz)
GetCaret()->SetSize(newSz);
+
+ int halfSize = newSz.y/2;
+ // If the caret is beyond the margin, hide it by moving it out of the way
+ if (((pt.y + halfSize) < GetBuffer().GetTopMargin()) || ((pt.y + halfSize) > (GetClientSize().y - GetBuffer().GetBottomMargin())))
+ pt.y = -200;
+
GetCaret()->Move(pt);
GetCaret()->Show();
}
wxTextAttr attr;
wxRichTextRange range = GetSelectionRange();
attr.SetFlags(wxTEXT_ATTR_FONT_WEIGHT);
- attr.SetFontWeight(wxBOLD);
+ attr.SetFontWeight(wxFONTWEIGHT_BOLD);
return HasCharacterAttributes(range, attr);
}
{
if (IsDefaultStyleShowing())
wxRichTextApplyStyle(attr, GetDefaultStyleEx());
- return attr.GetFontWeight() == wxBOLD;
+ return attr.GetFontWeight() == wxFONTWEIGHT_BOLD;
}
}
return false;
wxRichTextRange range = GetSelectionRange();
wxTextAttr attr;
attr.SetFlags(wxTEXT_ATTR_FONT_ITALIC);
- attr.SetFontStyle(wxITALIC);
+ attr.SetFontStyle(wxFONTSTYLE_ITALIC);
return HasCharacterAttributes(range, attr);
}
{
if (IsDefaultStyleShowing())
wxRichTextApplyStyle(attr, GetDefaultStyleEx());
- return attr.GetFontStyle() == wxITALIC;
+ return attr.GetFontStyle() == wxFONTSTYLE_ITALIC;
}
}
return false;
{
wxTextAttr attr;
attr.SetFlags(wxTEXT_ATTR_FONT_WEIGHT);
- attr.SetFontWeight(IsSelectionBold() ? wxNORMAL : wxBOLD);
+ attr.SetFontWeight(IsSelectionBold() ? wxFONTWEIGHT_NORMAL : wxFONTWEIGHT_BOLD);
if (HasSelection())
return SetStyleEx(GetSelectionRange(), attr, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY);
{
wxTextAttr attr;
attr.SetFlags(wxTEXT_ATTR_FONT_ITALIC);
- attr.SetFontStyle(IsSelectionItalics() ? wxNORMAL : wxITALIC);
+ attr.SetFontStyle(IsSelectionItalics() ? wxFONTSTYLE_NORMAL : wxFONTSTYLE_ITALIC);
if (HasSelection())
return SetStyleEx(GetSelectionRange(), attr, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY);
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
m_yOld = -1;
m_richTextCtrl = NULL;
m_needsUpdate = false;
+ m_flashOn = true;
}
wxRichTextCaret::~wxRichTextCaret()
{
+ if (m_timer.IsRunning())
+ m_timer.Stop();
}
// ----------------------------------------------------------------------------
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();
}
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