Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]


txtshell example code

Found in: examples\AppFramework\Text

Note: This example is designed to work properly with Techview and there is no guarantee that it will work with other interfaces.

This document reproduces some of the files contained in the examples. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

[Top]


Description

txtshell is an application that provides a shell for the text example code to run in. It provides four concrete text example controls, CGlobalControl, CRichControl, CStyleControl and CViewControl, all derived from the abstract base class CGraphicExampleControl. Each of these controls implements an UpdateModelL() function that is called each time the current step in the example is advanced. Each step modifies the content, formatting, or display of the text in a different way. For details, see the appropriate control example.

Each of these controls illustrates a different set of operations which can be performed on a text object or a text view.


Base class for graphics and text examplesCGraphicExampleControl

// TXTEXAMP.H
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.
//

#ifndef __TXTEXAMP_H
#define __TXTEXAMP_H

#include <coemain.h>
#include <coecntrl.h>
#include <s32file.h>
#include <txtglobl.h>
#include <frmtview.h>
#include <txtfmlyr.h>

//
// class MGraphicsExampleObserver
//

class MGraphicsExampleObserver
    // Defines an interface that controls can call to inform the shell 
    // that they have finished, or that the status message display needs 
    // updating. It is implemented by CExampleShellContainer  
    {
public:
    // Notify user that example has finished
    virtual void NotifyGraphicExampleFinished()=0;
    // Notify user of the current status of the example
    virtual void NotifyStatus(const TDesC& aMessage)=0;
    };

//
// class CGraphicExampleControl
//

/*
    Usage

        This class is used as a base class for graphics and text 
        examples. It uses CONE's facilities to provide an initialized 
        graphics environment.

        It creates a 600x200 window in which drawing can be done.

        It supports multiple phases, so different drawings can be 
        done from one phase to another.  Tap the spacebar or click the
        mouse (anywhere) to advance a phase.

        Quit the program by pressing the exit button.

    Writing derived classes

        A minimal derived class should have a Draw() function
        which puts a drawing onto the screen.

        If you are using multiple phases, code a constructor which
        calls SetMaxPhases() specifying the number of phases.  Have
        Draw() honour the phase number, available using Phase().
*/

#pragma warning(disable : 4100)
        // disable "parameter not used" warning on HandleKey()

class CGraphicExampleControl : public CCoeControl
    {
public:
    // construct/destruct
    void ConstructL(const TRect& aRect, MGraphicsExampleObserver* aObserver, const CCoeControl& aParent);
        // second-phase construction
    ~CGraphicExampleControl();
    // public so container can offer keys
    TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
        // intercepts space; offers other keys to derived classes
protected:
    // derived classes must provide the next 2 functions
    virtual void UpdateModelL() =0; // empty update model function
    virtual void Draw(const TRect& /* aRect */) const {}; // empty draw function
    // use Phase() in Draw() to tell what phase we're in
    TInt Phase() const { return iPhase; }; // get phase number
    void SetMaxPhases(TInt aMaxPhases) { iMaxPhases=aMaxPhases; };
            // use this from derived-class constructor to set number of phases
    CFont* iMessageFont; // font for messages
private:
    // functions provided for CCoeControl protocol
    void HandlePointerEventL(const TPointerEvent& aPointerEvent);
        // advances phase on pointer-down
    void Quit(); // does termination
    void NextPhaseL(); // advances phase: quits if all phases done
    // phase control for graphics examples
    TInt iPhase; // phase number
    TInt iMaxPhases; // maximum phases
protected:
    MGraphicsExampleObserver* iFormObserver;
    TBool iUpdateModelDoesRedraw; // whether UpdateModelL() does a redraw for us
    };

// sundry derived classes

class CGlobalText;
class CRichText;
class CParaFormatLayer;
class CCharFormatLayer;
class CTextLayout;
class CTextView;
class CStyleList;
class CParagraphStyle;


class CGlobalControl : public CGraphicExampleControl
    {
    // Demonstrates the use of global text
public:
    CGlobalControl() { SetMaxPhases(16); };
    void UpdateModelL();
    void Draw(const TRect& aRect) const;
    ~CGlobalControl();
private:
    CGlobalText* iGlobalText; // global text object
    CParaFormatLayer* iParaFormatLayer;
    CCharFormatLayer* iCharFormatLayer;
    TStreamId iStreamId; // required when storing and restoring global text
    // text layout and view stuff
    CTextLayout* iLayout; // text layout
    CTextView* iTextView; // text view
    TRect iViewRect; // rectangle through which to view text
    };

class CRichControl : public CGraphicExampleControl
    {
    // Demonstrates the use of rich text
public:
    CRichControl() { SetMaxPhases(14);}; 
    ~CRichControl(); // destructor
    void UpdateModelL();
    void Draw(const TRect& aRect) const;
private:
    CRichText* iRichText; // global text object
    CParaFormatLayer* iParaFormatLayer;
    CCharFormatLayer* iCharFormatLayer;
    TStreamId iStreamId; // required when storing and restoring global text
    // text layout and view stuff
    CTextLayout* iLayout; // text layout
    CTextView* iTextView; // text view
    TRect iViewRect; // rectangle through which to view text
    };

class CStyleControl : public CGraphicExampleControl
    {
    // Demonstrates the use of styles in rich text
public:
    CStyleControl() { SetMaxPhases(9);}; 
    ~CStyleControl(); // destructor
    void UpdateModelL();
    void Draw(const TRect& aRect) const;
private:
    void CreateNormal(); // Create Normal style (the global layers) 
    void CreateStyles(); // Create some paragraph styles
private:
    CRichText* iRichText; // rich text object
    CParaFormatLayer* iNormalParaFormatLayer;
    CCharFormatLayer* iNormalCharFormatLayer;
    TStreamId iStreamId; // required when storing and restoring global text
    // text layout and view stuff
    CTextLayout* iLayout; // text layout
    CTextView* iTextView; // text view
    TRect iViewRect; // rectangle through which to view text
    CStyleList* iStyleList; // Style list holds the two styles
    CParagraphStyle* iStyleOne;
    CParagraphStyle* iStyleTwo;
    };

class CViewControl : public CGraphicExampleControl
    {
    // Demonstrates the use of the text view and text layout classes
public:
    CViewControl() { SetMaxPhases(14);}; 
    ~CViewControl(); 
    void UpdateModelL();
    void Draw(const TRect& aRect) const;
private:
    CRichText* iRichText; // rich text object
    CParaFormatLayer* iParaFormatLayer;
    CCharFormatLayer* iCharFormatLayer;
    // text layout and view stuff
    CTextLayout* iLayout; // text layout
    CTextView* iTextView; // text view
    TRect iViewRect; // rectangle through which to view text
    CFbsBitmap* iBitmap; // line cursor bitmap
    };

#endif

Global text control (CGlobalControl)

Illustrates the following:

Example code

