#include <opclip.h>
Inheritance diagram for OpApplyClipView:
Public Member Functions | |
OpApplyClipView () | |
Constructor. | |
~OpApplyClipView () | |
Destructor. | |
virtual void | GetOpName (String_256 *pstrOpName) |
virtual void | Do (OpDescriptor *pOpDesc) |
virtual BOOL | MayChangeNodeBounds () const |
Static Public Member Functions | |
static BOOL | Init () |
static OpState | GetState (String_256 *pstrDescription, OpDescriptor *pOpDesc) |
Private Member Functions | |
CC_DECLARE_DYNCREATE (OpApplyClipView) |
Definition at line 120 of file opclip.h.
|
Constructor.
Definition at line 132 of file opclip.cpp.
|
|
Destructor.
Definition at line 150 of file opclip.cpp.
|
|
|
|
Reimplemented from Operation. Definition at line 288 of file opclip.cpp. 00289 { 00290 // obtain the current selection. 00291 Range Sel(*(GetApplication()->FindSelection())); 00292 RangeControl rc = Sel.GetRangeControlFlags(); 00293 rc.PromoteToParent = TRUE; 00294 Sel.Range::SetRangeControl(rc); 00295 00296 // check that at least two nodes are selected. 00297 Node* pNode = NULL; 00298 Node* pFirstNode = Sel.FindFirst(); 00299 if (pFirstNode != NULL) 00300 pNode = Sel.FindNext(pFirstNode); 00301 00302 if (pFirstNode == NULL || pNode == NULL) 00303 { 00304 ERROR3("OpApplyClipView invoked with less than two selected nodes. This should never occur."); 00305 End(); 00306 return; 00307 } 00308 00309 // render blobs off for tools which don't automatically redraw their blobs. 00310 Tool* pTool = Tool::GetCurrent(); 00311 Spread* pSpread = Document::GetSelectedSpread(); 00312 if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection()) 00313 pTool->RenderToolBlobs(pSpread, NULL); 00314 00315 // record the current selection state and if required, render off any selection blobs. 00316 if (!DoStartSelOp(FALSE, FALSE)) 00317 { 00318 End(); 00319 return; 00320 } 00321 00322 // invalidate the region bounding the selection. 00323 // the commented code doesn't do the job properly (doesn't tackle undo) 00324 // though it should - I get the feeling I'm not using it correctly. 00325 // so we'll just have to invalidate the selection node by node. 00326 // if (!DoInvalidateNodesRegions(Sel, TRUE, FALSE, FALSE)) 00327 // { 00328 // End(); 00329 // return; 00330 // } 00331 Node* pSelNode = Sel.FindFirst(); 00332 while (pSelNode != NULL) 00333 { 00334 if (pSelNode->IsAnObject()) 00335 { 00336 if (!DoInvalidateNodeRegion((NodeRenderableInk*)pSelNode, TRUE)) 00337 { 00338 End(); 00339 return; 00340 } 00341 } 00342 pSelNode = Sel.FindNext(pSelNode); 00343 } 00344 00345 // we need to insert the controller node at the position of the highest 00346 // selected node in the z-order, ie last in the selection, so find it. 00347 Node* pLastNode = NULL; 00348 while (pNode != NULL) 00349 { 00350 pLastNode = pNode; 00351 pNode = Sel.FindNext(pLastNode); 00352 } // loop terminates with pNode == NULL, pLastNode == last-node-in-sel. 00353 00354 // create a new NodeClipViewController, which we will shortly insert into the tree; 00355 // note that ALLOC_WITH_FAIL automatically calls FailAndExecute() if things go wrong. 00356 NodeClipViewController* pClipViewController = NULL; 00357 ALLOC_WITH_FAIL(pClipViewController, new NodeClipViewController, this); 00358 BOOL ok = (pClipViewController != NULL); 00359 00360 // put an action to hide the NodeClipViewController onto the undo action-list, 00361 // so that if the user presses undo then it will be hidden. 00362 if (ok) 00363 { 00364 HideNodeAction* pUndoHideNodeAction = NULL; 00365 ActionCode ac = HideNodeAction::Init(this, 00366 &UndoActions, 00367 pClipViewController, 00368 FALSE, // don't include subtree size 00369 (Action**)&pUndoHideNodeAction, 00370 FALSE); // don't tell subtree when undone 00371 if (ac == AC_FAIL) 00372 { 00373 delete pClipViewController; 00374 End(); 00375 return; 00376 } 00377 else 00378 { 00379 // right! we've got our node, we've got our action - lets stick it in the tree 00380 // (at a position just next to the last node which will go in the group). 00381 pClipViewController->AttachNode(pLastNode, NEXT); 00382 } 00383 } 00384 00385 // move each item from the selection into our ClipView group, 00386 // remembering to deselect them as we go. 00387 // TODO: 00388 // sneaky suspicion I should be putting this in a Do fn in UndoableOperation... 00389 if (ok) 00390 { 00391 pNode = Sel.FindNext(pFirstNode); // the node we're moving now. 00392 ok = DoMoveNode(pFirstNode, pClipViewController, FIRSTCHILD); 00393 if (ok) 00394 ((NodeRenderable*)pFirstNode)->DeSelect(FALSE); 00395 } 00396 00397 Node* pNextNode = NULL; // the next node to move. 00398 Node* pAnchorNode = pFirstNode; // the node we've just moved. 00399 while (ok && pNode != NULL) 00400 { 00401 // get the next node to move. 00402 pNextNode = Sel.FindNext(pNode); 00403 00404 // now move the current node next to the anchor and deselect it. 00405 ok = DoMoveNode(pNode, pAnchorNode, NEXT); 00406 if (ok) 00407 ((NodeRenderable*)pNode)->DeSelect(FALSE); 00408 00409 // get the new anchor node and the next node to move. 00410 pAnchorNode = pNode; 00411 pNode = pNextNode; 00412 } 00413 00414 // try and locate a suitable candidate for a keyhole node. 00415 Node* pKeyhole = NULL; 00416 if (ok) 00417 { 00418 // now get the keyhole node, which is the first object-node child of the NCVC. 00419 pKeyhole = pClipViewController->FindFirstChild(); 00420 while (pKeyhole != NULL && !pKeyhole->IsAnObject()) 00421 { 00422 pKeyhole = pKeyhole->FindNext(); 00423 } 00424 00425 // doh! can't find _one_ NodeRenderableInk child! I don't know... 00426 if (pKeyhole == NULL) 00427 { 00428 ok = FALSE; 00429 ERROR2RAW("ClipViewController has no object children"); 00430 } 00431 } 00432 00433 // now attach a new NodeClipView, as the immediate NEXT-sibling of the keyhole node. 00434 NodeClipView* pClipView = NULL; 00435 if (ok) 00436 { 00437 ALLOC_WITH_FAIL(pClipView, new NodeClipView(pKeyhole, NEXT), this); 00438 ok = (pClipView != NULL); 00439 } 00440 00441 // wow - succeeded! now all we need to do is some house-keeping. 00442 if (ok) 00443 { 00444 // tell the new NodeClipViewController that its current keyhole path is now invalid. 00445 pClipViewController->MarkKeyholeInvalid(); 00446 00447 // invalidate ours and our parent's bounding rects. our bounding rect is almost 00448 // certainly already invalid, as we haven't done anything to make it valid yet. 00449 // this is why we invalidate *both* rects - just to cover all cases. 00450 pClipViewController->InvalidateBoundingRect(); 00451 Node* pParent = pClipViewController->FindParent(); 00452 if (pParent != NULL && pParent->IsBounded()) 00453 ((NodeRenderableBounded*)pParent)->InvalidateBoundingRect(); 00454 00455 // select the new NodeClipViewController, but don't draw any blobs yet. 00456 pClipViewController->Select(FALSE); 00457 00458 // invalidate the region bounding the selection. 00459 if (!DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE, FALSE, FALSE)) 00460 { 00461 End(); 00462 return; 00463 } 00464 00465 // factor out any common attributes. 00466 if (!DoFactorOutCommonChildAttributes(pClipViewController)) 00467 { 00468 End(); 00469 return; 00470 } 00471 00472 // render blobs back on if the current tool doesn't automatically redraw its blobs. 00473 if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection()) 00474 pTool->RenderToolBlobs(pSpread, NULL); 00475 } 00476 else 00477 { 00478 FailAndExecute(); 00479 } 00480 00481 // end the operation. 00482 End(); 00483 }
|
|
Reimplemented from Operation. Definition at line 267 of file opclip.cpp. 00268 { 00269 *pstrOpName = String_256("ClipView Object(s)"); 00270 }
|
|
Definition at line 207 of file opclip.cpp. 00208 { 00209 // default is an unticked, *GREYED*, on-menu state. 00210 OpState OpSt; 00211 OpSt.Greyed = TRUE; 00212 *pstrDescription = String_256(_R(IDS_CLIPVIEW_NEEDS_MULTIPLE_NODES)); 00213 00214 // obtain the app's current selection. 00215 // we want to treat bevels/contours etc. as atomic objects. 00216 Range Sel(*(GetApplication()->FindSelection())); 00217 RangeControl rc = Sel.GetRangeControlFlags(); 00218 rc.PromoteToParent = TRUE; 00219 Sel.Range::SetRangeControl(rc); 00220 00221 // is there actually anything in the selection? 00222 Node* pNode = Sel.FindFirst(); 00223 if (pNode != NULL) 00224 { 00225 // yes - then is it only one node? 00226 if (Sel.FindNext(pNode) == NULL) 00227 { 00228 // yes - then if that node is a NodeClipViewController, remove ourself from the menu. 00229 if (pNode->IsANodeClipViewController()) 00230 { 00231 OpSt.RemoveFromMenu = TRUE; 00232 pstrDescription->Empty(); 00233 } 00234 } 00235 00236 // two or more nodes - that's ok, but only if there is currently no select-inside. 00237 else if (Sel.ContainsSelectInside()) 00238 { 00239 *pstrDescription = String_256(_R(IDS_GREY_WHEN_SELECT_INSIDE)); 00240 } 00241 else 00242 { 00243 OpSt.Greyed = FALSE; 00244 pstrDescription->Empty(); 00245 } 00246 } 00247 00248 return OpSt; 00249 }
|
|
Reimplemented from SimpleCCObject. Definition at line 171 of file opclip.cpp. 00172 { 00173 return RegisterOpDescriptor(0, // Tool ID 00174 _R(IDS_APPLY_CLIPVIEW), // String resource ID 00175 CC_RUNTIME_CLASS(OpApplyClipView), // Runtime class 00176 OPTOKEN_APPLY_CLIPVIEW, // Token string 00177 OpApplyClipView::GetState, // GetState function 00178 0, // Help ID 00179 _R(IDBBL_APPLY_CLIPVIEW), // Bubble ID 00180 0, // Resource ID 00181 0, // Control ID 00182 SYSTEMBAR_ILLEGAL, // Bar ID 00183 TRUE, // Receive system messages 00184 FALSE, // Smart duplicate operation 00185 FALSE, // Clean operation 00186 0, // No vertical counterpart 00187 GREY_WHEN_NO_CURRENT_DOC | 00188 DONT_GREY_WHEN_SELECT_INSIDE); // automatic state checking. 00189 }
|
|
Reimplemented from SelOperation. Definition at line 144 of file opclip.h. 00144 { return FALSE; }
|