OpTextPaste Class Reference

An undoable operation to paste the contents of the clipboard into a text story. More...

#include <textops.h>

Inheritance diagram for OpTextPaste:

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

Public Member Functions

 OpTextPaste ()
 Constructor for paste text operation.
void Do (OpDescriptor *)
 see OpTextPaste::DoPasteTextHelper()

Static Public Member Functions

static BOOL Init ()
 Registers the specilised text paste operation.
static OpState GetState (String_256 *, OpDescriptor *)
 Controls whether the text paste operation is available or not. Currently, is always available.

Protected Member Functions

BOOL DoPasteTextHelper ()
 If there is a single TextStory on clipboard and a focus story in the doc, the story on the clipboard is pasted at caret in focus story, else the normal paste method is used.
BOOL DoPasteText (TextStory *pPasteStory, TextStory *pFocusStory, Range *pPasteRange)
 Paste a story into the Focus story at the caret.

Detailed Description

An undoable operation to paste the contents of the clipboard into a text story.

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

Definition at line 337 of file textops.h.


Constructor & Destructor Documentation

OpTextPaste::OpTextPaste  ) 
 

Constructor for paste text operation.

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

Definition at line 4541 of file textops.cpp.

04542 {
04543     // Dummy constructor
04544 }


Member Function Documentation

void OpTextPaste::Do OpDescriptor  )  [virtual]
 

see OpTextPaste::DoPasteTextHelper()

Author:
Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/7/96
Parameters:
pOpDesc - unused [INPUTS]

Reimplemented from OpPaste.

Definition at line 4594 of file textops.cpp.

04595 {
04596     BeginSlowJob();
04597     if (!DoPasteTextHelper())
04598         FailAndExecute();
04599     End();
04600 }

BOOL OpTextPaste::DoPasteText TextStory pPasteStory,
TextStory pFocusStory,
Range pPasteRange
[protected]
 

Paste a story into the Focus story at the caret.

Author:
Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/7/96
Parameters:
pPasteStory - story to paste [INPUTS] pFocusStory - story to paste into
pPasteRange - Range of nodes pasted into focus story [OUTPUTS]
Returns:
FALSE if fails

Definition at line 4710 of file textops.cpp.