// TXTGLOB.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include "txtexamp.h"

#include <fldset.h>
#include <fldbase.h>
#include <fldbltin.h>
#include <flddef.h>

//
// field factory
//

class TExampleFieldFactory : public MTextFieldFactory
    // A text field factory. 
    // It creates date/time fields only.
    {
public:
    virtual CTextField* NewFieldL(TUid aFieldType);
    };

CTextField* TExampleFieldFactory::NewFieldL(TUid aFieldType)
    {
    CTextField* field = NULL; // NULL keeps GCC compiler happy 
    // Factory only produces date time fields, if aFieldType is 
    // not a date time field type, do nothing.
    if (aFieldType==KDateTimeFieldUid)
        field = (CTextField*)new(ELeave) CDateTimeField();
    return field;
    }

//
// CGlobalControl implementation
//

CGlobalControl::~CGlobalControl()
    {
    delete iTextView; // text view
    delete iLayout; // layout
    delete iGlobalText; // contained text object
    delete iCharFormatLayer; // char format layer
    delete iParaFormatLayer; // and para format layer
    }

void CGlobalControl::UpdateModelL()
    {
    // Create all constant literal descriptors used in this function, 
    // e.g. for message text
    _LIT(KPath,"\\globtxt.dat");
    _LIT(KText1,"Some global text.");
    _LIT(KText5, "To be, or not to be, that is the question; \
whether 'tis nobler in the mind to suffer the \
slings and arrows of outrageous fortune, or \
to stand against a sea of troubles, and by \
opposing end them."); 
    _LIT(KText6,"Word at pos %d (\"%S\") has %d characters, starts at pos %d");
    _LIT(KText2," And some more global text.");
    _LIT(KText3,"A new paragraph.");
    _LIT(KText4,"Number of characters=%d, words=%d, paras=%d");
    _LIT(KText8,"%D%M%Y%H:%T:%S %1/%2/%3");
    _LIT(KStatus0,"Initialised global text object and text view");
    _LIT(KStatus1,"InsertL() at position zero");
    _LIT(KStatus2,"InsertL() at end of document");
    _LIT(KStatus3,"Insert new paragraph, and more text");
    _LIT(KStatus5,"Inserted lots of text");
    _LIT(KStatus7,"Inserted date time field");
    _LIT(KStatus8,"Centre aligned paragraphs");
    _LIT(KStatus9,"Set bold, italic and underline (and updated the field)");
    _LIT(KStatus10,"Used StoreL() to store text and fields");
    _LIT(KStatus12,"Used RestoreL() to restore text and fields");
    _LIT(KStatus13,"Deleted lots of text");
    _LIT(KStatus14,"Paragraph and character formatting reset to default values");
    _LIT(KStatusReset,"Reset();");
    _LIT(KStatusDefault,"(Overshot!!)");

    TBufC<28>   name(KPath);

    switch (Phase())
        {
    case 0:
        {
        // Create text object, text view and layout.
        iParaFormatLayer=CParaFormatLayer::NewL(); // required para format layer
        iCharFormatLayer=CCharFormatLayer::NewL(); // required char format layer
        // Create an empty global text object
        iGlobalText=CGlobalText::NewL(iParaFormatLayer, iCharFormatLayer);
        // prerequisites for view - viewing rectangle
        iViewRect=Rect();
        iViewRect.Shrink(3,3);
        // context and device
        CWindowGc& gc=SystemGc(); // get graphics context
        CBitmapDevice *device=(CBitmapDevice*) (gc.Device()); // device
        // Create the text layout, (required by text view),
        // with the text object and a wrap width (=width of view rect)
        iLayout=CTextLayout::NewL(iGlobalText,iViewRect.Width());
        // Create text view
        iTextView=CTextView::NewL(iLayout, iViewRect,
                device,
                device,
                &Window(),
                0, // no window group
                &iCoeEnv->WsSession()
                ); // new view
        // message to say what we did
        iFormObserver->NotifyStatus(KStatus0);
        break;
        }
    case 1:
        // Insert some text
        iGlobalText->InsertL(0,KText1);
        iFormObserver->NotifyStatus(KStatus1);
        break;
    case 2:
        // Insert some more text
        iGlobalText->InsertL(iGlobalText->LdDocumentLength(),KText2);
        iFormObserver->NotifyStatus(KStatus2);
        break;
    case 3:
        // Insert a new paragraph
        iGlobalText->InsertL(iGlobalText->LdDocumentLength(),CEditableText::EParagraphDelimiter);
        // Insert text to follow new paragraph delimiter
        iGlobalText->InsertL(iGlobalText->LdDocumentLength(),KText3);
        iFormObserver->NotifyStatus(KStatus3);
        break;
    case 4:
        {
        // Display document info in status message
        TBuf<80> message; // for formatting status messages
        message.Format(KText4,
                iGlobalText->LdDocumentLength(),
                        // length up to and excluding final para mark
                iGlobalText->WordCount(), // white-space delimited words
                iGlobalText->ParagraphCount() // number paras including the final one
                );
        iFormObserver->NotifyStatus(message);
        break;
        }
    case 5:
        // Insert lots of text
        iGlobalText->InsertL(iGlobalText->LdDocumentLength(),CEditableText::EParagraphDelimiter);
        iGlobalText->InsertL(iGlobalText->LdDocumentLength(),KText5);
        iFormObserver->NotifyStatus(KStatus5);
        break;
    case 6:
        {
        // Display information about a random document position
        TBuf<80> message; // for formatting status messages
        // Print info about word at a document position
        TInt pos=iGlobalText->LdDocumentLength()/2;
        TInt startPos, length; // results of function
        iGlobalText->GetWordInfo(pos,startPos,length,EFalse,ETrue);
                // gets startPos and length, given pos
        // Insert all text into buffer from startPos (start of word at 
        // position pos) onwards
        TPtrC ptr=iGlobalText->Read(startPos,length); 
        // Print out word and word info
        message.Format(KText6, pos, &ptr, length, startPos);
        iFormObserver->NotifyStatus(message);
        break;
        }
    case 7:
        {
        // Insert date/time field into document
        TExampleFieldFactory* factory = new(ELeave) TExampleFieldFactory();
        CleanupStack::PushL(factory);
        // Set up the field factory
        iGlobalText->SetFieldFactory(factory);
        CTextField* field = iGlobalText->NewTextFieldL(KDateTimeFieldUid);
        // Format date to hour:minute:second day/month/year 
        ((CDateTimeField*)field)->SetFormat(KText8); 
        iGlobalText->InsertFieldL(0,field,KDateTimeFieldUid);
        // Evaluate the field (makes contents visible)
        iGlobalText->UpdateAllFieldsL();
        // Insert new para delimiter after field
        // First get length of field we've just inserted
        TFindFieldInfo info; 
        TInt pos=0;
        TInt range=0;
        iGlobalText->FindFields(info,pos,range);
        iGlobalText->InsertL(info.iFirstFieldLen,CEditableText::EParagraphDelimiter);
        iFormObserver->NotifyStatus(KStatus7);
        // clean up
        CleanupStack::PopAndDestroy(); // factory
        break;
        }
    case 8:
        {
        // Set some paragraph formatting - applied globally
        CParaFormat* paraFormat=CParaFormat::NewLC();
        TParaFormatMask paraFormatMask;
        // Set centre alignment
        paraFormat->iHorizontalAlignment=CParaFormat::ECenterAlign; 
        paraFormatMask.SetAttrib(EAttAlignment);
        // apply formatting - pos and length are irrelevent
        iGlobalText->ApplyParaFormatL(paraFormat,paraFormatMask,0,0);
        iFormObserver->NotifyStatus(KStatus8);
        CleanupStack::PopAndDestroy();  // paraFormat
        break;
        }
    case 9:
        {
        // Set some character formatting - applied globally
        TCharFormat charFormat;
        TCharFormatMask charFormatMask;
        // Interested in underline, posture and weight
        charFormatMask.SetAttrib(EAttFontUnderline); // set underline
        charFormatMask.SetAttrib(EAttFontPosture); // and posture (for italic)
        charFormatMask.SetAttrib(EAttFontStrokeWeight); // and weight (for bold)
        // Set bold, italics and underlining
        charFormat.iFontPresentation.iUnderline=EUnderlineOn;
        charFormat.iFontSpec.iFontStyle.SetPosture(EPostureItalic); 
        charFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
        // apply formatting - pos and length are irrelevent
        iGlobalText->ApplyCharFormatL(charFormat,charFormatMask, 0,0);
        // And update the field
        iGlobalText->UpdateFieldL(0);
        iFormObserver->NotifyStatus(KStatus9);
        break;
        }
// Storing and restoring
    case 10:                                      
        // set up a file store
        {
       RFs         theFs;
        CFileStore* theStore;
        TParse      filestorename;
        // Make a connection to the file server
        theFs.Connect();
        theFs.Parse(name,filestorename);
        theStore=CDirectFileStore::ReplaceLC(theFs,filestorename.FullName(),EFileRead|EFileWrite);
        theStore->SetTypeL(KDirectFileStoreLayoutUid);
        // store global text to file store
        iStreamId=iGlobalText->StoreL(*theStore);
        // close file store
        CleanupStack::PopAndDestroy(); // pop and destroy store
        // Disconnect from file server
        theFs.Close();
        iFormObserver->NotifyStatus(KStatus10);
        break;
        }
    case 11:
        // reset document, clearing it of all content
        iGlobalText->Reset();
        iFormObserver->NotifyStatus(KStatusReset);
        break;
    case 12:
        {
        // set up file store
        RFs         theFs;
        CFileStore* theStore;
        TParse      filestorename;

        theFs.Connect();
        theFs.Parse(name,filestorename);
        theStore=CDirectFileStore::OpenLC(theFs,filestorename.FullName(),EFileRead|EFileShareReadersOnly);
        if (theStore->Type()[0]!=KDirectFileStoreLayoutUid)
            User::Leave(KErrUnknown);
        // restore text and components from file store
        iGlobalText->RestoreL(*theStore,iStreamId);
        // close file store
        CleanupStack::PopAndDestroy(); // pop and destroy store
        theFs.Close();
        iGlobalText->UpdateFieldL(0);
        iFormObserver->NotifyStatus(KStatus12);
        break;
        }
    case 13:
        // Delete all text from paragraph containing a random doc position to 
        // end of document. Also delete preceding paragraph delimiter to keep 
        // paragraph count correct.
        {
        TInt pos=iGlobalText->LdDocumentLength()/2;
        iGlobalText->ToParagraphStart(pos); // pos set to start of paragraph
        pos--; // decrement so pos = preceding para delimiter
        iGlobalText->DeleteL(pos, iGlobalText->LdDocumentLength()-pos);
                // delete rest of text
        iFormObserver->NotifyStatus(KStatus13);
        break;
        }
    case 14:
        {
        // Reset all formatting back to the default
        TCharFormat charFormat;
        TCharFormatMask charFormatMask;
        CParaFormat* paraFormat=CParaFormat::NewLC();
        TParaFormatMask paraFormatMask;
        // Reset all character format attributes
        charFormatMask.SetAll();
        iGlobalText->ApplyCharFormatL(charFormat,charFormatMask,0,1);
            // format is all empty, mask is all set: thus, everything to default
        paraFormatMask.SetAll();
        iGlobalText->ApplyParaFormatL(paraFormat, paraFormatMask, 0,1);
            // ditto
        iFormObserver->NotifyStatus(KStatus14);
        CleanupStack::PopAndDestroy();  // paraFormat
        break;
        }
    case 15:
        // reset document, clearing it of all text content and fields
        iGlobalText->Reset();
        iFormObserver->NotifyStatus(KStatusReset);
        break;
    default:
        iFormObserver->NotifyStatus(KStatusDefault);
        break;
        }
    }

