#include <attrappl.h>
Inheritance diagram for OpReplaceAttributes:
Public Member Functions | |
OpReplaceAttributes () | |
OpReplaceAttributes constructor. | |
void | DoWithParam (OpDescriptor *OpDesc, OpParam *pOpParam) |
Performs the OpReplaceAttributes operation. This function applies the NodeAttribute to all selected objects. | |
virtual void | GetOpName (String_256 *OpName) |
The GetOpName fn is overridden so that we return back a description appropriate to the type of attribute that the operation applies. | |
NodeAttribute * | GetAttribute () |
Static Public Member Functions | |
static BOOL | Init () |
OpReplaceAttributes initialiser method. | |
static OpState | GetState (String_256 *, OpDescriptor *) |
For finding OpReplaceAttributes state. | |
Private Member Functions | |
BOOL | DoReplace (NodeAttribute *NewAttr, NodeAttribute *OldAttr) |
Private Attributes | |
UINT32 | UndoAttribStrID |
NodeAttribute * | m_pAttr |
Definition at line 382 of file attrappl.h.
|
OpReplaceAttributes constructor.
Definition at line 3842 of file attrappl.cpp. 03842 : SelOperation() 03843 { 03844 m_pAttr = NULL; 03845 }
|
|
Definition at line 3996 of file attrappl.cpp. 03997 { 03998 Node* CurrentNode = OldAttr->FindParent(); 03999 ERROR3IF(CurrentNode == NULL, "Can't find parent node in Replace Attr"); 04000 04001 BOOL bOldWasEffect = OldAttr->IsEffectAttribute(); 04002 04003 if (!DoInvalidateNodeRegion((NodeRenderableBounded*)CurrentNode, FALSE, TRUE, FALSE, FALSE)) // Do not recache 04004 return FALSE; 04005 04006 // >>>> Temporary BODGE to aid select-inside... 04007 // >>>> ALWAYS clear any attributes of the same type from the subtree (even if the 04008 // >>>> attribute just applied replaced an existing one) so that dubious 04009 // >>>> attribute states (due to this routine not dealing with Select-inside 04010 // >>>> properly yet) can be cleared. 04011 // >>>> NOTE! the current att (n) is passed in to DoRemoveAttTypeFromSubtree so 04012 // >>>> that it won't be deleted along with atts of the same type - that would be 04013 // >>>> (has been) disastrous! 04014 if (CurrentNode->IsCompoundClass() && !((NodeCompound*)CurrentNode)->IsValidEffectAttr(NewAttr)) 04015 // if ((!AttributeExists) && (CurrentNode->IsCompound())) 04016 { 04017 // Remove all instances of attributes of the same type from the subtree. 04018 // This is not neccessary if the AttributeExists flag is TRUE because 04019 // we know in this situation that the subtree cannot contain any other 04020 // instances of the attribute !. 04021 if (!DoRemoveAttrTypeFromSubtree(CurrentNode, NewAttr->GetAttributeType(), OldAttr)) 04022 { 04023 return FALSE; 04024 } 04025 } 04026 04027 NodeAttribute* AttribClone = NULL; 04028 04029 // Have we have got an Attribute to do something with ? 04030 if (OldAttr != NULL) 04031 { 04032 // We're gunna just replace the attribute with the new one. 04033 04034 // First make a copy of the new attribute. 04035 ALLOC_WITH_FAIL(AttribClone ,((NodeAttribute*)NewAttr->SimpleCopy()), this) 04036 04037 if (AttribClone == NULL) 04038 { 04039 // We have failed to create the clone 04040 return FALSE; 04041 } 04042 04043 // Complication !! 04044 // If we are replacing a Fill Attribute and the attribute we are replacing 04045 // is already filled, then we need to extract the colour of the existing 04046 // fill and use them for the new fill. 04047 if ( OldAttr->IsAFillAttr() ) 04048 { 04049 AttrFillGeometry* NodeReplaced = (AttrFillGeometry*)OldAttr; 04050 04051 // Are these both Graduated Fills ? 04052 if ( (NodeReplaced->GetAttributeType() == CC_RUNTIME_CLASS(AttrFillGeometry)) || 04053 (NodeReplaced->GetAttributeType() == CC_RUNTIME_CLASS(AttrTranspFillGeometry)) ) 04054 { 04055 // Copy the old colours into the new Fill 04056 04057 // NOTE: 04058 // This should really be done with a virtual function 04059 04060 if (NodeReplaced->IsAFlatFill()) 04061 { 04062 ((AttrFillGeometry*)AttribClone)->SetEndColour(NodeReplaced->GetStartColour()); 04063 ((AttrFillGeometry*)AttribClone)->SetEndTransp(NodeReplaced->GetStartTransp()); 04064 } 04065 else 04066 { 04067 ((AttrFillGeometry*)AttribClone)->SetStartColour(NodeReplaced->GetStartColour()); 04068 ((AttrFillGeometry*)AttribClone)->SetEndColour(NodeReplaced->GetEndColour()); 04069 ((AttrFillGeometry*)AttribClone)->SetStartTransp(NodeReplaced->GetStartTransp()); 04070 ((AttrFillGeometry*)AttribClone)->SetEndTransp(NodeReplaced->GetEndTransp()); 04071 } 04072 04073 ((AttrFillGeometry*)AttribClone)->SetTranspType(NodeReplaced->GetTranspType()); 04074 ((AttrFillGeometry*)AttribClone)->SetTesselation(NodeReplaced->GetTesselation()); 04075 ((AttrFillGeometry*)AttribClone)->SetSeed(NodeReplaced->GetSeed()); 04076 ((AttrFillGeometry*)AttribClone)->SetGraininess(NodeReplaced->GetGraininess()); 04077 ((AttrFillGeometry*)AttribClone)->SetGravity(NodeReplaced->GetGravity()); 04078 ((AttrFillGeometry*)AttribClone)->SetSquash(NodeReplaced->GetSquash()); 04079 ((AttrFillGeometry*)AttribClone)->SetTileable(NodeReplaced->GetTileable()); 04080 ((AttrFillGeometry*)AttribClone)->AttachBitmap(NodeReplaced->GetBitmap()); 04081 ((AttrFillGeometry*)AttribClone)->RecalcFractal(); 04082 04083 } 04084 04085 if ( NewAttr->IsATranspFill() && NewAttr->IsAFlatFill()) 04086 { 04087 ((AttrFillGeometry*)OldAttr)->RenderFillBlobs(); 04088 } 04089 } 04090 04091 // Now we have done with the old attribute, so lets hide it, so 04092 // the changes can be undone 04093 if(!DoHideNode(OldAttr, 04094 TRUE // Include the subtree size 04095 )) 04096 { 04097 return FALSE; 04098 } 04099 } 04100 04101 // Finally !! We can add the new attribute node into the tree. 04102 if (bOldWasEffect) 04103 AttribClone->AttachNode(CurrentNode, LASTCHILD); 04104 else 04105 AttribClone->AttachNode(CurrentNode, FIRSTCHILD); 04106 04107 AttributeManager::pLastNodeAppliedTo = (NodeRenderableInk*)CurrentNode; 04108 04109 // And now it's in the tree, we need to make sure that any fill control 04110 // points are valid. 04111 if (AttribClone->IsAFillAttr()) 04112 { 04113 ((AttrFillGeometry*)AttribClone)->AttributeChanged(); 04114 } 04115 04116 HideNodeAction* UndoHideNodeAction; 04117 04118 // Create an action to hide the attribute when we undo 04119 if ( HideNodeAction::Init(this, 04120 &UndoActions, 04121 AttribClone, 04122 TRUE, // When the attribute gets hidden we 04123 // must include its size 04124 (Action**)(&UndoHideNodeAction)) 04125 == AC_FAIL) 04126 { 04127 AttribClone->CascadeDelete(); 04128 delete (AttribClone); 04129 return FALSE; 04130 } 04131 04132 ReleaseCachedForAttrApply((NodeRenderableBounded*)CurrentNode, bOldWasEffect); 04133 04134 if (!DoInvalidateNodeRegion((NodeRenderableBounded*)CurrentNode, FALSE, TRUE, FALSE, FALSE)) // Do not recache 04135 return FALSE; 04136 04137 return TRUE; 04138 }
|
|
Performs the OpReplaceAttributes operation. This function applies the NodeAttribute to all selected objects.
Reimplemented from Operation. Definition at line 3865 of file attrappl.cpp. 03866 { 03867 ERROR3IF(pOpParam == NULL, "The OpReplaceAttributes operation requires an attribute parameter"); 03868 ERROR3IF(!IS_A(pOpParam, ReplaceAttributesParam), "Wrong kind of param in OpReplaceAttributes"); 03869 03870 AttributeManager::pLastNodeAppliedTo = NULL; 03871 03872 // Objects used to mark changed nodes, so that parents will update after attr replacement 03873 ObjChangeFlags cFlags; 03874 cFlags.Attribute = TRUE; 03875 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this); 03876 BOOL ok; 03877 03878 // Obtain a pointer to the attribute which we will need to apply to all selected nodes 03879 NodeAttribute* NewAttr = ((ReplaceAttributesParam*)pOpParam)->m_pAttr; 03880 03881 m_pAttr = NewAttr; 03882 03883 List* OldAttrs = ((ReplaceAttributesParam*)pOpParam)->m_pOldAttrs; 03884 03885 ListItem* pAttr; 03886 03887 // Get a description of the attribute being applied so that we can use it to create the 03888 // undo string. 03889 UndoAttribStrID = NewAttr->GetAttrNameID(); 03890 03891 if (!DoStartSelOp(FALSE,FALSE, TRUE,TRUE)) // Try to record the selection state , don't 03892 // render the blobs though 03893 { 03894 goto EndOperation; 03895 } 03896 03897 // Ask all parents of all attrs in the list if it's ok to do the op 03898 ok = TRUE; 03899 pAttr = OldAttrs->GetHead(); 03900 while (pAttr != NULL && ok) 03901 { 03902 Node* pParent = ((NodeAttributePtrItem*)pAttr)->NodeAttribPtr->FindParent(); 03903 ObjChange.SetRetainCachedData(((NodeAttributePtrItem*)pAttr)->NodeAttribPtr->IsEffectAttribute()); 03904 ok = (pParent != NULL) && pParent->AllowOp(&ObjChange); 03905 pAttr = OldAttrs->GetNext(pAttr); 03906 } 03907 if (!ok) 03908 { 03909 FailAndExecute(); 03910 goto EndOperation; 03911 } 03912 03913 pAttr = OldAttrs->GetHead(); 03914 while (pAttr != NULL) 03915 { 03916 DoReplace(((NodeAttributePtrItem*)pAttr)->NodeAttribPtr, NewAttr); 03917 03918 pAttr = OldAttrs->GetNext(pAttr); 03919 } 03920 03921 // If the user has specified that the Last Attribute applied should 03922 // become current, then we need to update the Current Attribute now. 03923 if (AttributeManager::LastAttrAppliedBecomesCurrent) 03924 { 03925 NodeAttribute* NewCurrent; 03926 NodeAttribute* LastAttr; 03927 03928 if (AttributeManager::pLastNodeAppliedTo != NULL) 03929 { 03930 LastAttr = AttributeManager::pLastNodeAppliedTo->FindAppliedAttribute(NewAttr->GetAttributeType()); 03931 03932 if (LastAttr != NULL) 03933 { 03934 ALLOC_WITH_FAIL(NewCurrent ,((NodeAttribute*)LastAttr->SimpleCopy()), this) 03935 03936 if (NewCurrent->IsAFillAttr()) 03937 { 03938 DocRect Bounds = AttributeManager::pLastNodeAppliedTo->GetBoundingRect(); 03939 ((AttrFillGeometry*)NewCurrent)->SetBoundingRect(Bounds); 03940 } 03941 03942 if (LastAttr->IsAFractalFill()) 03943 { 03944 // The current attr, should always use the default DPI for fractals. 03945 ((AttrFillGeometry*)NewCurrent)->SetFractalDPI(AttrFillGeometry::FractalDPI); 03946 } 03947 03948 // Find the Attr Groups that need updating 03949 List AttrGroups; 03950 if (AttributeManager::CanBeAppliedToNode(AttributeManager::pLastNodeAppliedTo, 03951 LastAttr, &AttrGroups)) 03952 { 03953 AttributeManager::UpdateCurrentAttr(NewCurrent, FALSE, &AttrGroups); 03954 } 03955 03956 AttrGroups.DeleteAll(); 03957 delete NewCurrent; 03958 } 03959 } 03960 } 03961 03962 AttrFillGeometry::LastRenderedMesh = NULL; 03963 03964 if (Document::GetSelected()) 03965 Document::GetSelected()->SetModified(TRUE); 03966 03967 // Update all parents of this 03968 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this); 03969 ObjChange.SetRetainCachedData(TRUE); // Tell TextStory not to invalidate everything in OnChildChange 03970 if (!UpdateChangedNodes(&ObjChange)) 03971 FailAndExecute(); 03972 03973 EndOperation: 03974 End(); // End of operation 03975 }
|
|
Definition at line 396 of file attrappl.h. 00396 { return m_pAttr; }
|
|
The GetOpName fn is overridden so that we return back a description appropriate to the type of attribute that the operation applies.
Reimplemented from Operation. Definition at line 4233 of file attrappl.cpp. 04234 { 04235 04236 *OpName = String_256(UndoAttribStrID); 04237 *OpName += String_256(_R(IDS_CHANGE)); 04238 }
|
|
For finding OpReplaceAttributes state.
Definition at line 4206 of file attrappl.cpp.
|
|
OpReplaceAttributes initialiser method.
Reimplemented from SimpleCCObject. Definition at line 4158 of file attrappl.cpp. 04159 { 04160 04161 // Register the opdescriptors for the OpReplaceAttributes operation 04162 OpDescriptor* OpDesc = new OpDescriptor( 04163 0, 04164 _R(IDS_REPLACEATTRSOP), 04165 CC_RUNTIME_CLASS(OpReplaceAttributes), 04166 OPTOKEN_REPLACEATTRS, 04167 OpReplaceAttributes::GetState); 04168 04169 04170 if (OpDesc != NULL) 04171 { 04172 // Bodge this needs to use faby Macro technology so that the op is attached to 04173 // a system bar. 04174 OpDesc = new OpChangeLineWidthOpDesc(0, 04175 _R(IDS_CHANGELINEWIDTH), 04176 CC_RUNTIME_CLASS(OpReplaceAttributes), 04177 OPTOKEN_CHANGELINEWIDTH, 04178 OpChangeLineWidthOpDesc::GetState, 04179 0, 04180 _R(IDBBL_CHANGELINEWIDTH)); 04181 04182 } 04183 04184 04185 04186 04187 ERRORIF(!OpDesc, _R(IDE_NOMORE_MEMORY), FALSE); 04188 return(OpDesc != NULL); 04189 }
|
|
Definition at line 401 of file attrappl.h. |
|
Definition at line 400 of file attrappl.h. |