OpTextFormat Class Reference

This class implements many of the 'operations' which will cause the TextStory to be reformated. More...

#include <textops.h>

Inheritance diagram for OpTextFormat:

OpTextUndoable SelOperation UndoableOperation Operation MessageHandler ListItem CCObject SimpleCCObject List of all members.

Public Types

enum  InsertStatus { INSERT, OVER }
enum  DeleteType { DEL, BACKSPACE }

Public Member Functions

 OpTextFormat ()
 OpTextFormat constructor.
void DoInsertChar (WCHAR Ch, OpTextFormat::InsertStatus InsStatus)
 see DoInsertCharHelper()
BOOL DoInsertCharHelper (WCHAR Ch)
 Inserts a new character to the left of the caret deleting any selection in the story that exists.
void DoDeleteChar (OpTextFormat::DeleteType DelTyp)
 If there is no sub-selection the char to the right/left of the caret is deleted else sub-selection is deleted and caret placed to left of 1st selected char.
void DoSwapCase ()
 The character to the right of the character has its case swapped, and the caret is moved right one character.
BOOL DoReturn (OpTextFormat::InsertStatus InsStatus)
 Break the text line at the caret with a hard EOL For simplicity, a new line is created the word wrapper tidies up.
BOOL DoTab ()
void GetOpName (String_256 *OpName)
 Returns the name of the operation.

Private Member Functions

BOOL DoDeleteSelection (TextStory *pTextStory, BOOL ReattachAttributes, BOOL *AllowOpRefused=NULL)
 Delete any sub-selection within pTextStory (exc caret).

Detailed Description

This class implements many of the 'operations' which will cause the TextStory to be reformated.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/7/93
A seperate Do function is provided for each of these ops

Definition at line 229 of file textops.h.


Member Enumeration Documentation

enum OpTextFormat::DeleteType
 

Enumerator:
DEL 
BACKSPACE 

Definition at line 239 of file textops.h.

00239 {DEL, BACKSPACE};                    // Same as keys 

enum OpTextFormat::InsertStatus
 

Enumerator:
INSERT 
OVER 

Definition at line 238 of file textops.h.

00238 {INSERT, OVER};                  // Insert or overwrite


Constructor & Destructor Documentation

OpTextFormat::OpTextFormat  ) 
 

OpTextFormat constructor.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/02/95

Definition at line 637 of file textops.cpp.

00638 {
00639 }


Member Function Documentation

void OpTextFormat::DoDeleteChar OpTextFormat::DeleteType  DelTyp  ) 
 

If there is no sub-selection the char to the right/left of the caret is deleted else sub-selection is deleted and caret placed to left of 1st selected char.

Author:
Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> (originally Peter)
Date:
12/2/96
Parameters:
DelTyp - DELETE => delete char to right of caret [INPUTS] BACKSPACE => delete char to left of caret

Definition at line 792 of file textops.cpp.