void CGlobalControl::Draw(const TRect& aRect) const
    {
    // draw surround
    CGraphicsContext& gc=SystemGc(); // context to draw into
    TRect rect=Rect(); // screen boundary
    gc.DrawRect(rect); // outline screen boundary
    rect.Shrink(1,1);
    gc.SetPenColor(KRgbWhite);
    gc.DrawRect(rect);
    rect.Shrink(1,1);
    gc.SetPenColor(KRgbBlack);
    gc.DrawRect(rect);
    // draw editable text - will work unless OOM
    TInt err;
    TRAP(err,iTextView->FormatTextL());
    if (err) return;
    TRAP(err,iTextView->DrawL(aRect));
    }

Rich text control (CRichControl)

Example code

Illustrates the following:

// TXTRICH.CPP
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.
//

#include "txtexamp.h"

#include <txtrich.h>

CRichControl::~CRichControl()
    {
    delete iTextView; // text view
    delete iLayout; // text layout
    delete iRichText; // contained text object
    delete iCharFormatLayer; // character format layer
    delete iParaFormatLayer; // and para format layer
    }


void CRichControl::UpdateModelL()
    {
    // Create all constant literal descriptors used in this function, 
    // e.g. for message text
    _LIT(KHamletSpeech, "To be, or not to be, that is the question; \
whether 'tis nobler in the mind to suffer the \
slings and arrows of outrageous fortune, or \
to stand against a sea of troubles, and by \
opposing end them."); 
    _LIT(KPath,"\\richtxt.dat");
    _LIT(KText1,"Default rich text. ");
    _LIT(KText2,"Much larger rich text.");
    _LIT(KText5,"New text has preserved formatting at insertion point. ");
    _LIT(KText7,"New text has lost formatting at insertion point. ");
    _LIT(KStatus0,"Initialised rich text object and text view");
    _LIT(KStatus1,"InsertL() at position zero");
    _LIT(KStatus2,"Inserted text with specific formatting applied");
    _LIT(KStatus3,"Underlining applied to part of paragraph");
    _LIT(KStatus4,"Deleted text, but preserved formatting ...");
    _LIT(KStatus5,"... and inserted with same format");
    _LIT(KStatus6,"Deleted text and forgot about formatting ...");
    _LIT(KStatus7,"... and inserted with format before new text");
    _LIT(KStatus8,"Added 2 new paragraphs with default formatting");
    _LIT(KStatus9,"Set alignment for second paragraph");
    _LIT(KStatus10,"Used StoreL() to store rich text and components");
    _LIT(KStatus12,"Used RestoreL() to restore rich text and components");
    _LIT(KStatusReset,"Reset();");
    _LIT(KStatusDefault,"(overshot!!)");

    TBufC<28>   name(KPath);

    switch (Phase())
        {
    case 0:
        {
        // Create text object, text view and layout.
        iParaFormatLayer=CParaFormatLayer::NewL(); // required para format layer
        iCharFormatLayer=CCharFormatLayer::NewL(); // required char format layer
        // Create an empty rich text object
        iRichText=CRichText::NewL(iParaFormatLayer, iCharFormatLayer);
        // prerequisites for view - viewing rectangle
        iViewRect=Rect();
        iViewRect.Shrink(3,3);
        // context and device
        CWindowGc& gc=SystemGc(); // get graphics context
        CBitmapDevice *device=(CBitmapDevice*) (gc.Device()); // device
        // Create the text layout, (required by text view),
        // with the text object and a wrap width (=width of view rect)
        iLayout=CTextLayout::NewL(iRichText,iViewRect.Width());
        // Create text view
        iTextView=CTextView::NewL(iLayout, iViewRect,
                device,
                device,
                &Window(),
                0, // no window group
                &iCoeEnv->WsSession()
                ); // new view
        // message to say what we did
        iFormObserver->NotifyStatus(KStatus0);
        break;
        }
    case 1:
        // Insert some text
        iRichText->InsertL(0,KText1);
        iFormObserver->NotifyStatus(KStatus1);
        break;
    case 2:
        // Insert some more text with specific formatting
        {
        TCharFormat charFormat;
        TCharFormatMask charFormatMask;
        charFormatMask.SetAttrib(EAttFontHeight); // interested in font height
        charFormat.iFontSpec.iHeight=480; // (in twips) increase it from default to 1/3 inch
        TInt pos=iRichText->DocumentLength(); // insertion position = end of doc
        iRichText->SetInsertCharFormatL(charFormat, charFormatMask,pos);
            // Set formatting, when inserting at this position
        iRichText->InsertL(pos,KText2); // Insert text at this position
        iRichText->CancelInsertCharFormat(); // Cancel "insert pending" state
            // This is necessary before inserting anywhere else
        iFormObserver->NotifyStatus(KStatus2);
        break;
        }
    case 3:
        {
        // Apply underlining to text which uses a mixture of formatting.
        TCharFormat charFormat;
        TCharFormatMask charFormatMask;
        charFormatMask.SetAttrib(EAttFontUnderline); // interested in underline
        charFormat.iFontPresentation.iUnderline=EUnderlineOn; // set it on
        iRichText->ApplyCharFormatL(charFormat, charFormatMask,13,10);
                // apply this character formatting, from position 13, 10 characters
        iFormObserver->NotifyStatus(KStatus3);
        break;
        }
    case 4:
        // delete text, then insert new text at same point to 
        // demonstrate preserving the deleted text's formatting.
        iRichText->DelSetInsertCharFormatL(19,(iRichText->DocumentLength()-19));
            // delete from pos 19, for rest of document; retain formatting at pos 19
        iFormObserver->NotifyStatus(KStatus4);
        break;
    case 5:
        // ... and then insert with same format
        iRichText->InsertL(19,KText5);
            // inserted with old formatting
        iRichText->CancelInsertCharFormat(); // must cancel before inserting elsewhere
        iFormObserver->NotifyStatus(KStatus5);
        break;
    case 6:
        // delete some text ... 
        iRichText->DeleteL(19,(iRichText->DocumentLength()-19));
            // DeleteL() deletes, and forgets formatting
        iFormObserver->NotifyStatus(KStatus6);
        break;
    case 7:
        // ... then insert new text at that point to 
        // demonstrate how DeleteL() differs from DelSetInsertCharFormatL(). 
        iRichText->InsertL(19,KText7);
            // insert, inheriting current formatting from char before 10
            // (no need to cancel anything!)
        iFormObserver->NotifyStatus(KStatus7);
        break;
    case 8:
        {
        // Rich text paragraph formatting.
        // Insert another 2 paragraphs using default formatting.
        // First remove specific formatting from final paragraph delimiter,
        // otherwise new paragraphs would pick up this formatting.
        iRichText->RemoveSpecificCharFormatL(iRichText->DocumentLength()-1,1);
        iRichText->InsertL(iRichText->DocumentLength(),
            CEditableText::EParagraphDelimiter); // new para
        for (TInt count=0;count<2;count++) // insert lots of text, twice over
            {   
            iRichText->InsertL(iRichText->DocumentLength(),KHamletSpeech); 
            iRichText->InsertL(iRichText->DocumentLength(),
                CEditableText::EParagraphDelimiter); // end para
            };
        iFormObserver->NotifyStatus(KStatus8);
        break;
        }
    case 9:
        {
        CParaFormat* paraFormat=CParaFormat::NewLC();
        TParaFormatMask paraFormatMask;
        // make para 1 right-aligned (numbering starts at 0)
        TInt pos, length;
        paraFormatMask.SetAttrib(EAttAlignment); // interested in alignment
        paraFormat->iHorizontalAlignment=CParaFormat::ERightAlign; // right-align
        pos=iRichText->CharPosOfParagraph(length,1); // start of para 2
        iRichText->ApplyParaFormatL(paraFormat,paraFormatMask,pos,1);
            // apply format to entire para - even 1 char will do
        iFormObserver->NotifyStatus(KStatus9);
        CleanupStack::PopAndDestroy();  // paraFormat
        break;
        }
// Storing and restoring
    case 10:
        // set up a file store
        {
        RFs         theFs;
        CFileStore* theStore;
        TParse      filestorename;
        // Make a connection to the file server
        theFs.Connect();
        theFs.Parse(name,filestorename);
        theStore=CDirectFileStore::ReplaceLC(theFs,filestorename.FullName(),EFileRead|EFileWrite);
        theStore->SetTypeL(KDirectFileStoreLayoutUid);
        // store rich text to file store
        iStreamId=iRichText->StoreL(*theStore); 
        // close the store
        CleanupStack::PopAndDestroy(); // pop and destroy store
        // Disconnect from file server
        theFs.Close();
        iFormObserver->NotifyStatus(KStatus10);
        break;
        }
    case 11:
        // reset document, clearing it of all content
        iRichText->Reset();
        iFormObserver->NotifyStatus(KStatusReset);
        break;
    case 12:
        // open the store
        {
        RFs         theFs;
        CFileStore* theStore;
        TParse      filestorename;

        theFs.Connect();
        theFs.Parse(name,filestorename);
        theStore=CDirectFileStore::OpenLC(theFs,filestorename.FullName(),EFileRead|EFileShareReadersOnly);
        if (theStore->Type()[0]!=KDirectFileStoreLayoutUid)
            User::Leave(KErrUnknown);
        // internalize from the store
        iRichText->RestoreL(*theStore,iStreamId);
        // close the store
        CleanupStack::PopAndDestroy(); // pop and destroy store
        theFs.Close();
        iFormObserver->NotifyStatus(KStatus12);
        break;
        }
    case 13:
        //reset document
        iRichText->Reset();
        // message to say what we did
        iFormObserver->NotifyStatus(KStatusReset);
        break;
    default:
        iFormObserver->NotifyStatus(KStatusDefault);
        break;
        }
    }