04711 {
04712     BaseDocument* pDoc = pFocusStory->FindOwnerDoc();
04713     ERROR2IF(pPasteStory==NULL, FALSE, "Null paste story passed to PasteText()");
04714     ERROR2IF(pFocusStory==NULL, FALSE, "Null focus story passed to PasteText()");
04715     UndoableOperation* pUndoOp = this;
04716 
04717     // get some useful pointers ...
04718     CaretNode* pCaret = pFocusStory->GetCaret();
04719     ERROR2IF(pCaret==NULL,FALSE,"OpTextPaste::DoPasteText() - focus story has no caret!");
04720     TextLine* pCaretLine = pCaret->FindParentLine();
04721     ERROR2IF(pCaretLine==NULL,FALSE,"OpTextPaste::DoPasteText() - caret in dest story has no parent TextLine");
04722     TextLine* pFirstSrcLine = pPasteStory->FindFirstLine();
04723     ERROR2IF(pFirstSrcLine==NULL,FALSE,"OpTextPaste::DoPasteText() - story to paste has no lines");
04724     VisibleTextNode* pCaretLineLastVTN = pCaretLine->FindLastVTN();
04725     ERROR2IF(pCaretLineLastVTN==NULL,FALSE,"OpTextPaste::DoPasteText() - Caret line has no VTN!");
04726     
04727     // get the set of non line level attrs on both stories
04728     AttrTypeSet NonLineLevelAttrs;
04729     BOOL    ok = pPasteStory->AddNonLineLevelDescendantAttrsToSet(&NonLineLevelAttrs);
04730     if (ok) ok = pFocusStory->AddNonLineLevelDescendantAttrsToSet(&NonLineLevelAttrs);
04731 
04732     // ptrs to create a range of node pasted
04733     VisibleTextNode* pFirstPastedVTN = NULL;
04734     VisibleTextNode* pLastPastedVTN  = NULL;
04735 
04736     // copy all VTN on the first line to be pasted before the caret, noting the first copied
04737     // - Localise/FactorOut to/from chars global as attrs on whole story may change
04738     // - Localise/FactorOut to/from chars excludes LineLevelAttrs ensuring LLA merged correctly
04739     // - Localise/FactorOut to/from chars on clipboard not done undoably
04740     if (ok) ok = pCaretLine->DoLocaliseCommonAttributes(pUndoOp,FALSE,TRUE,&NonLineLevelAttrs);
04741     if (ok) ok = pFirstSrcLine->DoLocaliseCommonAttributes(NULL,FALSE,TRUE,&NonLineLevelAttrs);
04742     VisibleTextNode* pSrcVTN = pFirstSrcLine->FindFirstVTN();
04743     while (ok && pSrcVTN!=NULL)
04744     {
04745         if (!pSrcVTN->IsACaret())   // don't paste caret
04746         {
04747             VisibleTextNode* pVTNCopy = NULL;
04748             CALL_WITH_FAIL(pSrcVTN->NodeCopy((Node**)&pVTNCopy), pUndoOp, ok);
04749             if (ok) pVTNCopy->ClearSelection(TRUE);     // ensure new node not selected
04750             if (ok) ok = pVTNCopy->DoInsertNewNode(pUndoOp,pCaret,PREV);
04751 
04752             if (ok)
04753             {
04754                 // Ensure component references are up to date /before/ we start to optimise
04755                 // attributes!
04756                 Node* pNode = pVTNCopy->FindFirstDepthFirst();
04757                 while (ok && pNode && pNode!=pVTNCopy)
04758                 {
04759                     if (pNode->IsRenderable())
04760                         ok = ((NodeRenderable*)pNode)->CopyComponentData(InternalClipboard::Instance(), pDoc);
04761 
04762                     pNode = pNode->FindNextDepthFirst(pVTNCopy);
04763                 }
04764                 if (!ok)
04765                     pDoc->AbortComponentCopy(); // Cancel all data which has been copied
04766             }
04767 
04768 #ifdef PHIL_ATTRS_FIX
04769             // Apply any missing attributes to this node (leaving original copies alone)
04770             if (ok) ok = pCaret->DoApplyAttrsTo(pUndoOp, pVTNCopy, FALSE);
04771 #endif
04772 
04773             if (pFirstPastedVTN==NULL)
04774                 pFirstPastedVTN = pVTNCopy;
04775         }
04776         pSrcVTN = pSrcVTN->FindNextVTNInLine();
04777     }
04778     if (ok) ok = pFirstSrcLine->DoFactorOutCommonChildAttributes(NULL,TRUE,&NonLineLevelAttrs);
04779     if (ok) ok = pCaretLine->DoFactorOutCommonChildAttributes(pUndoOp,TRUE,&NonLineLevelAttrs);
04780 
04781     // then move all nodes from caret to last VTN on line to a new line after the caret line
04782     // - Localise/FactorOut to/from chars local as attrs on story unchanged (only moving nodes)
04783     // - Localise/FactorOut to/from chars includes LineLevelAttrs as new line needs them
04784     TextLine* pNewLine = NULL;
04785     if (ok) pNewLine = new TextLine;
04786     if (ok) ok = (pNewLine!=NULL);
04787     if (ok) ok = pNewLine->DoInsertNewNode(pUndoOp,pCaretLine,NEXT);
04788     if (ok) ok = pCaretLine->DoLocaliseCommonAttributes(pUndoOp,FALSE,FALSE,NULL);
04789     if (ok) ok = pCaret->DoMoveNodes(pUndoOp,pCaretLineLastVTN,pNewLine,FIRSTCHILD);
04790     if (ok) ok = pCaretLine->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,NULL);
04791     if (ok) ok = pNewLine->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,NULL);
04792     pCaretLine = pNewLine;
04793 
04794     // insert all remaining lines to be pasted before the (new) caret line
04795     // - Localise/FactorOut to/from lines global as attrs on whole story may change (inc LLA)
04796     // - Localise/FactorOut to/from lines on clipboard not done undoably
04797     TextLine* pSrcLine = pFirstSrcLine->FindNextLine();
04798     if (pSrcLine!=NULL)
04799     {
04800         if (ok) ok = pFocusStory->DoLocaliseCommonAttributes(pUndoOp,FALSE,TRUE,NULL);
04801         if (ok) ok = pPasteStory->DoLocaliseCommonAttributes(NULL,FALSE,TRUE,NULL);
04802         while (ok && pSrcLine!=NULL)
04803         {
04804             TextLine* pLineCopy = NULL;
04805             CALL_WITH_FAIL(pSrcLine->NodeCopy((Node**)&pLineCopy), pUndoOp, ok);
04806             pLineCopy->ClearSelection(TRUE);        // ensure new node not selected
04807 
04808 #ifndef PHIL_ATTRS_FIX
04809             CaretNode* pCaret = ((TextLine*)pLineCopy)->FindCaret();
04810             if (pCaret!=NULL)   // remove any caret pasted
04811             {
04812                 pCaret->CascadeDelete();
04813                 delete pCaret;
04814             }
04815             if (ok) ok = pLineCopy->DoInsertNewNode(pUndoOp,pCaretLine,PREV);
04816 #else
04817             CaretNode* pCopyCaret = ((TextLine*)pLineCopy)->FindCaret();
04818             if (pCopyCaret!=NULL)   // remove any caret pasted
04819             {
04820                 pCopyCaret->CascadeDelete();
04821                 delete pCopyCaret;
04822                 pCopyCaret = NULL;
04823             }
04824             if (ok) ok = pLineCopy->DoInsertNewNode(pUndoOp,pCaretLine,PREV);
04825 
04826             // Apply any missing attributes to the nodes in this line (leaving original copies alone)
04827             VisibleTextNode* pLineNode = pLineCopy->FindFirstVTN();
04828             if (ok) ok = pLineCopy->DoLocaliseCommonAttributes(pUndoOp,FALSE,FALSE,NULL);
04829             if (ok) ok = pCaretLine->DoLocaliseCommonAttributes(pUndoOp,FALSE,FALSE,NULL);
04830             while (ok && pLineNode)
04831             {
04832                 if (ok) ok = pCaret->DoApplyAttrsTo(pUndoOp, pLineNode, FALSE);
04833                 pLineNode = pLineNode->FindNextVTNInLine();
04834             }
04835             if (ok) ok = pCaretLine->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,NULL);
04836             if (ok) ok = pLineCopy->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,NULL);
04837 #endif
04838             pSrcLine = pSrcLine->FindNextLine();
04839         }
04840         if (ok) ok = pFocusStory->DoFactorOutCommonChildAttributes(pUndoOp,TRUE,NULL);
04841         if (ok) ok = pPasteStory->DoFactorOutCommonChildAttributes(NULL,TRUE,NULL);
04842     }
04843 
04844     // if last EOL pasted virtual, delete it and append (new) caret line to prev line
04845     // - Localise/FactorOut to/from chars local as attrs on story unchanged (only moving nodes)
04846     // - Localise/FactorOut to/from chars excludes LineLevelAttrs ensuring LLA merged correctly
04847     if (ok)
04848     {
04849         TextLine* pLastPastedLine = pCaretLine->FindPrevLine();
04850         ERROR2IF(pLastPastedLine==NULL,FALSE,"OpTextPaste::DoPasteText() - could not find last line pasted!");
04851         EOLNode* pLastPastedEOL = pLastPastedLine->FindEOLNode();
04852         ERROR2IF(pLastPastedEOL==NULL,FALSE,"OpTextPaste::DoPasteText() - story to paste has no final EOL");
04853         pLastPastedVTN = pLastPastedEOL;
04854         if (pLastPastedEOL->IsVirtual())
04855         {
04856             pLastPastedVTN = pLastPastedVTN->FindPrevVTNInStory();
04857             ERROR2IF(pLastPastedVTN==NULL,FALSE,"OpTextPaste::DoPasteText() - no chars on pasted line which ended in a virtual EOL");
04858             if (ok) ok = pLastPastedLine->DoLocaliseCommonAttributes(pUndoOp,FALSE,FALSE,&NonLineLevelAttrs);
04859             if (ok) ok =      pCaretLine->DoLocaliseCommonAttributes(pUndoOp,FALSE,FALSE,&NonLineLevelAttrs);
04860             if (ok) ok = pLastPastedEOL->DoHideNode(pUndoOp);
04861             if (ok) ok = pCaret->DoMoveNodes(pUndoOp,pCaretLineLastVTN,pLastPastedLine,LASTCHILD);
04862             if (ok) ok = pCaretLine->DoHideNode(pUndoOp);   // delete the empty line
04863             if (ok) ok = pLastPastedLine->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,&NonLineLevelAttrs);
04864         }
04865     }
04866 
04867     // create a range of nodes which have been pasted
04868     if (ok)
04869     {
04870         Range r(pFirstPastedVTN, pLastPastedVTN, RangeControl(TRUE,TRUE,FALSE));
04871         *pPasteRange = r;
04872     }
04873     return ok;
04874 }

