OpRepeatApplyAttribToSelected Class Reference

This class represents the OpApplyAttribToSelected operation. It applies the specified attribute to all selected objects. More...

#include <attrappl.h>

Inheritance diagram for OpRepeatApplyAttribToSelected:

Operation MessageHandler ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 OpRepeatApplyAttribToSelected ()
 OpRepeatApplyAttribToSelected constructor.
void DoWithParam (OpDescriptor *OpDesc, OpParam *pOpParam)
 Performs the OpApplyAttribToSelected 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.

Static Public Member Functions

static BOOL Init ()
 OpApplyAttribToSelected initialiser method.
static OpState GetState (String_256 *, OpDescriptor *)
 For finding OpRepeatApplyAttribToSelected state.

Static Public Attributes

static FillBlobSelectionState FillBlobState

Protected Member Functions

BOOL ApplyToSelection (NodeAttribute *Attrib, BOOL Mutate)
virtual BOOL DoApply (Node *CurrentNode, NodeAttribute *Attrib, BOOL Mutate, BOOL bEffectRootOnly)

Detailed Description

This class represents the OpApplyAttribToSelected operation. It applies the specified attribute to all selected objects.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/3/95

Definition at line 317 of file attrappl.h.


Constructor & Destructor Documentation

OpRepeatApplyAttribToSelected::OpRepeatApplyAttribToSelected  ) 
 

OpRepeatApplyAttribToSelected constructor.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/3/95
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 2806 of file attrappl.cpp.

02806                                                             : Operation()                               
02807 {                              
02808 }


Member Function Documentation

BOOL OpRepeatApplyAttribToSelected::ApplyToSelection NodeAttribute Attrib,
BOOL  Mutate
[protected]
 

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/4/95
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
TRUE if successful FALSE if the operation should be aborted (TIDYUP THEN CALL End()!)

Errors: -

See also:
-

Definition at line 3024 of file attrappl.cpp.

03025 {
03026     SelRange* Sel = GetApplication()->FindSelection();
03027     ERROR3IF(Sel==NULL,"Can't find SelRange!");
03028     if (Sel==NULL) return FALSE;
03029     Node* FirstSelectedNode = Sel->FindFirst();
03030 
03031     // Find out which spread the selection is on
03032 //  Spread* pSpread = FirstSelectedNode->FindParentSpread();
03033 
03034     if (FirstSelectedNode != NULL)    // Can't do anything if nothing is selected
03035     {   
03036         EffectsStack* pStack = Sel->GetEffectsStack(FALSE, FALSE);  // Get cached stack, don't escape derived objects (allow attrs to be applie to derived objects)
03037         ERROR3IF(pStack==NULL, "Failed to get PPStack in ApplyToSelection");
03038         INT32 stackpos = STACKPOS_TOP;
03039         Range* pLevel = pStack->GetLevelRange(&stackpos, FALSE);        // Don't escape old controllers, apply attr to base nodes
03040         Node* pCurrentNode = pLevel->FindFirst();
03041 
03042         // While there are still nodes to apply the attribute to
03043         while (pCurrentNode != NULL)   
03044         {
03045             BOOL bEffect = (pCurrentNode->IsAnObject() && ((NodeRenderableInk*)pCurrentNode)->IsValidEffectAttr(Attrib));
03046 
03047             Node* pApplyNode = pCurrentNode;
03048             if (pApplyNode->IsAnObject())
03049                 pApplyNode = ((NodeRenderableInk*)pApplyNode)->GetObjectToApplyTo(Attrib->GetRuntimeClass());
03050 
03051             if (!DoApply(pApplyNode, Attrib, Mutate, bEffect))
03052                 return FALSE;
03053 
03054             ContinueSlowJob();
03055 
03056             pCurrentNode = pLevel->FindNext(pCurrentNode);
03057         } 
03058     }
03059 
03060     return TRUE;
03061 }

