OpApplyAttrib Class Reference

Virtual base class for ops that apply attibutes. More...

#include <attrappl.h>

Inheritance diagram for OpApplyAttrib:

SelOperation UndoableOperation Operation MessageHandler ListItem CCObject SimpleCCObject OpApplyAttribsToSelected OpApplyAttribToNode OpApplyAttribToSelected OpApplyAttrInteractive OpEditFill List of all members.

Public Member Functions

virtual CCRuntimeClass * GetValueChangeType ()
virtual BOOL IsMergeableApplyOp ()
virtual void SetMergeable (BOOL bNewState)
NodeAttribute * GetAttributeToApply ()

Static Public Member Functions

static NodeRenderableInk * FindCompoundNodeWhichRequiresAttribute (NodeRenderableInk *pStartNode, CCRuntimeClass *pAttribClass)
static BOOL KeepExistingCharacteristics (AttrFillGeometry *, AttrFillGeometry *)
 Retains the previous fill charateristics when applying a new fill.
static BOOL DoApplyToSelection (SelOperation *pOp, NodeAttribute *Attrib, BOOL bMutate, BOOL bOptimise)

Protected Member Functions

BOOL DoInvalidateRegions (Range *NodeRange, NodeAttribute *Attrib, BOOL Mutate, NodeAttribute *OtherAttr, BOOL OtherMutate)
 Invalidates the regions of every node in the range.

Protected Attributes

CCRuntimeClass * ValueChangeType
BOOL MergeRepeats
NodeAttribute * m_pAttr

Detailed Description

Virtual base class for ops that apply attibutes.

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

Definition at line 126 of file attrappl.h.


Member Function Documentation

BOOL OpApplyAttrib::DoApplyToSelection (  SelOperation *  pOp,
NodeAttribute *  Attrib,
BOOL  bMutate,
BOOL  bOptimise
)  [static]
 

Definition at line 1432 of file attrappl.cpp.