BOOL OpTextPaste::DoPasteTextHelper  )  [protected]
 

If there is a single TextStory on clipboard and a focus story in the doc, the story on the clipboard is pasted at caret in focus story, else the normal paste method is used.

Author:
Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/7/96
Returns:
FALSE if fails

Definition at line 4614 of file textops.cpp.

04615 {
04616     // get a ptr to the clipbaord and prepare it for a paste
04617     BOOL ExternalData = FALSE;
04618     if (!InternalClipboard::PrepareForPaste(&ExternalData)) return FALSE;
04619 
04620     // determine how many objects and text stories on the clipboard, keeping ptr to 1st text story
04621     INT32 NumObjects = 0;
04622     INT32 NumStories = 0;
04623     TextStory* pFirstStory = NULL;
04624     Node* pNode = InternalClipboard::GetInsertionLayer()->FindFirstChild();
04625     while (pNode!=NULL)
04626     {
04627         NumObjects += 1;
04628         if (IS_A(pNode,TextStory))
04629         {
04630             NumStories += 1;
04631             if (pFirstStory==NULL)
04632                 pFirstStory = (TextStory*)pNode;
04633         }
04634         pNode = pNode->FindNext();
04635     }
04636 
04637     // if no focus story or not a single text story on the clipboard, do a normal paste op
04638     TextStory* pFocusStory = TextStory::GetFocusStory();
04639     if (NumStories!=1 || NumObjects!=1 || pFocusStory==NULL)
04640         return DoPasteStandard(FALSE,ExternalData);
04641 
04642     if (!DoStartSelOp(TRUE,TRUE))  
04643         return FALSE;
04644 
04645     // create a range of selected nodes in the focus story and call AllowOp() on them
04646     VisibleTextNode* pFirstVTN = pFocusStory->FindFirstVTN();
04647     VisibleTextNode* pLastVTN  = pFocusStory->FindLastVTN();
04648     ERROR2IF(pFirstVTN==NULL || pLastVTN==NULL, FALSE,"OpTextPaste::PasteTextHelper() - Focus story has no VTN");
04649     Range pFocusStorySelection(pFirstVTN,pLastVTN,RangeControl(TRUE));
04650     ObjChangeParam ObjChange(OBJCHANGE_STARTING,ObjChangeFlags(),NULL,this);
04651     if (!pFocusStorySelection.AllowOp(&ObjChange))
04652         //ERROR2(FALSE,"OpTextPaste::PasteTextHelper() - op should have been greyed!");
04653         return DoPasteStandard(FALSE,ExternalData); // doesn't allow me to paste in - but we need to do something! so we do a general paste to app.
04654 
04655     String_256 MasterText = pFocusStory->GetStoryAsString();
04656 
04657     // delete any selected text
04658     if (!pFocusStory->DeleteSelectedText(this))
04659         return FALSE;
04660 
04661     // After op ends need to inform all DocComponents in dest doc of the outcome
04662     BaseDocument* pDoc = pFocusStory->FindOwnerDoc();
04663     ERROR2IF(pDoc==NULL,FALSE,"OpTextPaste::PasteTextHelper() - Focus story has no parent document!");
04664 
04665     // Ensure that EndComponentCopy and/or AbortComponentCopy will be called when the Op ends
04666     InformDocComponentsOfOperationsOutcome(pDoc); 
04667 
04668     // paste story into focus story at the caret, ensuring dest doc component data up to date
04669     BOOL ok = TRUE;
04670     CALL_WITH_FAIL((pDoc->StartComponentCopy()),this, ok)
04671     if (!ok) return FALSE;
04672     Range PasteRange;
04673     if (!DoPasteText(pFirstStory,pFocusStory,&PasteRange))
04674         return FALSE;
04675     CALL_WITH_FAIL((PasteRange.CopyComponentDataToDoc(InternalClipboard::Instance(), pDoc)), this, ok);
04676     if (!ok) return FALSE;
04677     
04678     // inform the clipboard the paste has finished
04679     if (!InternalClipboard::PasteCompleted()) return FALSE;
04680 
04681     CaretNode* pCaret = pFocusStory->GetCaret();
04682     if (!DoSelectNode(pCaret,NULL)) return FALSE;
04683 
04684     // update other textstories that are dependant on this one
04685     SliceHelper::OnTextStoryChanged(pFocusStory, this, &ObjChange, MasterText);
04686         
04687     // Update all the changed nodes, i.e. tell all the parents of the children that have been effected
04688     ObjChange.Define(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,this);
04689     if (!UpdateChangedNodes(&ObjChange))
04690         return FALSE;
04691 
04692     // Make sure the caret is still in view
04693     pCaret->ScrollToShow();
04694     return TRUE;
04695 }

OpState OpTextPaste::GetState String_256 ,
OpDescriptor
[static]
 

Controls whether the text paste operation is available or not. Currently, is always available.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/01/95
Returns:
Returns a default OpState.

Reimplemented from OpPaste.

Definition at line 4578 of file textops.cpp.

04579 {
04580     OpState os;
04581     return os;
04582 }

BOOL OpTextPaste::Init void   )  [static]
 

Registers the specilised text paste operation.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/01/95
Returns:
TRUE if the op is correctly registered.

Reimplemented from OpPaste.

Definition at line 4556 of file textops.cpp.

04557 {
04558     return RegisterOpDescriptor(0, 
04559                                 _R(IDS_TEXTPASTEOP),
04560                                 CC_RUNTIME_CLASS(OpTextPaste),
04561                                 OPTOKEN_TEXTPASTE, 
04562                                 OpTextPaste::GetState,
04563                                 0,
04564                                 _R(IDBBL_TEXTPASTEOP));
04565 }


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