void CRichControl::Draw(const TRect& aRect) const
    {
    // draw surround
    CGraphicsContext& gc=SystemGc(); // context to draw into
    TRect rect=Rect(); // screen boundary
    gc.DrawRect(rect); // outline screen boundary
    rect.Shrink(1,1);
    gc.SetPenColor(KRgbWhite);
    gc.DrawRect(rect);
    rect.Shrink(1,1);
    gc.SetPenColor(KRgbBlack);
    gc.DrawRect(rect);
    // draw editable text - will work unless OOM
    TInt err;
    TRAP(err,iTextView->FormatTextL());
    if (err) return;
    TRAP(err,iTextView->DrawL(aRect));
}

Rich text control with style list (CStyleControl)

Illustrates the following:

Example Code

// TXTSTYL.CPP
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.
//

#include "txtexamp.h"

#include <txtrich.h>

CStyleControl::~CStyleControl()
    {
    delete iTextView; // text view
    delete iLayout; // layout
    delete iRichText; // contained text object
    delete iNormalCharFormatLayer; // char format layer
    delete iNormalParaFormatLayer; // para format layer
    }

void CStyleControl::CreateNormal()
    {
    // Create the "Normal" style 
    // = the global format layers upon which all styles will be based.
    // Use default formatting except for an increased left margin and line spacing.
    CParaFormat* paraFormat=CParaFormat::NewLC();
    TParaFormatMask paraFormatMask;
    paraFormat->iLeftMarginInTwips=360;
    paraFormatMask.SetAttrib(EAttLeftMargin);
    paraFormat->iLineSpacingInTwips=300;
    paraFormatMask.SetAttrib(EAttLineSpacing);
    // Create the normal (global) style
    iNormalParaFormatLayer=CParaFormatLayer::NewL(paraFormat,paraFormatMask);
    CleanupStack::PopAndDestroy();  // paraFormat
    TCharFormat charFormat;
    TCharFormatMask charFormatMask;
    charFormatMask.SetAttrib(EAttFontHeight);
    iNormalCharFormatLayer=CCharFormatLayer::NewL(charFormat,charFormatMask); 
    }

