Text Editors

Text editors are feature-rich editors that can comprise single or multiple lines of text. They have numerous configurable attributes, such as: their dimensions, the case of the characters they display and so on.

There are three main types of text editors:

  • Plain Editor ” This is the most basic text editor, which contains unformatted text as shown in Figure 8-1.

    Figure 8-1. A plain text editor.


  • Global Editor ” This allows global formatting of paragraphs and characters but does not allow you to format characters and paragraphs individually ”it applies the formatting to all of the text.

  • Rich Text Editor ” This allows individual formatting of paragraphs and characters, as shown in Figure 8-2. It encompasses all of the functionality of a global editor, and because it is a functional superset, only the rich text editor will be illustrated in this chapter.

    Figure 8-2. A rich text editor.


Table 8-1 details the classes, resource and control types for each of the text editors. You will see how to use the plain and rich text editors in the examples that follow.

Table 8-1. Text Editor Resource and Classes

Text Editor

Class

Resource

Control

Plain

CEikEdwin

EDWIN

EEikCtEdwin

Global

CEikGlobalTextEditor

GTXTED

EEikCtGlobalTextEditor

Rich Text

CEikRichTextEditor

RICHTEXTED

EEikCtRichTextEditor


Text editors have features that you can define, either statically (defining a resource in a resource file), or dynamically (using the text editor's API in code at runtime). Further information on these two general types of control interface can be found in Chapter 5. More specific information on the dynamic features of text editors is available in the SDK documentation for CEikEdwin . Additionally, static (resource file) features of text editors are covered in the SDK documentation for the appropriate text editor resource (such as EDWIN , GTXTED and so on).

The common features that can be defined for all text editors are:

  • Dimensions ” For example, width and number of lines.

  • Input Mode ” Controls what type of characters the keypad can generate (such as all alphabetical, or all numeric), and by doing so, controls the type of input the control accepts.

  • Input Case ” Governs the case convention for text input by controlling what the keypad can generate, such as all capitals or all lowercase characters.

  • Numeric Key Map ” Provides a means of conveniently accessing commonly required nonnumeric characters in numeric input mode ”for example, the asterisk (or "star") character: "*".

  • Special Character Table ” Provides a means of conveniently accessing groups of special characters that do not map directly to the keypad.

  • Properties ” Special characteristics that can be applied.

The following subsections discuss each of these features in more detail. In addition, there are a number of features that cannot be set in a resource and must be accessed using the text editor's API. These features are shown in Table 8-2.

Table 8-2. Dynamic Text Editor Features

Feature

Example Use

Read-Only

To check and set whether an editor is read-only.

Text

To get and set the text, and count the words in it.

Selected Text

To get and set the selected text, to select all text, and to clear all selected text

Cursor Position

To get and set the cursor position.

Infrared

Use infrared to send or receive the editor text.

Clipboard

To cut, copy and paste.

Fields

To insert new fields (for example, a field could mark a table of contents in a rich text editor) and to update fields.

Sizes and Colors

To set margins and to set the background color .

Zoom

To set a zoom factor.

Search and Replace

To search for text and replace it.

Scroll Bars

To display and update the scroll bars.

Utility Functions

For example, to remove non-ASCII characters, calculate the average number of characters per line and so on.

Miscellaneous Properties

To word wrap, and to determine whether the editor owns the text it is editing.

Formatting

To format characters and paragraphs (in global and rich text editors only).

Objects

To insert pictures (in rich text editors only).


Dimensions and Input Capacity

All text editors have three basic configurable characteristics: height (or number of lines of text to display), width and input capacity. These are detailed in Table 8-3.

Table 8-3. Characteristics That Determine Dimensions and Input Capacity for a Text Editor

Characteristic

Description

Additional Information

Width

This is the physical width of the control. The width can be specified either by the number of characters to accommodate, or by pixels.

Editors have a default font, and this font's characters are proportional. So if the width is set in characters rather than pixels, the editor sets the width based on the font's widest character. If the user enters narrower characters, it is possible that they will see more characters per line than expected. For example, with a width of five, they would get more than five "i" characters per line.

Global and rich text editors always have their width defined in pixels.

Number of Lines

This is the number of lines of text that the editor can display at a time. The default value for this is one.

Rich and global text editors also define a height, in pixels, in addition to the number of lines. You can use either of these characteristics to define a multiline editor.

Maximum Length

This is the maximum number of characters that can be stored in the editor. It is different from the above two characteristics because it specifies capacity instead of a physical dimension.

The editor will scroll if the maximum length is greater than the number of characters it can display in the width.

Rich and global text editors use the term "text limit" in their API methods and resource definition, to refer to the maximum length.


Filtering Keypad Input

The Series 60 keypad allows users to input more characters than there are keys ”each key on the keypad maps to multiple characters, and users can, for example, scroll through a key's mappings by pressing that key rapidly . Series 60 editors can reduce the inefficiency of having to make numerous key presses by filtering out those characters that are not relevant to the editor's corresponding data format. For example, editors that exclusively require numeric characters (such as an editor field for inputting a person's age) can be configured to filter out all alphabetic characters from keypad input. The subsection that follows explains the three primary input modes that are used to accomplish this type of filtering.

Input Modes

Essentially, input modes are filters that make data entry more efficient for the user. At the same time, they also prevent editors from receiving input that is invalid for their purposes. The three main modes available are text, numeric and secret, as described in Table 8-4.

Table 8-4. Text Editor Input Modes

Input Mode

Description

Text

Key presses can produce letters , numbers and special characters, as normal.

Numeric

Key presses produce only numbers (and characters defined by the numeric key map).

Secret

Text is replaced by an asterisk ( * ) on screen as the user types.


Editors have a default input mode, but it is also possible to specify additional allowed input modes. For example, an MMS address may be purely numeric if sending to another phone, or alphanumeric if sending to an email account. An editor can be set up to allow both modes, and users can manually switch modes (if more than one is attributed to an editor) by pressing the hash (#) key.

To switch between text and numeric input modes, users must press and hold down the hash (#) key.


You must take care not to choose conflicting values ”the list of allowed input modes must include the default input mode. By default, the input mode is text and the editor allows all input modes.

Input Case

Input case settings also filter input, but only when the editor's input mode is set to text. Text input can be set so that it is uppercase only, lowercase only, or follows text rules ”for example, setting the first letter of the first word in a sentence to uppercase. You can set the editor so that it has a default case, and a set of allowed cases ”a combination of cases the editor will allow you to change to.

Again, you must take care not to choose conflicting default and allowed values. For example, you cannot set the allowed cases to be uppercase only and then set the default case to lowercase only. By default, the case follows text rules, and the editor allows all cases. Table 8-5 shows the enumeration values allowed:

Table 8-5. Text Editor Input Cases

Input Case

Use

Screenshot

EAknEditorUpperCase

Uppercase only.

EAknEditorLowerCase

Lowercase only.

EAknEditorTextCase

Automatic. First letter is uppercase.

EAknEditorAllCaseModes

Upper, lower and text cases.

Any of the above.


Providing Mappings to Additional Characters

Certain data types require a subset of special characters. URLs, for example, typically comprise alphanumeric characters interspersed with colons, forward slashes and full stops (such as http://www.emccsoft.com). For efficiency, it is necessary to group together these additional characters and to provide a convenient and consistent mechanism for accessing them. The asterisk ( * ) key provides the necessary extension ”pressing it will bring up a visible array of all additional characters available for a particular editor. Users can then use the direction and Selection keys to acquire characters from this map (see Table 8-6 for examples of various context-dependent mappings).

A single control can deploy more than one mapping, as detailed in the next two subsections ”it can provide different mappings according to its current input mode.

Numeric Key Maps

When the input mode is numeric, the asterisk ( * ) and hash ( # ) keys can be used to input numerical operators and signs. Generally, the asterisk key brings up a mapping of multiple characters.

Editors in numeric mode default to a mapping suitable for phone numbers (that is, " * ", " + ", " p " or " w " for the asterisk key and " # " for the hash key), as shown in Figure 8-3.

Figure 8-3. The standard numeric key map for the asterisk key.


In a phone number, the " p " and " w " characters are used to respectively pause and wait before dialing a number. The user can employ this when dialing automated services. For example, a voicemail system may require the user to dial a number and then, on answer, enter their mailbox number. In this case, they could specify the number to dial followed by w , and then their mailbox number. This would dial the number, and then wait. When the voicemail answered , the user could then press the Send key to send the remaining mailbox number digits.


Alternative settings bring up mappings suitable for other entry types, such as calculations (" + ", " - ", " * " and " / " for the asterisk key and " . " for the hash key), as shown in Figure 8-4.

Figure 8-4. The calculator numeric key map for the asterisk key.


Providing Specific Mappings for Text-Based Entries with Special Character Tables

When the input mode is text, pressing and holding the asterisk ( * ) key displays a special character table. This allows the user to select punctuation and other special characters to input into the editor.

There are different types of special character tables, which contain different characters. The Standard, Email Address, URL and Currency character tables are shown in Table 8-6.

Table 8-6. Text Editor Special Character Tables

Use

Resource Identifier

Screenshot

Default

R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG

URL Addresses

R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG

Email Addresses

R_AVKON_EMAIL_ADDR_SPECIAL_CHARACTER_TABLE_DIALOG

Currency

R_AVKON_CURRENCY_NAME_SPECIAL_CHARACTER_TABLE_DIALOG

Note that these settings may not give you exactly what you would expect ”the currency table has no pound ( & pound ;), yen ( ), euro ( ) or general currency ( ) characters, only the dollar ($) character!


Properties

Text editors also allow a number of special properties to be set, which you can use to perform tasks such as:

  • Preventing the case from being changed.

  • Preventing predictive text (T9) entry.

  • Removing the edit indicators from the navigation pane.

  • Preventing left and right scrolling.

  • Preventing the special character table from displaying.

  • Enabling the scroll bar indicator.

  • Enabling the text to overwrite rather than insert.

  • Enabling the numeric key map, and preventing anything other than Latin characters from being entered.

  • Specifying the width as being measured in pixels.

  • Making the editor read-only.

  • Disabling the cursor.

These properties are set by flags, as will be illustrated in the PlainTextEditor example. By default, no properties are set.

Configuring a Plain Text Editor

The PlainTextEditor example, as shown in Figure 8-5, illustrates all of the attributes and features discussed so far. The example control is configured to facilitate URL entries. It demonstrates the following concepts:

  • Configuring a plain text editor in a resource file.

  • Providing multiple input modes (text and numeric).

  • Providing multiple case modes (upper or lowercase).

  • Providing a URL-specific special character mapping for text input mode.

  • Instantiating the editor from its resource definition.

Figure 8-5. The PlainTextEditor main screen.


The editor does not accept predictive text entry, and it has no numeric key map ”this means that when the input mode is set to numeric, the asterisk ( * ) and hash ( # ) keys have no effect. If the input mode is set to text, then pressing the asterisk key will display a special character table suitable for URLs, as shown in Figure 8-6.

Figure 8-6. The PlainTextEditor special character table.


A short press of the hash key switches case in text mode, and a long press switches between text and numeric input modes.

Defining a Plain Text Editor Resource

The resource structure for the plain text editor is given below. Note that the resource type for a plain text editor is EDWIN .

 RESOURCE EDWIN r_plaintexteditor_urleditor    {    width = KUrlWidth;    lines = KUrlNumberLines;    maxlength = KMaxUrlLength;    flags = EEikEdwinWidthInPixels;    avkon_flags = EAknEditorFlagNoT9;    default_case = EAknEditorLowerCase;    allowed_case_modes = EAknEditorUpperCase  EAknEditorLowerCase;    numeric_keymap = EAknEditorPlainNumberModeKeymap;    allowed_input_modes = EAknEditorTextInputMode  EAknEditorNumericInputMode;    default_input_mode = EAknEditorTextInputMode;    special_character_table = R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG;    } 

This structure complies with the minimum required definition by specifying width , lines and maxlength ”these set the dimensions of the editor, as described previously.

Note that constants are used to set the values of the dimensions, and these are defined by macro (rather than using const TInt as you might expect), because they occur within a resource file:

 #define KUrlWidth 176 #define KUrlNumberLines 1 #define KMaxUrlLength 256 

Note also that Series 60 has expanded on the Symbian OS implementations and defined new fields in the text editor resources. For example, in EDWIN the new fields are: avkon_flags , default_case , allowed_case_modes , numeric_keymap , allowed_input_modes , default_input_mode , special_character_table , max_view_height_in_lines and base_line_delta . There are also some Series 60-specific values defined for flags ”these all contain the word Avkon in their name .

The configurable features of the text editor in the PlainTextEditor example span six main categories. Table 8-7 provides a breakdown of the resource definition, in terms of the category each resource line addresses, and its purpose.

Table 8-8 provides a breakdown of the properties applied by specific avkon_flags .

Table 8-7. Explanation of Resource Definitions for the PlainTextEditor Example

General Feature Affected

Line Item

Purpose in Resource Definition

Reference Information

Dimensions

 Width Lines maxlength 

Specifies the dimensions of the control.

See Table 8-3

Input Mode

 allowed_input_modes default_input_mode 

The default input mode is set to text. However, numeric input is specified as an additional allowed mode, because URLs can sometimes require numeric input.

See Table 8-10

Input Case

 default_case allowed_case_modes 

These specify which filter to apply when the editor is in text mode. The resource states that lowercase should be the default mode, but uppercase is included as an additional allowed mode.

See uikon.hrh

Numeric Key Map

numeric_keymap

This line sets the numeric key map to be used when the editor is in numeric entry mode. The chosen value actually prevents a map from being presented.

See Table 8-9

Special Character Table

special_character _table

This line sets the mapping (for when the editor is in text mode) to a collection of characters that are often required in URL entries.

See Table 8-6

Properties

flags

EEikEdwinWidthInPixels sets the control so that its width is determined in pixels instead of characters.

All flags are defined within uikon.hrh . Additionally, the SDK documentation for CEikEdwin describes a number of flags ( TFlags ) that you can set when constructing an editor dynamically using ConstructL () .

Properties

avkon_flags

EAknEditorFlagNoT9 disables predictive text, which may confuse users when entering URLs.

See Table 8-8 for a list of avkon_flags properties.

All files referenced in this table can be found in the directory \epoc32\include in the root of your SDK .


Table 8-8. Text Editor avkon_flags Properties

Value of avkon_flags

Use

EAknEditorFlagDefault

Default. Resets all flags.

EAknEditorFlagFixedCase

Prevents the case from being changed.

EAknEditorFlagNoT9

Prevents predictive text entry.

EAknEditorFlagNoEditIndicators

Removes edit indicators from the navigation pane. Particularly useful in tabbed views, such as with multipage dialogs.

EAknEditorFlagNoLRNavigation

Prevents left and right scrolling.

EAknEditorFlagSupressShiftMenu

Prevents the special character table from displaying.

EAknEditorFlagEnableScrollBars

Enables the scroll bar indicator.

EAknEditorFlagMTAutoOverwrite

Enables the text to overwrite rather than insert.

EAknEditorFlagUseSCTNumericCharmap

In numeric mode, the editor displays the special character table rather than the numeric key map when the user presses and holds down the asterisk (*) key. It does this only if you have defined a special character table in the editor using the special_character_table field.

EAknEditorFlagLatinInputModesOnly

Prevents anything other than Latin characters from being entered.

EAknEditorFlagForceTransparentFepModes

Forces front-end-processor (FEP) modes to be transparent. For example, in the find pane in Chinese variants, a pop-up window would be displayed to allow the user to choose between Stroke and Zhuyin text entry. If this flag is set, the entry will be transparent ”no pop-up window will be displayed.


Table 8-9 provides a breakdown of the numeric key map modes.

Table 8-9. Text Editor Numeric Key Maps

Value of numeric_keymap

* Key Enters

# Key Events

EAknEditorStandardNumberModeKeyMap

*, +, p, w

#

EAknEditorPlainNumberModeKeyMap

Nothing

Nothing

EAknEditorCalculatorNumberModeKeyMap

+, -, *, /

.

EAknEditorConverterNumberModeKeyMap

+, -, E

.

EAknEditorToFieldNumberModeKeyMap

+

;

EAknEditorFixedDiallingNumberModeKeyMap

*, +, p, w

#

EAknEditorSATNumberModeKeymap

*, +

#

EAknEditorSATHiddenNumberModeKeymap

*

#


Table 8-10 provides a breakdown of the available input modes.

Table 8-10. Text Editor Input Modes

Value of default_input_mode and allowed_input_modes

Use

EAknEditorTextInputMode

Text

EAknEditorNumericInputMode

Numeric

EAknEditorSecretAlphaInputMode

Secret

EAknEditorAllInputModes

All of the above


Instantiating a Plain Text Editor from a Resource

The plain text editor is constructed using an instance of CEikEdwin . PlainTextEditor performs this construction in the container's second-phase constructor:

 void CPlainTextEditorContainer::ConstructL(const TRect& aRect)    {    CreateWindowL();    iEditor = new (ELeave) CEikEdwin;    iEditor->SetContainerWindowL(*this);    TResourceReader reader;    iCoeEnv->CreateResourceReaderLC(reader, R_PLAINTEXTEDITOR_URLEDITOR);    iEditor->ConstructFromResourceL(reader);    CleanupStack::PopAndDestroy(); // reader    iEditor->SetFocus(ETrue);    SetRect(aRect);    ActivateL();    } 

As shown above, it is necessary to call the first-phase constructor for CEikEdwin , construct it from a resource using ConstructFromResourceL() , and set the editor so that the user can type into it, by calling SetFocus() with a value of Etrue .

Key events must be offered to the control so that it receives keypad input from special keys (such as the Clear key). For this purpose, CPlainTextEditorContainer overrides OfferKeyEventL() :

[View full width]
 
[View full width]
TKeyResponse CPlainTextEditorContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent ,TEventCode aType) { if (iEditor) { return iEditor->OfferKeyEventL(aKeyEvent, aType); } else { return CCoeControl::OfferKeyEventL(aKeyEvent, aType); } }

Note that, as this is a Traditional Symbian OS Architecture example (as described in Chapter 4), the container class derives from CCoeControl , and so is itself offered key events by the application framework. It passes these first to its child editor control here.

Configuring a Rich Text Editor

The main purpose of PlainTextEditor was to show how you can configure editors to facilitate different types of data entry. RichTextEditor focuses instead on using an editor to display formatted text. The example emulates a help document browser by displaying a body of formatted sample help text, as shown in Figure 8-7. It allows the user to scroll up and down by page increments . In keeping with text browser characteristics, the editor is read-only and the cursor is hidden. These aims are accomplished by using a rich text editor.

Figure 8-7. The RichTextEditor main screen.


RichTextEditor demonstrates the basic programming tasks associated with rich text editors. These tasks include defining the editor within a resource file and instantiating the editor from resource.

In addition, RichTextEditor demonstrates how to develop a customized control by deriving from CRichTextEditor . The derived class in the example conveniently encapsulates some of the CRichTextEditor text formatting capabilities in intuitively-named public member functions (such as SetUnderlineOn() and SetBoldOn() ). The custom control also enables additional help browser behavior, such as scrolling by page.

Defining a Rich Text Editor Resource

A rich text editor is defined in an RTXTED resource structure, as shown below:

 RESOURCE RTXTED r_richtexteditor_rich_text_editor    {    width = KWidth;    height = KHeight;    textlimit = KMaxLength;    flags = EEikEdwinReadOnly  EEikEdwinAvkonDisableCursor;    avkon_flags = EAknEditorFlagEnableScrollBars;    } 

The minimum specification of the above structure comprises the width and height of the editor in pixels, and the maximum number of characters that the editor will hold ( textlimit ).

The RichTextEditor example also specifies values for flags and avkon_flags . Please refer to Table 8-7 for a general explanation of how these and other optional fields can be used. (Note, though, that values in Table 8-7 refer specifically to the PlainTextEditor example.)

Because the example is designed only to display text, and not to accept user input, the value of flags is set to make the editor read-only ( EEikEdwinReadOnly ) and hide the cursor from display ( EEikEdwinAvkonDisableCursor ). To enable scrolling, the value of avkon_flags is set to EAknEditorFlagEnableScrollBars . This causes scroll bars to appear when the length of the editor's text exceeds its physical dimensions.

Creating a Custom Rich Text Editor Control

Although it is possible to use a rich text editor object ( CEikRichTextEditor ) directly, RichTextEditor uses a custom class that inherits from CEikRichTextEditor . The derived control provides help browser behavior (such as scrolling in page increments) and presents a simplified interface for formatting text. Consider the custom control's class definition below:

 class CRichTextEditorRichTextEditor : public CEikRichTextEditor    { public: // Constructors and destructor    static CRichTextEditorRichTextEditor* NewL();    static CRichTextEditorRichTextEditor* NewLC(); private: // Constructor    void ConstructL(); public: // from CoeControl    TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType); public: // members    void SetUnderlineOn(TBool aOn);    void SetBoldOn(TBool aOn);    void AddCarriageReturnL ();    void AddTextL(const TDesC& aText);    void DisplayStartOfHelpTextL(); private: // data    TCharFormatMask iCharFormatMask;    // Current formatting, e.g. bold, etc.    TCharFormat iCharFormat;            // Current formatting, e.g. bold, etc.    }; 

Notable member functions of this class include:

  • An overridden version of OfferKeyEventL() to implement scrolling a page at a time.

  • Members that simplify the rich text editor interface, such as SetBoldOn() .

  • Member data for character formatting.

You will see the implementation of these methods and use of the member data as you work through this example.

Setting Formatting Attributes

Text formatting in a rich text editor can be applied to either individual characters or entire paragraphs. The RichTextEditor example uses character (rather than paragraph) formatting and encapsulates this formatting functionality via member functions that set up individual attributes.

The following is the code for CRichTextEditorRichTextEditor::SetBoldOn() :

 void CRichTextEditorRichTextEditor::SetBoldOn(TBool aOn)    {    iCharFormatMask.SetAttrib(EAttFontStrokeWeight);    if (aOn)       {    iCharFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);       }    else       {    iCharFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightNormal);       } 

To set a particular attribute, you use a character format mask ( TCharFormatMask ) to identify the attribute (such as the font stroke weight) that you wish to set, calling the SetAttrib() method to set the actual attribute. In RichTextEditor , the attribute used is EAttFontStrokeWeight .

Next, you need to use a character format ( TCharFormat ) to set the value of this attribute (such as bold or normal). The character format has two (public) member variables that you can set ”the font specification ( iFontSpec ) and the font presentation ( iFontPresentation ). The font specification gives you access to the typeface, height and font style. The font presentation gives you access to the highlighting and alignment of the characters. RichTextEditor deploys the font specification to set the stroke weight, setting it to EStrokeWeightBold or EStrokeWeightNormal as appropriate.

Further information on the full range of specifiable attributes and values is available in the SDK documentation.

If you wish to set paragraph attributes rather than character attributes, you should use a TParaFormatMask format mask and a CParaFormat format object instead.


Setting the Text in a Rich Text Editor and Applying Character Formatting

A rich text editor contains a CRichText object, and this object is used to set and update the editor's text and apply formatting to it. The RichTextEditor example illustrates the use of this object in its AddCarriageReturnL() and AddTextL() functions:

 void CRichTextEditorRichTextEditor::AddTextL(const TDesC& aText)    {    CRichText* richText = RichText();    TInt documentLength = richText->DocumentLength();    richText->InsertL(documentLength, aText);    richText->ApplyCharFormatL(iCharFormat, iCharFormatMask, documentLength, aText.Length());    } 

As shown here, a handle on the rich text object is obtained by calling the RichText() method of CEikRichTextEditor . Despite RichText() returning a pointer to the object, there is no transfer of ownership. Therefore, you must not put it on the Cleanup Stack or destroy it.

Like the rich text editor, other text editors also contain text objects, although of different types. A plain text editor ( CEikEdwin ) contains a CPlainText object, and a global text editor ( CEikGlobalTextEditor ) contains a CGlobalText object. You can obtain pointers to these objects by using CEikEdwin::Text() and CEikGlobalTextEditor::GlobalText() , respectively. All text objects derive from CPlainText .


The rich text object does not have a method for appending text. However, it does have one for inserting text. If you wish to append text to the end of the existing text and apply character formatting to it, you will need to:

  • Calculate the length of the existing text using the DocumentLength() method.

  • Insert the new text at the calculated position using the InsertL() method. This requires two arguments: the position and the text. The RichTextEditor example code shown previously passes in the length of the existing text ( documentLength ) as the position so that the text appends onto the existing text.

  • Apply the formatting to the text by calling ApplyCharFormatL() . This requires four arguments: the character format, the character format mask, the position where the formatting should begin and the number of characters to format. In the RichTextEditor example, the recently appended text gets formatted by setting the start position to the length of the previously existing text ( documentLength ), and the number of characters to be the length of the text that was just added ( aText.Length() ).

If you are applying paragraph formatting, rather than character formatting, then call ApplyParaFormatL() instead.


A carriage return is appended to the text in AddCarriageReturnL() by inserting CEditableText::ELineBreak at the end of the text:

 void CRichTextEditorRichTextEditor::AddCarriageReturnL()    {    CRichText* richText = RichText();    richText->InsertL(richText->DocumentLength(), CEditableText::ELineBreak);    } 

Positioning the Editor s Cursor

To make the text scroll a page at a time, you need to handle up and down scroll key events. As with all key events, you can do this by overriding the OfferKeyEventL() method:

[View full width]
 
[View full width]
TKeyResponse CRichTextEditorRichTextEditor::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType) { if (aType == EEventKey) { if (aKeyEvent.iCode == EKeyDownArrow) { MoveCursorL(TCursorPosition::EFPageDown, EFalse); return EKeyWasConsumed; } else if (aKeyEvent.iCode == EKeyUpArrow) { MoveCursorL(TCursorPosition::EFPageUp, EFalse); return EKeyWasConsumed; } else { return CEikRichTextEditor::OfferKeyEventL(aKeyEvent, aType); } } return EKeyWasNotConsumed; }

To scroll the text, you simply need to move the cursor to the appropriate position using the MoveCursorL() method. This requires two arguments: a desired logical position and a flag indicating whether to select all text delimited by the cursor's previous and new positions . If the selection flag is set to ETRue , then the text between the current cursor position and the position you are moving to is selected. In the RichTextEditor example, selection of text is not appropriate, so the value passed in is EFalse .

The TCursorPosition enumeration defines the possible logical positions to move to. In RichTextEditor , the application moves up and down "pages" using the values EFPageUp and EFPageDown .

If, as in RichTextEditor , you have appended to the existing text, you will find that the cursor is positioned at the end of that text. If there is more text than will fit on the screen, you will also find that the last page of text is displayed rather than the first. In order to make the first page display, you will need to move the cursor to the start of the text. This is accomplished in CRichTextEditorRichTextEditor::DisplayStartOfHelpTextL() :

 void CRichTextEditorRichTextEditor::DisplayStartOfHelpTextL()    {    SetCursorPosL(0, EFalse);    } 

This simply calls the SetCursorPosL() method, with the new cursor position ( ) and a flag ( EFalse ) indicating whether to select the text between the current position and the new one.

It is important to call this method after you have activated the containing window . In RichTextEditor this occurs in CRichTextEditorContainer::ConstructL() :

 void CRichTextEditorContainer::ConstructL(const TRect& aRect)    {    CreateWindowL();    iEditor = CRichTextEditorRichTextEditor::NewL();    iEditor->SetContainerWindowL(*this);    AddTextToEditorL();    SetRect(aRect);    ActivateL();    iEditor->DisplayStartOfHelpTextL();    } 

As you can see, this method creates the container's window and the rich text editor object, sets the editor's container window, adds text to the editor, activates the container and then moves the cursor to the start of the text.

Constructing a Rich Text Editor from a Resource

The following excerpt shows how to construct a rich text editor from a resource file, using ConstructFromResourceL() . The CRichTextEditorRichTextEditor class wraps up its construction into standard NewL() , and NewLC() factory methods. These factory methods call the first-phase constructor and an overridden ConstructL() , as shown below:

 void CRichTextEditorRichTextEditor::ConstructL()    {    TResourceReader reader;    iCoeEnv->CreateResourceReaderLC(reader, R_RICHTEXTEDITOR_RICH_TEXT_EDITOR);    ConstructFromResourceL(reader);    CleanupStack::PopAndDestroy(); // reader    SetFocus(ETrue);    } 

As you can see, this completes the construction using ConstructFromResourceL() with the RTXTED resource that was defined in the resource file. After construction, it then sets the editor's input focus by calling SetFocus() with a value of Etrue . This is an important step, without which the editor will not receive keypad input.

Using the Custom Rich Text Editor Control

To complete this example, the following code shows how formatted text is added to the custom rich text editor control. It is taken from the AddTextToEditorL() function and uses the SetBoldOn() , SetUnderlineOn() , AddCarriageReturnL() and AddTextL() methods discussed previously in order to create and format the text:

 ... HBufC* header1 = StringLoader::LoadLC(R_RICHTEXTEDITOR_HELP_HEADER1); iEditor->SetUnderlineOn(ETrue); iEditor->SetBoldOn(ETrue); iEditor->AddTextL(*header1); CleanupStack::PopAndDestroy(header1); iEditor->AddCarriageReturnL(); iEditor->SetUnderlineOn(EFalse); iEditor->SetBoldOn(EFalse); ... 

The results of this code can be seen in the first line of text presented in Figure 8-7.

Using Styles

In addition to formatting characters as shown in the RichTextEditor example, it is possible to specify named styles that can be applied to whole paragraphs. You could, for example, have a named style, Heading , which you could use to apply formatting for all headings in your text. This could, for example, specify that font underlining is on and that the stroke weight is set to bold.

All the styles for an editor are stored in a style list. You can pass this to the CRichText object on construction or set it afterward. The style list is a CStyleList object, which encapsulates a fixed-length array of pointers to RParagraphStyleInfo objects. Each RParagraphStyleInfo encapsulates a CParagraphStyle , which contains the formatting for a paragraph, and an optional reference to the next paragraph style. This optional reference allows you to know which style to apply to the next paragraph. For example, you may want the Normal style to always follow the Heading style, so in the Heading 's RParagraphStyleInfo you would set the next paragraph style to be Normal .

For each defined style you need to construct a CParagraphStyle , passing in a CParaFormatLayer , and a CCharFormatLayer ”these are constructed using masks and formats, as in the RichTextEditor example. You then need to construct an instance of RParagraphStyleInfo , passing in the CParagraphStyle on construction, and add this RParagraphStyleInfo to the CStyleList using the AppendL() method.

Styles are applied to paragraphs much as character formatting is applied, but this time using the ApplyParagraphStyleL() method, rather than the ApplyCharFormatL() method. You can obtain the particular style required using the CStyleList API methods.

For further information on using styles, refer to the SDK documentation.



Developing Series 60 Applications. A Guide for Symbian OS C++ Developers
Developing Series 60 Applications: A Guide for Symbian OS C++ Developers: A Guide for Symbian OS C++ Developers
ISBN: 0321227220
EAN: 2147483647
Year: 2003
Pages: 139

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net