01433 {
01434     SelRange* Sel = GetApplication()->FindSelection();
01435     ERROR3IF(Sel==NULL,"Can't find SelRange!");
01436     if (Sel==NULL) return FALSE;
01437     Node* FirstSelNode = Sel->FindFirst();
01438     BOOL bAttrWasRequired = FALSE;
01439 
01440     // Find out which spread the selection is on
01441     if (FirstSelNode != NULL)     // Can't do anything if nothing is selected
01442     {   
01443         ERROR2IF(!FirstSelNode->IsAnObject(), FALSE, "ApplyToSelection SelRange doesn't have an Ink node in it");
01444 //      NodeRenderableInk* FirstSelectedNode = (NodeRenderableInk*)FirstSelNode;
01445 //      Spread *pSpread = FirstSelectedNode->FindParentSpread();
01446 
01447         // Set up a range of all selected nodes 
01448         EffectsStack* pStack = Sel->GetEffectsStack(FALSE, FALSE);  // Get cached stack, don't escape derived objects (allow attrs to be applie to derived objects)
01449         ERROR3IF(pStack==NULL, "Failed to get PPStack in ApplyToSelection");
01450         INT32 stackpos = STACKPOS_TOP;
01451         Range* pLevel = pStack->GetLevelRange(&stackpos, FALSE);            // Don't escape old controllers, apply attr to base nodes
01452         Node* CurrentNode = pLevel->FindFirst();
01453 //      Node* FirstNode = CurrentNode;
01454 
01455         BOOL bCanDiscardUndo = TRUE;
01456 
01457         // While there are still nodes to apply the attribute to
01458         while (CurrentNode != NULL)
01459         {
01460             // move to the next one but remember the current one
01461             Node* OldNode = CurrentNode;
01462             CurrentNode = pLevel->FindNext(CurrentNode);
01463 
01464             if (OldNode->IsAnObject())
01465             {
01466                 // Scan up through the stack to find the appropriate level to apply this attribute
01467                 NodeRenderableInk * pNodeToApply = OpApplyAttrib::FindCompoundNodeWhichRequiresAttribute((NodeRenderableInk *)OldNode,
01468                                                                                 Attrib->GetRuntimeClass());
01469 
01470                 if (pNodeToApply != OldNode)
01471                 {
01472                     // apply the attribute to all ink-children of the given node.
01473                     Node * pChildNode = pNodeToApply->FindFirstChild();
01474                     
01475                     while (pChildNode != NULL)
01476                     {
01477                         Node * pNextChildNode = pChildNode->FindNext();
01478 
01479                         if (pChildNode->IsAnObject() && ((NodeRenderableInk*)pChildNode)->RequiresAttrib(Attrib))
01480                         {
01481                             if (!DoApply(pOp, pChildNode, Attrib, bMutate, FALSE, TRUE, bOptimise, &bAttrWasRequired, &bCanDiscardUndo))    // Will only apply Attrib if the node requires it.
01482                                 return FALSE; 
01483                         }
01484 
01485                         pChildNode = pNextChildNode;
01486                     }
01487                 }
01488                 else
01489                 {
01490                     if (!DoApply(pOp, OldNode, Attrib, bMutate, FALSE, TRUE, bOptimise, &bAttrWasRequired, &bCanDiscardUndo))    // Will not apply Attrib if the node does
01491                     // not require it.
01492                     {
01493                         return FALSE; 
01494                     }
01495                 }
01496 
01497 
01498                 // now, if the node to apply is still a parent of the other nodes, skip past them
01499                 if (pNodeToApply != OldNode && pNodeToApply->IsCompoundClass())
01500                 {
01501                     if (((NodeCompound*)pNodeToApply)->PromoteAttributeApplicationToMe(Attrib->GetRuntimeClass()))
01502                     {
01503                         while (CurrentNode != NULL && CurrentNode->FindParent(pNodeToApply->GetRuntimeClass()) == pNodeToApply)
01504                         {
01505                             CurrentNode = pLevel->FindNext(CurrentNode);
01506                         }
01507                     }
01508                 }
01509             }
01510             else
01511             {
01512                 if (!DoApply(pOp, OldNode, Attrib, bMutate, FALSE, TRUE, bOptimise, &bAttrWasRequired, &bCanDiscardUndo))    // Will not apply Attrib if the node does not require it.
01513                 {
01514                     return FALSE; 
01515                 }
01516             }
01517 
01518             // a bodge to handle the case when a line width is applied to a transparent line.
01519             // what we want in this case is to change the line colour (as well as the line width)
01520             // so the line becomes visible. Black colour is set on those lines.
01521 
01522             if ((IS_A(Attrib, AttrLineWidth)) && OldNode->IsAnObject())
01523             {
01524                 NodeRenderableInk *pRendNode = ((NodeRenderableInk*)OldNode)->GetObjectToApplyTo(Attrib->GetAttributeType());
01525 
01526                 // find the line colour attribute applied to that node
01527                 NodeAttribute *pAppliedAttr = NULL;
01528                 pRendNode->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeColour), &pAppliedAttr);
01529                 if (!pAppliedAttr) // should always find one 
01530                     continue; 
01531 
01532                 // get the colour attribute from it
01533                 ColourFillAttribute *pColAttr = (ColourFillAttribute *)pAppliedAttr->GetAttributeValue();
01534                 if (!pColAttr)
01535                     continue;
01536 
01537                 // get the actual colour
01538                 DocColour *Col = pColAttr->GetStartColour();
01539                 if (!Col)
01540                     continue;
01541                 
01542                 // check if the line colour for that node is set to 'no colour'
01543                 if (Col->IsTransparent())
01544                 {
01545                     // we have to replace the applied attribute with black colour
01546 
01547                     // create a new stroke colour attribute, 
01548                     AttrStrokeColour *pAttr = new AttrStrokeColour();
01549                     if (pAttr == NULL)
01550                         continue;
01551 
01552                     // and set it with black colour
01553                     DocColour ColourToApply(COLOUR_BLACK);
01554                     ((AttrStrokeColour *)pAttr)->SetStartColour(&ColourToApply);
01555 
01556                     // apply the new line colour to the node
01557                     if (!DoApply(pOp, OldNode, pAttr, bMutate, FALSE, FALSE, bOptimise, &bAttrWasRequired, &bCanDiscardUndo))
01558                         continue; 
01559 
01560                     // remove the attribute
01561                     delete pAttr;
01562                     pAttr = NULL;
01563                 }
01564             }
01565 
01566             ContinueSlowJob();
01567         }
01568 
01569         // Nasty textism.  EOL nodes can now have attributes, but the last EOL cannot be selected by
01570         // the user, causing the text tool to show <multiple> when it shouldn't really.
01571         // So if the last node in the range is the node before the last EOL in a text story then we
01572         // apply the attribute to the EOL too.
01573         Node* pLastSelected = pLevel->FindLast();
01574         if (pLastSelected!=NULL && pLastSelected->IsABaseTextClass())
01575         {
01576             // Alternative approach to fix other EOLNode problems that have appeared. (Bugs 5371 & 5372)
01577             // If the AbstractTextChar following the last selected node is an EOLNode then apply to it too.
01578             if (pLastSelected->IsAVisibleTextNode())
01579             {
01580                 AbstractTextChar* pNextATChar = (AbstractTextChar*)pLastSelected->FindNext(CC_RUNTIME_CLASS(AbstractTextChar));
01581                 if (pNextATChar!=NULL && pNextATChar->IsAnEOLNode())
01582                 {
01583                     if (!DoApply(pOp, pNextATChar, Attrib, bMutate, FALSE, TRUE, bOptimise, &bAttrWasRequired, &bCanDiscardUndo))
01584                         return FALSE; 
01585                 }
01586             }
01587 
01588 //          TextStory* pStory = ((BaseTextClass*)pLastSelected)->FindParentStory();
01589 //          if (pStory!=NULL)
01590 //          {
01591 //              // Get a pointer to the last EOL in the story
01592 //              VisibleTextNode* pLastEOL = pStory->FindLastVTN();
01593 //              ERROR3IF(!pLastEOL->IsAnEOLNode(), "Last node in story was not EOL");
01594 //
01595 //              // is the EOL next to the last node in the selected?
01596 //              if (pLastEOL!=NULL && pLastEOL==pLastSelected->FindNext(CC_RUNTIME_CLASS(AbstractTextChar)))
01597 //              {
01598 //                  if (!DoApply(pLastEOL, Attrib, Mutate, FALSE))
01599 //                      return FALSE; 
01600 //              }
01601 //          }
01602         }
01603 
01604         // If all nodes report DiscardsAttributeChildren() = TRUE
01605         // Then we can abandon the entire Op once it's finished
01606         if (bCanDiscardUndo)
01607             pOp->SucceedAndDiscard();
01608 
01609     }
01610     return TRUE;
01611 }

