#include "wx/filename.h"
#include "wx/dcbuffer.h"
#include "wx/arrimpl.cpp"
+#include "wx/fontenum.h"
// DLL options compatibility check:
#include "wx/app.h"
DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_LEFT_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_RETURN)
-#if wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
IMPLEMENT_CLASS( wxRichTextCtrl, wxControl )
-#else
-IMPLEMENT_CLASS( wxRichTextCtrl, wxScrolledWindow )
-#endif
IMPLEMENT_CLASS( wxRichTextEvent, wxNotifyEvent )
-#if wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
BEGIN_EVENT_TABLE( wxRichTextCtrl, wxControl )
-#else
-BEGIN_EVENT_TABLE( wxRichTextCtrl, wxScrolledWindow )
-#endif
EVT_PAINT(wxRichTextCtrl::OnPaint)
EVT_ERASE_BACKGROUND(wxRichTextCtrl::OnEraseBackground)
EVT_IDLE(wxRichTextCtrl::OnIdle)
* wxRichTextCtrl
*/
+wxArrayString wxRichTextCtrl::sm_availableFontNames;
+
wxRichTextCtrl::wxRichTextCtrl()
-#if wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
- : wxScrollHelper(this)
-#endif
+ : wxScrollHelper(this)
{
Init();
}
-wxRichTextCtrl::wxRichTextCtrl( wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style)
-#if wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
- : wxScrollHelper(this)
-#endif
+wxRichTextCtrl::wxRichTextCtrl(wxWindow* parent,
+ wxWindowID id,
+ const wxString& value,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style)
+ : wxScrollHelper(this)
{
Init();
Create(parent, id, value, pos, size, style);
/// Creation
bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style)
{
-#if wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
- if (!wxTextCtrlBase::Create(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE
- ))
+ if (!wxTextCtrlBase::Create(parent, id, pos, size,
+ style|wxFULL_REPAINT_ON_RESIZE))
return false;
-#else
- if (!wxScrolledWindow::Create(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE
- ))
- return false;
-#endif
if (!GetFont().Ok())
{
GetBuffer().SetRichTextCtrl(this);
+ if (style & wxTE_READONLY)
+ SetEditable(false);
+
wxTextAttrEx attributes;
attributes.SetFont(GetFont());
attributes.SetTextColour(*wxBLACK);
SetupScrollbars();
Refresh(false);
}
- SendUpdateEvent();
+ SendTextUpdatedEvent();
}
/// Painting
// Paint the background
PaintBackground(dc);
- wxRegion dirtyRegion = GetUpdateRegion();
-
wxRect drawingArea(GetLogicalPoint(wxPoint(0, 0)), GetClientSize());
wxRect availableSpace(GetClientSize());
if (GetBuffer().GetDirty())
event.Skip();
return;
}
-
+
default:
{
if (event.CmdDown() || event.AltDown())
return;
}
+ if (keycode == wxT('\t'))
+ {
+ // See if we need to promote or demote the selection or paragraph at the cursor
+ // position, instead of inserting a tab.
+ long pos = GetAdjustedCaretPosition(GetCaretPosition());
+ wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(pos);
+ if (para && para->GetRange().GetStart() == pos && para->GetAttributes().HasListStyleName())
+ {
+ wxRichTextRange range;
+ if (HasSelection())
+ range = GetSelectionRange();
+ else
+ range = para->GetRange().FromInternal();
+
+ int promoteBy = event.ShiftDown() ? 1 : -1;
+
+ PromoteList(promoteBy, range, NULL);
+ return;
+ }
+ }
+
BeginBatchUndo(_("Insert Text"));
long newPos = m_caretPosition;
// file IO functions
// ----------------------------------------------------------------------------
-#if !wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
-bool wxRichTextCtrl::LoadFile(const wxString& filename, int fileType)
-{
- return DoLoadFile(filename, fileType);
-}
-
-bool wxRichTextCtrl::SaveFile(const wxString& filename, int fileType)
-{
- wxString filenameToUse = filename.empty() ? m_filename : filename;
- if ( filenameToUse.empty() )
- {
- // what kind of message to give? is it an error or a program bug?
- wxLogDebug(wxT("Can't save textctrl to file without filename."));
-
- return false;
- }
-
- return DoSaveFile(filenameToUse, fileType);
-}
-#endif
-
bool wxRichTextCtrl::DoLoadFile(const wxString& filename, int fileType)
{
bool success = GetBuffer().LoadFile(filename, fileType);
PositionCaret();
SetupScrollbars(true);
Refresh(false);
- SendUpdateEvent();
+ SendTextUpdatedEvent();
if (success)
return true;
{
if (position < 0 || position > GetBuffer().GetRange().GetEnd())
return false;
-
+
wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(position);
if (!para)
return false;
long positionStart = position;
long positionEnd = position;
-
+
for (positionStart = position; positionStart >= para->GetRange().GetStart(); positionStart --)
{
wxString text = GetBuffer().GetTextForRange(wxRichTextRange(positionStart, positionStart));
}
if (positionStart < para->GetRange().GetStart())
positionStart = para->GetRange().GetStart();
-
+
for (positionEnd = position; positionEnd < para->GetRange().GetEnd(); positionEnd ++)
{
wxString text = GetBuffer().GetTextForRange(wxRichTextRange(positionEnd, positionEnd));
}
if (positionEnd >= para->GetRange().GetEnd())
positionEnd = para->GetRange().GetEnd();
-
+
SetSelection(positionStart, positionEnd+1);
if (positionStart >= 0)
{
MoveCaret(positionStart-1, true);
- SetDefaultStyleToCursorStyle();
+ SetDefaultStyleToCursorStyle();
}
return true;
return GetRange(from, to);
}
-// do the window-specific processing after processing the update event
-#if !wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
-void wxRichTextCtrl::DoUpdateWindowUI(wxUpdateUIEvent& event)
-{
- // call inherited
- wxWindowBase::DoUpdateWindowUI(event);
-
- // update text
- if ( event.GetSetText() )
- {
- if ( event.GetText() != GetValue() )
- SetValue(event.GetText());
- }
-}
-#endif // !wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
-
// ----------------------------------------------------------------------------
// hit testing
// ----------------------------------------------------------------------------
return GetBuffer().GetTextForRange(wxRichTextRange(from, to-1));
}
-void wxRichTextCtrl::SetValue(const wxString& value)
+void wxRichTextCtrl::DoSetValue(const wxString& value, int flags)
{
Clear();
// edit controls mostly)
if ( (value.length() > 0x400) || (value != GetValue()) )
{
- DoWriteText(value, false /* not selection only */);
+ DoWriteText(value);
// for compatibility, don't move the cursor when doing SetValue()
SetInsertionPoint(0);
}
else // same text
{
- // still send an event for consistency
- SendUpdateEvent();
+ if ( flags & SetValue_SendEvent )
+ {
+ // still send an event for consistency
+ SendTextUpdatedEvent();
+ }
}
// we should reset the modified flag even if the value didn't really change
DoWriteText(value);
}
-void wxRichTextCtrl::DoWriteText(const wxString& value, bool WXUNUSED(selectionOnly))
+void wxRichTextCtrl::DoWriteText(const wxString& value, int flags)
{
wxString valueUnix = wxTextFile::Translate(value, wxTextFileType_Unix);
GetBuffer().InsertTextWithUndo(m_caretPosition+1, valueUnix, this);
+
+ if ( flags & SetValue_SendEvent )
+ SendTextUpdatedEvent();
}
void wxRichTextCtrl::AppendText(const wxString& text)
// Editing
// ----------------------------------------------------------------------------
-void wxRichTextCtrl::Replace(long WXUNUSED(from), long WXUNUSED(to), const wxString& value)
+void wxRichTextCtrl::Replace(long WXUNUSED(from), long WXUNUSED(to),
+ const wxString& value)
{
BeginBatchUndo(_("Replace"));
DeleteSelectedContent();
- DoWriteText(value, true /* selection only */);
+ DoWriteText(value, SetValue_SelectionOnly);
EndBatchUndo();
}
}
}
-// ----------------------------------------------------------------------------
-// text control event processing
-// ----------------------------------------------------------------------------
-
-bool wxRichTextCtrl::SendUpdateEvent()
-{
- wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
- InitCommandEvent(event);
-
- return GetEventHandler()->ProcessEvent(event);
-}
-
-void wxRichTextCtrl::InitCommandEvent(wxCommandEvent& event) const
-{
- event.SetEventObject((wxControlBase *)this); // const_cast
-
- switch ( m_clientDataType )
- {
- case wxClientData_Void:
- event.SetClientData(GetClientData());
- break;
-
- case wxClientData_Object:
- event.SetClientObject(GetClientObject());
- break;
-
- case wxClientData_None:
- // nothing to do
- ;
- }
-}
-
-
wxSize wxRichTextCtrl::DoGetBestSize() const
{
return wxSize(10, 10);
/// Set font, and also the buffer attributes
bool wxRichTextCtrl::SetFont(const wxFont& font)
{
-#if wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
wxControl::SetFont(font);
-#else
- wxScrolledWindow::SetFont(font);
-#endif
wxTextAttrEx attr = GetBuffer().GetAttributes();
attr.SetFont(font);
GetBuffer().SetBasicStyle(attr);
-#if !wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
- // Don't set the default style, since it will be inherited from
- // the basic style.
- GetBuffer().SetDefaultStyle(attr);
-#endif
-
GetBuffer().Invalidate(wxRICHTEXT_ALL);
Refresh(false);
}
/// Apply a named style to the selection
-void wxRichTextCtrl::ApplyStyle(wxRichTextStyleDefinition* def)
+bool wxRichTextCtrl::ApplyStyle(wxRichTextStyleDefinition* def)
{
// Flags are defined within each definition, so only certain
// attributes are applied.
wxRichTextAttr attr(def->GetStyle());
-
+
int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE;
+ if (def->IsKindOf(CLASSINFO(wxRichTextListStyleDefinition)))
+ {
+ flags |= wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY;
+
+ wxRichTextRange range;
+
+ if (HasSelection())
+ range = GetSelectionRange();
+ else
+ {
+ long pos = GetAdjustedCaretPosition(GetCaretPosition());
+ range = wxRichTextRange(pos, pos+1);
+ }
+
+ return SetListStyle(range, (wxRichTextListStyleDefinition*) def, flags);
+ }
+
// Make sure the attr has the style name
if (def->IsKindOf(CLASSINFO(wxRichTextParagraphStyleDefinition)))
{
attr.SetParagraphStyleName(def->GetName());
-
+
// If applying a paragraph style, we only want the paragraph nodes to adopt these
- // attributes, and not the leaf nodes. This will allow the context (e.g. text)
+ // attributes, and not the leaf nodes. This will allow the content (e.g. text)
// to change its style independently.
flags |= wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY;
}
attr.SetCharacterStyleName(def->GetName());
if (HasSelection())
- SetStyleEx(GetSelectionRange(), attr, flags);
+ return SetStyleEx(GetSelectionRange(), attr, flags);
else
+ {
SetAndShowDefaultStyle(attr);
+ return true;
+ }
}
/// Apply the style sheet to the buffer, for example if the styles have changed.
SetInternalSelectionRange(range1);
}
+/// Set list style
+bool wxRichTextCtrl::SetListStyle(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags, int startFrom, int specifiedLevel)
+{
+ return GetBuffer().SetListStyle(range.ToInternal(), def, flags, startFrom, specifiedLevel);
+}
+
+bool wxRichTextCtrl::SetListStyle(const wxRichTextRange& range, const wxString& defName, int flags, int startFrom, int specifiedLevel)
+{
+ return GetBuffer().SetListStyle(range.ToInternal(), defName, flags, startFrom, specifiedLevel);
+}
+
+/// Clear list for given range
+bool wxRichTextCtrl::ClearListStyle(const wxRichTextRange& range, int flags)
+{
+ return GetBuffer().ClearListStyle(range.ToInternal(), flags);
+}
+
+/// Number/renumber any list elements in the given range
+bool wxRichTextCtrl::NumberList(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags, int startFrom, int specifiedLevel)
+{
+ return GetBuffer().NumberList(range.ToInternal(), def, flags, startFrom, specifiedLevel);
+}
+
+bool wxRichTextCtrl::NumberList(const wxRichTextRange& range, const wxString& defName, int flags, int startFrom, int specifiedLevel)
+{
+ return GetBuffer().NumberList(range.ToInternal(), defName, flags, startFrom, specifiedLevel);
+}
+
+/// Promote the list items within the given range. promoteBy can be a positive or negative number, e.g. 1 or -1
+bool wxRichTextCtrl::PromoteList(int promoteBy, const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags, int specifiedLevel)
+{
+ return GetBuffer().PromoteList(promoteBy, range.ToInternal(), def, flags, specifiedLevel);
+}
+
+bool wxRichTextCtrl::PromoteList(int promoteBy, const wxRichTextRange& range, const wxString& defName, int flags, int specifiedLevel)
+{
+ return GetBuffer().PromoteList(promoteBy, range.ToInternal(), defName, flags, specifiedLevel);
+}
+
+const wxArrayString& wxRichTextCtrl::GetAvailableFontNames()
+{
+ if (sm_availableFontNames.GetCount() == 0)
+ {
+ sm_availableFontNames = wxFontEnumerator::GetFacenames();
+ sm_availableFontNames.Sort();
+ }
+ return sm_availableFontNames;
+}
+
+void wxRichTextCtrl::ClearAvailableFontNames()
+{
+ sm_availableFontNames.Clear();
+}
+
#endif
// wxUSE_RICHTEXT
-