00793 {
00794     TextStory* pStory = TextStory::GetFocusStory();
00795     if (pStory==NULL)
00796         End();  // no focus story so normal node deletion used which does not restore a caret
00797 
00798     String_256 MasterText = pStory->GetStoryAsString();
00799 
00800     BOOL ok = DoStartTextOp(pStory);
00801 
00802     BOOL DeletingAtCaret    = FALSE;    // assume not deleting at caret
00803     BOOL AttachAttrsToCaret = TRUE;     // assume attach carets from char to left after deletion
00804 
00805     // If just the caret is selected then select the character to the left/right
00806     CaretNode* pCaret = pStory->GetCaret();
00807     ERROR3IF(pCaret==NULL,"OpTextFormat::DoDeleteChar() - Focus story had no caret");
00808     VisibleTextNode* pForcedSel = NULL;
00809     // Caret is always selected, so test for subselection using selection end pointer
00810     if (ok && pCaret!=NULL && pStory->GetSelectionEnd()==NULL)
00811     {
00812         DeletingAtCaret = TRUE;
00813         if (DelTyp==OpTextFormat::DEL)
00814         {
00815             pForcedSel = pCaret->FindNextVTNInStory();
00816             ERROR3IF(pForcedSel==NULL,"No VisibleTextNode following the caret");
00817             if (pForcedSel!=NULL && pForcedSel==pStory->FindLastVTN())
00818                 pForcedSel = NULL;      // ensure last EOL in story is not deleted
00819         }
00820         else
00821         {
00822             pForcedSel = pCaret->FindPrevVTNInStory();
00823             if (pForcedSel!=NULL && !pForcedSel->IsAnEOLNode())
00824             {
00825                 pStory->AttachCaretAttributes(); // ensure caret has attrs of node to be deleted
00826                 AttachAttrsToCaret = FALSE;
00827             }
00828                     
00829         }
00830 
00831         // if we have a char to delete, select the char to delete
00832         if (pForcedSel!=NULL)
00833         {
00834             pForcedSel->SetSelected(TRUE);
00835             pCaret->SetSelected(FALSE);
00836         }
00837     }
00838 
00839     // do the deletion
00840     if (!DeletingAtCaret || pForcedSel!=NULL)
00841     {
00842         // Delete the selected character(s)
00843         BOOL AllowOpRefused = TRUE;
00844         ok = DoDeleteSelection(pStory, AttachAttrsToCaret, &AllowOpRefused);
00845 
00846         // if we were deleting at the caret, restore the selection
00847         if (ok && AllowOpRefused && pForcedSel!=NULL)
00848         {
00849             pForcedSel->SetSelected(FALSE);
00850             pCaret->SetSelected(TRUE);
00851         }
00852 
00853         // Mark the document as modified (as we don't have an opDescriptor)
00854         if (GetWorkingDoc()!=NULL)
00855             GetWorkingDoc()->SetModified(TRUE); 
00856         
00857         ObjChangeFlags cFlags; // use these so we have some objchange params to pass to the ontextstory changed fn
00858         ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
00859 
00860         if (ok)
00861         {
00862             // update other textstories that are dependant on this one
00863             SliceHelper::OnTextStoryChanged(pStory, this, &ObjChange, MasterText);
00864         }
00865 
00866         ObjChange.Define(OBJCHANGE_FINISHED,ObjChangeFlags(TRUE),NULL,this);
00867 
00868 
00869         if (ok) ok = UpdateChangedNodes(&ObjChange);
00870 
00871         if (ok) pCaret->ScrollToShow();
00872     }
00873 
00874     if (!ok)
00875     {
00876         InformError();
00877         FailAndExecute();
00878     }
00879 
00880     End();  
00881 }   

BOOL OpTextFormat::DoDeleteSelection TextStory pTextStory,
BOOL  ReAttachAttributes,
BOOL *  AllowOpRefused = NULL
[private]
 

Delete any sub-selection within pTextStory (exc caret).

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/5/95
Parameters:
pTextStory - The TextStory to operate on [INPUTS] ReAttachAttributes - TRUE => reattach caret's attributes after deletion
AllowOpRefused - TRUE => AllowOp said we could not delete [OUTPUTS]
Returns:
FALSE if failed

Definition at line 655 of file textops.cpp.

