1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <fucopy.hxx>
21 #include <sfx2/progress.hxx>
22 #include <svl/intitem.hxx>
23
24 #include <sdattr.hrc>
25 #include <sdresid.hxx>
26 #include <strings.hrc>
27 #include <ViewShell.hxx>
28 #include <View.hxx>
29 #include <drawdoc.hxx>
30 #include <DrawDocShell.hxx>
31 #include <svx/svdobj.hxx>
32 #include <svx/xcolit.hxx>
33 #include <svx/xflclit.hxx>
34 #include <svx/xdef.hxx>
35 #include <svx/xfillit0.hxx>
36 #include <svx/sdangitm.hxx>
37 #include <sfx2/request.hxx>
38 #include <sdabstdlg.hxx>
39 #include <memory>
40
41 using namespace com::sun::star;
42
43 namespace sd {
44
45
FuCopy(ViewShell * pViewSh,::sd::Window * pWin,::sd::View * pView,SdDrawDocument * pDoc,SfxRequest & rReq)46 FuCopy::FuCopy (
47 ViewShell* pViewSh,
48 ::sd::Window* pWin,
49 ::sd::View* pView,
50 SdDrawDocument* pDoc,
51 SfxRequest& rReq)
52 : FuPoor(pViewSh, pWin, pView, pDoc, rReq)
53 {
54 }
55
Create(ViewShell * pViewSh,::sd::Window * pWin,::sd::View * pView,SdDrawDocument * pDoc,SfxRequest & rReq)56 rtl::Reference<FuPoor> FuCopy::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
57 {
58 rtl::Reference<FuPoor> xFunc( new FuCopy( pViewSh, pWin, pView, pDoc, rReq ) );
59 xFunc->DoExecute(rReq);
60 return xFunc;
61 }
62
DoExecute(SfxRequest & rReq)63 void FuCopy::DoExecute( SfxRequest& rReq )
64 {
65 if( !mpView->AreObjectsMarked() )
66 return;
67
68 // Undo
69 OUString aString = mpView->GetDescriptionOfMarkedObjects() +
70 " " + SdResId( STR_UNDO_COPYOBJECTS );
71 mpView->BegUndo( aString );
72
73 const SfxItemSet* pArgs = rReq.GetArgs();
74
75 if( !pArgs )
76 {
77 SfxItemSet aSet( mpViewShell->GetPool(),
78 svl::Items<ATTR_COPY_START, ATTR_COPY_END>{} );
79
80 // indicate color attribute
81 SfxItemSet aAttr( mpDoc->GetPool() );
82 mpView->GetAttributes( aAttr );
83 const SfxPoolItem* pPoolItem = nullptr;
84
85 if( SfxItemState::SET == aAttr.GetItemState( XATTR_FILLSTYLE, true, &pPoolItem ) )
86 {
87 drawing::FillStyle eStyle = static_cast<const XFillStyleItem*>(pPoolItem)->GetValue();
88
89 if( eStyle == drawing::FillStyle_SOLID &&
90 SfxItemState::SET == aAttr.GetItemState( XATTR_FILLCOLOR, true, &pPoolItem ) )
91 {
92 const XFillColorItem* pItem = static_cast<const XFillColorItem*>(pPoolItem);
93 XColorItem aXColorItem( ATTR_COPY_START_COLOR, pItem->GetName(),
94 pItem->GetColorValue() );
95 aSet.Put( aXColorItem );
96
97 }
98 }
99
100 SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
101 ScopedVclPtr<AbstractCopyDlg> pDlg(pFact->CreateCopyDlg(mpViewShell->GetFrameWeld(), aSet, mpView ));
102
103 sal_uInt16 nResult = pDlg->Execute();
104
105 switch( nResult )
106 {
107 case RET_OK:
108 pDlg->GetAttr( aSet );
109 rReq.Done( aSet );
110 pArgs = rReq.GetArgs();
111 break;
112
113 default:
114 {
115 pDlg.disposeAndClear();
116 mpView->EndUndo();
117 return; // Cancel
118 }
119 }
120 }
121
122 ::tools::Rectangle aRect;
123 sal_Int32 lWidth = 0, lHeight = 0, lSizeX = 0, lSizeY = 0;
124 Degree100 lAngle(0);
125 sal_uInt16 nNumber = 0;
126 Color aStartColor, aEndColor;
127 bool bColor = false;
128 const SfxPoolItem* pPoolItem = nullptr;
129
130 // Count
131 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_NUMBER, true, &pPoolItem ) )
132 nNumber = static_cast<const SfxUInt16Item*>( pPoolItem )->GetValue();
133
134 // translation
135 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_MOVE_X, true, &pPoolItem ) )
136 lSizeX = static_cast<const SfxInt32Item*>( pPoolItem )->GetValue();
137 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_MOVE_Y, true, &pPoolItem ) )
138 lSizeY = static_cast<const SfxInt32Item*>( pPoolItem )->GetValue();
139 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_ANGLE, true, &pPoolItem ) )
140 lAngle = static_cast<const SdrAngleItem*>( pPoolItem )->GetValue();
141
142 // scale
143 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_WIDTH, true, &pPoolItem ) )
144 lWidth = static_cast<const SfxInt32Item*>( pPoolItem )->GetValue();
145 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_HEIGHT, true, &pPoolItem ) )
146 lHeight = static_cast<const SfxInt32Item*>( pPoolItem )->GetValue();
147
148 // start/end color
149 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_START_COLOR, true, &pPoolItem ) )
150 {
151 aStartColor = static_cast<const XColorItem*>( pPoolItem )->GetColorValue();
152 bColor = true;
153 }
154 if( pArgs && SfxItemState::SET == pArgs->GetItemState( ATTR_COPY_END_COLOR, true, &pPoolItem ) )
155 {
156 aEndColor = static_cast<const XColorItem*>( pPoolItem )->GetColorValue();
157 if( aStartColor == aEndColor )
158 bColor = false;
159 }
160 else
161 bColor = false;
162
163 // remove handles
164 //HMHmpView->HideMarkHdl();
165
166 std::unique_ptr<SfxProgress> pProgress;
167 bool bWaiting = false;
168
169 if( nNumber > 1 )
170 {
171 OUString aStr = SdResId( STR_OBJECTS ) +
172 " " + SdResId( STR_UNDO_COPYOBJECTS );
173
174 pProgress.reset(new SfxProgress( mpDocSh, aStr, nNumber ));
175 mpDocSh->SetWaitCursor( true );
176 bWaiting = true;
177 }
178
179 const SdrMarkList aMarkList( mpView->GetMarkedObjectList() );
180 const size_t nMarkCount = aMarkList.GetMarkCount();
181 SdrObject* pObj = nullptr;
182
183 // calculate number of possible copies
184 aRect = mpView->GetAllMarkedRect();
185
186 if( lWidth < 0 )
187 {
188 ::tools::Long nTmp = ( aRect.Right() - aRect.Left() ) / -lWidth;
189 nNumber = static_cast<sal_uInt16>(std::min( nTmp, static_cast<::tools::Long>(nNumber) ));
190 }
191
192 if( lHeight < 0 )
193 {
194 ::tools::Long nTmp = ( aRect.Bottom() - aRect.Top() ) / -lHeight;
195 nNumber = static_cast<sal_uInt16>(std::min( nTmp, static_cast<::tools::Long>(nNumber) ));
196 }
197
198 for( sal_uInt16 i = 1; i <= nNumber; i++ )
199 {
200 if( pProgress )
201 pProgress->SetState( i );
202
203 aRect = mpView->GetAllMarkedRect();
204
205 if( ( 1 == i ) && bColor )
206 {
207 SfxItemSet aNewSet( mpViewShell->GetPool(), svl::Items<XATTR_FILLSTYLE, XATTR_FILLCOLOR>{} );
208 aNewSet.Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
209 aNewSet.Put( XFillColorItem( OUString(), aStartColor ) );
210 mpView->SetAttributes( aNewSet );
211 }
212
213 // make a copy of selected objects
214 mpView->CopyMarked();
215
216 // get newly selected objects
217 SdrMarkList aCopyMarkList( mpView->GetMarkedObjectList() );
218 const size_t nCopyMarkCount = aMarkList.GetMarkCount();
219
220 // set protection flags at marked copies to null
221 for( size_t j = 0; j < nCopyMarkCount; ++j )
222 {
223 pObj = aCopyMarkList.GetMark( j )->GetMarkedSdrObj();
224
225 if( pObj )
226 {
227 pObj->SetMoveProtect( false );
228 pObj->SetResizeProtect( false );
229 }
230 }
231
232 Fraction aWidth( aRect.Right() - aRect.Left() + lWidth, aRect.Right() - aRect.Left() );
233 Fraction aHeight( aRect.Bottom() - aRect.Top() + lHeight, aRect.Bottom() - aRect.Top() );
234
235 if( mpView->IsResizeAllowed() )
236 mpView->ResizeAllMarked( aRect.TopLeft(), aWidth, aHeight );
237
238 if( mpView->IsRotateAllowed() )
239 mpView->RotateAllMarked( aRect.Center(), lAngle );
240
241 if( mpView->IsMoveAllowed() )
242 mpView->MoveAllMarked( Size( lSizeX, lSizeY ) );
243
244 // set protection flags at marked copies to original values
245 if( nMarkCount == nCopyMarkCount )
246 {
247 for( size_t j = 0; j < nMarkCount; ++j )
248 {
249 SdrObject* pSrcObj = aMarkList.GetMark( j )->GetMarkedSdrObj();
250 SdrObject* pDstObj = aCopyMarkList.GetMark( j )->GetMarkedSdrObj();
251
252 if( pSrcObj && pDstObj &&
253 ( pSrcObj->GetObjInventor() == pDstObj->GetObjInventor() ) &&
254 ( pSrcObj->GetObjIdentifier() == pDstObj->GetObjIdentifier() ) )
255 {
256 pDstObj->SetMoveProtect( pSrcObj->IsMoveProtect() );
257 pDstObj->SetResizeProtect( pSrcObj->IsResizeProtect() );
258 }
259 }
260 }
261
262 if( bColor )
263 {
264 // probably room for optimizations, but may can lead to rounding errors
265 sal_uInt8 nRed = aStartColor.GetRed() + static_cast<sal_uInt8>( ( static_cast<::tools::Long>(aEndColor.GetRed()) - static_cast<::tools::Long>(aStartColor.GetRed()) ) * static_cast<::tools::Long>(i) / static_cast<::tools::Long>(nNumber) );
266 sal_uInt8 nGreen = aStartColor.GetGreen() + static_cast<sal_uInt8>( ( static_cast<::tools::Long>(aEndColor.GetGreen()) - static_cast<::tools::Long>(aStartColor.GetGreen()) ) * static_cast<::tools::Long>(i) / static_cast<::tools::Long>(nNumber) );
267 sal_uInt8 nBlue = aStartColor.GetBlue() + static_cast<sal_uInt8>( ( static_cast<::tools::Long>(aEndColor.GetBlue()) - static_cast<::tools::Long>(aStartColor.GetBlue()) ) * static_cast<::tools::Long>(i) / static_cast<::tools::Long>(nNumber) );
268 Color aNewColor( nRed, nGreen, nBlue );
269 SfxItemSet aNewSet( mpViewShell->GetPool(), svl::Items<XATTR_FILLSTYLE, XATTR_FILLCOLOR>{} );
270 aNewSet.Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
271 aNewSet.Put( XFillColorItem( OUString(), aNewColor ) );
272 mpView->SetAttributes( aNewSet );
273 }
274 }
275
276 pProgress.reset();
277
278 if ( bWaiting )
279 mpDocSh->SetWaitCursor( false );
280
281 // show handles
282 mpView->AdjustMarkHdl(); //HMH sal_True );
283 //HMHpView->ShowMarkHdl();
284
285 mpView->EndUndo();
286 }
287
288 } // end of namespace
289
290 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
291