X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5f35b46aabdab414602d27bb92034c371bc09d2e..d2b23b67301bd2d286366d4326a21da3132558fa:/docs/latex/wx/richtextoverview.tex diff --git a/docs/latex/wx/richtextoverview.tex b/docs/latex/wx/richtextoverview.tex index e9a5116a6d..cb7e946f75 100644 --- a/docs/latex/wx/richtextoverview.tex +++ b/docs/latex/wx/richtextoverview.tex @@ -1,34 +1,420 @@ \section{wxRichTextCtrl overview}\label{wxrichtextctrloverview} -Classes: \helpref{wxRichTextCtrl}{wxrichtextctrl}, \helpref{wxRichTextBuffer}{wxrichtextbuffer}, -\helpref{wxRichTextAttr}{wxrichtextattr}, \helpref{wxTextAttrEx}{wxtextattrex}, -\helpref{wxRichTextCharacterStyleDefinition}{wxrichtextcharacterstyledefinition}, +{\bf Major classes:} \helpref{wxRichTextCtrl}{wxrichtextctrl}, \helpref{wxRichTextBuffer}{wxrichtextbuffer}, \helpref{wxRichTextEvent}{wxrichtextevent} + +{\bf Helper classes:} \helpref{wxRichTextAttr}{wxrichtextattr}, \helpref{wxTextAttrEx}{wxtextattrex}, +\helpref{wxRichTextRange}{wxrichtextrange} + +{\bf File handler classes:} \helpref{wxRichTextFileHandler}{wxrichtextfilehandler}, \helpref{wxRichTextHTMLHandler}{wxrichtexthtmlhandler}, +\helpref{wxRichTextXMLHandler}{wxrichtextxmlhandler} + +{\bf Style classes:} \helpref{wxRichTextCharacterStyleDefinition}{wxrichtextcharacterstyledefinition}, \helpref{wxRichTextParagraphStyleDefinition}{wxrichtextparagraphstyledefinition}, -\helpref{wxRichTextStyleSheet}{wxrichtextstylesheet}, +\helpref{wxRichTextListStyleDefinition}{wxrichtextliststyledefinition}, +\helpref{wxRichTextStyleSheet}{wxrichtextstylesheet} + +{\bf Additional controls:} \helpref{wxRichTextStyleComboCtrl}{wxrichtextstylecomboctrl}, \helpref{wxRichTextStyleListBox}{wxrichtextstylelistbox}, -\helpref{wxRichTextEvent}{wxrichtextevent}, \helpref{wxRichTextRange}{wxrichtextrange}, -\helpref{wxRichTextFileHandler}{wxrichtextfilehandler}, \helpref{wxRichTextHTMLHandler}{wxrichtexthtmlhandler}, -\helpref{wxRichTextXMLHandler}{wxrichtextxmlhandler} +\helpref{wxRichTextStyleListCtrl}{wxrichtextstylelistctrl} + +{\bf Printing classes:} \helpref{wxRichTextPrinting}{wxrichtextprinting}, +\helpref{wxRichTextPrintout}{wxrichtextprintout}, +\helpref{wxRichTextHeaderFooterData}{wxrichtextheaderfooterdata} + +{\bf Dialog classes:} \helpref{wxRichTextStyleOrganiserDialog}{wxrichtextstyleorganiserdialog}, +\helpref{wxRichTextFormattingDialog}{wxrichtextformattingdialog}, +\helpref{wxSymbolPickerDialog}{wxsymbolpickerdialog} + +wxRichTextCtrl provides a generic implementation of a rich text editor that can handle different character +styles, paragraph formatting, and images. It's aimed at editing 'natural' language text - if you need an editor +that supports code editing, wxStyledTextCtrl is a better choice. + +Despite its name, it cannot currently read or write RTF (rich text format) files. Instead, it +uses its own XML format, and can also read and write plain text. In future we expect to provide +RTF file capabilities. Custom file formats can be supported by creating additional +file handlers and registering them with the control. + +wxRichTextCtrl is largely compatible with the wxTextCtrl API, but extends it where necessary. +The control can be used where the native rich text capabilities of wxTextCtrl are not +adequate (this is particularly true on Windows) and where more direct access to +the content representation is required. It is difficult and inefficient to read +the style information in a wxTextCtrl, whereas this information is readily +available in wxRichTextCtrl. Since it's written in pure wxWidgets, any customizations +you make to wxRichTextCtrl will be reflected on all platforms. + +wxRichTextCtrl supports basic printing via the easy-to-use \helpref{wxRichTextPrinting}{wxrichtextprinting} class. +Creating applications with simple word processing features is simplified with the inclusion of\rtfsp +\helpref{wxRichTextFormattingDialog}{wxrichtextformattingdialog}, a tabbed dialog allowing +interactive tailoring of paragraph and character styling. Also provided is the multi-purpose dialog\rtfsp +\helpref{wxRichTextStyleOrganiserDialog}{wxrichtextstyleorganiserdialog} that can be used for +managing style definitions, browsing styles and applying them, or selecting list styles with +a renumber option. -wxRichTextCtrl provides a generic implementation of a rich text editor +There are a few disadvantages to using wxRichTextCtrl. It is not native, +so does not behave exactly as a native wxTextCtrl, although common editing conventions +are followed. Users may miss the built-in spelling correction on Mac OS X, or any +special character input that may be provided by the native control. It would also +be a poor choice if intended users rely on screen readers that would be not work well +with non-native text input implementation. You might mitigate this by providing +the choice between wxTextCtrl and wxRichTextCtrl, with fewer features in the +former case. -The following screenshot shows the wxRichTextCtrl sample in action: +A good way to understand wxRichTextCtrl's capabilities is to compile and run the +sample, {\tt samples/richtext}, and browse the code. The following screenshot shows the sample in action: $$\image{8cm;0cm}{richtextctrl.gif}$$ \wxheading{Example}\label{wxrichtextctrlexample} -TODO +The following code is taken from the sample, and adds text and styles to a rich text control programmatically. {\small \begin{verbatim} + wxRichTextCtrl* richTextCtrl = new wxRichTextCtrl(splitter, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200, 200), wxVSCROLL|wxHSCROLL|wxNO_BORDER|wxWANTS_CHARS); + + wxFont textFont = wxFont(12, wxROMAN, wxNORMAL, wxNORMAL); + wxFont boldFont = wxFont(12, wxROMAN, wxNORMAL, wxBOLD); + wxFont italicFont = wxFont(12, wxROMAN, wxITALIC, wxNORMAL); + + wxFont font(12, wxROMAN, wxNORMAL, wxNORMAL); + + m_richTextCtrl->SetFont(font); + + wxRichTextCtrl& r = richTextCtrl; + + r.BeginSuppressUndo(); + + r.BeginParagraphSpacing(0, 20); + + r.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE); + r.BeginBold(); + + r.BeginFontSize(14); + r.WriteText(wxT("Welcome to wxRichTextCtrl, a wxWidgets control for editing and presenting styled text and images")); + r.EndFontSize(); + r.Newline(); + + r.BeginItalic(); + r.WriteText(wxT("by Julian Smart")); + r.EndItalic(); + + r.EndBold(); + + r.Newline(); + r.WriteImage(wxBitmap(zebra_xpm)); + + r.EndAlignment(); + + r.Newline(); + r.Newline(); + + r.WriteText(wxT("What can you do with this thing? ")); + r.WriteImage(wxBitmap(smiley_xpm)); + r.WriteText(wxT(" Well, you can change text ")); + + r.BeginTextColour(wxColour(255, 0, 0)); + r.WriteText(wxT("colour, like this red bit.")); + r.EndTextColour(); + + r.BeginTextColour(wxColour(0, 0, 255)); + r.WriteText(wxT(" And this blue bit.")); + r.EndTextColour(); + + r.WriteText(wxT(" Naturally you can make things ")); + r.BeginBold(); + r.WriteText(wxT("bold ")); + r.EndBold(); + r.BeginItalic(); + r.WriteText(wxT("or italic ")); + r.EndItalic(); + r.BeginUnderline(); + r.WriteText(wxT("or underlined.")); + r.EndUnderline(); + + r.BeginFontSize(14); + r.WriteText(wxT(" Different font sizes on the same line is allowed, too.")); + r.EndFontSize(); + + r.WriteText(wxT(" Next we'll show an indented paragraph.")); + + r.BeginLeftIndent(60); + r.Newline(); + + r.WriteText(wxT("Indented paragraph.")); + r.EndLeftIndent(); + + r.Newline(); + + r.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40).")); + + r.BeginLeftIndent(100, -40); + r.Newline(); + + r.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter.")); + r.EndLeftIndent(); + + r.Newline(); + + r.WriteText(wxT("Numbered bullets are possible, again using subindents:")); + + r.BeginNumberedBullet(1, 100, 60); + r.Newline(); + + r.WriteText(wxT("This is my first item. Note that wxRichTextCtrl doesn't automatically do numbering, but this will be added later.")); + r.EndNumberedBullet(); + + r.BeginNumberedBullet(2, 100, 60); + r.Newline(); + + r.WriteText(wxT("This is my second item.")); + r.EndNumberedBullet(); + + r.Newline(); + + r.WriteText(wxT("The following paragraph is right-indented:")); + + r.BeginRightIndent(200); + r.Newline(); + + r.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable.")); + r.EndRightIndent(); + + r.Newline(); + + wxArrayInt tabs; + tabs.Add(400); + tabs.Add(600); + tabs.Add(800); + tabs.Add(1000); + wxTextAttrEx attr; + attr.SetFlags(wxTEXT_ATTR_TABS); + attr.SetTabs(tabs); + r.SetDefaultStyle(attr); + + r.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab")); + + r.Newline(); + r.WriteText(wxT("Other notable features of wxRichTextCtrl include:")); + + r.BeginSymbolBullet(wxT('*'), 100, 60); + r.Newline(); + r.WriteText(wxT("Compatibility with wxTextCtrl API")); + r.EndSymbolBullet(); + + r.WriteText(wxT("Note: this sample content was generated programmatically from within the MyFrame constructor in the demo. The images were loaded from inline XPMs. Enjoy wxRichTextCtrl!")); + + r.EndSuppressUndo(); \end{verbatim} } -\wxheading{Programming with wxRichTextCtrl} +\subsection{Programming with wxRichTextCtrl} + +\subsubsection{Starting to use wxRichTextCtrl} + +You need to include {\tt } in your source, and link +with the appropriate wxWidgets library with {\tt richtext} suffix. Put the rich text +library first in your link line to avoid unresolved symbols. + +Then you can create a wxRichTextCtrl, with the wxWANT\_CHARS style if you want tabs to +be processed by the control rather than being used for navigation between controls. + +\subsubsection{wxRichTextCtrl and styles} + +Styling attributes are represented by three classes: \helpref{wxTextAttr}{wxtextattr}, \helpref{wxTextAttrEx}{wxtextattrex} and \helpref{wxRichTextAttr}{wxrichtextattr}. +wxTextAttr is shared across all controls that are derived from wxTextCtrlBase and +can store basic character and paragraph attributes. wxTextAttrEx derives +from wxTextAttr and adds some further attributes that are only supported +by wxRichTextCtrl. Finally, wxRichTextAttr is a more efficient version +of wxTextAttrEx that doesn't use a wxFont object and can be used to +query styles more quickly. wxTextAttrEx and wxRichTextAttr are largely +interchangeable and have suitable conversion operators between them. + +When setting a style, the flags of the attribute object determine which +attributes are applied. When querying a style, the passed flags are ignored +except (optionally) to determine whether attributes should be retrieved from +character content or from the paragraph object. + +wxRichTextCtrl takes a layered approach to styles, so that different parts of +the content may be responsible for contributing different attributes to the final +style you see on the screen. + +There are four main notions of style within a control: + +\begin{enumerate}\itemsep=0pt +\item {\bf Basic style:} the fundamental style of a control, onto which any other +styles are layered. It provides default attributes, and changing the basic style +may immediately change the look of the content depending on what other styles +the content uses. Calling wxRichTextCtrl::SetFont changes the font for the basic style. +The basic style is set with \helpref{wxRichTextCtrl::SetBasicStyle}{wxrichtextctrlsetbasicstyle}. +\item {\bf Paragraph style:} each paragraph has attributes that are set independently +from other paragraphs and independently from the content within the paragraph. +Normally, these attributes are paragraph-related, such as alignment and indentation, +but it is possible to set character attributes too. +The paragraph style can be set independently of its content by passing wxRICHTEXT\_SETSTYLE\_PARAGRAPHS\_ONLY +to \helpref{wxRichTextCtrl::SetStyleEx}{wxrichtextctrlsetstyleex}. +\item {\bf Character style:} characters within each paragraph can have attributes. +A single character, or a run of characters, can have a particular set of attributes. +The character style can be with \helpref{wxRichTextCtrl::SetStyle}{wxrichtextctrlsetstyle} or +\helpref{wxRichTextCtrl::SetStyleEx}{wxrichtextctrlsetstyleex}. +\item {\bf Default style:} this is the `current' style that determines the +style of content that is subsequently typed, pasted or programmatically inserted. +The default style is set with \helpref{wxRichTextCtrl::SetDefaultStyle}{wxrichtextctrlsetdefaultstyle}. +\end{enumerate} + +What you see on the screen is the dynamically {\it combined} style, found by merging +the first three of the above style types (the fourth is only a guide for future content +insertion and therefore does not affect the currently displayed content). + +To make all this more concrete, here are examples of where you might set these different +styles: + +\begin{enumerate}\itemsep=0pt +\item You might set the {\bf basic style} to have a Times Roman font in 12 point, +left-aligned, with two millimetres of spacing after each paragraph. +\item You might set the {\bf paragraph style} (for one particular paragraph) to +be centred. +\item You might set the {\bf character style} of one particular word to bold. +\item You might set the {\bf default style} to be underlined, for subsequent +inserted text. +\end{enumerate} + +Naturally you can do any of these things either using your own UI, or programmatically. + +The basic wxTextCtrl doesn't make the same distinctions as wxRichTextCtrl regarding +attribute storage. So we need finer control when setting and retrieving +attributes. \helpref{wxRichTextCtrl::SetStyleEx}{wxrichtextctrlsetstyleex} takes a {\it flags} parameter: + +\begin{itemize}\itemsep=0pt +\item wxRICHTEXT\_SETSTYLE\_OPTIMIZE specifies that the style should be changed only if +the combined attributes are different from the attributes for the current object. This is important when +applying styling that has been edited by the user, because he has just edited the {\it combined} (visible) +style, and wxRichTextCtrl wants to leave unchanged attributes associated with their original objects +instead of applying them to both paragraph and content objects. +\item wxRICHTEXT\_SETSTYLE\_PARAGRAPHS\_ONLY specifies that only paragraph objects within the given range +should take on the attributes. +\item wxRICHTEXT\_SETSTYLE\_CHARACTERS\_ONLY specifies that only content objects (text or images) within the given range +should take on the attributes. +\item wxRICHTEXT\_SETSTYLE\_WITH\_UNDO specifies that the operation should be undoable. +\end{itemize} + +It's great to be able to change arbitrary attributes in a wxRichTextCtrl, but +it can be unwieldy for the user or programmer to set attributes separately. Word processors have collections +of styles that you can tailor or use as-is, and this means that you can set a heading with one click +instead of marking text in bold, specifying a large font size, and applying a certain +paragraph spacing and alignment for every such heading. Similarly, +wxWidgets provides a class called \helpref{wxRichTextStyleSheet}{wxrichtextstylesheet} which manages style definitions +(\helpref{wxRichTextParagraphStyleDefinition}{wxrichtextparagraphstyledefinition}, \helpref{wxRichTextListStyleDefinition}{wxrichtextliststyledefinition} and \helpref{wxRichTextCharacterStyleDefinition}{wxrichtextcharacterstyledefinition}). +Once you have added definitions to a style sheet and associated it with a wxRichTextCtrl, +you can apply a named definition to a range of text. The classes \helpref{wxRichTextStyleComboCtrl}{wxrichtextstylecomboctrl}\rtfsp +and \helpref{wxRichTextStyleListBox}{wxrichtextstylelistbox} can be used to present the user with a list +of styles in a sheet, and apply them to the selected text. + +You can reapply a style sheet to the contents of the control, by calling \helpref{wxRichTextCtrl::ApplyStyleSheet}{wxrichtextctrlapplystylesheet}. +This is useful if the style definitions have changed, and you want the content to reflect this. +It relies on the fact that when you apply a named style, the style definition name is recorded in the +content. So ApplyStyleSheet works by finding the paragraph attributes with style names and re-applying the definition's +attributes to the paragraph. Currently, this works with paragraph and list style definitions only. + +\subsection{wxRichTextCtrl dialogs}\label{wxrichtextctrldialogs} + +wxRichTextCtrl comes with standard dialogs to make it easier to implement +text editing functionality. + +\helpref{wxRichTextFormattingDialog}{wxrichtextformattingdialog} can be used +for character or paragraph formatting, or a combination of both. It's a wxPropertySheetDialog +with the following available tabs: Font, Indents \& Spacing, Tabs, Bullets, Style, and List Style. +You can select which pages will be shown by supplying flags to the dialog constructor. +In a character formatting dialog, typically only the Font page will be shown. +In a paragraph formatting dialog, you'll show the Indents \& Spacing, Tabs and Bullets +pages. The Style tab is useful when editing a style definition. + +You can customize this dialog by providing your own wxRichTextFormattingDialogFactory +object, which tells the formatting dialog how many pages are supported, what their identifiers +are, and how to creates the pages. + +\helpref{wxRichTextStyleOrganiserDialog}{wxrichtextstyleorganiserdialog} is a multi-purpose dialog +that can be used for managing style definitions, browsing styles and applying them, or selecting list styles with +a renumber option. See the sample for usage - it is used for the "Manage Styles" and "Bullets and Numbering" +menu commands. + +\helpref{wxSymbolPickerDialog}{wxsymbolpickerdialog} lets the user insert a symbol from +a specified font. It has no wxRichTextCtrl dependencies besides being included in +the rich text library. + +\subsection{How wxRichTextCtrl is implemented} + +Data representation is handled by wxRichTextBuffer, and a wxRichTextCtrl +always has one such buffer. + +The content is represented by a hierarchy of objects, all derived from +wxRichTextObject. An object might be an image, a fragment of text, a paragraph, +or a whole buffer. Objects store a wxTextAttrEx containing style information; +a paragraph object can contain both paragraph and character information, but +content objects such as text can only store character information. The final +style displayed in the control or in a printout is a combination of base +style, paragraph style and content (character) style. + +The top of the hierarchy is the buffer, a kind of wxRichTextParagraphLayoutBox. +containing further wxRichTextParagraph objects, each of which can include text, +images and potentially other types of object. + +Each object maintains a range (start and end position) measured +from the start of the main parent object. + +When Layout is called on an object, it is given a size which the object +must limit itself to, or one or more flexible directions (vertical +or horizontal). So, for example, a centred paragraph is given the page +width to play with (minus any margins), but can extend indefinitely +in the vertical direction. The implementation of Layout caches the calculated +size and position. + +When the buffer is modified, a range is invalidated (marked as requiring +layout), so that only the minimum amount of layout is performed. + +A paragraph of pure text with the same style contains just one further +object, a wxRichTextPlainText object. When styling is applied to part of +this object, the object is decomposed into separate objects, one object +for each different character style. So each object within a paragraph always has +just one wxTextAttrEx object to denote its character style. Of course, this can +lead to fragmentation after a lot of edit operations, potentially leading +to several objects with the same style where just one would do. So +a Defragment function is called when updating the control's display, to ensure that +the minimum number of objects is used. + +\subsection{wxRichTextCtrl roadmap} + +\wxheading{Bugs} + +This is an incomplete list of bugs. + +\begin{itemize}\itemsep=0pt +\item Moving the caret up at the beginning of a line sometimes incorrectly positions the +caret. +\item As the selection is expanded, the text jumps slightly due to kerning differences between +drawing a single text string versus drawing several fragments separately. This could +be improved by using wxDC::GetPartialTextExtents to calculate exactly where the separate fragments +should be drawn. Note that this problem also applies to separation of text fragments due to difference in their attributes. +\end{itemize} + +\wxheading{Features} + +This is a list of some of the features that have yet to be implemented. Help with them will be appreciated. -TODO +\begin{itemize}\itemsep=0pt +\item RTF input and output +\item Conversion from HTML +\item Open Office input and output +\item Floating images, with content wrapping around them +\item A ruler control +\item Standard editing toolbars +\item Tables +\item Bitmap bullets +\item Borders +\item Text frames +\item Justified text, in print/preview at least +\end{itemize} -\wxheading{How wxRichTextCtrl is implemented} +There are also things that could be done to take advantage of the underlying text capabilities of the platform; +higher-level text formatting APIs are available on some platforms, such as Mac OS X, and some of translation from +high level to low level wxDC API is unnecessary. However this would require additions to the wxWidgets API. -TODO