00656 {
00657     if (AllowOpRefused != NULL)
00658         *AllowOpRefused = FALSE;
00659 
00660     BOOL ok = TRUE;
00661     TextStory* pStory = TextStory::GetFocusStory();
00662     if (pStory != NULL)
00663     {
00664         BOOL DontDelete = FALSE;
00665         BOOL FoundDeletable = FALSE;
00666         
00667         // Call AllowOp on all the selected characters.
00668         VisibleTextNode* pChar = pStory->FindFirstVTN();
00669         ok = (pChar != NULL);
00670         ObjChangeParam ObjEdit(OBJCHANGE_STARTING,ObjChangeFlags(TRUE),NULL,this);
00671         while (ok && !DontDelete && (pChar != NULL))
00672         {
00673             if (pChar->IsSelected() && !pChar->IsACaret())
00674             {
00675                 FoundDeletable = TRUE;
00676                 DontDelete = !(pChar->AllowOp(&ObjEdit));
00677             }
00678             pChar = pChar->FindNextVTNInStory();
00679         }
00680 
00681         if (DontDelete && (AllowOpRefused != NULL))
00682             *AllowOpRefused = TRUE;
00683 
00684         if (FoundDeletable && !DontDelete)
00685         {
00686             // Get the story to delete the selection - it does all attribute localising and factoring out
00687             if (ok && !DontDelete)
00688                 ok = pStory->DeleteSelectedText(this);
00689 
00690             CaretNode* pCaret = pStory->GetCaret();
00691             if (ok && !DontDelete && (pCaret!=NULL))
00692                 pCaret->SetSelected(TRUE);
00693 
00694             // Attach new attributes to the caret
00695             if (ok && ReAttachAttributes)
00696                 ok = pStory->AttachCaretAttributes();
00697 
00698             // Mark the document as modified (as we don't have an opDescriptor)
00699             if (GetWorkingDoc() != NULL)
00700                 GetWorkingDoc()->SetModified(TRUE);
00701         }
00702     }
00703 
00704     return ok;
00705 }

void OpTextFormat::DoInsertChar WCHAR  ch,
OpTextFormat::InsertStatus  InsStatus
 

see DoInsertCharHelper()

Author:
Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/7/96
Parameters:
ch - The character to insert at the caret position [INPUTS] InsStatus - not yet implemented

Definition at line 718 of file textops.cpp.

00719 {
00720     if (!DoInsertCharHelper(ch))
00721         FailAndExecute();
00722     End();
00723 }

BOOL OpTextFormat::DoInsertCharHelper WCHAR  ch  ) 
 

Inserts a new character to the left of the caret deleting any selection in the story that exists.

Author:
Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/7/96
Parameters:
ch - The character to insert at the caret position [INPUTS]

Definition at line 736 of file textops.cpp.

00737 {
00738     // get ptrs to story and caret
00739     TextStory* pStory = TextStory::GetFocusStory();
00740     ERROR2IF(pStory==NULL,FALSE,"OpTextFormat::DoInsertCharHelper() - no focus story");
00741     CaretNode* pCaret = pStory->GetCaret();
00742     ERROR2IF(pCaret==NULL,FALSE,"OpTextFormat::DoInsertCharHelper() - Story has no caret");
00743 
00744     String_256 MasterText = pStory->GetStoryAsString();
00745 
00746     // start the text op (must be done before AllopOp() which may insert actions)
00747     BOOL ok = DoStartTextOp(pStory);
00748 
00749     // ask caret if it and it's parents allow char to be inserted (allows blend to remap)
00750     ObjChangeParam ObjInsert(OBJCHANGE_STARTING,ObjChangeFlags(),NULL,this);
00751     if (ok) ok = pCaret->AllowOp(&ObjInsert);
00752 
00753     // delete any sub-selection if it exists
00754     if (ok) ok = DoDeleteSelection(pStory,TRUE);
00755 
00756     // Create a new text character node, and insert into tree, and apply caret attrs to it
00757     TextChar* pNewChar = NULL;
00758     if (ok) { ALLOC_WITH_FAIL(pNewChar, (new TextChar()) , this); }
00759     if (ok) ok = (pNewChar!=NULL);
00760     if (ok) pNewChar->SetUnicodeValue(ch); 
00761     if (ok) ok = pNewChar->DoInsertNewNode(this,pCaret,PREV);
00762     if (ok) ok = pCaret->DoApplyAttrsTo(this,pNewChar);
00763 
00764     // Mark the document as modified (as we don't have an opDescriptor)
00765     if (ok && GetWorkingDoc()!=NULL)
00766         GetWorkingDoc()->SetModified(TRUE); 
00767 
00768     // update other textstories that are dependant on this one
00769     SliceHelper::OnTextStoryChanged(pStory, this, &ObjInsert, MasterText);
00770     
00771     // Update all the changed nodes
00772     ObjChangeParam ObjChange(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,this);
00773     if (ok) ok = UpdateChangedNodes(&ObjChange);
00774 
00775     if (ok) pCaret->ScrollToShow();
00776 
00777     return ok;
00778 }