BOOL OpApplyAttrib::DoInvalidateRegions (  Range *  NodeRange,
NodeAttribute *  Attrib,
BOOL  Mutate,
NodeAttribute *  OtherAttr,
BOOL  OtherMutate
)  [protected]
 

Invalidates the regions of every node in the range.

Parameters:
NodeRange,: The range of nodes to invalidate [INPUTS] Attrib: The attribute to be applied Mutate:
Returns:
TRUE if region invalidated ok.

Errors: -

See also:
OpApplyAttrib::InvalidateNodeRegion

Definition at line 1159 of file attrappl.cpp.

01164 {
01165     // Include the blobs, if the attribute will change the parents bounds.
01166     BOOL IncludeBlobs = ((Attrib->EffectsParentBounds()) || (OtherAttr && (OtherAttr->EffectsParentBounds())));
01167 
01168     if (((Mutate && !Attrib->IsAValueChange()) ||
01169          Attrib->GetRuntimeClass() == CC_RUNTIME_CLASS(AttrBitmapDpiChange)) ||
01170          (OtherAttr && ((OtherMutate && !OtherAttr->IsAValueChange()) ||
01171          (OtherAttr->GetRuntimeClass() == CC_RUNTIME_CLASS(AttrBitmapDpiChange))) )
01172         )
01173     {
01174         // Check for special cases of, either a mutate from one fill type to another,
01175         // or a dpi change.  Both of these can change the blob bounds.
01176         IncludeBlobs = TRUE;
01177     }
01178 
01179     // Invalidate the bounds of the node, including the blobs if necessary.
01180     if (!DoInvalidateNodesRegions(*NodeRange, IncludeBlobs, FALSE, FALSE, FALSE))   // NOTE! We do not release cached info!
01181                                                                                     // Must be used in conjunction with ApplyToSelection
01182     {
01183         // Summit went wrong.
01184         return FALSE;
01185     }
01186 
01187     return TRUE;    // All ok
01188 }