BOOL OpRepeatApplyAttribToSelected::DoApply Node CurrentNode,
NodeAttribute Attrib,
BOOL  Mutate,
BOOL  bEffectRootOnly
[protected, virtual]
 

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/4/95
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
Returns: TRUE if successful FALSE if the operation should be aborted (TIDYUP THEN CALL End()!)

Errors: -

See also:
- Note: This routine may no longer be needed now that OpApplyAttrib::DoApply is static and can be told not to write undo info.

Definition at line 3085 of file attrappl.cpp.

03086 {
03087     ERROR3IF(!CurrentNode->IsBounded(), "DoApply assumes CurrentNode is bounded");
03088 
03089     // have we been allowed to do this ???
03090     Spread* pSpread = (Spread*)CurrentNode->FindParent(CC_RUNTIME_CLASS(Spread)); 
03091     DocRect TempRect = ((NodeRenderableBounded*)CurrentNode)->GetBoundingRect();
03092 
03093     BOOL AttributeExists = FALSE;  // Until we find that the attribute does exist
03094 
03095     CCRuntimeClass* AttrType = Attrib->GetAttributeType();
03096 
03097     // -----------------------------------------------------------------------------
03098     // Determine if the current node already has an attribute which is the same 
03099     // runtime class as Attrib. 
03100     Node* n = CurrentNode->FindFirstChild(); 
03101     Node* pLastBoundedNode = NULL;
03102     if (bEffectRootOnly)
03103     {
03104         // BODGE! ------------------------------------------------------------
03105         // Don't apply stroke transparency as an effect attribute - nothing
03106         // needs it. Test has to be done here because other objects in the
03107         // selection might need it...
03108         if (AttrType==CC_RUNTIME_CLASS(AttrStrokeTransp))
03109             return TRUE;
03110         // END-BODGE! --------------------------------------------------------
03111 
03112         pLastBoundedNode = CurrentNode->FindLastChild(CC_RUNTIME_CLASS(NodeRenderableBounded));
03113         ERROR3IF(pLastBoundedNode==NULL, "Attempt to apply effect attr to node with no children");
03114 
03115         if (pLastBoundedNode) n = pLastBoundedNode->FindNext();
03116     }
03117 
03118     while (n != NULL)
03119     {
03120         // Now lets see if we can find an attribute of the same type
03121         // as the one we are interested in.
03122         if (n->IsAnAttribute())
03123         {
03124             if( ((NodeAttribute*)n)->GetAttributeType() == AttrType)
03125             {
03126                 AttributeExists = TRUE; 
03127                 break; 
03128             }
03129         }
03130         n = n->FindNext(); // Find next child of CurrentNode
03131     }   
03132 
03133     // At this point we have Either .....
03134     //      1. Found an attribute of the same type as the new one, and we will
03135     //         now replace it.
03136     //      2. Found the specific attribute we were looking for and will replace
03137     //         that.
03138     //      3. Found an attribute to mutate.
03139     //      4. Found no attribute of the correct type, indicating that it has
03140     //         been factored out, and we need to put a new one in here.
03141 
03142     // Have we have got an Attribute to do something with ?
03143     NodeAttribute* AttribClone = NULL; 
03144     NodeAttribute* pAttr = (NodeAttribute*)n;
03145     if (pAttr)
03146     {
03147         // Yes !
03148         if (Mutate)
03149         {
03150             // Mutate it into the new type.
03151             AttribClone = ((AttrFillGeometry*)pAttr)->Mutate((AttrFillGeometry*)Attrib);
03152         }
03153 
03154         if (AttribClone != NULL)
03155         {
03156             // Set the attribute directly
03157             *((AttrFillGeometry*)pAttr) = *((AttrFillGeometry*)AttribClone);
03158 
03159             AttributeManager::pLastNodeAppliedTo = (NodeRenderableInk*)CurrentNode;
03160 
03161             delete AttribClone;
03162             AttribClone = NULL;
03163         }
03164     }
03165     else
03166     {
03167         // We've not found an attribute to replace, so we'll have to put
03168         // a new one in
03169         NodeAttribute* TempAttr = NULL;
03170 
03171         BOOL FoundAttr = ((NodeRenderableInk*)CurrentNode)->
03172                             FindAppliedAttribute(Attrib->GetAttributeType(), &TempAttr);
03173 
03174         if (!FoundAttr || TempAttr == NULL)
03175             return FALSE;
03176 
03177         if (Mutate)
03178         {
03179             AttribClone = ((AttrFillGeometry*)TempAttr)->Mutate((AttrFillGeometry*)Attrib);
03180         }
03181         else
03182         {
03183             // We'll just put a copy of our attribute in the tree.
03184             ALLOC_WITH_FAIL(AttribClone ,((NodeAttribute*)Attrib->SimpleCopy()), this)
03185 
03186             if (TempAttr->IsAFillAttr())
03187             {
03188                 AttrFillGeometry* NodeReplaced = (AttrFillGeometry*)TempAttr;
03189 
03190                 // Copy the old fill characteristics into the new Fill
03191                 if (!OpApplyAttrib::KeepExistingCharacteristics(NodeReplaced, (AttrFillGeometry*)AttribClone))
03192                     return FALSE;
03193             }
03194 
03195             if (Attrib->IsATranspFill() && Attrib->IsAFlatFill())
03196             {
03197                 // If we are mutating into a flat fill, then we need
03198                 // to make sure we remove any existing fill blobs.
03199                 ((AttrFillGeometry*)TempAttr)->RenderFillBlobs();
03200             }
03201         }
03202 
03203         // If the AttribClone has the same value as an applied attribute 
03204         // (A default attr if the attribs have been localised). Then we don't want to apply it !
03205         if (AttribClone && AttribClone->ShouldBeOptimized() && !bEffectRootOnly)
03206         {
03207             NodeAttribute* pAppliedAttr;
03208             if (((NodeRenderableInk*)CurrentNode)->FindAppliedAttribute(AttribClone->GetAttributeType(), 
03209                                                   &pAppliedAttr))
03210             {
03211                 // Do the attributes have the same value ?
03212                 if ((IS_SAME_CLASS(AttribClone, pAppliedAttr)))
03213                 {
03214                     if ((*AttribClone)==(*pAppliedAttr))
03215                     {
03216                         AttribClone->CascadeDelete();       // Delete the attribute
03217 
03218                         // If attribute affect's the bounds of the object (eg. a LineWidth) then invalidate the
03219                         // bounds of the object
03220 
03221                         if (pAppliedAttr->EffectsParentBounds())
03222                         {
03223                             ((NodeRenderableBounded*)CurrentNode)->InvalidateBoundingRect(TRUE);
03224                         }
03225 
03226                         delete AttribClone;
03227                         AttribClone = NULL;
03228                     }
03229                 }
03230             }
03231         }
03232 
03233         // Effect attributes don't optimise so if the value of this is the
03234         // same as the default value we should not add it here
03235         //
03236         if (AttribClone && bEffectRootOnly && AttribClone->HasEquivalentDefaultValue())
03237         {
03238             // Just allow the attribute to be hidden
03239             AttribClone->CascadeDelete();       // Delete the attribute
03240             delete AttribClone;
03241             AttribClone = NULL;
03242         }
03243 
03244         if (AttribClone)
03245         {
03246             // Finally !! We can add the new attribute node into the tree.
03247             if (bEffectRootOnly)
03248                 AttribClone->AttachNode(pLastBoundedNode, NEXT);
03249             else
03250                 AttribClone->AttachNode(CurrentNode, FIRSTCHILD);
03251 
03252             AttributeManager::pLastNodeAppliedTo = (NodeRenderableInk*)CurrentNode;
03253 
03254             // And now it's in the tree, we need to make sure that any fill control
03255             // points are valid.
03256             if (AttribClone->IsAFillAttr())
03257             {
03258                 ((AttrFillGeometry*)AttribClone)->AttributeChanged();
03259             }
03260         }
03261     }
03262 
03263     // Now that the attr value has been set (or left unchanged) test to see if we can remove effect attrs
03264     // Only try to "optimise" effect attributes here if this is going to be a permanent tree change
03265     // Don't bother in the middle of slider dragging
03266     if (pAttr && pAttr->IsEffectAttribute() && bEffectRootOnly)
03267     {
03268         // Effect attributes don't optimise so if the value of this is the
03269         // same as the default value  we should remove it here
03270         //
03271         if (pAttr->HasEquivalentDefaultValue())
03272         {
03273             // "Hide" the node
03274             pAttr->CascadeDelete();
03275             delete pAttr;
03276         }
03277     }
03278 
03279     // Now force a redraw on the attribute
03280     // We release cached data manually, because we need to be clever about effect attributes
03281     // only releasing parent cached data...
03282 //  ReleaseCachedForAttrApply((NodeRenderableBounded*)CurrentNode, bEffectRootOnly); // Function not available in this class!
03283     if (bEffectRootOnly)
03284         ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);     // Parents and Derived data only
03285     else
03286         ((NodeRenderableBounded*)CurrentNode)->ReleaseCached();                                                 // Self, Parents and Children
03287 
03288     // (GetSelected... URGH.)
03289     Document::GetSelected()->ForceRedraw(pSpread, TempRect, TRUE, CurrentNode, FALSE);  // No automatic call to ReleaseCached
03290     return TRUE;
03291 }

void OpRepeatApplyAttribToSelected::DoWithParam OpDescriptor OpDesc,
OpParam pOpParam
[virtual]
 

Performs the OpApplyAttribToSelected operation. This function applies the NodeAttribute to all selected objects.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/3/95
Parameters:
OpDescriptor [INPUTS]
pOpParam,: Param1 contains a pointer to the NodeAttribute to apply to the [OUTPUTS] currently selected nodes
Returns:
-

Errors: -

See also:
-

Reimplemented from Operation.

Definition at line 2828 of file attrappl.cpp.

02829 {    
02830     ERROR3IF(pOpParam == NULL, "The OpApplyAttribToSelected operation requires an attribute parameter"); 
02831 
02832     AttrTypeSet AttrTypes; 
02833     NodeRenderableInk* pLocalisedCompound = NULL;
02834     NodeRenderableInk* pFactoredOutCompound = NULL;
02835     Node* pCurrent;
02836 
02837     Range SelRng(*(GetApplication()->FindSelection()));
02838 
02839     BeginSlowJob();
02840     AttributeManager::pLastNodeAppliedTo = NULL;
02841 
02842     // Obtain a pointer to the attribute which we will need to apply to all selected nodes 
02843     NodeAttribute* Attrib = (NodeAttribute*)(void *)pOpParam->Param1;
02844 
02845     BOOL Mutate = FALSE;
02846     NodeAttribute* OldAttr = NULL;
02847 
02848     if (Attrib == NULL)
02849     {
02850         // If the first param is NULL then we are doing a mutation
02851         Attrib = (NodeAttribute*)(void *)pOpParam->Param2;
02852         Mutate = TRUE;
02853     }   
02854     else
02855     {
02856         // Someone has specified a Particular Attribute that we should replace
02857         // and ignore all others.
02858         OldAttr = (NodeAttribute*)(void *)pOpParam->Param2;
02859     }
02860 
02861     SelRange* Sel;
02862     ObjChangeFlags cFlags;
02863     cFlags.Attribute = TRUE;
02864     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL);
02865 
02866     Sel = GetApplication()->FindSelection();
02867     if (!Sel->AllowOp(&ObjChange))
02868     {
02869         FailAndExecute();
02870         goto EndOperation;
02871     }
02872 
02873     // Some Attributes require a second attribute to be changed as well,
02874     // which has to be done within this op.
02875     NodeAttribute* OtherAttrib;
02876     BOOL IsMutate;
02877     OtherAttrib = AttributeManager::GetOtherAttrToApply(Attrib, &IsMutate);
02878 
02879     // Before we apply the attribute to the selection we must localise all attributes
02880     // with the same type that we are going to apply. If we don't do this then the
02881     // tree will be left in an invalid state. 
02882 
02883     AttrTypes.AddToSet((Attrib->GetAttributeType())); 
02884     if (OtherAttrib != NULL)
02885     {
02886         AttrTypes.AddToSet((OtherAttrib->GetAttributeType())); 
02887     }
02888         
02889 //  if (!DoLocaliseForAttrChange(&SelRng, &AttrTypes))
02890 //  {
02891 //      goto EndOperation;
02892 //  }
02893 
02894     pCurrent = SelRng.FindFirst();
02895 
02896     // There is no need to localise a compound more than once so we remember the last localised 
02897 
02898     CCRuntimeClass* AttrType;
02899     Node* pParent;
02900     Node* pObject;
02901                         
02902     while (pCurrent)
02903     {
02904         pObject = pCurrent;
02905         // Determine if the attribute will get applied to this object, or an alternative object
02906         // (probably its parent)
02907         if (!AttrTypes.IsEmpty())
02908         {
02909             AttrType = ((AttrTypeItem*)AttrTypes.GetHead())->AttributeType;
02910             ERROR3IF(!AttrType, "AttrType set contains NULL attribute type");  
02911             pObject = ((NodeRenderableInk*)pObject)->GetObjectToApplyTo(AttrType);
02912         }
02913 
02914         {
02915             // We only need to localise those nodes which have a compound parent
02916             pParent = pObject->FindParent(); 
02917             ERROR3IF(pParent == NULL, "Range::DoLocaliseForAttrChange, node found without a parent"); 
02918         
02919             // Only localise the parent if it is a compound node which has not already been localised
02920             if ((pParent->IsCompound()) && (pParent != pLocalisedCompound))
02921             {
02922                 ((NodeRenderableInk*)pParent)->LocaliseCommonAttributes(FALSE,      // No need to check for duplicates
02923                                                                         TRUE,       // Localise globally
02924                                                                         &AttrTypes);// Only attributes of these types
02925 
02926                 pLocalisedCompound = (NodeRenderableInk*)pParent;  // Remember that it's been localised
02927             }
02928         }
02929         
02930         pCurrent = SelRng.FindNext(pCurrent); 
02931     }
02932 
02933     ApplyToSelection(Attrib, Mutate);
02934 
02935     if (OtherAttrib != NULL)
02936     {
02937         ApplyToSelection(OtherAttrib, IsMutate);
02938         delete OtherAttrib;
02939     }   
02940 
02941     // Having applied the attributes, we  must now try and factor out the newly 
02942     // applied attributes
02943 //  if (!DoFactorOutAfterAttrChange(&SelRng, 
02944 //                                  &AttrTypes))
02945 //  {
02946 //      goto EndOperation;
02947 //  }
02948 
02949     // Scan the range
02950     pCurrent = SelRng.FindFirst();
02951 
02952     // There is no need to factor out the attributes on a compound more than once, so we 
02953     // remember the last compound node which has had its attributes factored out 
02954 
02955     while (pCurrent)
02956     {
02957         // If the object can discard its attribute children then we should not try to factor
02958         // out its attributes
02959         CCRuntimeClass* AttrType;
02960         
02961         pObject = pCurrent;
02962         if (!AttrTypes.IsEmpty())
02963         {
02964             AttrType = ((AttrTypeItem*)AttrTypes.GetHead())->AttributeType;
02965             ERROR3IF(!AttrType, "AttrType set contains NULL attribute type");  
02966             pObject = ((NodeRenderableInk*)pObject)->GetObjectToApplyTo(AttrType);
02967         }
02968 
02969         {
02970             // We only need to factor out attributes on nodes which have a compound parent
02971             pParent = pObject->FindParent(); 
02972             ERROR3IF(pParent == NULL, "Range::DoFactorOutAfterAttrChange, node found without a parent"); 
02973         
02974             // Only factor out attribs if  the parent has not already had its attribs factored out
02975             if ((pParent->IsCompound()) && (pParent != pFactoredOutCompound))
02976             {
02977                 ((NodeRenderableInk*)pParent)->FactorOutCommonChildAttributes(TRUE, &AttrTypes);
02978                  
02979                 pFactoredOutCompound = (NodeRenderableInk*)pParent;  // Remember that it's been localised
02980             }
02981         }
02982         
02983         pCurrent = SelRng.FindNext(pCurrent); 
02984     }
02985 
02986     AttrFillGeometry::LastRenderedMesh = NULL;
02987 
02988     if (Document::GetSelected())
02989         Document::GetSelected()->SetModified(TRUE);
02990 
02991     ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,NULL);
02992     if (!UpdateChangedNodes(&ObjChange))
02993         FailAndExecute();
02994 
02995     AttributeManager::LastAppliedBounds = Sel->GetBoundingRect();
02996 
02997 EndOperation:           
02998     AttrTypes.DeleteAll();
02999 
03000     EndSlowJob();
03001     End();              // End of operation
03002 } 

