00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 #include "camtypes.h"
00101
00102 #include "attrappl.h"
00103
00104
00105
00106 #include "lineattr.h"
00107 #include "linwthop.h"
00108
00109 #include "nodedoc.h"
00110
00111
00112
00113
00114 #include "toollist.h"
00115
00116 #include "ndoptmz.h"
00117 #include "objchge.h"
00118
00119 #include "progress.h"
00120 #include "fillndge.h"
00121
00122 #include "nodetxtl.h"
00123
00124 #include "colormgr.h"
00125
00126 #include "nodecont.h"
00127 #include "lineattr.h"
00128 #include "opdrbrsh.h"
00129 #include "brshattr.h"
00130 #include "effects_stack.h"
00131 #include "ophist.h"
00132
00133 #include "nodetext.h"
00134 #include "ppbrush.h"
00135
00136 CC_IMPLEMENT_DYNCREATE(OpApplyAttrib, SelOperation)
00137 CC_IMPLEMENT_DYNCREATE(OpApplyAttribToSelected, OpApplyAttrib)
00138 CC_IMPLEMENT_DYNCREATE(OpApplyAttrInteractive, OpApplyAttrib)
00139 CC_IMPLEMENT_DYNCREATE(OpApplyAttribsToSelected, OpApplyAttrib)
00140 CC_IMPLEMENT_DYNCREATE(OpRepeatApplyAttribToSelected, Operation)
00141 CC_IMPLEMENT_DYNCREATE(OpApplyAttribToNode, OpApplyAttrib)
00142 CC_IMPLEMENT_DYNCREATE(OpReplaceAttributes, SelOperation)
00143 CC_IMPLEMENT_DYNCREATE(ReplaceAttributesParam, OpParam)
00144 CC_IMPLEMENT_MEMDUMP(ApplyAttribsToSelectedParam, OpParam)
00145
00146
00147 #define new CAM_DEBUG_NEW
00148
00149
00150
00151 FillBlobSelectionState OpRepeatApplyAttribToSelected::FillBlobState;
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 NodeRenderableInk * OpApplyAttrib::FindCompoundNodeWhichRequiresAttribute(
00173 NodeRenderableInk * pStartNode,
00174 CCRuntimeClass * pClass)
00175 {
00176 NodeRenderableInk * pNodeToApply = pStartNode;
00177
00178 if (!pStartNode->NeedsParent(NULL))
00179 {
00180 Node * pParent = pNodeToApply->FindParent();
00181
00182 while (pParent)
00183 {
00184 if (pParent->IsCompoundClass())
00185 {
00186 if (((NodeCompound*)pParent)->PromoteAttributeApplicationToMe(pClass))
00187 {
00188 pNodeToApply = (NodeRenderableInk *)pParent;
00189 }
00190 }
00191
00192
00193 pParent = pParent->FindParent();
00194 }
00195 }
00196
00197 return pNodeToApply;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 BOOL SelOperation::DoApply(Node* CurrentNode,
00230 NodeAttribute* Attrib,
00231 BOOL Mutate,
00232 BOOL InvalidateRegion,
00233 BOOL KeepExistingCols,
00234 BOOL* pbAttribWasRequired,
00235 BOOL* pbCanDiscardUndo
00236 )
00237 {
00238 return SelOperation::DoApply(this, CurrentNode, Attrib, Mutate, InvalidateRegion, KeepExistingCols, TRUE, pbAttribWasRequired, pbCanDiscardUndo);
00239 }
00240
00241 BOOL SelOperation::DoApply( SelOperation* pOp,
00242 Node* CurrentNode,
00243 NodeAttribute* Attrib,
00244 BOOL Mutate,
00245 BOOL InvalidateRegion,
00246 BOOL KeepExistingCols,
00247 BOOL bOptimise,
00248 BOOL* pbAttribWasRequired,
00249 BOOL* pbCanDiscardUndo
00250 )
00251 {
00252 BOOL AttributeExists = FALSE;
00253
00254 CCRuntimeClass* AttrType = Attrib->GetAttributeType();
00255
00256 ERROR3IF(!CurrentNode->IsAnObject(), "Trying to apply an attribute to a non-NodeRenderableInk");
00257
00258
00259 ERROR3IF(!(Attrib->CanBeAppliedToObject()), "Trying to apply an illegal attribute to the object");
00260
00261 if (!(Attrib->CanBeAppliedToObject()))
00262 return TRUE;
00263
00264 Node* OriginalCurrentNode = CurrentNode;
00265
00266 if (CurrentNode->IsAnObject())
00267 {
00268
00269
00270 CurrentNode = ((NodeRenderableInk*)CurrentNode)->GetObjectToApplyTo(Attrib->GetAttributeType());
00271 if (!CurrentNode)
00272 {
00273 ERROR3("OpApplyAttrib::DoApply, Unable to find object to apply to");
00274 return TRUE;
00275 }
00276 }
00277
00278
00279 BOOL bEffectRootOnly = (CurrentNode->IsAnObject() && ((NodeRenderableInk*)CurrentNode)->IsValidEffectAttr(Attrib));
00280
00281
00282
00283 if (pbCanDiscardUndo)
00284 *pbCanDiscardUndo = *pbCanDiscardUndo && CurrentNode->DiscardsAttributeChildren();
00285
00286
00287
00288
00289
00290 if (bEffectRootOnly && AttrType == CC_RUNTIME_CLASS(AttrStrokeTransp))
00291 return TRUE;
00292
00293
00294
00295 BOOL AddEvenIfMultiple = FALSE;
00296
00297
00298 if ((((NodeRenderableInk*)CurrentNode)->RequiresAttrib(Attrib)))
00299 {
00300
00301 if (pbAttribWasRequired)
00302 *pbAttribWasRequired = TRUE;
00303
00304 if (CurrentNode != OriginalCurrentNode)
00305 {
00306
00307
00308
00309
00310 ObjChangeFlags cFlags;
00311 cFlags.Attribute = TRUE;
00312 ObjChangeParam ObjChange(OBJCHANGE_STARTING, cFlags, NULL, pOp);
00313
00314 if (!CurrentNode->AllowOp(&ObjChange))
00315 {
00316
00317 ERROR3("Doing op when no nodes will allow it");
00318 }
00319 }
00320
00321
00322
00323
00324 Node* n = CurrentNode->FindFirstChild();
00325 Node* pLastBoundedNode = NULL;
00326 if (bEffectRootOnly)
00327 {
00328 pLastBoundedNode = CurrentNode->FindLastChild(CC_RUNTIME_CLASS(NodeRenderableBounded));
00329 ERROR3IF(pLastBoundedNode==NULL, "Attempt to apply effect attr to node with no children");
00330
00331 if (pLastBoundedNode) n = pLastBoundedNode->FindNext();
00332 }
00333
00334 while (n && (n->IsOrHidesAnAttribute()))
00335 {
00336
00337
00338 if (n->IsAnAttribute())
00339 {
00340 NodeAttribute* pNdAttr = (NodeAttribute*)n;
00341
00342 if( pNdAttr->GetAttributeType() == AttrType)
00343 {
00344
00345
00346
00347
00348 BOOL LookForMultiple = FALSE;
00349
00350 if (Attrib->CanBeMultiplyApplied())
00351 {
00352
00353
00354 if (Attrib->GetAttributeClassID() == pNdAttr->GetAttributeClassID())
00355 {
00356 LookForMultiple = FALSE;
00357 AddEvenIfMultiple = FALSE;
00358 }
00359 else
00360 {
00361
00362
00363 LookForMultiple = TRUE;
00364 AddEvenIfMultiple = TRUE;
00365 }
00366 }
00367
00368
00369
00370
00371
00372 if (IS_SAME_CLASS(pNdAttr, Attrib))
00373 {
00374
00375 if ((*pNdAttr)==(*Attrib))
00376 return TRUE;
00377
00378 if (Attrib->IsABrush())
00379 ((AttrBrushType*)Attrib)->OnReplaceAttribute((AttrBrushType*)pNdAttr);
00380 }
00381
00382
00383 if (!LookForMultiple)
00384 {
00385 AttributeExists = TRUE;
00386 break;
00387 }
00388 }
00389 }
00390 n = n->FindNext();
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 if (CurrentNode->IsCompound() && !Attrib->CanBeMultiplyApplied() && !bEffectRootOnly)
00403 {
00404
00405
00406
00407
00408 if (pOp && !pOp->DoRemoveAttrTypeFromSubtree(CurrentNode, Attrib->GetAttributeType(), n))
00409 {
00410 pOp->FailAndExecute();
00411 return FALSE;
00412 }
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 NodeAttribute* AttribClone = NULL;
00428 if ( !AddEvenIfMultiple && n && n->IsAnAttribute())
00429 {
00430
00431 NodeAttribute* pAttr = (NodeAttribute*)n;
00432
00433 if (Mutate)
00434 {
00435
00436 AttribClone = ((AttrFillGeometry*)n)->Mutate((AttrFillGeometry*)Attrib, bOptimise);
00437 }
00438 else
00439 {
00440
00441
00442
00443 if (pOp)
00444 ALLOC_WITH_FAIL(AttribClone ,((NodeAttribute*)Attrib->SimpleCopy()), pOp)
00445 else
00446 AttribClone = (NodeAttribute*)Attrib->SimpleCopy();
00447 if (AttribClone == NULL)
00448 return FALSE;
00449
00450
00451
00452
00453
00454 if ( KeepExistingCols && ((NodeAttribute*)n)->IsAFillAttr() )
00455 {
00456 AttrFillGeometry* NodeReplaced = (AttrFillGeometry*)n;
00457
00458
00459 if (!OpApplyAttrib::KeepExistingCharacteristics(NodeReplaced, (AttrFillGeometry*)AttribClone))
00460 return FALSE;
00461 }
00462
00463 if ( Attrib->IsATranspFill() && Attrib->IsAFlatFill())
00464 {
00465 ((AttrFillGeometry*)n)->RenderFillBlobs();
00466 }
00467 }
00468
00469
00470
00471
00472 if (AttribClone == NULL)
00473 return TRUE;
00474
00475
00476
00477
00478
00479
00480
00481
00482 ReleaseCachedForAttrApply((NodeRenderableBounded*)CurrentNode, bEffectRootOnly);
00483
00484
00485 if (InvalidateRegion)
00486 {
00487
00488 if (!InvalidateNodeRegion(pOp, (NodeRenderableBounded*)CurrentNode, Attrib, Mutate))
00489 return FALSE;
00490 }
00491
00492
00493
00494
00495
00496
00497 if (pOp && !CurrentNode->DiscardsAttributeChildren())
00498 {
00499
00500
00501
00502
00503
00504
00505 if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpApplyAttrInteractive)))
00506 {
00507 ApplyAction* pUndoApply;
00508
00509 if ( ApplyAction::Init(pOp,
00510 pOp->GetUndoActionList(),
00511 CurrentNode,
00512 pAttr,
00513 TRUE,
00514
00515 (Action**)(&pUndoApply))
00516 == AC_FAIL)
00517 {
00518 return FALSE;
00519 }
00520 pAttr->CascadeDelete();
00521 delete pAttr;
00522 pAttr = NULL;
00523 }
00524 else
00525 {
00526 if (!pOp->DoHideNode(n, TRUE))
00527 return FALSE;
00528 }
00529 }
00530 else
00531 {
00532 pAttr->CascadeDelete();
00533 delete pAttr;
00534 pAttr = NULL;
00535 }
00536
00537 }
00538 else
00539 {
00540
00541
00542 NodeAttribute* TempAttr = NULL;
00543
00544 BOOL FoundAttr = ((NodeRenderableInk*)CurrentNode)->
00545 FindAppliedAttribute(Attrib->GetAttributeType(), &TempAttr);
00546
00547 if (!FoundAttr || TempAttr == NULL)
00548 return FALSE;
00549
00550 if (Mutate)
00551 {
00552 AttribClone = ((AttrFillGeometry*)TempAttr)->Mutate((AttrFillGeometry*)Attrib, bOptimise);
00553 }
00554 else
00555 {
00556
00557 if (pOp)
00558 ALLOC_WITH_FAIL(AttribClone ,((NodeAttribute*)Attrib->SimpleCopy()), pOp)
00559 else
00560 AttribClone = (NodeAttribute*)Attrib->SimpleCopy();
00561
00562 if ( KeepExistingCols && (TempAttr->IsAFillAttr()) )
00563 {
00564 AttrFillGeometry* NodeReplaced = (AttrFillGeometry*)TempAttr;
00565
00566
00567 if (!OpApplyAttrib::KeepExistingCharacteristics(NodeReplaced, (AttrFillGeometry*)AttribClone))
00568 return FALSE;
00569 }
00570
00571 if (Attrib->IsATranspFill() && Attrib->IsAFlatFill())
00572 {
00573
00574
00575 ((AttrFillGeometry*)TempAttr)->RenderFillBlobs();
00576 }
00577 }
00578
00579 if (AttribClone)
00580 {
00581 ReleaseCachedForAttrApply((NodeRenderableBounded*)CurrentNode, bEffectRootOnly);
00582
00583 if (InvalidateRegion)
00584 {
00585
00586 if (!InvalidateNodeRegion(pOp, (NodeRenderableBounded*)CurrentNode, Attrib, Mutate))
00587 return FALSE;
00588 }
00589 }
00590 }
00591
00592
00593
00594 if (AttribClone && AttribClone->ShouldBeOptimized() && !bEffectRootOnly && bOptimise)
00595 {
00596 NodeAttribute* pAppliedAttr;
00597 if (((NodeRenderableInk*)CurrentNode)->FindAppliedAttribute(AttribClone->GetAttributeType(),
00598 &pAppliedAttr))
00599 {
00600
00601 if ((IS_SAME_CLASS(AttribClone, pAppliedAttr)))
00602 {
00603 if ((*AttribClone)==(*pAppliedAttr))
00604 {
00605 AttribClone->CascadeDelete();
00606
00607
00608
00609
00610 if (pAppliedAttr->EffectsParentBounds())
00611 {
00612 ((NodeRenderableBounded*)CurrentNode)->InvalidateBoundingRect(TRUE);
00613 }
00614
00615 delete AttribClone;
00616 AttribClone = NULL;
00617 }
00618 }
00619 }
00620 }
00621
00622
00623
00624
00625 if (AttribClone && bEffectRootOnly && AttribClone->HasEquivalentDefaultValue() && bOptimise)
00626 {
00627
00628 AttribClone->CascadeDelete();
00629 delete AttribClone;
00630 AttribClone = NULL;
00631 }
00632
00633 if (AttribClone)
00634 {
00635
00636 if (bEffectRootOnly)
00637 AttribClone->AttachNode(pLastBoundedNode, NEXT);
00638 else
00639 AttribClone->AttachNode(CurrentNode, FIRSTCHILD);
00640
00641 AttributeManager::pLastNodeAppliedTo = (NodeRenderableInk*)CurrentNode;
00642
00643
00644
00645 if (AttribClone->IsAFillAttr())
00646 {
00647 ((AttrFillGeometry*)AttribClone)->AttributeChanged();
00648 }
00649
00650 if (pOp && !CurrentNode->DiscardsAttributeChildren())
00651 {
00652
00653
00654
00655
00656
00657
00658 if (pOp->IsKindOf(CC_RUNTIME_CLASS(OpApplyAttrInteractive)))
00659 {
00660 UnApplyAction* pUndoApply;
00661
00662 if ( UnApplyAction::Init(pOp,
00663 pOp->GetUndoActionList(),
00664 CurrentNode,
00665 AttribClone,
00666 TRUE,
00667
00668 (Action**)(&pUndoApply))
00669 == AC_FAIL)
00670 {
00671 AttribClone->CascadeDelete();
00672 delete (AttribClone);
00673 return FALSE;
00674 }
00675 }
00676 else
00677 {
00678 HideNodeAction* UndoHideNodeAction;
00679
00680 if ( HideNodeAction::Init(pOp,
00681 pOp->GetUndoActionList(),
00682 AttribClone,
00683 TRUE,
00684
00685 (Action**)(&UndoHideNodeAction))
00686 == AC_FAIL)
00687 {
00688 AttribClone->CascadeDelete();
00689 delete (AttribClone);
00690 return FALSE;
00691 }
00692 }
00693 }
00694
00695 }
00696
00697 ReleaseCachedForAttrApply((NodeRenderableBounded*)CurrentNode, bEffectRootOnly);
00698
00699 if (InvalidateRegion)
00700 {
00701
00702 if (!InvalidateNodeRegion(pOp, (NodeRenderableBounded*)CurrentNode, Attrib, Mutate))
00703 return FALSE;
00704 }
00705 }
00706
00707
00708 if (pOp)
00709 {
00710 if (!pOp->ApplyAttributeToBrush(CurrentNode, Attrib))
00711 return FALSE;
00712 }
00713 return TRUE;
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737 BOOL SelOperation::ReleaseCachedForAttrApply(NodeRenderableBounded* pNode, BOOL bEffectRootOnly)
00738 {
00739 if (bEffectRootOnly)
00740 pNode->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
00741 else
00742 pNode->ReleaseCached();
00743
00744 return TRUE;
00745 }
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 BOOL SelOperation::ApplyAttributeToBrush(Node* pCurrentNode, NodeAttribute* pAttr)
00771 {
00772 ERROR2IF(pCurrentNode == NULL, FALSE, "Current node is NULL");
00773 ERROR2IF(pAttr == NULL, FALSE, "Attribute is NULL");
00774
00775
00776 if (!pAttr->IsKindOf(CC_RUNTIME_CLASS(AttrStrokeColourChange)) && !pAttr->IsATranspFill()
00777 && !pAttr->IsKindOf(CC_RUNTIME_CLASS(AttrLineWidth)) && !pAttr->IsABrush())
00778 return TRUE;
00779
00780
00781 AttrBrushType* pAttrBrush = NULL;
00782
00783 ((NodeRenderableInk*)pCurrentNode)->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrBrushType),
00784 (NodeAttribute**)&pAttrBrush);
00785
00786
00787 if (pAttr->IsABrush())
00788 {
00789 AttrBrushType* pNewAttrBrush = (AttrBrushType*)pAttr;
00790 return ApplyBrushAttr(pCurrentNode, pNewAttrBrush);
00791 }
00792
00793
00794
00795 if (pAttrBrush == NULL || pAttrBrush->GetBrushHandle() == BrushHandle_NoBrush)
00796 return TRUE;
00797
00798
00799 if (pAttr->IsKindOf(CC_RUNTIME_CLASS(AttrStrokeColourChange)))
00800 {
00801
00802 AttrStrokeColourChange* pStrokeCol = static_cast<AttrStrokeColourChange*>(pAttr);
00803 DocColour* pCol = pStrokeCol->GetStartColour();
00804
00805 if (pCol->IsTransparent())
00806 return TRUE;
00807
00808 return ApplyStrokeColourToBrush(pAttrBrush, (NodeRenderableInk*)pCurrentNode);
00809 }
00810
00811
00812
00813
00814 if (pAttr->IsKindOf(CC_RUNTIME_CLASS(AttrLineWidth)))
00815 return ApplyLineWidthToBrush(pAttrBrush, (NodeRenderableInk*)pCurrentNode, pAttr);
00816
00817
00818 pAttrBrush->ClearCachedRect();
00819
00820
00821 return TRUE;
00822 }
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 BOOL SelOperation::ApplyTransparencyToBrush(AttrBrushType* pAttrBrush, NodeRenderableInk* pBrushedNode)
00839 {
00840 ERROR2IF(pAttrBrush == NULL, FALSE, "Attribute pointer is NULL in OnApplyAttrib::ApplyTransparencyToBrush");
00841 ERROR2IF(pBrushedNode == NULL, FALSE, "Attribute pointer is NULL in OnApplyAttrib::ApplyTransparencyToBrush");
00842
00843
00844 ChangeBrushOpParam Param;
00845
00846 Param.ChangeType = CHANGEBRUSH_USELOCALTRANSP;
00847 Param.m_bNewUseLocalTransp = TRUE;
00848 ChangeBrushAction* pAction = NULL;
00849
00850 if (ChangeBrushAction::Init(this, &UndoActions, pBrushedNode, &Param, &pAction) == AC_FAIL)
00851 return FALSE;
00852
00853 return TRUE;
00854 }
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 BOOL SelOperation::ApplyStrokeColourToBrush(AttrBrushType* pAttrBrush, NodeRenderableInk* pBrushedNode)
00872 {
00873 ERROR2IF(pAttrBrush == NULL, FALSE, "Attribute pointer is NULL in OnApplyAttrib::ApplyStrokeColourToBrush");
00874 ERROR2IF(pBrushedNode == NULL, FALSE, "Attribute pointer is NULL in OnApplyAttrib::ApplyStrokeColourToBrush");
00875
00876
00877
00878
00879
00880 PathProcessorBrush *pPPB = pAttrBrush->GetPathProcessor();
00881 if (pPPB == NULL)
00882 return TRUE;
00883
00884 if (pPPB->GetUseLocalFillColour() || !pPPB->GetUseNamedColours())
00885 return TRUE;
00886
00887
00888 ChangeBrushOpParam Param;
00889
00890 Param.ChangeType = CHANGEBRUSH_USENAMEDCOL;
00891 Param.m_bNewUseNamed = FALSE;
00892 ChangeBrushAction* pAction = NULL;
00893
00894 if (ChangeBrushAction::Init(this, &UndoActions, pBrushedNode,
00895 &Param, &pAction) == AC_FAIL)
00896 return FALSE;
00897
00898 return TRUE;
00899 }
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921 BOOL SelOperation::ApplyLineWidthToBrush(AttrBrushType* pAttrBrush, NodeRenderableInk* pBrushedNode,
00922 NodeAttribute* pAttr)
00923 {
00924 ERROR2IF(pAttrBrush == NULL, FALSE, "Attribute pointer is NULL in OnApplyAttrib::ApplyLineWidthToBrush");
00925 ERROR2IF(pBrushedNode == NULL, FALSE, "Node pointer is NULL in OnApplyAttrib::ApplyLineWidthToBrush");
00926 ERROR2IF(pAttr == NULL, FALSE, "Attribute pointer is NULL in OnApplyAttrib::ApplyLineWidthToBrush");
00927
00928
00929 PathProcessorBrush* pPPB = pAttrBrush->GetPathProcessor();
00930 if (pPPB != NULL)
00931 {
00932
00933 AttrLineWidth* pLineWidth = (AttrLineWidth*)pAttr;
00934 BOOL UsesPressure = pAttrBrush->GetPressureCache() != NULL;
00935 pPPB->ScaleToValue(pLineWidth->Value.LineWidth, !UsesPressure);
00936 pPPB->AdjustSpacingForClosedPath(pBrushedNode);
00937 }
00938
00939 return TRUE;
00940 }
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 BOOL SelOperation::ApplyBrushAttr(Node* pCurrentNode, AttrBrushType* pAttrBrush)
00962 {
00963 ERROR2IF(pCurrentNode == NULL || pAttrBrush == NULL, FALSE, "Null input pointers to OpApplyAttrib::ApplyBrushAttr");
00964 ERROR2IF(!pCurrentNode->IsAnObject(), FALSE, "Input node is not an ink node in OpApplyAttrib::ApplyBrushAttr");
00965
00966
00967 if (pCurrentNode->IsCompound())
00968 return TRUE;
00969
00970 AttrLineWidth* pCurrentLineWidth = NULL;
00971 ((NodeRenderableInk*)pCurrentNode)->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrLineWidth), (NodeAttribute**)&pCurrentLineWidth);
00972
00973 if (pCurrentLineWidth != NULL)
00974 {
00975
00976 AttrLineWidth* pDefault = (AttrLineWidth*)(AttributeManager::GetDefaultAttribute(ATTR_LINEWIDTH));
00977 if (pDefault == NULL)
00978 {
00979 ERROR3("Unable to get default line width, theres no way this can happen Jim!");
00980
00981 }
00982 else
00983 {
00984
00985 if (pCurrentLineWidth->Value.LineWidth != pDefault->Value.LineWidth-1)
00986 {
00987 delete pDefault;
00988 PathProcessorBrush* pPPB = pAttrBrush->GetPathProcessor();
00989 if (pPPB)
00990 {
00991 BOOL UsesPressure = pAttrBrush->GetPressureCache() != NULL;
00992 pPPB->ScaleToValue(pCurrentLineWidth->Value.LineWidth, !UsesPressure);
00993 pPPB->AdjustSpacingForClosedPath((NodeRenderableInk*)pCurrentNode);
00994 }
00995
00996 return TRUE;
00997 }
00998 delete pDefault;
00999 }
01000 }
01001
01002
01003
01004 MILLIPOINT LineWidth = pAttrBrush->GetDefaultLineWidth(TRUE);
01005
01006
01007 AttrLineWidth NewLineWidth;
01008
01009 NewLineWidth.Value.LineWidth = LineWidth;
01010
01011
01012 return DoApply(pCurrentNode, &NewLineWidth, FALSE, FALSE);
01013
01014 }
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031 BOOL OpApplyAttrib::KeepExistingCharacteristics(AttrFillGeometry* OldAttr,
01032 AttrFillGeometry* NewAttr)
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
01044
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 }
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092 BOOL SelOperation::InvalidateNodeRegion( SelOperation* pOp,
01093 NodeRenderableBounded* CurrentNode,
01094 NodeAttribute* Attrib,
01095 BOOL Mutate)
01096 {
01097
01098 BOOL IncludeBlobs = Attrib->EffectsParentBounds();
01099
01100 if ( (Mutate && !Attrib->IsAValueChange()) ||
01101 Attrib->GetRuntimeClass() == CC_RUNTIME_CLASS(AttrBitmapDpiChange) )
01102 {
01103
01104
01105 IncludeBlobs = TRUE;
01106 }
01107
01108
01109 if (pOp)
01110 {
01111 if (!pOp->DoInvalidateNodeRegion(CurrentNode, IncludeBlobs, FALSE, FALSE, FALSE))
01112
01113 {
01114
01115 return FALSE;
01116 }
01117 }
01118 else
01119 {
01120 BaseDocument* pBaseDoc = CurrentNode->FindOwnerDoc();
01121 if (pBaseDoc && pBaseDoc->IsKindOf(CC_RUNTIME_CLASS(Document)))
01122 {
01123 Document* pDoc = (Document*)pBaseDoc;
01124 Spread* pSpread = (Spread*)CurrentNode->FindParent(CC_RUNTIME_CLASS(Spread));
01125 DocRect TempRect;
01126 TempRect = (IncludeBlobs ?
01127 (CurrentNode->GetUnionBlobBoundingRect()):
01128 (CurrentNode->GetBoundingRect())
01129 );
01130 TempRect = TempRect.Union(CurrentNode->GetEffectStackBounds());
01131 pDoc->ForceRedraw(pSpread, TempRect, TRUE, CurrentNode, FALSE);
01132 }
01133 }
01134
01135 return TRUE;
01136 }
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159 BOOL OpApplyAttrib::DoInvalidateRegions(Range* NodeRange,
01160 NodeAttribute* Attrib,
01161 BOOL Mutate,
01162 NodeAttribute* OtherAttr,
01163 BOOL OtherMutate)
01164 {
01165
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
01175
01176 IncludeBlobs = TRUE;
01177 }
01178
01179
01180 if (!DoInvalidateNodesRegions(*NodeRange, IncludeBlobs, FALSE, FALSE, FALSE))
01181
01182 {
01183
01184 return FALSE;
01185 }
01186
01187 return TRUE;
01188 }
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207 OpApplyAttribToSelected::OpApplyAttribToSelected(): OpApplyAttrib()
01208 {
01209 ValueChangeType = NULL;
01210 MergeRepeats = FALSE;
01211 m_pAttr = NULL;
01212 }
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232 void OpApplyAttribToSelected::DoWithParam(OpDescriptor* OpDesc, OpParam* pOpParam)
01233 {
01234 #ifndef STANDALONE
01235
01236 AttrTypeSet AttrTypes;
01237
01238 Range SelRng(*(GetApplication()->FindSelection()));
01239
01240
01241 ERROR3IF(pOpParam == NULL, "The OpApplyAttribToSelected operation requires an attribute parameter");
01242
01243 BeginSlowJob();
01244 AttributeManager::pLastNodeAppliedTo = NULL;
01245
01246
01247 NodeAttribute* Attrib = (NodeAttribute*)(void *)pOpParam->Param1;
01248 m_pAttr = Attrib;
01249
01250
01251 if (Attrib)
01252 {
01253 ValueChangeType = Attrib->GetRuntimeClass();
01254 }
01255
01256 NodeAttribute* pAppliedAttrib;
01257
01258 BOOL Mutate = FALSE;
01259 BOOL RedrawBlobs = FALSE;
01260 NodeAttribute* OldAttr = NULL;
01261
01262 if (Attrib == NULL)
01263 {
01264
01265 Attrib = (NodeAttribute*)(void *)pOpParam->Param2;
01266 m_pAttr = Attrib;
01267
01268
01269 if (Attrib)
01270 {
01271 ValueChangeType = Attrib->GetRuntimeClass();
01272 }
01273
01274 Mutate = TRUE;
01275
01276 ValueChangeType = Attrib->GetRuntimeClass();
01277
01278 if( ValueChangeType == CC_RUNTIME_CLASS(AttrTranspChange)
01279 || ValueChangeType == CC_RUNTIME_CLASS(FillGeometryNudger)
01280 )
01281 {
01282 MergeRepeats = TRUE;
01283 }
01284 }
01285 else
01286 {
01287
01288
01289 OldAttr = (NodeAttribute*)(void *)pOpParam->Param2;
01290 RedrawBlobs = Attrib->EffectsParentBounds();
01291 }
01292
01293 SelRange* Sel;
01294 ObjChangeFlags cFlags;
01295 cFlags.Attribute = TRUE;
01296 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
01297
01298 Sel = GetApplication()->FindSelection();
01299
01300 if (!Sel->AllowOp(&ObjChange))
01301 {
01302 FailAndExecute();
01303 goto EndOperation;
01304 }
01305
01306
01307
01308 UndoAttribStrID = Attrib->GetAttrNameID();
01309
01310 if (!DoStartSelOp(RedrawBlobs, RedrawBlobs, TRUE,TRUE))
01311 {
01312 goto EndOperation;
01313 }
01314
01315 NodeAttribute* OtherAttrib;
01316
01317
01318
01319
01320 BOOL IsMutate;
01321 OtherAttrib = AttributeManager::GetOtherAttrToApply(Attrib, &IsMutate);
01322
01323
01324
01325
01326
01327 AttrTypes.AddToSet((Attrib->GetAttributeType()));
01328 if (OtherAttrib != NULL)
01329 {
01330 AttrTypes.AddToSet((OtherAttrib->GetAttributeType()));
01331 }
01332
01333
01334 if (!DoInvalidateRegions(&SelRng,
01335 Attrib,
01336 Mutate,
01337 OtherAttrib,
01338 IsMutate))
01339 {
01340 goto EndOperation;
01341 }
01342
01343
01344 if (!DoLocaliseForAttrChange(&SelRng, &AttrTypes))
01345 {
01346 goto EndOperation;
01347 }
01348
01349 if (!ApplyToSelection(Attrib, Mutate))
01350 {
01351 goto EndOperation;
01352 }
01353
01354 pAppliedAttrib = Attrib;
01355 Attrib = OtherAttrib;
01356
01357
01358
01359
01360 if (Attrib != NULL && !pAppliedAttrib->OtherAttrIsAppliedSelectively())
01361 {
01362 if (!ApplyToSelection(Attrib, IsMutate))
01363 {
01364 delete Attrib;
01365 goto EndOperation;
01366 }
01367 }
01368
01369
01370 if (!DoInvalidateRegions(&SelRng,
01371 pAppliedAttrib,
01372 Mutate,
01373 OtherAttrib,
01374 IsMutate))
01375 {
01376 delete Attrib;
01377 goto EndOperation;
01378 }
01379
01380 delete Attrib;
01381
01382
01383
01384 if (!DoFactorOutAfterAttrChange(&SelRng, &AttrTypes))
01385 {
01386 goto EndOperation;
01387 }
01388
01389 AttrFillGeometry::LastRenderedMesh = NULL;
01390
01391 if (Document::GetSelected())
01392 Document::GetSelected()->SetModified(TRUE);
01393
01394 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
01395 if (!UpdateChangedNodes(&ObjChange))
01396 FailAndExecute();
01397
01398 AttributeManager::LastAppliedBounds = Sel->GetBoundingRect();
01399
01400 EndOperation:
01401 EndSlowJob();
01402
01403 AttrTypes.DeleteAll();
01404
01405 #endif
01406 End();
01407 }
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427 BOOL OpApplyAttribToSelected::ApplyToSelection(NodeAttribute* Attrib, BOOL Mutate)
01428 {
01429 return DoApplyToSelection(this, Attrib, Mutate, TRUE);
01430 }
01431
01432 BOOL OpApplyAttrib::DoApplyToSelection(SelOperation* pOp, NodeAttribute* Attrib, BOOL bMutate, BOOL bOptimise)
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
01441 if (FirstSelNode != NULL)
01442 {
01443 ERROR2IF(!FirstSelNode->IsAnObject(), FALSE, "ApplyToSelection SelRange doesn't have an Ink node in it");
01444
01445
01446
01447
01448 EffectsStack* pStack = Sel->GetEffectsStack(FALSE, FALSE);
01449 ERROR3IF(pStack==NULL, "Failed to get PPStack in ApplyToSelection");
01450 INT32 stackpos = STACKPOS_TOP;
01451 Range* pLevel = pStack->GetLevelRange(&stackpos, FALSE);
01452 Node* CurrentNode = pLevel->FindFirst();
01453
01454
01455 BOOL bCanDiscardUndo = TRUE;
01456
01457
01458 while (CurrentNode != NULL)
01459 {
01460
01461 Node* OldNode = CurrentNode;
01462 CurrentNode = pLevel->FindNext(CurrentNode);
01463
01464 if (OldNode->IsAnObject())
01465 {
01466
01467 NodeRenderableInk * pNodeToApply = OpApplyAttrib::FindCompoundNodeWhichRequiresAttribute((NodeRenderableInk *)OldNode,
01468 Attrib->GetRuntimeClass());
01469
01470 if (pNodeToApply != OldNode)
01471 {
01472
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))
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))
01491
01492 {
01493 return FALSE;
01494 }
01495 }
01496
01497
01498
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))
01513 {
01514 return FALSE;
01515 }
01516 }
01517
01518
01519
01520
01521
01522 if ((IS_A(Attrib, AttrLineWidth)) && OldNode->IsAnObject())
01523 {
01524 NodeRenderableInk *pRendNode = ((NodeRenderableInk*)OldNode)->GetObjectToApplyTo(Attrib->GetAttributeType());
01525
01526
01527 NodeAttribute *pAppliedAttr = NULL;
01528 pRendNode->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeColour), &pAppliedAttr);
01529 if (!pAppliedAttr)
01530 continue;
01531
01532
01533 ColourFillAttribute *pColAttr = (ColourFillAttribute *)pAppliedAttr->GetAttributeValue();
01534 if (!pColAttr)
01535 continue;
01536
01537
01538 DocColour *Col = pColAttr->GetStartColour();
01539 if (!Col)
01540 continue;
01541
01542
01543 if (Col->IsTransparent())
01544 {
01545
01546
01547
01548 AttrStrokeColour *pAttr = new AttrStrokeColour();
01549 if (pAttr == NULL)
01550 continue;
01551
01552
01553 DocColour ColourToApply(COLOUR_BLACK);
01554 ((AttrStrokeColour *)pAttr)->SetStartColour(&ColourToApply);
01555
01556
01557 if (!DoApply(pOp, OldNode, pAttr, bMutate, FALSE, FALSE, bOptimise, &bAttrWasRequired, &bCanDiscardUndo))
01558 continue;
01559
01560
01561 delete pAttr;
01562 pAttr = NULL;
01563 }
01564 }
01565
01566 ContinueSlowJob();
01567 }
01568
01569
01570
01571
01572
01573 Node* pLastSelected = pLevel->FindLast();
01574 if (pLastSelected!=NULL && pLastSelected->IsABaseTextClass())
01575 {
01576
01577
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
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602 }
01603
01604
01605
01606 if (bCanDiscardUndo)
01607 pOp->SucceedAndDiscard();
01608
01609 }
01610 return TRUE;
01611 }
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632 BOOL OpApplyAttribToSelected::Init()
01633 {
01634
01635 OpDescriptor* OpDesc = new OpDescriptor(
01636 0,
01637 _R(IDS_APPLYATTRIBOP),
01638 CC_RUNTIME_CLASS(OpApplyAttribToSelected),
01639 OPTOKEN_APPLYATTRIB,
01640 OpApplyAttribToSelected::GetState);
01641 ERRORIF(!OpDesc, _R(IDE_NOMORE_MEMORY), FALSE);
01642
01643 OpDesc = new OpDescriptor(
01644 0,
01645 _R(IDS_APPLYATTR_INTERACTIVE),
01646 CC_RUNTIME_CLASS(OpApplyAttrInteractive),
01647 OPTOKEN_APPLYATTRINTERACTIVE,
01648 OpApplyAttrInteractive::GetState);
01649 ERRORIF(!OpDesc, _R(IDE_NOMORE_MEMORY), FALSE);
01650
01651
01652
01653
01654 OpDesc = new OpChangeLineWidthOpDesc(0,
01655 _R(IDS_CHANGELINEWIDTH),
01656 CC_RUNTIME_CLASS(OpApplyAttribToSelected),
01657 OPTOKEN_CHANGELINEWIDTH,
01658 OpChangeLineWidthOpDesc::GetState,
01659 0,
01660 _R(IDBBL_CHANGELINEWIDTH),
01661 _R(IDCB_LINEWIDTH_COMBO_BOX),
01662 _R(IDCB_LINEWIDTH_COMBO_BOX));
01663 ERRORIF(!OpDesc, _R(IDE_NOMORE_MEMORY), FALSE);
01664
01665 if (!OpRepeatApplyAttribToSelected::Init())
01666 return FALSE;
01667
01668 return TRUE;
01669 }
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686 OpState OpApplyAttribToSelected::GetState(String_256*, OpDescriptor* OpDesc)
01687 {
01688 OpState OpSt;
01689
01690 SelRange* Sel = GetApplication()->FindSelection();
01691 ERROR2IF(Sel==NULL,OpSt,"Can't find SelRange!");
01692
01693
01694 OpSt.Greyed = ( (Sel->FindFirst() == NULL) );
01695
01696 return(OpSt);
01697 }
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717 void OpApplyAttribToSelected::GetOpName(String_256* OpName)
01718 {
01719
01720 *OpName = String_256(UndoAttribStrID);
01721 *OpName += String_256(_R(IDS_CHANGE));
01722 }
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749 OpApplyAttrInteractive::OpApplyAttrInteractive(): OpApplyAttrib()
01750 {
01751 }
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771 OpState OpApplyAttrInteractive::GetState(String_256*, OpDescriptor* OpDesc)
01772 {
01773 OpState OpSt;
01774
01775 SelRange* Sel = GetApplication()->FindSelection();
01776 ERROR2IF(Sel==NULL,OpSt,"Can't find SelRange!");
01777
01778
01779 OpSt.Greyed = ( (Sel->FindFirst() == NULL) );
01780
01781 return OpSt;
01782 }
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803 void OpApplyAttrInteractive::GetOpName(String_256* OpName)
01804 {
01805 *OpName = String_256(m_UndoAttribStrID);
01806 *OpName += String_256(_R(IDS_CHANGE));
01807 }
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827 BOOL OpApplyAttrInteractive::DoDragAttr(AttrValueChange* pNewValue)
01828 {
01829
01830
01831 AttrFillGeometry* pMutator = NULL;
01832
01833 BOOL ApplyAttribute = FALSE;
01834
01835 ERROR2IF(pNewValue==NULL, FALSE, "DoDragattr not given a decent attribute pointer");
01836 ERROR3IF(!pNewValue->IsAFillAttr(), "A Mutator must be a fill attribute");
01837 pMutator = (AttrFillGeometry*)pNewValue;
01838
01839 SelRange* Sel = GetApplication()->FindSelection();
01840 ERROR3IF(Sel==NULL, "Can't find SelRange!");
01841 if (Sel==NULL) return FALSE;
01842
01843 ApplyAttribute = AttributeManager::CanBeAppliedToSelection(pMutator, &m_AttrGroupList);
01844
01845 if (ApplyAttribute)
01846 {
01847
01848
01849
01850
01851
01852
01853
01854
01855 BOOL bMutateOther;
01856 NodeAttribute* pOtherAttrib = AttributeManager::GetOtherAttrToApply(pNewValue, &bMutateOther);
01857
01858
01859
01860 DoApplyToSelection(this, pNewValue, TRUE, FALSE);
01861
01862 if (pOtherAttrib && !pNewValue->OtherAttrIsAppliedSelectively())
01863 DoApplyToSelection(this, pOtherAttrib, bMutateOther, FALSE);
01864
01865 if (pOtherAttrib)
01866 {
01867 delete pOtherAttrib;
01868 pOtherAttrib = NULL;
01869 }
01870
01871
01872 Operation::SetQuickRender(TRUE, this);
01873
01874
01875 Sel->ForceRedrawView(GetWorkingDocView(), TRUE, TRUE, TRUE);
01876 GetWorkingDocView()->FlushRedraw();
01877 GetApplication()->ServiceRendering();
01878 }
01879
01880 return ApplyAttribute;
01881 }
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901 BOOL OpApplyAttrInteractive::DragAttrChanged(AttrValueChange* pNewValue)
01902 {
01903
01904 SelRange* Sel = GetApplication()->FindSelection();
01905 ERROR3IF(Sel==NULL, "Can't find SelRange!");
01906 if (Sel==NULL) return FALSE;
01907
01908 BOOL bMutateOther;
01909 NodeAttribute* pOtherAttrib = AttributeManager::GetOtherAttrToApply(pNewValue, &bMutateOther);
01910
01911 DoApplyToSelection(NULL, pNewValue, TRUE, FALSE);
01912
01913 if (pOtherAttrib && !pNewValue->OtherAttrIsAppliedSelectively())
01914 DoApplyToSelection(NULL, pOtherAttrib, bMutateOther, FALSE);
01915
01916 if (pOtherAttrib)
01917 {
01918 delete pOtherAttrib;
01919 pOtherAttrib = NULL;
01920 }
01921
01922
01923 Sel->ForceRedrawView(GetWorkingDocView(), TRUE, TRUE, TRUE);
01924 GetWorkingDocView()->FlushRedraw();
01925 GetApplication()->ServiceRendering();
01926
01927 return TRUE;
01928 }
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948 BOOL OpApplyAttrInteractive::DragAttrFinished(AttrValueChange* pNewValue, BOOL bSuccess)
01949 {
01950 SelRange* Sel = GetApplication()->FindSelection();
01951 ERROR3IF(Sel==NULL, "Can't find SelRange!");
01952 if (Sel==NULL)
01953 {
01954 FailAndExecute();
01955 End();
01956 return FALSE;
01957 }
01958
01959
01960 Operation::SetQuickRender(FALSE, this);
01961
01962 if (!bSuccess)
01963 {
01964
01965 BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::NONCOLOURATTCHANGED));
01966 FailAndExecute();
01967 End();
01968 return FALSE;
01969 }
01970
01971 BeginSlowJob();
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982 FailAndExecute();
01983 KeepOnEnd();
01984 End();
01985
01986
01987 m_AttrTypes.DeleteAll();
01988 AttributeManager::pLastNodeAppliedTo = NULL;
01989 ValueChangeType = pNewValue->GetRuntimeClass();
01990 BOOL RedrawBlobs = FALSE;
01991 NodeAttribute* pOtherAttrib = NULL;
01992
01993 ObjChangeFlags cFlags;
01994 cFlags.Attribute = TRUE;
01995 ObjChangeParam ObjChange(OBJCHANGE_STARTING, cFlags, NULL, this);
01996
01997 if (!Sel->AllowOp(&ObjChange))
01998 {
01999 FailAndExecute();
02000 goto EndOperation;
02001 }
02002
02003
02004
02005 m_UndoAttribStrID = pNewValue->GetAttrNameID();
02006
02007 if (!DoStartSelOp(RedrawBlobs, RedrawBlobs, TRUE, TRUE))
02008 {
02009 FailAndExecute();
02010 goto EndOperation;
02011 }
02012
02013
02014
02015 BOOL bMutateOther;
02016 pOtherAttrib = AttributeManager::GetOtherAttrToApply(pNewValue, &bMutateOther);
02017
02018
02019
02020
02021 m_AttrTypes.AddToSet((pNewValue->GetAttributeType()));
02022 if (pOtherAttrib)
02023 m_AttrTypes.AddToSet((pOtherAttrib->GetAttributeType()));
02024
02025
02026 if (!DoInvalidateRegions(Sel,
02027 pNewValue,
02028 TRUE,
02029 pOtherAttrib,
02030 bMutateOther))
02031 {
02032 FailAndExecute();
02033 goto EndOperation;
02034 }
02035
02036 if (!DoLocaliseForAttrChange(Sel, &m_AttrTypes))
02037 {
02038 FailAndExecute();
02039 goto EndOperation;
02040 }
02041
02042
02043 DoApplyToSelection(this, pNewValue, TRUE, TRUE);
02044
02045 if (pOtherAttrib && !pNewValue->OtherAttrIsAppliedSelectively())
02046 DoApplyToSelection(this, pOtherAttrib, bMutateOther, TRUE);
02047
02048 if (pOtherAttrib)
02049 {
02050 delete pOtherAttrib;
02051 pOtherAttrib = NULL;
02052 }
02053
02054
02055
02056 if (!DoInvalidateRegions(Sel,
02057 pNewValue,
02058 TRUE,
02059 pOtherAttrib,
02060 bMutateOther))
02061 {
02062 FailAndExecute();
02063 goto EndOperation;
02064 }
02065
02066
02067
02068 if (!DoFactorOutAfterAttrChange(Sel, &m_AttrTypes))
02069 {
02070 FailAndExecute();
02071 goto EndOperation;
02072 }
02073
02074 AttrFillGeometry::LastRenderedMesh = NULL;
02075
02076 if (Document::GetSelected())
02077 Document::GetSelected()->SetModified(TRUE);
02078
02079 cFlags.Attribute = TRUE;
02080 ObjChange.Define(OBJCHANGE_FINISHED, cFlags, NULL, this);
02081 if (!UpdateChangedNodes(&ObjChange))
02082 FailAndExecute();
02083
02084 AttributeManager::LastAppliedBounds = Sel->GetBoundingRect();
02085
02086
02087 AttributeManager::UpdateCurrentAppliedAttr(pNewValue, &m_AttrGroupList, TRUE, TRUE);
02088 AttributeManager::UpdateAfterAttrApplied(pNewValue);
02089
02090
02091 EndOperation:
02092 EndSlowJob();
02093
02094 m_AttrTypes.DeleteAll();
02095 m_AttrGroupList.DeleteAll();
02096
02097 End();
02098
02099 Sel->BroadcastAnyPendingMessages();
02100
02101 return TRUE;
02102 }
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122 void OpApplyAttrInteractive::PerformMergeProcessing()
02123 {
02124
02125 OperationHistory* pOpHist = &pOurDoc->GetOpHistory();
02126
02127
02128
02129 ERROR3IF(pOpHist->FindLastOp() != this, "Last Op should be this op");
02130 if (pOpHist->FindLastOp() != this)
02131 return;
02132
02133
02134 Operation* pPrevOp = pOpHist->FindPrevToLastOp();
02135 if (pPrevOp == NULL)
02136 return;
02137
02138 if (!IS_A(pPrevOp, OpApplyAttrInteractive))
02139 return;
02140
02141
02142
02143
02144 RestoreSelectionsAction* pRestoreSelAct = (RestoreSelectionsAction*)
02145 GetUndoActionList()->FindActionOfClass(CC_RUNTIME_CLASS(RestoreSelectionsAction));
02146 ERROR3IF(pRestoreSelAct == NULL, "This op should have a RestoreSelectionsAction");
02147 SelectionState* ThisOpsSelection = pRestoreSelAct->GetSelState();
02148
02149 pRestoreSelAct = (RestoreSelectionsAction*)
02150 pPrevOp->GetUndoActionList()->FindActionOfClass(CC_RUNTIME_CLASS(RestoreSelectionsAction));
02151 ERROR3IF(pRestoreSelAct == NULL, "OpNudge op should have a RestoreSelectionsAction");
02152 SelectionState* LastOpsSelection = pRestoreSelAct->GetSelState();
02153
02154 if (! ((*ThisOpsSelection) == (*LastOpsSelection)))
02155 return;
02156
02157 ActionList* pPrevList = pPrevOp->GetUndoActionList();
02158 ActionList* pThisList = this->GetUndoActionList();
02159 if (pPrevList->GetCount()!=pThisList->GetCount())
02160 return;
02161
02162
02163 Action* pPrevAct = (Action*)pPrevList->GetHead();
02164 Action* pThisAct = (Action*)pThisList->GetHead();
02165 while (pPrevAct && pThisAct)
02166 {
02167 if (pPrevAct->GetRuntimeClass() != pThisAct->GetRuntimeClass())
02168 return;
02169
02170 if (pPrevAct->IsKindOf(CC_RUNTIME_CLASS(UnApplyAction)))
02171 {
02172 UnApplyAction* pPrevApplyAct = (UnApplyAction*)pPrevAct;
02173 UnApplyAction* pThisApplyAct = (UnApplyAction*)pThisAct;
02174 if (pPrevApplyAct->m_pApplyNode != pThisApplyAct->m_pApplyNode)
02175 return;
02176 }
02177
02178 pPrevAct = (Action*)pPrevList->GetNext(pPrevAct);
02179 pThisAct = (Action*)pThisList->GetNext(pThisAct);
02180 }
02181
02182
02183
02184
02185 pPrevAct = (Action*)pPrevList->GetHead();
02186 pThisAct = (Action*)pThisList->GetHead();
02187 while (pPrevAct && pThisAct)
02188 {
02189 ERROR3IF(pPrevAct->GetRuntimeClass() != pThisAct->GetRuntimeClass(), "This can't happen!");
02190 if (pPrevAct->GetRuntimeClass() != pThisAct->GetRuntimeClass())
02191 return;
02192
02193 if (pPrevAct->IsKindOf(CC_RUNTIME_CLASS(UnApplyAction)))
02194 {
02195 UnApplyAction* pPrevApplyAct = (UnApplyAction*)pPrevAct;
02196 UnApplyAction* pThisApplyAct = (UnApplyAction*)pThisAct;
02197 ERROR3IF(pPrevApplyAct->m_pApplyNode != pThisApplyAct->m_pApplyNode, "This can't happen!");
02198 if (pPrevApplyAct->m_pApplyNode != pThisApplyAct->m_pApplyNode)
02199 return;
02200
02201
02202
02203 if (pPrevApplyAct->m_pAttribute)
02204 delete pPrevApplyAct->m_pAttribute;
02205
02206 pPrevApplyAct->m_pAttribute = pThisApplyAct->m_pAttribute;
02207
02208 pThisApplyAct->m_pAttribute = NULL;
02209 }
02210
02211 pPrevAct = (Action*)pPrevList->GetNext(pPrevAct);
02212 pThisAct = (Action*)pThisList->GetNext(pThisAct);
02213 }
02214
02215
02216 pOpHist->DeleteLastOp();
02217 }
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243 void OpApplyAttrInteractive::DragFinished(DocCoord PointerPos,
02244 ClickModifiers ClickMods,
02245 Spread* pSpread,
02246 BOOL Success,
02247 BOOL bSolidDrag)
02248 {
02249 DragAttrFinished(NULL, Success);
02250 }
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274 OpApplyAttribsToSelected::OpApplyAttribsToSelected(): OpApplyAttrib()
02275 {
02276 ValueChangeType = NULL;
02277 MergeRepeats = FALSE;
02278 m_pAttribList = NULL;
02279
02280 }
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326 void OpApplyAttribsToSelected::DoWithParam(OpDescriptor* OpDesc,
02327 OpParam* pOpParam
02328 )
02329 {
02330 #ifndef STANDALONE
02331 BeginSlowJob();
02332
02333 UndoAttribStrID = ((ApplyAttribsToSelectedParam*)pOpParam)->UndoAttribStrID;
02334
02335 DoApplyAttribsToSelection(pOpParam, TRUE);
02336
02337 EndSlowJob();
02338
02339 #else
02340 End();
02341 #endif // STAND_ALONE
02342
02343 }
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388 BOOL SelOperation::DoApplyAttribsToSelection(OpParam* pOpParam, BOOL bClearIfNoneApplied)
02389 {
02390
02391 ERROR3IF(!pOpParam, "No parameters passed to OpApplyAttribsToSelected");
02392 ApplyAttribsToSelectedParam* pParam = (ApplyAttribsToSelectedParam*)pOpParam;
02393
02394 List* pAttrsToApply = pParam->AttribsToApply;
02395
02396
02397
02398
02399
02400 List* AttrGroupList = pParam->AttrGroupList;
02401 ERROR3IF(!(AttrGroupList->IsEmpty()),
02402 "AttributeGroupList not empty on entry to OpApplyAttribsToSelected");
02403 BOOL* Success = pParam->Success;
02404 *Success = FALSE;
02405 BOOL* AppliedAttrs = pParam->AnyAttrsApplied;
02406 *AppliedAttrs = FALSE;
02407 BOOL bAnyApplied = FALSE;
02408 BOOL bWeStartedThisOp = FALSE;
02409
02410
02411 Range SelRng(*(GetApplication()->FindSelection()));
02412
02413
02414
02415
02416
02417
02418
02419 AttrTypeSet LineLevelAttrTypes;
02420 AttrTypeSet OtherAttrTypes;
02421 NodeAttributePtrItem* pAttrItem = (NodeAttributePtrItem*)(pAttrsToApply->GetHead());
02422 NodeAttribute* pAttr;
02423 AttrTypeSet* SetToAddTo;
02424 while (pAttrItem)
02425 {
02426 pAttr = pAttrItem->NodeAttribPtr;
02427 ERROR3IF(!pAttr, "Should be an attribute");
02428 if (pAttr->IsALineLevelAttrib())
02429 SetToAddTo = &LineLevelAttrTypes;
02430 else
02431 SetToAddTo = &OtherAttrTypes;
02432
02433 if (!SetToAddTo->AddToSet(pAttr->GetAttributeType()))
02434 {
02435 FailAndExecute();
02436 goto EndOperation;
02437 }
02438 pAttrItem = (NodeAttributePtrItem*)(pAttrsToApply->GetNext(pAttrItem));
02439 }
02440
02441
02442 if (SelRng.FindFirst()!=NULL)
02443 {
02444 SelRange* Sel;
02445 ObjChangeFlags cFlags;
02446 cFlags.Attribute = TRUE;
02447 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
02448
02449 Sel = GetApplication()->FindSelection();
02450
02451 if (!Sel->AllowOp(&ObjChange))
02452 {
02453 FailAndExecute();
02454 goto EndOperation;
02455 }
02456 }
02457
02458 if (!GetStarted())
02459 {
02460 if (!DoStartSelOp(FALSE,FALSE, TRUE,TRUE))
02461
02462 goto EndOperation;
02463
02464 bWeStartedThisOp = TRUE;
02465 }
02466
02467
02468
02469
02470
02471
02472 if (!DoInvalidateNodesRegions(SelRng, TRUE, FALSE))
02473 goto EndOperation;
02474
02475
02476
02477
02478
02479 if (!LineLevelAttrTypes.IsEmpty() && SelRng.FindFirst()!=NULL)
02480 {
02481 if (!DoLocaliseForAttrChange(&SelRng, &LineLevelAttrTypes))
02482 goto EndOperation;
02483 }
02484
02485 if (!OtherAttrTypes.IsEmpty() && SelRng.FindFirst()!=NULL)
02486 {
02487 if (!DoLocaliseForAttrChange(&SelRng, &OtherAttrTypes))
02488 goto EndOperation;
02489 }
02490
02491
02492 if (!DoApplyToSelection(pAttrsToApply, AttrGroupList, &bAnyApplied))
02493 {
02494 goto EndOperation;
02495 }
02496
02497
02498
02499 if (bAnyApplied)
02500 {
02501
02502
02503 if (!LineLevelAttrTypes.IsEmpty())
02504 {
02505 if (!DoFactorOutAfterAttrChange(&SelRng,
02506 &LineLevelAttrTypes))
02507 {
02508 goto EndOperation;
02509 }
02510 }
02511
02512 if (!OtherAttrTypes.IsEmpty())
02513 {
02514 if (!DoFactorOutAfterAttrChange(&SelRng,
02515 &OtherAttrTypes))
02516 {
02517 goto EndOperation;
02518 }
02519 }
02520
02521 {
02522 ObjChangeFlags cFlags;
02523 cFlags.Attribute = TRUE;
02524
02525 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,cFlags,NULL,this);
02526 if (!UpdateChangedNodes(&ObjChange))
02527 {
02528 FailAndExecute();
02529 goto EndOperation;
02530 }
02531 }
02532
02533
02534 if (!DoInvalidateNodesRegions(SelRng, TRUE, FALSE))
02535 {
02536 goto EndOperation;
02537 }
02538 }
02539 else if (bClearIfNoneApplied)
02540 {
02541
02542
02543 SucceedAndDiscard();
02544 }
02545
02546
02547 *Success = TRUE;
02548 *AppliedAttrs = bAnyApplied;
02549
02550 EndOperation:
02551
02552
02553 LineLevelAttrTypes.DeleteAll();
02554 OtherAttrTypes.DeleteAll();
02555
02556 if (bWeStartedThisOp)
02557 End();
02558
02559 return *Success;
02560 }
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594 BOOL SelOperation::DoApplyToSelection(List* Attribs, List* AttrGroupList, BOOL* pAttribWasRequired)
02595 {
02596 ERROR3IF(!(AttrGroupList->IsEmpty()), "Invalid output param");
02597
02598
02599 SelRange* pSel = GetApplication()->FindSelection();
02600 EffectsStack* pStack = pSel->GetEffectsStack(FALSE, FALSE);
02601 ERROR3IF(pStack==NULL, "Failed to get PPStack in ApplyToSelection");
02602 INT32 stackpos = STACKPOS_TOP;
02603 Range* pLevel = pStack->GetLevelRange(&stackpos, FALSE);
02604
02605 BOOL bCanDiscardUndo = TRUE;
02606
02607 NodeAttributePtrItem* pAttrItem = (NodeAttributePtrItem*)(Attribs->GetHead());
02608 while (pAttrItem)
02609 {
02610 NodeAttribute* pAttr = pAttrItem->NodeAttribPtr;
02611
02612
02613 ListListItem* pAttrsSetItem = new ListListItem;
02614 if (!pAttrsSetItem)
02615 goto Failed;
02616 List* pAttrsSet = &(pAttrsSetItem->list);
02617 AttrGroupList->AddTail(pAttrsSetItem);
02618
02619
02620 Node* CurrentNode = pLevel->FindFirst();
02621
02622 while (CurrentNode)
02623 {
02624 NodeAttribute* AttrToApply = pAttr;
02625 BOOL AppliedAttribIsCopy = FALSE;
02626 BOOL ThisAttrWasRequired = FALSE;
02627 if (pAttr->IsAFillAttr())
02628 {
02629
02630 DocRect NodeBounds = ((NodeRenderableInk*)CurrentNode)->GetBoundingRect(TRUE);
02631
02632 AttrToApply = (NodeAttribute*)(pAttr->SimpleCopy());
02633 AppliedAttribIsCopy = TRUE;
02634 if (!AttrToApply)
02635 goto Failed;
02636 AttrToApply->TransformToNewBounds(NodeBounds);
02637 }
02638
02639 if (!DoApply(CurrentNode,
02640 AttrToApply,
02641 FALSE,
02642 FALSE,
02643 FALSE,
02644 &ThisAttrWasRequired,
02645 &bCanDiscardUndo))
02646 {
02647 goto Failed;
02648 }
02649
02650 if (ThisAttrWasRequired)
02651 {
02652 *pAttribWasRequired = TRUE;
02653
02654
02655
02656
02657
02658
02659
02660 CCRuntimeClass* NewAttrGroup = ((NodeRenderableInk*)CurrentNode)->GetCurrentAttribGroup();
02661 ERROR3IF(NewAttrGroup == NULL, "Object has a NULL attribute group");
02662 BOOL InSet = FALSE;
02663 AttributeGroupItem* pAttrGrpItem = (AttributeGroupItem*)pAttrsSet->GetHead();
02664 while(pAttrGrpItem != NULL)
02665 {
02666 CCRuntimeClass* InSetAttrGroup = pAttrGrpItem->AttrGroup;
02667 ERROR3IF(InSetAttrGroup == NULL, "NULL attribute group found");
02668 if (NewAttrGroup == InSetAttrGroup)
02669 {
02670 InSet = TRUE;
02671 break;
02672 }
02673 pAttrGrpItem = (AttributeGroupItem*)pAttrsSet->GetNext(pAttrGrpItem);
02674 }
02675
02676 if (!InSet)
02677 {
02678
02679 pAttrGrpItem = new AttributeGroupItem();
02680 if (!pAttrGrpItem)
02681 goto Failed;
02682
02683 pAttrGrpItem->AttrGroup = NewAttrGroup;
02684
02685
02686 pAttrsSet->AddHead(pAttrGrpItem);
02687 }
02688 }
02689
02690 if (CurrentNode->IsAnObject())
02691 ((NodeRenderableInk*)CurrentNode)->InvalidateBoundingRect();
02692
02693 CurrentNode = pLevel->FindNext(CurrentNode);
02694 if (AppliedAttribIsCopy)
02695 {
02696 delete AttrToApply;
02697 AttrToApply = NULL;
02698 }
02699 }
02700 ContinueSlowJob();
02701 pAttrItem = (NodeAttributePtrItem*)(Attribs->GetNext(pAttrItem));
02702 }
02703
02704
02705
02706 if (bCanDiscardUndo)
02707 SucceedAndDiscard();
02708
02709 return TRUE;
02710
02711 Failed:
02712
02713 AttrGroupList->DeleteAll();
02714 return FALSE;
02715 }
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732 BOOL OpApplyAttribsToSelected::Init()
02733 {
02734
02735
02736 OpDescriptor* OpDesc = new OpDescriptor(0,
02737 _R(IDS_APPLYATTRIBOP),
02738 CC_RUNTIME_CLASS(OpApplyAttribsToSelected),
02739 OPTOKEN_APPLYATTRIBS,
02740 OpApplyAttribsToSelected::GetState);
02741 ERRORIF(!OpDesc, _R(IDE_NOMORE_MEMORY), FALSE);
02742
02743 return(TRUE);
02744 }
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760 OpState OpApplyAttribsToSelected::GetState(String_256*, OpDescriptor* OpDesc)
02761 {
02762 OpState OpSt;
02763 return(OpSt);
02764 }
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779 void OpApplyAttribsToSelected::GetOpName(String_256* OpName)
02780 {
02781
02782 *OpName = String_256(UndoAttribStrID);
02783 }
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806 OpRepeatApplyAttribToSelected::OpRepeatApplyAttribToSelected(): Operation()
02807 {
02808 }
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828 void OpRepeatApplyAttribToSelected::DoWithParam(OpDescriptor* OpDesc, OpParam* pOpParam)
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
02843 NodeAttribute* Attrib = (NodeAttribute*)(void *)pOpParam->Param1;
02844
02845 BOOL Mutate = FALSE;
02846 NodeAttribute* OldAttr = NULL;
02847
02848 if (Attrib == NULL)
02849 {
02850
02851 Attrib = (NodeAttribute*)(void *)pOpParam->Param2;
02852 Mutate = TRUE;
02853 }
02854 else
02855 {
02856
02857
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
02874
02875 NodeAttribute* OtherAttrib;
02876 BOOL IsMutate;
02877 OtherAttrib = AttributeManager::GetOtherAttrToApply(Attrib, &IsMutate);
02878
02879
02880
02881
02882
02883 AttrTypes.AddToSet((Attrib->GetAttributeType()));
02884 if (OtherAttrib != NULL)
02885 {
02886 AttrTypes.AddToSet((OtherAttrib->GetAttributeType()));
02887 }
02888
02889
02890
02891
02892
02893
02894 pCurrent = SelRng.FindFirst();
02895
02896
02897
02898 CCRuntimeClass* AttrType;
02899 Node* pParent;
02900 Node* pObject;
02901
02902 while (pCurrent)
02903 {
02904 pObject = pCurrent;
02905
02906
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
02916 pParent = pObject->FindParent();
02917 ERROR3IF(pParent == NULL, "Range::DoLocaliseForAttrChange, node found without a parent");
02918
02919
02920 if ((pParent->IsCompound()) && (pParent != pLocalisedCompound))
02921 {
02922 ((NodeRenderableInk*)pParent)->LocaliseCommonAttributes(FALSE,
02923 TRUE,
02924 &AttrTypes);
02925
02926 pLocalisedCompound = (NodeRenderableInk*)pParent;
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
02942
02943
02944
02945
02946
02947
02948
02949
02950 pCurrent = SelRng.FindFirst();
02951
02952
02953
02954
02955 while (pCurrent)
02956 {
02957
02958
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
02971 pParent = pObject->FindParent();
02972 ERROR3IF(pParent == NULL, "Range::DoFactorOutAfterAttrChange, node found without a parent");
02973
02974
02975 if ((pParent->IsCompound()) && (pParent != pFactoredOutCompound))
02976 {
02977 ((NodeRenderableInk*)pParent)->FactorOutCommonChildAttributes(TRUE, &AttrTypes);
02978
02979 pFactoredOutCompound = (NodeRenderableInk*)pParent;
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();
03002 }
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024 BOOL OpRepeatApplyAttribToSelected::ApplyToSelection(NodeAttribute* Attrib, BOOL Mutate)
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
03032
03033
03034 if (FirstSelectedNode != NULL)
03035 {
03036 EffectsStack* pStack = Sel->GetEffectsStack(FALSE, FALSE);
03037 ERROR3IF(pStack==NULL, "Failed to get PPStack in ApplyToSelection");
03038 INT32 stackpos = STACKPOS_TOP;
03039 Range* pLevel = pStack->GetLevelRange(&stackpos, FALSE);
03040 Node* pCurrentNode = pLevel->FindFirst();
03041
03042
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 }
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085 BOOL OpRepeatApplyAttribToSelected::DoApply(Node* CurrentNode, NodeAttribute* Attrib, BOOL Mutate, BOOL bEffectRootOnly)
03086 {
03087 ERROR3IF(!CurrentNode->IsBounded(), "DoApply assumes CurrentNode is bounded");
03088
03089
03090 Spread* pSpread = (Spread*)CurrentNode->FindParent(CC_RUNTIME_CLASS(Spread));
03091 DocRect TempRect = ((NodeRenderableBounded*)CurrentNode)->GetBoundingRect();
03092
03093 BOOL AttributeExists = FALSE;
03094
03095 CCRuntimeClass* AttrType = Attrib->GetAttributeType();
03096
03097
03098
03099
03100 Node* n = CurrentNode->FindFirstChild();
03101 Node* pLastBoundedNode = NULL;
03102 if (bEffectRootOnly)
03103 {
03104
03105
03106
03107
03108 if (AttrType==CC_RUNTIME_CLASS(AttrStrokeTransp))
03109 return TRUE;
03110
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
03121
03122 if (n->IsAnAttribute())
03123 {
03124 if( ((NodeAttribute*)n)->GetAttributeType() == AttrType)
03125 {
03126 AttributeExists = TRUE;
03127 break;
03128 }
03129 }
03130 n = n->FindNext();
03131 }
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143 NodeAttribute* AttribClone = NULL;
03144 NodeAttribute* pAttr = (NodeAttribute*)n;
03145 if (pAttr)
03146 {
03147
03148 if (Mutate)
03149 {
03150
03151 AttribClone = ((AttrFillGeometry*)pAttr)->Mutate((AttrFillGeometry*)Attrib);
03152 }
03153
03154 if (AttribClone != NULL)
03155 {
03156
03157 *((AttrFillGeometry*)pAttr) = *((AttrFillGeometry*)AttribClone);
03158
03159 AttributeManager::pLastNodeAppliedTo = (NodeRenderableInk*)CurrentNode;
03160
03161 delete AttribClone;
03162 AttribClone = NULL;
03163 }
03164 }
03165 else
03166 {
03167
03168
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
03184 ALLOC_WITH_FAIL(AttribClone ,((NodeAttribute*)Attrib->SimpleCopy()), this)
03185
03186 if (TempAttr->IsAFillAttr())
03187 {
03188 AttrFillGeometry* NodeReplaced = (AttrFillGeometry*)TempAttr;
03189
03190
03191 if (!OpApplyAttrib::KeepExistingCharacteristics(NodeReplaced, (AttrFillGeometry*)AttribClone))
03192 return FALSE;
03193 }
03194
03195 if (Attrib->IsATranspFill() && Attrib->IsAFlatFill())
03196 {
03197
03198
03199 ((AttrFillGeometry*)TempAttr)->RenderFillBlobs();
03200 }
03201 }
03202
03203
03204
03205 if (AttribClone && AttribClone->ShouldBeOptimized() && !bEffectRootOnly)
03206 {
03207 NodeAttribute* pAppliedAttr;
03208 if (((NodeRenderableInk*)CurrentNode)->FindAppliedAttribute(AttribClone->GetAttributeType(),
03209 &pAppliedAttr))
03210 {
03211
03212 if ((IS_SAME_CLASS(AttribClone, pAppliedAttr)))
03213 {
03214 if ((*AttribClone)==(*pAppliedAttr))
03215 {
03216 AttribClone->CascadeDelete();
03217
03218
03219
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
03234
03235
03236 if (AttribClone && bEffectRootOnly && AttribClone->HasEquivalentDefaultValue())
03237 {
03238
03239 AttribClone->CascadeDelete();
03240 delete AttribClone;
03241 AttribClone = NULL;
03242 }
03243
03244 if (AttribClone)
03245 {
03246
03247 if (bEffectRootOnly)
03248 AttribClone->AttachNode(pLastBoundedNode, NEXT);
03249 else
03250 AttribClone->AttachNode(CurrentNode, FIRSTCHILD);
03251
03252 AttributeManager::pLastNodeAppliedTo = (NodeRenderableInk*)CurrentNode;
03253
03254
03255
03256 if (AttribClone->IsAFillAttr())
03257 {
03258 ((AttrFillGeometry*)AttribClone)->AttributeChanged();
03259 }
03260 }
03261 }
03262
03263
03264
03265
03266 if (pAttr && pAttr->IsEffectAttribute() && bEffectRootOnly)
03267 {
03268
03269
03270
03271 if (pAttr->HasEquivalentDefaultValue())
03272 {
03273
03274 pAttr->CascadeDelete();
03275 delete pAttr;
03276 }
03277 }
03278
03279
03280
03281
03282
03283 if (bEffectRootOnly)
03284 ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
03285 else
03286 ((NodeRenderableBounded*)CurrentNode)->ReleaseCached();
03287
03288
03289 Document::GetSelected()->ForceRedraw(pSpread, TempRect, TRUE, CurrentNode, FALSE);
03290 return TRUE;
03291 }
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312 BOOL OpRepeatApplyAttribToSelected::Init()
03313 {
03314
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 }
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341 OpState OpRepeatApplyAttribToSelected::GetState(String_256*, OpDescriptor* OpDesc)
03342 {
03343 OpState OpSt;
03344
03345 SelRange* Sel = GetApplication()->FindSelection();
03346 ERROR2IF(Sel==NULL,OpSt,"Can't find SelRange!");
03347
03348
03349 OpSt.Greyed = ( (Sel->FindFirst() == NULL) );
03350
03351 return(OpSt);
03352 }
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372 void OpRepeatApplyAttribToSelected::GetOpName(String_256* OpName)
03373 {
03374 *OpName = "";
03375 }
03376
03377 CCRuntimeClass* OpApplyAttrib::GetValueChangeType()
03378 {
03379 return ValueChangeType;
03380 }
03381
03382 BOOL OpApplyAttrib::IsMergeableApplyOp()
03383 {
03384 return MergeRepeats;
03385 }
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412 OpApplyAttribToNode::OpApplyAttribToNode(): OpApplyAttrib()
03413 {
03414 m_pAttr = NULL;
03415 }
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435 void OpApplyAttribToNode::DoWithParam(OpDescriptor* OpDesc, OpParam* pOpParam)
03436 {
03437 ERROR3IF(pOpParam == NULL, "The OpApplyAttribToNode operation requires an attribute parameter");
03438
03439
03440 NodeRenderableInk* InkNode = (NodeRenderableInk*)(void *)pOpParam->Param1;
03441 NodeAttribute* NewAttr = (NodeAttribute*)(void *)pOpParam->Param2;
03442 m_pAttr = NewAttr;
03443
03444 ValueChangeType = NewAttr->GetRuntimeClass();
03445
03446 if (NewAttr)
03447 UndoAttribStrID = NewAttr->GetAttrNameID();
03448
03449 ObjectSet LocalisedCompoundSet;
03450
03451
03452 AttrTypeSet AttrTypes;
03453
03454 BOOL OtherIsMutate;
03455 NodeAttribute* OtherAttr = AttributeManager::GetOtherAttrToApply(NewAttr, &OtherIsMutate);
03456
03457
03458 ObjChangeFlags cFlags;
03459 cFlags.Attribute = TRUE;
03460 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
03461
03462
03463
03464 BOOL AttrAffectsBounds = NewAttr->EffectsParentBounds();
03465 if (!DoStartSelOp(AttrAffectsBounds, FALSE, TRUE, TRUE))
03466 {
03467 goto End;
03468 }
03469
03470
03471 ERROR3IF(NewAttr==NULL,"NewAttr == NULL");
03472 AttrTypes.AddToSet((NewAttr->GetAttributeType()));
03473
03474 if (OtherAttr != NULL)
03475 {
03476 AttrTypes.AddToSet((OtherAttr->GetAttributeType()));
03477 }
03478
03479
03480
03481 if (InkNode->IsAnAbstractTextChar() && InkNode->IsSelected())
03482 {
03483 AbstractTextChar* Scan = (AbstractTextChar*)InkNode;
03484 AbstractTextChar* Last;
03485
03486
03487 do
03488 {
03489 InkNode = Scan;
03490 Scan = Scan->FindPrevAbstractTextCharInStory();
03491 } while ((Scan != NULL) && (Scan->IsSelected()));
03492
03493
03494 Scan = (AbstractTextChar*)InkNode;
03495 do
03496 {
03497 Last = Scan;
03498 Scan = Scan->FindNextAbstractTextCharInStory();
03499 } while ((Scan != NULL) && (Scan->IsSelected()));
03500
03501 Range SubSelRange(InkNode, Last, RangeControl(TRUE));
03502
03503
03504 if (!SubSelRange.AllowOp(&ObjChange))
03505 {
03506 FailAndExecute();
03507 goto End;
03508 }
03509
03510
03511 if (!DoInvalidateRegions(&SubSelRange,
03512 NewAttr,
03513 NewAttr->IsAFillAttr(),
03514 OtherAttr,
03515 OtherIsMutate))
03516 {
03517 goto End;
03518 }
03519
03520
03521 do
03522 {
03523 if (!DoApplyAttrib(InkNode, NewAttr, &AttrTypes, &LocalisedCompoundSet))
03524 {
03525
03526 FailAndExecute();
03527 goto End;
03528 }
03529 InkNode = ((AbstractTextChar*)InkNode)->FindNextAbstractTextCharInStory();
03530 } while ((InkNode != NULL) && (InkNode->IsSelected()));
03531
03532
03533
03534 if (!DoInvalidateRegions(&SubSelRange,
03535 NewAttr,
03536 NewAttr->IsAFillAttr(),
03537 OtherAttr,
03538 OtherIsMutate))
03539 {
03540 goto End;
03541 }
03542 }
03543 else
03544 {
03545
03546 if (!InkNode->AllowOp(&ObjChange))
03547 {
03548 FailAndExecute();
03549 goto End;
03550 }
03551
03552 if (!DoApplyAttrib(InkNode, NewAttr, &AttrTypes, &LocalisedCompoundSet, TRUE))
03553 {
03554 goto End;
03555 }
03556
03557 }
03558
03559
03560 if (!DoFactorOutAfterAttrChange(&LocalisedCompoundSet,
03561 &AttrTypes))
03562 {
03563 goto End;
03564 }
03565
03566
03567
03568 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
03569 if (!UpdateChangedNodes(&ObjChange))
03570 {
03571 FailAndExecute();
03572 }
03573
03574 End:
03575
03576 AttrTypes.DeleteAll();
03577 LocalisedCompoundSet.DeleteAll();
03578
03579 if (OtherAttr)
03580 {
03581 delete OtherAttr;
03582 }
03583
03584
03585 End();
03586 }
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621 BOOL OpApplyAttribToNode::DoApplyAttrib(NodeRenderableInk* InkNode, NodeAttribute* NewAttr,
03622 AttrTypeSet* pAttrTypesToBeApplied,
03623 ObjectSet* pLocalisedCompounds,
03624 BOOL InvalidateBounds)
03625 {
03626 NodeAttribute* OtherAttr;
03627
03628 AttributeManager::pLastNodeAppliedTo = NULL;
03629
03630 ERROR3IF(InkNode==NULL,"InkNode == NULL");
03631 ERROR3IF(NewAttr==NULL,"NewAttr == NULL");
03632 if (InkNode == NULL) return FALSE;
03633
03634
03635
03636
03637 UndoAttribStrID = NewAttr->GetAttrNameID();
03638
03639 if (!AttrFillGeometry::HitList.IsEmpty())
03640 {
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652 ListItem* pAttrPtr = AttrFillGeometry::HitList.GetHead();
03653
03654 while (pAttrPtr != NULL)
03655 {
03656
03657
03658 NodeAttribute* pAttr = ((NodeAttributePtrItem*)pAttrPtr)->NodeAttribPtr;
03659 NodeRenderableInk* pParent = (NodeRenderableInk*)pAttr->FindParent();
03660
03661
03662 if (!DoLocaliseForAttrChange(pParent,
03663 pAttrTypesToBeApplied,
03664 pLocalisedCompounds))
03665 {
03666 return FALSE;
03667 }
03668
03669 if (!DoApply(pParent, NewAttr, NewAttr->IsAFillAttr(), InvalidateBounds))
03670 {
03671 return FALSE;
03672 }
03673
03674
03675
03676
03677
03678 BOOL IsMutate;
03679 OtherAttr = AttributeManager::GetOtherAttrToApply(NewAttr, &IsMutate);
03680
03681 if (OtherAttr != NULL)
03682 {
03683 if (!DoApply(pParent, OtherAttr, IsMutate, InvalidateBounds))
03684 {
03685 return FALSE;
03686 }
03687 delete OtherAttr;
03688 }
03689
03690 pAttrPtr = AttrFillGeometry::HitList.GetNext(pAttrPtr);
03691 }
03692
03693
03694 AttrFillGeometry::HitList.DeleteAll();
03695 }
03696 else
03697 {
03698
03699 if (!DoLocaliseForAttrChange(InkNode,
03700 pAttrTypesToBeApplied,
03701 pLocalisedCompounds))
03702 {
03703 return FALSE;
03704 }
03705
03706 if (!DoApply(InkNode, NewAttr, NewAttr->IsAFillAttr(), InvalidateBounds))
03707 return FALSE;
03708
03709
03710
03711
03712 BOOL IsMutate;
03713 OtherAttr = AttributeManager::GetOtherAttrToApply(NewAttr, &IsMutate);
03714
03715 if (OtherAttr != NULL)
03716 {
03717 if (!DoApply(InkNode, OtherAttr, IsMutate, InvalidateBounds))
03718 {
03719 return FALSE;
03720 }
03721 delete OtherAttr;
03722 }
03723 }
03724
03725 if (Document::GetSelected())
03726 Document::GetSelected()->SetModified(TRUE);
03727
03728
03729 AttributeManager::LastAppliedBounds = InkNode->GetBoundingRect();
03730
03731 return TRUE;
03732 }
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753 BOOL OpApplyAttribToNode::Init()
03754 {
03755
03756
03757 OpDescriptor* OpDesc = new OpDescriptor(
03758 0,
03759 _R(IDS_APPLYTONODEOP),
03760 CC_RUNTIME_CLASS(OpApplyAttribToNode),
03761 OPTOKEN_APPLYTONODE,
03762 OpApplyAttribToNode::GetState);
03763
03764 ERRORIF(!OpDesc, _R(IDE_NOMORE_MEMORY), FALSE);
03765 return(OpDesc != NULL);
03766 }
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783 OpState OpApplyAttribToNode::GetState(String_256*, OpDescriptor* OpDesc)
03784 {
03785 OpState OpSt;
03786
03787 OpSt.Greyed = ( FALSE );
03788
03789 return(OpSt);
03790 }
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810 void OpApplyAttribToNode::GetOpName(String_256* OpName)
03811 {
03812
03813 *OpName = String_256(UndoAttribStrID);
03814 *OpName += String_256(_R(IDS_CHANGE));
03815 }
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842 OpReplaceAttributes::OpReplaceAttributes(): SelOperation()
03843 {
03844 m_pAttr = NULL;
03845 }
03846
03847
03848
03849
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865 void OpReplaceAttributes::DoWithParam(OpDescriptor* OpDesc, OpParam* pOpParam)
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
03873 ObjChangeFlags cFlags;
03874 cFlags.Attribute = TRUE;
03875 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
03876 BOOL ok;
03877
03878
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
03888
03889 UndoAttribStrID = NewAttr->GetAttrNameID();
03890
03891 if (!DoStartSelOp(FALSE,FALSE, TRUE,TRUE))
03892
03893 {
03894 goto EndOperation;
03895 }
03896
03897
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
03922
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
03945 ((AttrFillGeometry*)NewCurrent)->SetFractalDPI(AttrFillGeometry::FractalDPI);
03946 }
03947
03948
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
03968 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
03969 ObjChange.SetRetainCachedData(TRUE);
03970 if (!UpdateChangedNodes(&ObjChange))
03971 FailAndExecute();
03972
03973 EndOperation:
03974 End();
03975 }
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985
03986
03987
03988
03989
03990
03991
03992
03993
03994
03995
03996 BOOL OpReplaceAttributes::DoReplace(NodeAttribute* OldAttr, NodeAttribute* NewAttr)
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))
04004 return FALSE;
04005
04006
04007
04008
04009
04010
04011
04012
04013
04014 if (CurrentNode->IsCompoundClass() && !((NodeCompound*)CurrentNode)->IsValidEffectAttr(NewAttr))
04015
04016 {
04017
04018
04019
04020
04021 if (!DoRemoveAttrTypeFromSubtree(CurrentNode, NewAttr->GetAttributeType(), OldAttr))
04022 {
04023 return FALSE;
04024 }
04025 }
04026
04027 NodeAttribute* AttribClone = NULL;
04028
04029
04030 if (OldAttr != NULL)
04031 {
04032
04033
04034
04035 ALLOC_WITH_FAIL(AttribClone ,((NodeAttribute*)NewAttr->SimpleCopy()), this)
04036
04037 if (AttribClone == NULL)
04038 {
04039
04040 return FALSE;
04041 }
04042
04043
04044
04045
04046
04047 if ( OldAttr->IsAFillAttr() )
04048 {
04049 AttrFillGeometry* NodeReplaced = (AttrFillGeometry*)OldAttr;
04050
04051
04052 if ( (NodeReplaced->GetAttributeType() == CC_RUNTIME_CLASS(AttrFillGeometry)) ||
04053 (NodeReplaced->GetAttributeType() == CC_RUNTIME_CLASS(AttrTranspFillGeometry)) )
04054 {
04055
04056
04057
04058
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
04092
04093 if(!DoHideNode(OldAttr,
04094 TRUE
04095 ))
04096 {
04097 return FALSE;
04098 }
04099 }
04100
04101
04102 if (bOldWasEffect)
04103 AttribClone->AttachNode(CurrentNode, LASTCHILD);
04104 else
04105 AttribClone->AttachNode(CurrentNode, FIRSTCHILD);
04106
04107 AttributeManager::pLastNodeAppliedTo = (NodeRenderableInk*)CurrentNode;
04108
04109
04110
04111 if (AttribClone->IsAFillAttr())
04112 {
04113 ((AttrFillGeometry*)AttribClone)->AttributeChanged();
04114 }
04115
04116 HideNodeAction* UndoHideNodeAction;
04117
04118
04119 if ( HideNodeAction::Init(this,
04120 &UndoActions,
04121 AttribClone,
04122 TRUE,
04123
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))
04135 return FALSE;
04136
04137 return TRUE;
04138 }
04139
04140
04141
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158 BOOL OpReplaceAttributes::Init()
04159 {
04160
04161
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
04173
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 }
04190
04191
04192
04193
04194
04195
04196
04197
04198
04199
04200
04201
04202
04203
04204
04205
04206 OpState OpReplaceAttributes::GetState(String_256*, OpDescriptor* OpDesc)
04207 {
04208 OpState OpSt;
04209
04210 OpSt.Greyed = ( FALSE );
04211
04212 return(OpSt);
04213 }
04214
04215
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230
04231
04232
04233 void OpReplaceAttributes::GetOpName(String_256* OpName)
04234 {
04235
04236 *OpName = String_256(UndoAttribStrID);
04237 *OpName += String_256(_R(IDS_CHANGE));
04238 }
04239
04240