BOOL OpTextFormat::DoReturn OpTextFormat::InsertStatus  InsStatus  ) 
 

Break the text line at the caret with a hard EOL For simplicity, a new line is created the word wrapper tidies up.

Author:
Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/6/96
Parameters:
InsStatus - insert or overwrite mode (not yet used) [INPUTS]
Returns:
FALSE if fails

Definition at line 895 of file textops.cpp.

00896 {
00897     ERROR2IF(InsStatus!=OpTextFormat::INSERT,FALSE,"OpTextFormat::DoReturn() - only supports insert mode");
00898     UndoableOperation* pUndoOp = this;
00899 
00900     // Get pointers to focus story, caret, caret line and caret line EOL
00901     TextStory* pStory = TextStory::GetFocusStory();
00902     ERROR2IF(pStory==NULL, FALSE, "OpTextFormat::DoReturn() - No focus story");
00903     CaretNode* pCaret = pStory->GetCaret();
00904     ERROR2IF(pCaret==NULL, FALSE, "OpTextFormat::DoReturn() - Focus story had no caret");
00905     TextLine* pCaretLine = pCaret->FindParentLine();
00906     ERROR2IF(pCaretLine==NULL,FALSE,"OpTextFormat::DoReturn() - caret has no parent");
00907 
00908     String_256 MasterText = pStory->GetStoryAsString();
00909 
00910     // start the text op (must be done before AllopOp() which may insert actions)
00911     BOOL ok = DoStartTextOp(pStory);
00912 
00913     // see if the op is allowed
00914     ObjChangeParam ObjParam(OBJCHANGE_STARTING, ObjChangeFlags(), NULL, pUndoOp);
00915     if (pCaret->AllowOp(&ObjParam)==FALSE)
00916         return TRUE;
00917 
00918     // delete any sub-selection if it exists, then get ptr to last VTN on caret line
00919     if (ok) ok = DoDeleteSelection(pStory, TRUE);
00920 
00921     // After deleting the selection, the caret line may have been deleted
00922     // so we need to get it again in it's new location
00923     pCaret = pStory->GetCaret();
00924     ERROR2IF(pCaret==NULL, FALSE, "OpTextFormat::DoReturn() - Focus story had no caret");
00925     pCaretLine = pCaret->FindParentLine();
00926     ERROR2IF(pCaretLine==NULL,FALSE,"OpTextFormat::DoReturn() - caret has no parent");
00927 
00928     VisibleTextNode* pLastCaretLineVTN = pCaretLine->FindLastVTN();
00929     ERROR2IF(pLastCaretLineVTN==NULL,FALSE,"OpTextFormat::DoReturn() - caret line has no VTN");
00930 
00931     // insert a new EOL on src line before caret with caret's attributes
00932     EOLNode* pNewEOL = NULL;
00933     if (ok) pNewEOL = new EOLNode;
00934     if (ok) ok = (pNewEOL!=NULL);
00935     if (ok) ok = pNewEOL->DoInsertNewNode(pUndoOp,pCaret,PREV);
00936     if (ok) ok = pCaret->DoApplyAttrsTo(pUndoOp,pNewEOL);
00937 
00938     // insert a new line after caret line
00939     TextLine* pNewLine = NULL;
00940     if (ok) pNewLine = new TextLine;
00941     if (ok) ok = (pNewLine!=NULL);
00942     if (ok) ok = pNewLine->DoInsertNewNode(pUndoOp,pCaretLine,NEXT);
00943 
00944     // and move all nodes from the caret upto end of line to the new line
00945     if (ok) ok = pCaretLine->DoLocaliseCommonAttributes(pUndoOp,FALSE,FALSE,NULL);
00946     if (ok) ok = pCaret->DoMoveNodes(pUndoOp,pLastCaretLineVTN,pNewLine,FIRSTCHILD);
00947     if (ok) ok = pCaretLine->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,NULL);
00948     if (ok) ok = pNewLine->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,NULL);
00949 
00950     // update other textstories that are dependant on this one
00951     SliceHelper::OnTextStoryChanged(pStory, this, &ObjParam, MasterText);
00952 
00953     // Update all the changed nodes
00954     ObjChangeParam ObjChange(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,pUndoOp);
00955     if (ok) ok = UpdateChangedNodes(&ObjChange);
00956 
00957     if (ok) pCaret->ScrollToShow();
00958 
00959     if (!ok) FailAndExecute();
00960     End();
00961 
00962     return ok;
00963 }

