Creating a text editing command

You can create your own command classes either by deriving from one of the existing text command classes or by deriving your own class directly from TCommandOn<ATarget>. Your command classes should take an MTextSelection as a target, and, using the text selection, retrieve the selected data in the associated text representation object.

MTextRepresentation provides a set of functions that your commands can call to modify the encapsulated data. These functions act on the TTextArea encapsulated by the target selection. You can retrieve the TTextArea with the MTextSelection::GetTextArea function.

These functions are:

Generally, these functions do the following:

To create your own command class, derive from TCommandOn<MTextSelection> or from an existing derived class. Your command class must do the following:

  1. Provide standard constructors (an empty constructor and a copy constructor) and a destructor.
  2. Provide streaming operators and other MCollectible overrides as appropriate for your implementation.
  3. Override the necessary command member functions inherited from TCommandOn<MTextSelection>. You must override the TCommandOn<ATarget> function HandleDoBegin.
    If your command will be executed incrementally, also override:
    You might also need to override:
    See the information on commands in the manual Desktop Frameworks Concepts and the online class and member function documentation for TCommandOn<ATarget> for specific information on these functions. This information will help you determine which command functions you need to override for your command implementation.
  4. Maintain the necessary data to support Undo and Redo for the command.
For example, the following code shows the declaration and implementation of the command TReplaceTextCommand. This command derives from TCommandOn<MTextSelection>, and replaces the selected text with a given text string.

TReplaceTextCommand declaration

      // Copyright (C) 1994 Taligent, Inc. All rights reserved.
      class TReplaceTextCommand : public TCommandOn<MTextSelection>
      {
          public:
                                   TReplaceTextCommand ();
                                   TReplaceTextCommand(const TReplaceTextCommand&);
              virtual                  ~TReplaceTextCommand ();
      
      
            virtual void         SetText(const TText& text);
              virtual const TText* GetText() const;
      
              virtual TStream&     operator>>=(TStream&) const;
              virtual TStream&     operator<<=(TStream&);
              TReplaceTextCommand  &operator=(const TReplaceTextCommand&);
              MCollectibleDeclarationsMacro (TReplaceTextCommand);
      
          protected:
      
            virtual void         HandleDoBegin(MTextSelection&);
              virtual void         HandleUndo(MTextSelection&);
              virtual void         HandleRedo(MTextSelection&);
      
          private:
      
            TText* fDoText;
              TText* fUndoText;
              TTextArea fDoRegion;
              TTextArea fUndoRegion;
      };
      
    

TReplaceTextCommand implementation

      // Copyright (C) 1994 Taligent, Inc. All rights reserved.
      MCollectibleDefinitionsMacro(TReplaceTextCommand, 0);
      
      TReplaceTextCommand::TReplaceTextCommand ()
      : TCommandOn<MTextSelection>(TCommonCommand::kSerialUndo),
        fDoText(NIL),
        fUndoText(NIL)
      {
      }
      
      TReplaceTextCommand::TReplaceTextCommand (const TReplaceTextCommand& copy)
      : TCommandOn<MTextSelection>(copy),
        fDoText(NIL),
        fUndoText(NIL)
      {
          fDoText = ::CopyPointer(copy.fDoText);
          fUndoText = ::CopyPointer(copy.fUndoText);
          fDoRegion = copy.fDoRegion;
          fUndoRegion = copy.fUndoRegion;
      }
      
      
      TReplaceTextCommand::~TReplaceTextCommand ()
      {
          delete fDoText;
          delete fUndoText;
      }
      
      void
      TReplaceTextCommand::SetText (const TText& text)
      {
          if (fDoText != &text) {
              delete fDoText;
              fDoText = ::Copy(text);
          }
      }
      
      const TText*
      TReplaceTextCommand::GetText()const
      {
          if ( fDoText == NIL )
              ((TReplaceTextCommand*)this)->fDoText = new TStandardText;
          
          return fDoText;
      }
      
      TStream&
      TReplaceTextCommand::operator>>= (TStream& toWhere)const
      {
          WriteVersion(toWhere);
          TCommandOn<MTextSelection>::operator>>=(toWhere);
      
          ::Flatten(fDoText, toWhere);
          ::Flatten(fUndoText, toWhere);
          fDoRegion >>= toWhere;
          fUndoRegion >>= toWhere;
          return toWhere;
      }
      
      TStream&
      TReplaceTextCommand::operator<<= (TStream& fromWhere)
      {
          VersionInfo version = ReadVersion(fromWhere);
          TCommandOn<MTextSelection>::operator<<=(fromWhere);
      
          switch(version) {
      
        case 0: 
              delete fDoText;
              delete fUndoText;
              ::Resurrect(fDoText, fromWhere);
              ::Resurrect(fUndoText, fromWhere);
              fDoRegion <<= fromWhere;
              fUndoRegion <<= fromWhere;
              break;
          default:
              throw TInvalidVersionError();
          }
          return fromWhere;
      }
      TReplaceTextCommand&
      TReplaceTextCommand::operator= (const TReplaceTextCommand& obj)
      {
          if(&obj != this) {
              TCommandOn<MTextSelection>::operator=(obj);
              delete fDoText;
              delete fUndoText;
              fDoText = ::CopyPointer(obj.fDoText);
              fUndoText = ::CopyPointer(obj.fUndoText);
              fDoRegion = obj.fDoRegion;
              fUndoRegion = obj.fUndoRegion;
          }
          return *this;
      }
      
      void
      TReplaceTextCommand::HandleDoBegin(MTextSelection& selection)
      {
      
        fDoRegion = selection.GetTextArea();
          fUndoRegion = fDoRegion;
          
      
        MTextRepresentation* model = selection.GetTextForWriting();
          delete fUndoText;
          TTextRange firstRange;
          selection.GetFirstRange(firstRange);
          fUndoText = (model->GetText())->PartialCopy(firstRange);
          
      
        model->ReplaceText(*GetText(), fDoRegion);
          
      
        TTextCount textLength = GetText()->GetLength();
          if (textLength == 0) {
              fUndoRegion.SetInsertionOffset(firstRange.GetBegin());
          }
          else {
              firstRange.SetEnd( firstRange.GetBegin() + textLength );
              fUndoRegion.SetRange(firstRange);
          }
      
      
        selection.SetTextArea(fUndoRegion);
      }
      
      void
      TReplaceTextCommand::HandleUndo (MTextSelection& selection)
      {
          MTextRepresentation* model = selection.GetTextForWriting();
          model->ReplaceText(*fUndoText, fUndoRegion);
          selection.SetTextArea(fDoRegion);
      }
      
      void
      TReplaceTextCommand::HandleRedo (MTextSelection& selection)
      {
          MTextRepresentation* model = selection.GetTextForWriting();
          model->ReplaceText(*GetText(), fDoRegion);
          selection.SetTextArea(fUndoRegion);
      }

[Contents] [Previous] [Next]
Click the icon to mail questions or corrections about this material to Taligent personnel.
Copyright©1995 Taligent,Inc. All rights reserved.

Generated with WebMaker