static NodeRenderableInk* OpApplyAttrib::FindCompoundNodeWhichRequiresAttribute (  NodeRenderableInk *  pStartNode,
CCRuntimeClass *  pAttribClass
)  [static]
 

NodeAttribute* OpApplyAttrib::GetAttributeToApply (   )  [inline]
 

Definition at line 140 of file attrappl.h.

00140 { return m_pAttr; }

CCRuntimeClass * OpApplyAttrib::GetValueChangeType (   )  [virtual]
 

Definition at line 3377 of file attrappl.cpp.

03378 {
03379     return ValueChangeType;
03380 }

BOOL OpApplyAttrib::IsMergeableApplyOp (   )  [virtual]
 

Definition at line 3382 of file attrappl.cpp.

03383 {
03384     return MergeRepeats;
03385 }

BOOL OpApplyAttrib::KeepExistingCharacteristics (  AttrFillGeometry *  OldAttr,
AttrFillGeometry *  NewAttr
)  [static]
 

Retains the previous fill charateristics when applying a new fill.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/6/95
Parameters:
- [INPUTS]
Returns:
TRUE if all ok.

Errors: -

See also:
-

Definition at line 1031 of file attrappl.cpp.

01033 {
01034     NewAttr->SetStartTransp(OldAttr->GetStartTransp());
01035     NewAttr->SetEndTransp(OldAttr->GetEndTransp());
01036 
01037     NewAttr->SetTranspType(OldAttr->GetTranspType());
01038 
01039     if (OldAttr->IsAFlatFill())
01040     {
01041         if (OldAttr->FindParent()->IsNodeDocument())
01042         {
01043             // If the applied attr is the default fill at the top of the tree,
01044             // then we need to 'bodge' it to be black.
01045             DocColour DefFillCol;
01046             AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
01047                                                 _R(IDS_BLACKNAME), &DefFillCol);
01048             NewAttr->SetEndColour(&DefFillCol);
01049         }
01050         else
01051             NewAttr->SetEndColour(OldAttr->GetStartColour());
01052     }
01053     else
01054     {
01055         NewAttr->SetStartColour(OldAttr->GetStartColour());
01056         NewAttr->SetEndColour(OldAttr->GetEndColour());
01057     }
01058 
01059     NewAttr->SetTesselation(OldAttr->GetTesselation());
01060     NewAttr->AttachBitmap(OldAttr->GetBitmap());
01061 
01062     if (OldAttr->IsAFractalFill())
01063     {
01064         NewAttr->SetSeed(OldAttr->GetSeed());
01065         NewAttr->SetGraininess(OldAttr->GetGraininess());
01066         NewAttr->SetGravity(OldAttr->GetGravity());
01067         NewAttr->SetSquash(OldAttr->GetSquash());
01068         NewAttr->SetTileable(OldAttr->GetTileable());
01069         NewAttr->SetFractalDPI(AttrFillGeometry::FractalDPI);
01070         NewAttr->RecalcFractal();
01071     }
01072 
01073     return TRUE;
01074 }

virtual void OpApplyAttrib::SetMergeable (  BOOL  bNewState  )  [inline, virtual]
 

Definition at line 133 of file attrappl.h.

00133 {MergeRepeats = bNewState;}


Member Data Documentation

NodeAttribute* OpApplyAttrib::m_pAttr [protected]
 

Definition at line 156 of file attrappl.h.

BOOL OpApplyAttrib::MergeRepeats [protected]
 

Definition at line 153 of file attrappl.h.

CCRuntimeClass* OpApplyAttrib::ValueChangeType [protected]
 

Definition at line 152 of file attrappl.h.


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