#include <textops.h>
Inheritance diagram for OpTextPaste:
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. |
Definition at line 337 of file textops.h.
|
Constructor for paste text operation.
Definition at line 4541 of file textops.cpp.
|
|
see OpTextPaste::DoPasteTextHelper()
Reimplemented from OpPaste. Definition at line 4594 of file textops.cpp. 04595 { 04596 BeginSlowJob(); 04597 if (!DoPasteTextHelper()) 04598 FailAndExecute(); 04599 End(); 04600 }
|
|
Paste a story into the Focus story at the caret.
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 }
|
|
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.
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 }
|
|
Controls whether the text paste operation is available or not. Currently, is always available.
Reimplemented from OpPaste. Definition at line 4578 of file textops.cpp. 04579 { 04580 OpState os; 04581 return os; 04582 }
|
|
Registers the specilised text paste operation.
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 }
|