void OpRepeatApplyAttribToSelected::GetOpName String_256 OpName  )  [virtual]
 

The GetOpName fn is overridden so that we return back a description appropriate to the type of attribute that the operation applies.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/3/95
Parameters:
- [INPUTS]
The undo string for the operation [OUTPUTS]
Returns:

Errors: -

See also:
-

Reimplemented from Operation.

Definition at line 3372 of file attrappl.cpp.

03373 { 
03374     *OpName = "";
03375 }  

OpState OpRepeatApplyAttribToSelected::GetState String_256 ,
OpDescriptor OpDesc
[static]
 

For finding OpRepeatApplyAttribToSelected state.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/3/95
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
The state of the OpRepeatApplyAttribToSelected operation

Errors: -

See also:
-

Definition at line 3341 of file attrappl.cpp.

03342 {
03343     OpState OpSt;
03344 
03345     SelRange* Sel = GetApplication()->FindSelection();
03346     ERROR2IF(Sel==NULL,OpSt,"Can't find SelRange!");
03347 
03348     // The Operation is greyed if there are no nodes selected 
03349     OpSt.Greyed = ( (Sel->FindFirst() == NULL) );  
03350                                                 
03351     return(OpSt);   
03352 }

BOOL OpRepeatApplyAttribToSelected::Init void   )  [static]
 

OpApplyAttribToSelected initialiser method.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/3/95
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
TRUE if the operation could be successfully initialised FALSE if no more memory could be allocated

Errors: ERROR will be called if there was insufficient memory to allocate the operation.

See also:
-

Reimplemented from SimpleCCObject.

Definition at line 3312 of file attrappl.cpp.

03313 {
03314     // Register the opdescriptors for the OpApplyAttribToSelected operation
03315     OpDescriptor* OpDesc = new OpDescriptor(
03316                                             0,
03317                                             _R(IDS_APPLYATTRIBOP),              
03318                                             CC_RUNTIME_CLASS(OpRepeatApplyAttribToSelected),
03319                                             OPTOKEN_REPEATAPPLYATTRIB,
03320                                             OpRepeatApplyAttribToSelected::GetState);   
03321 
03322     ERRORIF(!OpDesc, _R(IDE_NOMORE_MEMORY), FALSE);
03323     return(OpDesc != NULL);
03324 }               


Member Data Documentation

FillBlobSelectionState OpRepeatApplyAttribToSelected::FillBlobState [static]
 

Definition at line 331 of file attrappl.h.


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