void CStyleControl::CreateStyles()
    {
    // Create two new styles, with names "Warning" and "ListBullet", 
    // add some appropriate formatting and append them to a style list.
    _LIT(KStyle,"Warning");
    _LIT(KStyleTwo,"ListBullet");
    CParaFormat* paraFormat=CParaFormat::NewLC();
    TParaFormatMask paraFormatMask;
    TCharFormat charFormat;
    TCharFormatMask charFormatMask;
    // Style 1 - "Warning style"
    iStyleOne=CParagraphStyle::NewL(
        *iNormalParaFormatLayer,*iNormalCharFormatLayer); // Base it on the "normal" layers

    // Enclose text in a paragraph border
    TParaBorder paraBorder;
    paraBorder.iLineStyle=TParaBorder::ESolid;
    paraBorder.iThickness=4; // border width
    paraBorder.iColor=KRgbGray; // set border color to gray
    paraBorder.iAutoColor=EFalse; // iColor overrides text color
    paraFormat->SetParaBorderL(CParaFormat::EParaBorderTop,paraBorder);
    paraFormat->SetParaBorderL(CParaFormat::EParaBorderBottom,paraBorder);
    paraFormat->SetParaBorderL(CParaFormat::EParaBorderLeft,paraBorder);
    paraFormat->SetParaBorderL(CParaFormat::EParaBorderRight,paraBorder);
    paraFormatMask.SetAttrib(EAttTopBorder);
    paraFormatMask.SetAttrib(EAttBottomBorder);
    paraFormatMask.SetAttrib(EAttRightBorder);
    paraFormatMask.SetAttrib(EAttLeftBorder);
    iStyleOne->SetL(paraFormat,paraFormatMask); 
    // Make it bold.
    // First, get handle to style 1's character format layer
    CCharFormatLayer* charStyleFormatLayer = iStyleOne->CharFormatLayer(); 
    charFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
    charFormatMask.SetAttrib(EAttFontStrokeWeight);
    // Set the style's character format layer
    charStyleFormatLayer->SetL(charFormat,charFormatMask);
    // Finally, set its name to "Warning"
    iStyleOne->iName=KStyle;

    // Style 2 - "listbullet"
    paraFormat->Strip(); // Clear paraformat ready for new style
    paraFormatMask.ClearAll(); // Clear mask
    iStyleTwo=CParagraphStyle::NewL(
        *iNormalParaFormatLayer,*iNormalCharFormatLayer);  // Base it on the "normal" layers
    paraFormat->iBullet=new(ELeave)TBullet;  
    paraFormat->iBullet->iHeightInTwips=480; // Size of bullet point character=480 twips
    paraFormat->iBullet->iHangingIndent=ETrue; // Indent the rest of the paragraph from the bullet
    paraFormatMask.SetAttrib(EAttBullet);
    iStyleTwo->SetL(paraFormat,paraFormatMask); 
    // Finally, set its name to "ListBullet"
    iStyleTwo->iName=KStyleTwo;

    // Create style table and insert styles.
    iStyleList=CStyleList::NewL();
    RParagraphStyleInfo info1(iStyleOne);
    RParagraphStyleInfo info2(iStyleTwo);
    iStyleList->AppendL(&info1);
    iStyleList->AppendL(&info2);
    // Create rich text object based on normal layers, with the style table.
    iRichText=CRichText::NewL(iNormalParaFormatLayer,iNormalCharFormatLayer,*iStyleList);
    CleanupStack::PopAndDestroy();  // paraFormat
}