void OpTextFormat::DoSwapCase  ) 
 

The character to the right of the character has its case swapped, and the caret is moved right one character.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
05/04/95

Definition at line 1029 of file textops.cpp.

01030 {
01031     // Get pointers
01032     TextStory* pStory = TextStory::GetFocusStory();
01033     ERROR3IF(pStory == NULL, "You attempted to swap a character without a focus story");
01034     CaretNode* pCaret = NULL;
01035     if (pStory != NULL)
01036         pCaret = pStory->GetCaret();
01037     ERROR3IF(pCaret == NULL, "The TextStory didn't have a caret!");
01038     if (pCaret == NULL)
01039         return;
01040 
01041     // If there is a sub-selection then don't do anything
01042     if (pStory->GetSelectionEnd() != NULL)
01043     {
01044         Beep();
01045         return;
01046     }
01047 
01048     // Get a pointer to the character to the right of the caret
01049     VisibleTextNode* pSwapChar = NULL;
01050     pSwapChar = pCaret->FindNextVTNInStory();
01051 
01052     BOOL ok = TRUE;
01053 
01054     if (pSwapChar != NULL)
01055     {
01056         ok = DoStartTextOp(pStory);
01057 
01058         // Tell parent nodes about the op so the story reformats
01059         if (ok)
01060         {
01061             ObjChangeParam ObjInsert(OBJCHANGE_STARTING,ObjChangeFlags(),NULL,this);
01062             if (pSwapChar->AllowOp(&ObjInsert)==FALSE)
01063                 pSwapChar=NULL;
01064         }
01065 
01066         // Swap the case of the found character
01067         if ((pSwapChar != NULL) && ok)
01068         {
01069             if (IS_A(pSwapChar,TextChar))
01070             {
01071                 TextChar* pSwapTextChar = (TextChar*)pSwapChar;
01072                 WCHAR CharValue = pSwapTextChar->GetUnicodeValue();
01073                 CharCase Result = TextManager::ProcessCharCase(&CharValue, Swap);
01074 
01075                 ok = (Result != Failed);
01076 
01077                 if (ok && (Result != UnknownType))
01078                 {
01079                     // Store the characters old UniCode value
01080                     ok = StoreCharCodeAction::DoStoreCharacterCode( this, &UndoActions, pSwapTextChar);
01081 
01082                     // Set it to the new value
01083                     if (ok)
01084                         pSwapTextChar->SetUnicodeValue(CharValue);
01085                 }
01086             }
01087 
01088             // advance the caret to the next character
01089             if (ok)
01090             {
01091                 pStory->MoveCaretRightAChar();
01092                 pStory->GetCaret()->HasMoved();
01093                 pStory->GetCaret()->ScrollToShow();
01094             }
01095         }
01096     }
01097 
01098     // Update all the changed nodes, i.e tell all the parents of the children that have been effected
01099     if (ok)
01100     {
01101         ObjChangeParam ObjChange(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,this);
01102         ok = UpdateChangedNodes(&ObjChange);
01103     }
01104 
01105     if (!ok)
01106     {
01107         InformError();
01108         FailAndExecute();
01109     }
01110 
01111     End();
01112 }

