Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / sd / source / ui / func / fucopy.cxx
bloba8cde2135f49b4efb0fbe8b167d87b510a3ef360
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <fucopy.hxx>
21 #include <sfx2/progress.hxx>
22 #include <svx/svxids.hrc>
24 #include <sdresid.hxx>
25 #include <sdattr.hxx>
26 #include <strings.hrc>
27 #include <ViewShell.hxx>
28 #include <View.hxx>
29 #include <Window.hxx>
30 #include <drawdoc.hxx>
31 #include <DrawDocShell.hxx>
32 #include <vcl/wrkwin.hxx>
33 #include <svx/svdobj.hxx>
34 #include <sfx2/app.hxx>
35 #include <svx/xcolit.hxx>
36 #include <svx/xflclit.hxx>
37 #include <svx/xdef.hxx>
38 #include <svx/xfillit0.hxx>
39 #include <sfx2/request.hxx>
40 #include <sdabstdlg.hxx>
41 #include <memory>
43 using namespace com::sun::star;
45 namespace sd {
48 FuCopy::FuCopy (
49 ViewShell* pViewSh,
50 ::sd::Window* pWin,
51 ::sd::View* pView,
52 SdDrawDocument* pDoc,
53 SfxRequest& rReq)
54 : FuPoor(pViewSh, pWin, pView, pDoc, rReq)
58 rtl::Reference<FuPoor> FuCopy::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
60 rtl::Reference<FuPoor> xFunc( new FuCopy( pViewSh, pWin, pView, pDoc, rReq ) );
61 xFunc->DoExecute(rReq);
62 return xFunc;
65 void FuCopy::DoExecute( SfxRequest& rReq )
67 if( mpView->AreObjectsMarked() )
69 // Undo
70 OUString aString( mpView->GetDescriptionOfMarkedObjects() );
71 aString += " " + SdResId( STR_UNDO_COPYOBJECTS );
72 mpView->BegUndo( aString );
74 const SfxItemSet* pArgs = rReq.GetArgs();
76 if( !pArgs )
78 SfxItemSet aSet( mpViewShell->GetPool(),
79 svl::Items<ATTR_COPY_START, ATTR_COPY_END>{} );
81 // indicate color attribute
82 SfxItemSet aAttr( mpDoc->GetPool() );
83 mpView->GetAttributes( aAttr );
84 const SfxPoolItem* pPoolItem = nullptr;
86 if( SfxItemState::SET == aAttr.GetItemState( XATTR_FILLSTYLE, true, &pPoolItem ) )
88 drawing::FillStyle eStyle = static_cast<const XFillStyleItem*>(pPoolItem)->GetValue();
90 if( eStyle == drawing::FillStyle_SOLID &&
91 SfxItemState::SET == aAttr.GetItemState( XATTR_FILLCOLOR, true, &pPoolItem ) )
93 const XFillColorItem* pItem = static_cast<const XFillColorItem*>(pPoolItem);
94 XColorItem aXColorItem( ATTR_COPY_START_COLOR, pItem->GetName(),
95 pItem->GetColorValue() );
96 aSet.Put( aXColorItem );
101 SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
102 if( pFact )
104 ScopedVclPtr<AbstractCopyDlg> pDlg(pFact->CreateCopyDlg(mpViewShell->GetActiveWindow(), aSet, mpView ));
105 if (!pDlg)
106 return;
108 sal_uInt16 nResult = pDlg->Execute();
110 switch( nResult )
112 case RET_OK:
113 pDlg->GetAttr( aSet );
114 rReq.Done( aSet );
115 pArgs = rReq.GetArgs();
116 break;
118 default:
120 pDlg.disposeAndClear();
121 mpView->EndUndo();
123 return; // Cancel
128 ::tools::Rectangle aRect;
129 sal_Int32 lWidth = 0, lHeight = 0, lSizeX = 0, lSizeY = 0, lAngle = 0;
130 sal_uInt16 nNumber = 0;
131 Color aStartColor, aEndColor;
132 bool bColor = false;
133 const SfxPoolItem* pPoolItem = nullptr;
135 // Count
136 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_NUMBER, true, &pPoolItem ) )
137 nNumber = static_cast<const SfxUInt16Item*>( pPoolItem )->GetValue();
139 // translation
140 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_MOVE_X, true, &pPoolItem ) )
141 lSizeX = static_cast<const SfxInt32Item*>( pPoolItem )->GetValue();
142 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_MOVE_Y, true, &pPoolItem ) )
143 lSizeY = static_cast<const SfxInt32Item*>( pPoolItem )->GetValue();
144 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_ANGLE, true, &pPoolItem ) )
145 lAngle = static_cast<const SfxInt32Item*>( pPoolItem )->GetValue();
147 // scale
148 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_WIDTH, true, &pPoolItem ) )
149 lWidth = static_cast<const SfxInt32Item*>( pPoolItem )->GetValue();
150 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_HEIGHT, true, &pPoolItem ) )
151 lHeight = static_cast<const SfxInt32Item*>( pPoolItem )->GetValue();
153 // start/end color
154 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_START_COLOR, true, &pPoolItem ) )
156 aStartColor = static_cast<const XColorItem*>( pPoolItem )->GetColorValue();
157 bColor = true;
159 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_END_COLOR, true, &pPoolItem ) )
161 aEndColor = static_cast<const XColorItem*>( pPoolItem )->GetColorValue();
162 if( aStartColor == aEndColor )
163 bColor = false;
165 else
166 bColor = false;
168 // remove handles
169 //HMHmpView->HideMarkHdl();
171 std::unique_ptr<SfxProgress> pProgress;
172 bool bWaiting = false;
174 if( nNumber > 1 )
176 OUString aStr( SdResId( STR_OBJECTS ) );
177 aStr += " " + SdResId( STR_UNDO_COPYOBJECTS );
179 pProgress.reset(new SfxProgress( mpDocSh, aStr, nNumber ));
180 mpDocSh->SetWaitCursor( true );
181 bWaiting = true;
184 const SdrMarkList aMarkList( mpView->GetMarkedObjectList() );
185 const size_t nMarkCount = aMarkList.GetMarkCount();
186 SdrObject* pObj = nullptr;
188 // calculate number of possible copies
189 aRect = mpView->GetAllMarkedRect();
191 if( lWidth < 0 )
193 long nTmp = ( aRect.Right() - aRect.Left() ) / -lWidth;
194 nNumber = static_cast<sal_uInt16>(std::min( nTmp, static_cast<long>(nNumber) ));
197 if( lHeight < 0 )
199 long nTmp = ( aRect.Bottom() - aRect.Top() ) / -lHeight;
200 nNumber = static_cast<sal_uInt16>(std::min( nTmp, static_cast<long>(nNumber) ));
203 for( sal_uInt16 i = 1; i <= nNumber; i++ )
205 if( pProgress )
206 pProgress->SetState( i );
208 aRect = mpView->GetAllMarkedRect();
210 if( ( 1 == i ) && bColor )
212 SfxItemSet aNewSet( mpViewShell->GetPool(), svl::Items<XATTR_FILLSTYLE, XATTR_FILLCOLOR>{} );
213 aNewSet.Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
214 aNewSet.Put( XFillColorItem( OUString(), aStartColor ) );
215 mpView->SetAttributes( aNewSet );
218 // make a copy of selected objects
219 mpView->CopyMarked();
221 // get newly selected objects
222 SdrMarkList aCopyMarkList( mpView->GetMarkedObjectList() );
223 const size_t nCopyMarkCount = aMarkList.GetMarkCount();
225 // set protection flags at marked copies to null
226 for( size_t j = 0; j < nCopyMarkCount; ++j )
228 pObj = aCopyMarkList.GetMark( j )->GetMarkedSdrObj();
230 if( pObj )
232 pObj->SetMoveProtect( false );
233 pObj->SetResizeProtect( false );
237 Fraction aWidth( aRect.Right() - aRect.Left() + lWidth, aRect.Right() - aRect.Left() );
238 Fraction aHeight( aRect.Bottom() - aRect.Top() + lHeight, aRect.Bottom() - aRect.Top() );
240 if( mpView->IsResizeAllowed() )
241 mpView->ResizeAllMarked( aRect.TopLeft(), aWidth, aHeight );
243 if( mpView->IsRotateAllowed() )
244 mpView->RotateAllMarked( aRect.Center(), lAngle );
246 if( mpView->IsMoveAllowed() )
247 mpView->MoveAllMarked( Size( lSizeX, lSizeY ) );
249 // set protection flags at marked copies to original values
250 if( nMarkCount == nCopyMarkCount )
252 for( size_t j = 0; j < nMarkCount; ++j )
254 SdrObject* pSrcObj = aMarkList.GetMark( j )->GetMarkedSdrObj();
255 SdrObject* pDstObj = aCopyMarkList.GetMark( j )->GetMarkedSdrObj();
257 if( pSrcObj && pDstObj &&
258 ( pSrcObj->GetObjInventor() == pDstObj->GetObjInventor() ) &&
259 ( pSrcObj->GetObjIdentifier() == pDstObj->GetObjIdentifier() ) )
261 pDstObj->SetMoveProtect( pSrcObj->IsMoveProtect() );
262 pDstObj->SetResizeProtect( pSrcObj->IsResizeProtect() );
267 if( bColor )
269 // probably room for optimizations, but may can lead to rounding errors
270 sal_uInt8 nRed = aStartColor.GetRed() + static_cast<sal_uInt8>( ( static_cast<long>(aEndColor.GetRed()) - static_cast<long>(aStartColor.GetRed()) ) * static_cast<long>(i) / static_cast<long>(nNumber) );
271 sal_uInt8 nGreen = aStartColor.GetGreen() + static_cast<sal_uInt8>( ( static_cast<long>(aEndColor.GetGreen()) - static_cast<long>(aStartColor.GetGreen()) ) * static_cast<long>(i) / static_cast<long>(nNumber) );
272 sal_uInt8 nBlue = aStartColor.GetBlue() + static_cast<sal_uInt8>( ( static_cast<long>(aEndColor.GetBlue()) - static_cast<long>(aStartColor.GetBlue()) ) * static_cast<long>(i) / static_cast<long>(nNumber) );
273 Color aNewColor( nRed, nGreen, nBlue );
274 SfxItemSet aNewSet( mpViewShell->GetPool(), svl::Items<XATTR_FILLSTYLE, XATTR_FILLCOLOR>{} );
275 aNewSet.Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
276 aNewSet.Put( XFillColorItem( OUString(), aNewColor ) );
277 mpView->SetAttributes( aNewSet );
281 pProgress.reset();
283 if ( bWaiting )
284 mpDocSh->SetWaitCursor( false );
286 // show handles
287 mpView->AdjustMarkHdl(); //HMH sal_True );
288 //HMHpView->ShowMarkHdl();
290 mpView->EndUndo();
294 } // end of namespace
296 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */