#include <groupops.h>
Inheritance diagram for OpUngroup:
Public Member Functions | |
OpUngroup () | |
OpUngroup constructor. | |
void | Do (OpDescriptor *) |
Performs the Ungroup operation. | |
Static Public Member Functions | |
static BOOL | Init () |
OpUngroup initialiser method. | |
static OpState | GetState (String_256 *, OpDescriptor *) |
For finding the OpUngroup's state. | |
Protected Member Functions | |
BOOL | UngroupSelectedGroups () |
The function scans the tree and ungroups selected group nodes. It implements the main body of the OpUngroup Do function. | |
BOOL | ParentAllowsUngroup (NodeGroup *pChild) |
Nasty BODGE code! | |
BOOL | FindSelectedEffectAttrs () const |
Definition at line 163 of file groupops.h.
|
OpUngroup constructor.
Definition at line 555 of file groupops.cpp. 00555 : SelOperation() 00556 { 00557 }
|
|
Performs the Ungroup operation.
Reimplemented from Operation. Reimplemented in OpUngroupSpecial. Definition at line 693 of file groupops.cpp. 00694 { 00695 if (DoStartSelOp(TRUE,TRUE)) // Try to record the selection state 00696 { 00697 if (!UngroupSelectedGroups()) 00698 { 00699 FailAndExecute(); 00700 } 00701 } 00702 End(); 00703 }
|
|
Definition at line 996 of file groupops.cpp. 00997 { 00998 Range* pRange = GetApplication()->FindSelection(); 00999 Node* pNode = pRange->FindFirst(); 01000 while (pNode) 01001 { 01002 if (pNode->IsAGroup()) 01003 { 01004 NodeAttribute* pAttr = NodeAttribute::FindFirstAppliedAttr(pNode); 01005 while (pAttr && pAttr->FindParent() == pNode) 01006 { 01007 if (pAttr->IsEffectAttribute() && !pAttr->HasEquivalentDefaultValue(TRUE)) 01008 return TRUE; 01009 01010 pAttr = NodeAttribute::FindPrevAppliedAttr(pAttr); 01011 } 01012 } 01013 01014 pNode = pRange->FindNext(pNode); 01015 } 01016 01017 return FALSE; 01018 }
|
|
For finding the OpUngroup's state.
Reimplemented in OpUngroupSpecial. Definition at line 617 of file groupops.cpp. 00618 { 00619 OpState OpSt; 00620 00621 String_256 DisableReason; 00622 00623 // Obtain the current selections 00624 Range Sel(*(GetApplication()->FindSelection())); 00625 00626 // Determine if there are any group nodes selected, 00627 // and if so, whether they lie within controller nodes. 00628 Node* n = Sel.FindFirst(); 00629 // Node* pParentController = NULL; 00630 BOOL SelectedGroup = FALSE; 00631 // BOOL InsideControllerNode = FALSE; 00632 while (n != NULL) 00633 { 00634 if ( n->IsSelected() && IS_A(n,NodeGroup) ) 00635 { 00636 /* pParentController = n->FindParent(); 00637 if (pParentController != NULL) 00638 { 00639 if (pParentController->IsABevelController() || 00640 // pParentController->IsAShadowController() || 00641 pParentController->IsAContourController()) 00642 { 00643 InsideControllerNode = TRUE; 00644 break; 00645 } 00646 } 00647 */ 00648 SelectedGroup = TRUE; 00649 break; 00650 } 00651 n = Sel.FindNext(n); 00652 } 00653 // OpSt.Greyed = (InsideControllerNode || !SelectedGroup); 00654 OpSt.Greyed = !SelectedGroup; 00655 if (OpSt.Greyed) 00656 { 00657 // Load reason why operation is disabled. 00658 /* 00659 // we're inside a controller node. 00660 if (InsideControllerNode) 00661 { 00662 String_256 DisableReason(_R(IDS_GROUPINSIDECONTROLLER)); 00663 *UIDescription = DisableReason; 00664 } 00665 */ 00666 // No group nodes are selected. 00667 // else if (!SelectedGroup) 00668 if(!SelectedGroup) 00669 { 00670 String_256 DisableReason(_R(IDS_NO_GROUPS_SEL)); 00671 *UIDescription = DisableReason; 00672 } 00673 } 00674 return(OpSt); 00675 }
|
|
OpUngroup initialiser method.
Reimplemented from SimpleCCObject. Reimplemented in OpUngroupSpecial. Definition at line 577 of file groupops.cpp. 00578 { 00579 return (RegisterOpDescriptor(0, 00580 _R(IDS_UNGROUPOP), 00581 CC_RUNTIME_CLASS(OpUngroup), 00582 OPTOKEN_UNGROUP, 00583 OpUngroup::GetState, 00584 0, /* help ID */ 00585 _R(IDBBL_UNGROUPOP), 00586 0, /* bitmap ID */ 00587 0, 00588 SYSTEMBAR_ILLEGAL, // For now ! 00589 TRUE, // Receive messages 00590 FALSE, 00591 FALSE, 00592 0, 00593 (GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION) 00594 00595 )); 00596 }
|
|
Nasty BODGE code!
Definition at line 730 of file groupops.cpp. 00731 { 00732 Node* pParent = pChild->FindParent(); 00733 UINT32 MessageID = 0; 00734 00735 if (pParent != NULL) 00736 { 00737 // if the parent is a NodeShadowController, 00738 // then post a message informing the user. 00739 if (pParent->IsABevelController()) 00740 MessageID = _R(IDS_GROUPINSIDEBEVEL); 00741 PORTNOTE("other", "Ungroup can't localise effects yet") 00742 #ifndef EXCLUDE_FROM_XARALX 00743 // We don't need this clause when shadows can be localised in ungroup 00744 // else if (pParent->IsAShadowController()) // Shadows are now PostProcessors and allow ungrouping 00745 // MessageID = _R(IDS_GROUPINSIDESHADOW); 00746 #else 00747 else if (pParent->IsAShadowController()) // Shadows are now PostProcessors and allow ungrouping 00748 MessageID = _R(IDS_GROUPINSIDESHADOW); 00749 #endif 00750 else if (pParent->IsAContourController()) 00751 MessageID = _R(IDS_GROUPINSIDECONTOUR); 00752 00753 if(MessageID != 0) 00754 { 00755 ::InformWarning(MessageID); 00756 return FALSE; 00757 } 00758 00759 // we must catch any group-derived nodes which make it past any ungroup checks. 00760 // the GetState() code should catch all such instances, so if execution gets here, 00761 // then something somewhere else is broken! 00762 if (pParent->IsAGroup()) 00763 { 00764 ERROR3("OpUngroup::UngroupSelectedGroups; Group-derived parent node got past OpUngroup checks!"); 00765 return FALSE; 00766 } 00767 } 00768 00769 return TRUE; 00770 }
|
|
The function scans the tree and ungroups selected group nodes. It implements the main body of the OpUngroup Do function.
Definition at line 797 of file groupops.cpp. 00798 { 00799 // Obtain the current selections 00800 00801 Range Sel(*(GetApplication()->FindSelection())); 00802 00803 BOOL Ungrouped = FALSE; // Set to true when we ungroup a group 00804 BOOL bSelectGroupsHaveEffectAttrs = FALSE; 00805 Node* FirstSelectedNode = Sel.FindFirst(); 00806 if (FirstSelectedNode != NULL) // No nodes selected so End 00807 { 00808 BOOL bLocalisePostPros = FALSE; 00809 BOOL bDeletePostPros = FALSE; 00810 EffectsStack* pStack = GetApplication()->FindSelection()->GetEffectsStack(); 00811 bSelectGroupsHaveEffectAttrs = FindSelectedEffectAttrs(); 00812 if ((pStack && !pStack->IsEmpty()) || bSelectGroupsHaveEffectAttrs) 00813 { 00814 bLocalisePostPros = TRUE; 00815 // If the preference is set of the user forces it by holding down Shift 00816 // We will ask the user what he wanst to do with effects 00817 ClickModifiers clickmods = ClickModifiers::GetClickModifiers(); 00818 if (OpGroup::bAskBeforeFactoringEffects || clickmods.Adjust) 00819 { 00820 OpGroup::bAskBeforeFactoringEffects = TRUE; 00821 00822 // We need to ask the user about removing or localising PostProcessors 00823 INT32 ret = AskQuestion(_R(IDS_LE_ASK_UNGROUPLOCALISE), _R(IDS_LE_COPY), _R(IDS_LE_ALWAYSCOPY), _R(IDS_LE_REMOVE), _R(IDS_CANCEL)); 00824 switch (ret) 00825 { 00826 case 1: bLocalisePostPros = TRUE; 00827 break; 00828 case 2: bLocalisePostPros = TRUE; 00829 OpGroup::bAskBeforeFactoringEffects = FALSE; 00830 OpGroup::bLocaliseEffects = TRUE; 00831 break; 00832 case 3: bDeletePostPros = TRUE; 00833 OpGroup::bLocaliseEffects = FALSE; // ? 00834 break; 00835 case 4: return FALSE; 00836 break; 00837 } 00838 } 00839 else 00840 { 00841 bLocalisePostPros = OpGroup::bLocaliseEffects; 00842 bDeletePostPros = !OpGroup::bLocaliseEffects; 00843 } 00844 } 00845 00846 // Get the current tool 00847 Tool* pTool = Tool::GetCurrent(); 00848 Spread* pSelSpread = Document::GetSelectedSpread(); 00849 00850 // Get the tool to remove all its blobs before we deselect the nodes. 00851 // Only do this if the current tool dosent update itself on sel changed messages 00852 if (pSelSpread!=NULL && pTool!=NULL && !pTool->AreToolBlobsRenderedOnSelection()) 00853 pTool->RenderToolBlobs(pSelSpread,NULL); 00854 00855 // Find out which spread the node to be ungrouped is in 00856 // Spread* pSpread = FirstSelectedNode->FindParentSpread(); 00857 00858 Node* CurrentNode = FirstSelectedNode; 00859 Node* NextCurrent; 00860 Node* GrpNode; 00861 Node* NxtGrpNode; 00862 Node* Anchor; 00863 00864 // Ungroup all selected groups 00865 while (CurrentNode != NULL) 00866 { 00867 NextCurrent = Sel.FindNext(CurrentNode); 00868 00869 if (CurrentNode->IsSelected() && IS_A(CurrentNode, NodeGroup)) 00870 { 00871 // Karim 09/10/2000 00872 // Shadows BODGE - if our parent is a NodeShadowController, then we cannot ungroup. 00873 // Phil 2005, Shadows are different now but other controllers still disallow 00874 // ungrouping! 00875 if (ParentAllowsUngroup((NodeGroup*)CurrentNode)) 00876 { 00877 Ungrouped = TRUE; 00878 00879 // Karim 09/10/2000 00880 // Invalidate region ONLY if in the middle of a background redraw UNLESS we were feathered. 00881 // Invalidate if we are changing effects so they the changes get redrawn 00882 BOOL RedrawNow = (CurrentNode->FindFirstChild(CC_RUNTIME_CLASS(AttrFeather))!=NULL || 00883 bDeletePostPros || bLocalisePostPros || 00884 bSelectGroupsHaveEffectAttrs 00885 ); 00886 DoInvalidateNodeRegion( ((NodeRenderableBounded*)CurrentNode), TRUE, FALSE, !RedrawNow); 00887 00888 // Localise any containing PostProcessors 00889 // (This will push down common attributes into the group) 00890 /* // Find topmost effect applied to the current node and localise attributes 00891 // down from there... 00892 Node* pTopNode = EffectsStack::EscapeOldControllers(CurrentNode); 00893 Node* pHighestLE = CurrentNode; 00894 do 00895 { 00896 if (pTopNode->IsPostProcessor()) 00897 pHighestLE = pTopNode; 00898 00899 pTopNode = pTopNode->FindParent(); 00900 } 00901 while (pTopNode && pTopNode->IsPostProcessor()); 00902 */ 00903 if (bLocalisePostPros) 00904 { 00905 PORTNOTETRACE("other", "Ungroup can't localise effects yet"); 00906 #if !defined(EXCLUDE_FROM_XARALX) 00907 BOOL bOK = TRUE; 00908 bOK = bOK && OpLiveEffect::DoLocaliseEffectAttrs(this, CurrentNode); 00909 bOK = bOK && OpLiveEffect::DoLocaliseLiveEffects(this, CurrentNode); 00910 if (!bOK) return FALSE; 00911 #endif 00912 } 00913 else if (bDeletePostPros) 00914 { 00915 PORTNOTETRACE("other", "Ungroup can't localise effects yet"); 00916 #if !defined(EXCLUDE_FROM_XARALX) 00917 if (CurrentNode->IsAnObject()) 00918 { 00919 BOOL bOK = (OpLiveEffect::DoDeleteAllPostProcessors(this, (NodeRenderableInk*)CurrentNode, FALSE, TRUE)!=NULL); 00920 // Effect attrs will be deleted when the group and/or postpros are deleted 00921 // because of this we need to force the Op to redraw (see If BgRedraw above) 00922 if (!bOK) return FALSE; 00923 } 00924 #endif 00925 } 00926 00927 // Localise the attributes 00928 if (!DoLocaliseCommonAttributes(((NodeGroup*)CurrentNode))) 00929 return FALSE; 00930 00931 // Deselect the group node, cos we have got to remove its blobs 00932 ((NodeGroup*)CurrentNode)->DeSelect(FALSE); 00933 00934 ENSURE(!(CurrentNode->IsSelected()), "Deselect failed to deselect current node"); 00935 00936 // Hide the group node 00937 NodeHidden* Hidden; 00938 if(!DoHideNode(CurrentNode, FALSE, &Hidden, FALSE)) 00939 return FALSE; 00940 00941 Anchor = Hidden; 00942 ENSURE(Anchor->IsNodeHidden(), 00943 "The parent of a hidden group node is not a NodeHidden"); 00944 00945 // Move and select each node in turn. 00946 GrpNode = CurrentNode->FindFirstChild(); // Group's first child node 00947 00948 // Make sure that the group has at least one child 00949 #ifdef _DEBUG 00950 if (GrpNode == NULL) 00951 { 00952 TRACE( _T("Whilst ungrouping a group node without any children was found - It must be a Corel file")); 00953 } 00954 #endif 00955 00956 //ENSURE(GrpNode != NULL, "Trying to ungroup a node which has no children"); 00957 while (GrpNode != NULL) 00958 { 00959 00960 // Find the next node to ungroup before we move the group node 00961 NxtGrpNode = GrpNode->FindNext(); 00962 00963 // If the node is not a NodeHidden then 00964 // Move the node to its new location in the tree. There is no need 00965 // to render the node. 00966 if (!GrpNode->IsAnAttribute() && !GrpNode->IsNodeHidden()) 00967 { 00968 if (!DoMoveNode(GrpNode, Anchor, NEXT)) 00969 return FALSE; 00970 00971 if (GrpNode->IsAnObject()) 00972 ((NodeRenderableInk*)GrpNode)->Select(FALSE); 00973 00974 Anchor = GrpNode; // Attach the next node to ungroup to the last one 00975 // so maintaining z ordering. 00976 } 00977 GrpNode = NxtGrpNode; 00978 } 00979 } 00980 } 00981 CurrentNode = NextCurrent; 00982 } 00983 00984 // Get the tool to remove all its blobs before we deselect the nodes. 00985 // Only do this if the current tool dosent update itself on sel changed messages 00986 if (pSelSpread!=NULL && pTool!=NULL && !pTool->AreToolBlobsRenderedOnSelection()) 00987 pTool->RenderToolBlobs(pSelSpread,NULL); 00988 } 00989 else 00990 return (FALSE); // No nodes selected 00991 00992 return (Ungrouped); // Ungrouped will be TRUE if we have ungrouped any groups 00993 }
|