BOOL OpTextFormat::DoTab  ) 
 

Definition at line 965 of file textops.cpp.

00966 {
00967     UndoableOperation* pUndoOp = this;
00968 
00969     // Get pointers to focus story, caret, caret line and caret line EOL
00970     TextStory* pStory = TextStory::GetFocusStory();
00971     ERROR2IF(pStory==NULL, FALSE, "OpTextFormat::DoTab() - No focus story");
00972     CaretNode* pCaret = pStory->GetCaret();
00973     ERROR2IF(pCaret==NULL, FALSE, "OpTextFormat::DoTab() - Focus story had no caret");
00974     TextLine* pCaretLine = pCaret->FindParentLine();
00975     ERROR2IF(pCaretLine==NULL,FALSE,"OpTextFormat::DoTab() - caret has no parent");
00976 
00977     // start the text op (must be done before AllopOp() which may insert actions)
00978     BOOL ok = DoStartTextOp(pStory);
00979 
00980     // see if the op is allowed
00981     ObjChangeParam ObjParam(OBJCHANGE_STARTING, ObjChangeFlags(), NULL, pUndoOp);
00982     if (pCaret->AllowOp(&ObjParam)==FALSE)
00983         return TRUE;
00984 
00985     // delete any sub-selection if it exists, then get ptr to last VTN on caret line
00986     if (ok) ok = DoDeleteSelection(pStory, TRUE);
00987 
00988     // After deleting the selection, the caret line may have been deleted
00989     // so we need to get it again in it's new location
00990     pCaret = pStory->GetCaret();
00991     ERROR2IF(pCaret==NULL, FALSE, "OpTextFormat::DoTab() - Focus story had no caret");
00992     pCaretLine = pCaret->FindParentLine();
00993     ERROR2IF(pCaretLine==NULL,FALSE,"OpTextFormat::DoTab() - caret has no parent");
00994 
00995     VisibleTextNode* pLastCaretLineVTN = pCaretLine->FindLastVTN();
00996     ERROR2IF(pLastCaretLineVTN==NULL,FALSE,"OpTextFormat::DoTab() - caret line has no VTN");
00997 
00998     // insert a new Tab node before caret with caret's attributes
00999     HorizontalTab* pTab = NULL;
01000     if (ok) pTab = new HorizontalTab;
01001     if (ok) ok = (pTab != NULL);
01002     if (ok) ok = pTab->DoInsertNewNode(pUndoOp,pCaret,PREV);
01003     if (ok) ok = pCaret->DoApplyAttrsTo(pUndoOp,pTab);
01004 
01005     // update other textstories that are dependant on this one
01006     //##SliceHelper::OnTextStoryChanged(pStory, this, &ObjParam, MasterText);
01007 
01008     // Update all the changed nodes
01009     ObjChangeParam ObjChange(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,pUndoOp);
01010     if (ok) ok = UpdateChangedNodes(&ObjChange);
01011 
01012     if (ok) pCaret->ScrollToShow();
01013 
01014     if (!ok) FailAndExecute();
01015     End();
01016 
01017     return ok;
01018 }

void OpTextFormat::GetOpName String_256 OpName  )  [virtual]
 

Returns the name of the operation.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/7/95
Parameters:
OpName,: The name of the operation (undo / redo string) [OUTPUTS]

Reimplemented from Operation.

Definition at line 1124 of file textops.cpp.

01125 {
01126     *OpName = String_256(_R(IDS_TYPING));
01127 }


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:59:02 2007 for Camelot by  doxygen 1.4.4