void NodeRenderableInk::DeleteLocalisedAttributes(BOOL Global, AttrTypeSet* pAffectedAttrTypes ) { // Do we need to delete any parent compound's attributes if (Global) { Node* pParent = FindParent(); if (pParent && pParent->IsCompound()) { // We need to localise the parent's attributes first (Recursive bit) ((NodeRenderableInk*)pParent)->DeleteLocalisedAttributes(Global, pAffectedAttrTypes); } } // Delete all moved attributes Node* Next; Node* Current = FindFirstChild(); while (Current != NULL && !Current->IsAnObject()) { Next = Current->FindNext(); if (Current->IsAnAttribute()) { BOOL DeleteAttr = TRUE; if (pAffectedAttrTypes) { // Only delete the attribute if it has been localised if (!(pAffectedAttrTypes->InSet(((NodeAttribute*)Current)->GetAttributeType()))) DeleteAttr = FALSE; } if (DeleteAttr) { // Die // Ilan 19/04/00 // More generally speaking, all attributes which returned FALSE in their ShouldBeOptimized() // calls, will not have been localised to the child nodes during DoLocaliseCommonAttributes(). // Hence don't want to delete these attributes, they must remain attached to the group node // which we are ungrouping so that they are present on an UNDO of a OpUngroup // Attributes in this category include Feather attibutes and TemplateAttributes at present // if (!Current->IsKindOf(CC_RUNTIME_CLASS(TemplateAttribute))) if( ((NodeAttribute*)Current)->ShouldBeOptimized()) { Current->CascadeDelete(); delete Current; } } } Current = Next; } }
BOOL NodeRenderableInk::MakeAttributeComplete(Node* Root, BOOL CheckForDuplicates, /* = TRUE */ AttrTypeSet* pAffectedAttrTypes, /* = NULL */ BOOL IncludeDefaults, /* = FALSE */ BOOL bIncludeEffectAttrs /* = FALSE */) { Node* Current = NULL; // Pointer to the current node in the tree NodeAttribute* CurAttr; CCRuntimeClass* AttrType; BOOL Exists; Node* PreFirstChild = FindFirstChild(); // Remember the FirstChild of the node before we add // any new attributes, this will come in handy if we // need to abort. // Loop until all attributes are copied, we are not interested in the defaults cos these are the // same for all docs !. if (bIncludeEffectAttrs) Current = NodeAttribute::FindFirstAppliedAttr(this, Root); else Current = NodeAttribute::FindPrevAppliedAttr(this, Root); while (Current && (IncludeDefaults || (!(IS_A(Current->FindParent(), NodeDocument)))) ) { // Find the next node, snaking up the tree if (Current->IsAnAttribute()) { CurAttr = (NodeAttribute*)Current; if (CurAttr->CanBeAppliedToObject() && CurAttr->ShouldBeOptimized()) { AttrType = CurAttr->GetAttributeType(); BOOL Required = RequiresAttrib(AttrType) || this->IsCompound(); // Is the attribute required ? if (Required && (!pAffectedAttrTypes || pAffectedAttrTypes->InSet(AttrType))) { Exists = FALSE; if (CheckForDuplicates) { // triggers can have duplicates if(!CurAttr->CanBeMultiplyApplied()) { // Does the node already have this child attribute Exists = (GetChildAttrOfType(AttrType) != NULL); } } #ifdef _DEBUG if (!CheckForDuplicates) { // If we feel there is no need to check for duplicates then there shouldn't be any ! if (!CurAttr->CanBeMultiplyApplied()) { NodeAttribute* pChildAttr = GetChildAttrOfType(AttrType); if ((pChildAttr != NULL)) { #if DEBUG_TREE DebugTreeDlg::DumpSubTree(this, 4); #endif TRACE(_T("Duplicate Attr found at %x %s\n"), pChildAttr, pChildAttr->GetRuntimeClass()->m_lpszClassName); } // ERROR3IF((pChildAttr != NULL), "MakeAttributeComplete: Duplicate attr found !"); } } #endif if (!Exists) { // Make a copy of the attribute NodeAttribute* NewAttr = (NodeAttribute*)CurAttr->SimpleCopy(); if (NewAttr == NULL) { goto OutOfMemory; } // Now add the attribute to this node NewAttr->AttachNode(this, FIRSTCHILD, TRUE, FALSE); } } } } Current = NodeAttribute::FindPrevAppliedAttr(Current, Root); // in order to copy brush ink nodes we need to break if the parent is NULL, else is violates if (Current!=NULL && Current->FindParent() == NULL) break; } return TRUE; OutOfMemory: // Delete any new attributes added to the node Current = FindFirstChild(); Node* Next; while (Current != PreFirstChild) { ENSURE(Current != NULL, "PreFirstChild could not be found"); ENSURE(Current->IsAnAttribute(), "Should be a NodeAttribute"); Next = Current->FindNext(); // Delete the attribute Current->CascadeDelete(); delete Current; Current = Next; } return FALSE; }