void CStyleControl::UpdateModelL()
    {
    // Create all constant literal descriptors used in this function, 
    // e.g. for message text
    _LIT(KText1,"Some text using normal style");
    _LIT(KText2,"Text in warning style - based on normal");
    _LIT(KText3,"Text in list bullet style");
    _LIT(KText4,"Some more text in list bullet style");
    _LIT(KText5,"Some text in italics");
    _LIT(KStatus0,"Initialised styles and view");
    _LIT(KStatus1,"Normal");
    _LIT(KStatus2,"Warning style");
    _LIT(KStatus3,"List bullet style");
    _LIT(KStatus4,"Character and paragraph formatting applied to styled text");
    _LIT(KStatus5,"All specific formatting removed from third paragraph");
    _LIT(KStatus6,"Inserted some normal text with specific formatting");
    _LIT(KStatus7,"Applied a style (warning) to text, retaining specific formatting");
    _LIT(KStatus8,"Reset();");
    _LIT(KStatusDefault,"(overshot!!)");

    switch (Phase())
        {
    // Apply paragraph styles
    case 0:
        {
       // Create the global format layers on which all styles are based.
        CreateNormal(); 
        // Create text object and styles.
        CreateStyles(); 
        // Prerequisites for view - viewing rectangle
        iViewRect=Rect();
        iViewRect.Shrink(3,3);
        // context and device
        CWindowGc& gc=SystemGc(); // get graphics context
        CBitmapDevice* device=(CBitmapDevice*) (gc.Device()); // device
        // layout
        iLayout=CTextLayout::NewL(iRichText,iViewRect.Width()); // new layout
            // construct layout, giving width of viewing rectangle
        // text view
        iTextView=CTextView::NewL(iLayout, iViewRect,
            device,
            device,
            &Window(),
            0, // no window group
            &iCoeEnv->WsSession()
            );
        iFormObserver->NotifyStatus(KStatus0);
        break;
        }
    case 1:
        // Insert a paragraph using the "normal" (default) formatting.
        iRichText->InsertL(0,KText1);
        iRichText->InsertL(iRichText->DocumentLength(),
            CEditableText::EParagraphDelimiter); 
        iFormObserver->NotifyStatus(KStatus1);
        break;
    case 2:
        {
        // Insert a paragraph in "warning" style
        TInt length;
        TInt startPos;
         iRichText->InsertL(iRichText->DocumentLength(),KText2);
        iRichText->InsertL(iRichText->DocumentLength(),
            CEditableText::EParagraphDelimiter); 
        // Get start position of second paragraph
        startPos=iRichText->CharPosOfParagraph(length,1); // Not interested in length
        // Apply warning style to second paragraph - single character is enough
        iRichText->ApplyParagraphStyleL(*iStyleList->At(0).iStyle,startPos,1,
            CParagraphStyle::ERetainAllSpecificFormats);
        iFormObserver->NotifyStatus(KStatus2);
        break;
        }
    case 3:
    // Insert two paragraphs in list bullet style
        {
        TInt length;
        TInt startPos;
        // Insert some text in bullet point style
        iRichText->InsertL(iRichText->DocumentLength(),KText3);
        iRichText->InsertL(iRichText->DocumentLength(),
            CEditableText::EParagraphDelimiter); 
                // end para
        iRichText->InsertL(iRichText->DocumentLength(),KText4);
        iRichText->InsertL(iRichText->DocumentLength(),
            CEditableText::EParagraphDelimiter);
                // end para
        // Get start position and length of third paragraph
        startPos=iRichText->CharPosOfParagraph(length,2); // Interested in length
        // Apply list bullet style to 3rd and 4th paragraphs, 
        // from start of para 2, for length of para2 + 1 characters.
        iRichText->ApplyParagraphStyleL(*iStyleList->At(1).iStyle,startPos,length+1,
            CParagraphStyle::ERetainAllSpecificFormats);
        iFormObserver->NotifyStatus(KStatus3);
        break;
        }
    case 4:
        // Apply character and paragraph formatting 
        // (underlining and right alignment) over a style
        {
        TInt startPos, length;
        // Get start pos and length of third paragraph
        startPos=iRichText->CharPosOfParagraph(length,2); 
        // set underlining
        TCharFormat charFormat;
        TCharFormatMask charFormatMask;
        charFormat.iFontPresentation.iUnderline=EUnderlineOn; 
        charFormatMask.SetAttrib(EAttFontUnderline); // interested in underlining
        // Apply character formatting, from start of para for para length 
        // minus one char (don't want trailing paragraph delimiter underlined)
        iRichText->ApplyCharFormatL(charFormat, charFormatMask,startPos,length-1);
        CParaFormat* paraFormat=CParaFormat::NewL();
        TParaFormatMask paraFormatMask;
        paraFormat->iHorizontalAlignment=CParaFormat::ERightAlign; 
        paraFormatMask.SetAttrib(EAttAlignment);
        // Apply right alignment to first paragraph. A single character is enough
        iRichText->ApplyParaFormatL(paraFormat, paraFormatMask,startPos,1);
        iFormObserver->NotifyStatus(KStatus4);
        delete paraFormat;
        break;
        }
    case 5:
        // Remove all specific formatting from third para
        {
        TInt startPos, length;
        startPos=iRichText->CharPosOfParagraph(length,2); 
        // Remove all specific character formatting from the paragraph 
        iRichText->RemoveSpecificCharFormatL(startPos,length);
        // Remove all specific para formatting from the paragraph
        iRichText->RemoveSpecificParaFormatL(startPos,2);
        iFormObserver->NotifyStatus(KStatus5);
        break;
        }
    case 6:
        // Insert text in italics at the end of the document
        {
        TCharFormat charFormat;
        TCharFormatMask charFormatMask;
        charFormat.iFontSpec.iFontStyle.SetPosture(EPostureItalic); 
        charFormatMask.SetAttrib(EAttFontPosture); // interested in italic
        // Set formatting for all text inserted at this position.
        iRichText->SetInsertCharFormatL(charFormat,charFormatMask,iRichText->DocumentLength());
        iRichText->InsertL(iRichText->DocumentLength(),KText5);
        iRichText->CancelInsertCharFormat(); // "Insert pending" state cancelled
        iRichText->InsertL(iRichText->DocumentLength(),
            CEditableText::EParagraphDelimiter); // add a para delimiter at end of paragraph
        iFormObserver->NotifyStatus(KStatus6);
        break;
        }
    case 7:
        {
        // Apply a style to text added in previous case; retain all its specific formatting.
        TInt startPos, length;
        // Get any document position in the 5th paragraph. Not interested in length.
        startPos=iRichText->CharPosOfParagraph(length,4);
        iRichText->ApplyParagraphStyleL(*iStyleList->At(0).iStyle,startPos,1,
            CParagraphStyle::ERetainAllSpecificFormats);
        iFormObserver->NotifyStatus(KStatus7);
        break;
        }
    case 8:
        //reset document
        iRichText->Reset();
        // message to say what we did
        iFormObserver->NotifyStatus(KStatus8);
        break;
    default:
        iFormObserver->NotifyStatus(KStatusDefault);
        break;
        }
    }

