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 CCRuntimeClassGetValueChangeType ()
virtual BOOL IsMergeableApplyOp ()
virtual void SetMergeable (BOOL bNewState)
NodeAttributeGetAttributeToApply ()

Static Public Member Functions

static NodeRenderableInkFindCompoundNodeWhichRequiresAttribute (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

CCRuntimeClassValueChangeType
BOOL MergeRepeats
NodeAttributem_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