void CStyleControl::Draw(const TRect& aRect) const
    {
    // draw surround
    CGraphicsContext& gc=SystemGc(); // context to draw into
    TRect rect=Rect(); // screen boundary
    gc.DrawRect(rect); // outline screen boundary
    rect.Shrink(1,1);
    gc.SetPenColor(KRgbWhite);
    gc.DrawRect(rect);
    rect.Shrink(1,1);
    gc.SetPenColor(KRgbBlack);
    gc.DrawRect(rect);
    // draw editable text - will work unless OOM
    TInt err;
    TRAP(err,iTextView->FormatTextL());
    if (err) return;
    TRAP(err,iTextView->DrawL(aRect));
    }

Advanced text view (CViewControl)

The example illustrates the following text view and layout operations:

Example Code

// TXTVIEW.CPP
//
// Copyright (c) 2000-2005 Symbian Software Ltd.  All rights reserved.
//

#include "txtexamp.h"

#include <txtrich.h>

CViewControl::~CViewControl()
    {
    delete iTextView; // text view
    delete iLayout; // text layout
    delete iRichText; // contained text object
    delete iCharFormatLayer; // char format layer
    delete iParaFormatLayer; // para format layer
    delete iBitmap; // line cursor character bitmap
    }

void CViewControl::UpdateModelL()
    {
    // Create all constant literal descriptors used in this function, 
    // e.g. for message text

    _LIT(KText1, "To be, or not to be, that is the question; \
whether 'tis nobler in the mind to suffer the \
slings and arrows of outrageous fortune, or \
to stand against a sea of troubles, and by \
opposing end them."); 
    _LIT(KText4,"Format band set. Num formatted lines=%d");
    _LIT(KText5,"Format band unset. Num formatted lines=%d");
    _LIT(KPathAndFile,"\\resource\\apps\\cursors.mbm");
    _LIT(KCDrive,"\\");
    _LIT(KZDrive,"Z:");
    _LIT(KStatus0,"Initialised - with grey fill colour");
    _LIT(KStatus1,"Added lots of text");
    _LIT(KStatus2,"Selected first paragraph");
    _LIT(KStatus3,"Formatted the selected text (and cancelled selection)");
    _LIT(KStatus6,"Set 20 pixel line cursor margin and 2 cursors");
    _LIT(KStatus7,"Reset the view rectangle - old wrapping still applies");
    _LIT(KStatus8,"Text wrapping set to new view rectangle");
    _LIT(KStatus9,"View rectangle and wrap width reset");
    _LIT(KStatus10,"Horizontal scroll left");
    _LIT(KStatus11,"Scrolling DOWN, blank space NOT scrolled");
    _LIT(KStatus12,"Back to top and horizontal scroll right");
    _LIT(KStatus13,"Reset();");
    _LIT(KStatusDefault,"(overshot!!)");

    
    switch (Phase())
        {
    case 0:
        {
        // Preparation for following cases:
        TCharFormat charFormat;
        TCharFormatMask charFormatMask;
        iUpdateModelDoesRedraw=ETrue; 
            // NextPhaseL() should call DrawNow() for the first case only
        // Create rich text object to be displayed in the text view
        iParaFormatLayer=CParaFormatLayer::NewL(); // required para format
        iCharFormatLayer=CCharFormatLayer::NewL(); // required char format
                // empty text objects
        iRichText=CRichText::NewL(iParaFormatLayer, iCharFormatLayer);
        // prerequisites for view - viewing rectangle
        iViewRect=Rect();
        iViewRect.Shrink(3,3);
        // context and device
        CWindowGc& gc=SystemGc(); // get graphics context
        CBitmapDevice* device=(CBitmapDevice*) (gc.Device()); // device
        // Construct the layout object used by the text view,
        // specifying wrap width (= width of viewing rectangle)
        iLayout=CTextLayout::NewL(iRichText,iViewRect.Width());
        // Construct text view
        iTextView=CTextView::NewL(iLayout, iViewRect,
            device,
            device,
            &Window(),
            &iCoeEnv->RootWin(), // window group, needed for cursor
            &iCoeEnv->WsSession()
            ); // new view
        // Set paragraph fill color and font height.
        // For visibility, set font height to 10 point.
        charFormatMask.SetAttrib(EAttFontHeight); 
            // height attribute only is relevant
        charFormat.iFontSpec.iHeight=200; // set to 10 point (200 twips)
        iRichText->ApplyCharFormatL(charFormat,charFormatMask,0,0);
        // Apply grey paragraph fill colour 
        CParaFormat* paraFormat=CParaFormat::NewL();
        TParaFormatMask paraFormatMask;
        paraFormat->iFillColor=TRgb(204,204,204); // Light grey
        paraFormatMask.SetAttrib(EAttFillColor);
            // fill colour attribute only is relevant
        iRichText->ApplyParaFormatL(paraFormat,paraFormatMask,0,0);
        iTextView->FormatTextL();
        iFormObserver->NotifyStatus(KStatus0);
        delete paraFormat;
        break;
        }
    case 1:
        {
        // insert lots of text
        for (TInt count=0;count<5;count++) // insert a paragraph, *5
            {   
            iRichText->InsertL(iRichText->DocumentLength(),KText1); // text
            iRichText->InsertL(iRichText->DocumentLength(),
                CEditableText::EParagraphDelimiter); // end para
            };
        TCursorSelection selection(0, iRichText->DocumentLength());
            // start and length of the inserted block
        iTextView->HandleInsertDeleteL(selection, 0); 
            // zero deleted characters 
        iFormObserver->NotifyStatus(KStatus1);
        break;
        }
    case 2:
        {
        // Select the first paragraph
        TInt pos=1;
        TUint scanMask=CPlainText::EScanToUnitEnd;
        iRichText->ScanParas(pos,scanMask);
            // get end position of current para
        // move cursor to end of para and select it
        iTextView->SetDocPosL(pos,ETrue); // ETrue = select the range
        iFormObserver->NotifyStatus(KStatus2);
        break;
        }
    case 3:
        {
        // Apply italics to the selected region
        TCursorSelection cursorSelection;
        TCharFormat charFormat;
        TCharFormatMask charFormatMask;
        // Set italics
        charFormat.iFontSpec.iFontStyle.SetPosture(EPostureItalic); 
        charFormatMask.SetAttrib(EAttFontPosture); 
            // font posture attribute only is relevant
        cursorSelection=iTextView->Selection(); // get range of selection
        TInt lowerPos=cursorSelection.LowerPos();
        TInt length=cursorSelection.Length();
        // Apply formatting to range
        iRichText->ApplyCharFormatL(charFormat,charFormatMask,lowerPos,length);
        iTextView->HandleRangeFormatChangeL(cursorSelection); // reformat from here
        iTextView->CancelSelectionL(); // remove selection and redraw
        iFormObserver->NotifyStatus(KStatus3);
        break;
        }
    case 4:
        {
        TBuf<80> message;
        // Set formatting to the band only and display the number of formatted lines.
        iLayout->SetAmountToFormat(CTextLayout::EFFormatBand);
        iTextView->HandleGlobalChangeL(); // global layout change 
        message.Format(KText4,iLayout->NumFormattedLines());
        iFormObserver->NotifyStatus(message);
        break;
        }
    case 5:
        {
        TBuf<80> message;
        // Set formatting to the whole document, then display the number of 
        // formatted lines.
        iLayout->SetAmountToFormat(CTextLayout::EFFormatAllText);
        iTextView->HandleGlobalChangeL(); // global layout change 
        message.Format(KText5,iLayout->NumFormattedLines());
        iFormObserver->NotifyStatus(message);
        break;
        }
    case 6:
        {
        // Set line cursor margin and line cursor bitmap
        iTextView->SetMarginWidths(0,20); // zero label margin, 20 pixel line cursor margin
        iTextView->DrawL(iViewRect); // update the view (SetMarginWidths() doesn't redraw)
        // Load in bitmap to represent line cursor.
        iBitmap=new(ELeave) CFbsBitmap();
        TBufC<40> pathandfile(KPathAndFile);
        TParse    bitmapFileName;
        TBufC<2>  c_drive(KCDrive);
        TBufC<2>  z_drive(KZDrive);

        bitmapFileName.Set(pathandfile,&c_drive,NULL);
        
        if (iBitmap->Load(bitmapFileName.FullName())) 
            // can't find cursor bitmap on C: drive, so try Z:
            {
            bitmapFileName.Set(pathandfile,&z_drive,NULL);
            iBitmap->Load(bitmapFileName.FullName());
            iTextView->SetLineCursorBitmap(iBitmap);
            iTextView->SetCursorVisibilityL(TCursor::EFCursorVisible,
                TCursor::EFCursorFlashing); 
            // both cursors now visible - flashing text cursor
            iFormObserver->NotifyStatus(KStatus6);
            }
        break;
        }
    case 7:
        {
        // Reset the view rectangle.
        // Before doing this, clear the existing one,
        // (the view should really be implemented as a control, in a container control,
        // and then the background would get cleared nicely by the container).
        ActivateGc();
        SystemGc().Clear(iViewRect);
        DeactivateGc();
        // Shrink the view rectangle by 40 pixels both directions
        iViewRect.Shrink(40,40);
        iTextView->SetViewRect(iViewRect);
        iTextView->DrawL(iViewRect); // Redraw the completely revamped view 
            // (SetViewRect() does not do a redraw)
        iFormObserver->NotifyStatus(KStatus7);
        break;
        }
    case 8:
        {
        // Wrap text to new view rectangle.
        // New wrap width = new view rect width minus total margin width.
        // First calculate the total margin width.
        TInt labelMarginWidth;
        TInt lineCursorMarginWidth;
        iTextView->MarginWidths(labelMarginWidth,lineCursorMarginWidth);
        iLayout->SetWrapWidth(iViewRect.Width()-(labelMarginWidth+lineCursorMarginWidth));
        iLayout->ForceNoWrapping(EFalse); // Ensure wrapping on
        iTextView->HandleGlobalChangeL();
        iFormObserver->NotifyStatus(KStatus8);
        break;
        }
    case 9:
        {
        // Reset view rectangle back to old dimensions and set wrapping
        // width accordingly
        TInt labelMarginWidth;
        TInt lineCursorMarginWidth;
        iTextView->MarginWidths(labelMarginWidth,lineCursorMarginWidth);
        iViewRect.Grow(40,40);
            // Increase view rectangle by 40 pixels both directions
        iTextView->SetViewRect(iViewRect);
        iLayout->SetWrapWidth(iViewRect.Width()-(labelMarginWidth+lineCursorMarginWidth));
        iTextView->HandleGlobalChangeL();
        iFormObserver->NotifyStatus((KStatus9));
        break;
        }
    case 10:
        // Horizontal scrolling
        iTextView->SetHorizontalScrollJump(40); // scroll jump is 40 pixels
        iTextView->ScrollDisplayL(TCursorPosition::EFLeft,CTextLayout::EFAllowScrollingBlankSpace); 
            // scroll to the left (scrolling blank space is allowed)
        iFormObserver->NotifyStatus(KStatus10);
        break;
    case 11:
        {
        // Vertical scrolling
        iFormObserver->NotifyStatus(KStatus11);
        TInt pixelsScrolled;
        // Scroll down to the bottom of the document, 
        do
            pixelsScrolled=iTextView->ScrollDisplayL(TCursorPosition::EFLineDown,
                CTextLayout::EFDisallowScrollingBlankSpace);
        while (pixelsScrolled);
        break;
        }
    case 12:
        {
        // Horizontal scroll back to left margin and to top of doc
        iFormObserver->NotifyStatus(KStatus12);
        TInt pixelsScrolled;
        do
            pixelsScrolled=iTextView->ScrollDisplayL(TCursorPosition::EFLineUp);     
        while (pixelsScrolled);
        iTextView->ScrollDisplayL(TCursorPosition::EFRight); 
            // scroll right (horizontal scroll jump value=40 pixels)
        break;
        }
    case 13:
        {
        // Reset document. 
        iRichText->Reset(); // change whole document!
        iTextView->FormatTextL(); // so format the whole lot
        iTextView->DrawL(iViewRect); // and draw it afresh
        iFormObserver->NotifyStatus(KStatus13);
        break;
        }
    default:
        iFormObserver->NotifyStatus(KStatusDefault);
        break;
        }
    }

void CViewControl::Draw(const TRect& aRect) const
    {
    // draw surround
    CGraphicsContext& gc=SystemGc(); // context to draw into
    TRect rect=Rect(); // screen boundary
    gc.DrawRect(rect); // outline screen boundary
    rect.Shrink(1,1);
    gc.SetPenColor(KRgbWhite);
    gc.DrawRect(rect);
    rect.Shrink(1,1);
    gc.SetPenColor(KRgbBlack);
    gc.DrawRect(rect);
    // draw editable text - will work unless OOM
    TInt err;
    TRAP(err,iTextView->DrawL(aRect));
    }

[Top]


Usage

Press F1 to get the menu which lists the examples. Select the appropriate example, and then press space to advance through a set of steps that illustrate features of that example.

[Top]


Class summary

All of the examples use the following classes:

Additionally, each control illustrates particular classes.

CGlobalControl illustrates CGlobalText (global text) and CPlainText (plain text without formatting).

CRichControl illustrates CRichText (rich text).

CStyleControl illustrates CParagraphStyle (paragraph style information), and CStyleList (list of paragraph styles).

CViewControl illustrates TCursorPosition (cursor position), TCursorSelection (cursor and anchor position for selection) and TViewYPosQualifier (vertical view control).