xref: /aoo41x/main/sd/source/ui/func/fucopy.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sd.hxx"
30 
31 
32 #include "fucopy.hxx"
33 #include <sfx2/progress.hxx>
34 #include <svx/svxids.hrc>
35 
36 #include "sdresid.hxx"
37 #include "sdattr.hxx"
38 #include "strings.hrc"
39 #include "ViewShell.hxx"
40 #include "View.hxx"
41 #include "drawdoc.hxx"
42 #include "DrawDocShell.hxx"
43 #include <vcl/wrkwin.hxx>
44 #include <svx/svdobj.hxx>
45 #include <vcl/msgbox.hxx>
46 #include <sfx2/app.hxx>
47 #include <svx/xcolit.hxx>
48 #include <svx/xflclit.hxx>
49 #include <svx/xdef.hxx>
50 #include <svx/xfillit0.hxx>
51 #include <sfx2/request.hxx>
52 #include "sdabstdlg.hxx"
53 #include "copydlg.hrc"
54 namespace sd {
55 
56 TYPEINIT1( FuCopy, FuPoor );
57 
58 /*************************************************************************
59 |*
60 |* Konstruktor
61 |*
62 \************************************************************************/
63 
64 FuCopy::FuCopy (
65     ViewShell* pViewSh,
66     ::sd::Window* pWin,
67     ::sd::View* pView,
68     SdDrawDocument* pDoc,
69     SfxRequest& rReq)
70 	: FuPoor(pViewSh, pWin, pView, pDoc, rReq)
71 {
72 }
73 
74 FunctionReference FuCopy::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
75 {
76 	FunctionReference xFunc( new FuCopy( pViewSh, pWin, pView, pDoc, rReq ) );
77 	xFunc->DoExecute(rReq);
78 	return xFunc;
79 }
80 
81 void FuCopy::DoExecute( SfxRequest& rReq )
82 {
83 	if( mpView->AreObjectsMarked() )
84 	{
85 		// Undo
86 		String aString( mpView->GetDescriptionOfMarkedObjects() );
87 		aString.Append( sal_Unicode(' ') );
88 		aString.Append( String( SdResId( STR_UNDO_COPYOBJECTS ) ) );
89 		mpView->BegUndo( aString );
90 
91 		const SfxItemSet* pArgs = rReq.GetArgs();
92 
93 		if( !pArgs )
94 		{
95 			SfxItemSet aSet( mpViewShell->GetPool(),
96 								ATTR_COPY_START, ATTR_COPY_END, 0 );
97 
98 			// Farb-Attribut angeben
99 			SfxItemSet aAttr( mpDoc->GetPool() );
100 			mpView->GetAttributes( aAttr );
101 			const SfxPoolItem*	pPoolItem = NULL;
102 
103 			if( SFX_ITEM_SET == aAttr.GetItemState( XATTR_FILLSTYLE, sal_True, &pPoolItem ) )
104 			{
105 				XFillStyle eStyle = ( ( const XFillStyleItem* ) pPoolItem )->GetValue();
106 
107 				if( eStyle == XFILL_SOLID &&
108 					SFX_ITEM_SET == aAttr.GetItemState( XATTR_FILLCOLOR, sal_True, &pPoolItem ) )
109 				{
110 					const XFillColorItem* pItem = ( const XFillColorItem* ) pPoolItem;
111 					XColorItem aXColorItem( ATTR_COPY_START_COLOR, pItem->GetName(),
112 														pItem->GetColorValue() );
113 					aSet.Put( aXColorItem );
114 
115 				}
116 			}
117 
118 			SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
119 			if( pFact )
120 			{
121 				AbstractCopyDlg* pDlg = pFact->CreateCopyDlg(NULL, aSet, mpDoc->GetColorTable(), mpView );
122 				if( pDlg )
123 				{
124 					sal_uInt16 nResult = pDlg->Execute();
125 
126 					switch( nResult )
127 					{
128 						case RET_OK:
129 							pDlg->GetAttr( aSet );
130 							rReq.Done( aSet );
131 							pArgs = rReq.GetArgs();
132 						break;
133 
134 						default:
135 						{
136 							delete pDlg;
137 							mpView->EndUndo();
138 						}
139 						return; // Abbruch
140 					}
141 					delete( pDlg );
142 				}
143 			}
144 		}
145 
146 		Rectangle	        aRect;
147 		sal_Int32		        lWidth = 0, lHeight = 0, lSizeX = 0L, lSizeY = 0L, lAngle = 0L;
148 		sal_uInt16		        nNumber = 0;
149 		Color		        aStartColor, aEndColor;
150 		sal_Bool		        bColor = sal_False;
151 		const SfxPoolItem*  pPoolItem = NULL;
152 
153 		// Anzahl
154 		if( SFX_ITEM_SET == pArgs->GetItemState( ATTR_COPY_NUMBER, sal_True, &pPoolItem ) )
155 			nNumber = ( ( const SfxUInt16Item* ) pPoolItem )->GetValue();
156 
157 		// Verschiebung
158 		if( SFX_ITEM_SET == pArgs->GetItemState( ATTR_COPY_MOVE_X, sal_True, &pPoolItem ) )
159 			lSizeX = ( ( const SfxInt32Item* ) pPoolItem )->GetValue();
160 		if( SFX_ITEM_SET == pArgs->GetItemState( ATTR_COPY_MOVE_Y, sal_True, &pPoolItem ) )
161 			lSizeY = ( ( const SfxInt32Item* ) pPoolItem )->GetValue();
162 		if( SFX_ITEM_SET == pArgs->GetItemState( ATTR_COPY_ANGLE, sal_True, &pPoolItem ) )
163 			lAngle = ( ( const SfxInt32Item* )pPoolItem )->GetValue();
164 
165 		// Verrgroesserung / Verkleinerung
166 		if( SFX_ITEM_SET == pArgs->GetItemState( ATTR_COPY_WIDTH, sal_True, &pPoolItem ) )
167 			lWidth = ( ( const SfxInt32Item* ) pPoolItem )->GetValue();
168 		if( SFX_ITEM_SET == pArgs->GetItemState( ATTR_COPY_HEIGHT, sal_True, &pPoolItem ) )
169 			lHeight = ( ( const SfxInt32Item* ) pPoolItem )->GetValue();
170 
171 		// Startfarbe / Endfarbe
172 		if( SFX_ITEM_SET == pArgs->GetItemState( ATTR_COPY_START_COLOR, sal_True, &pPoolItem ) )
173 		{
174 			aStartColor = ( ( const XColorItem* ) pPoolItem )->GetColorValue();
175 			bColor = sal_True;
176 		}
177 		if( SFX_ITEM_SET == pArgs->GetItemState( ATTR_COPY_END_COLOR, sal_True, &pPoolItem ) )
178 		{
179 			aEndColor = ( ( const XColorItem* ) pPoolItem )->GetColorValue();
180 			if( aStartColor == aEndColor )
181 				bColor = sal_False;
182 		}
183 		else
184 			bColor = sal_False;
185 
186 		// Handles wegnehmen
187 		//HMHmpView->HideMarkHdl();
188 
189 		SfxProgress*    pProgress = NULL;
190 		sal_Bool            bWaiting = sal_False;
191 
192 		if( nNumber > 1 )
193 		{
194 			String aStr( SdResId( STR_OBJECTS ) );
195 			aStr.Append( sal_Unicode(' ') );
196 			aStr.Append( String( SdResId( STR_UNDO_COPYOBJECTS ) ) );
197 
198 			pProgress = new SfxProgress( mpDocSh, aStr, nNumber );
199 			mpDocSh->SetWaitCursor( sal_True );
200 			bWaiting = sal_True;
201 		}
202 
203 		const SdrMarkList 	aMarkList( mpView->GetMarkedObjectList() );
204 		const sal_uLong			nMarkCount = aMarkList.GetMarkCount();
205 		SdrObject*		    pObj = NULL;
206 
207 		// Anzahl moeglicher Kopien berechnen
208 		aRect = mpView->GetAllMarkedRect();
209 
210 		if( lWidth < 0L )
211 		{
212 			long nTmp = ( aRect.Right() - aRect.Left() ) / -lWidth;
213 			nNumber = (sal_uInt16) Min( nTmp, (long)nNumber );
214 		}
215 
216 		if( lHeight < 0L )
217 		{
218 			long nTmp = ( aRect.Bottom() - aRect.Top() ) / -lHeight;
219 			nNumber = (sal_uInt16) Min( nTmp, (long)nNumber );
220 		}
221 
222 		for( sal_uInt16 i = 1; i <= nNumber; i++ )
223 		{
224 			if( pProgress )
225 				pProgress->SetState( i );
226 
227 			aRect = mpView->GetAllMarkedRect();
228 
229 			if( ( 1 == i ) && bColor )
230 			{
231 				SfxItemSet aNewSet( mpViewShell->GetPool(), XATTR_FILLSTYLE, XATTR_FILLCOLOR, 0L );
232 				aNewSet.Put( XFillStyleItem( XFILL_SOLID ) );
233 				aNewSet.Put( XFillColorItem( String(), aStartColor ) );
234 				mpView->SetAttributes( aNewSet );
235 			}
236 
237 			// make a copy of selected objects
238 			mpView->CopyMarked();
239 
240     		// get newly selected objects
241     		SdrMarkList aCopyMarkList( mpView->GetMarkedObjectList() );
242 	    	sal_uLong		j, nCopyMarkCount = aMarkList.GetMarkCount();
243 
244 			// set protection flags at marked copies to null
245 			for( j = 0; j < nCopyMarkCount; j++ )
246 			{
247 				pObj = aCopyMarkList.GetMark( j )->GetMarkedSdrObj();
248 
249 				if( pObj )
250 				{
251 					pObj->SetMoveProtect( sal_False );
252 					pObj->SetResizeProtect( sal_False );
253 				}
254 			}
255 
256 			Fraction aWidth( aRect.Right() - aRect.Left() + lWidth, aRect.Right() - aRect.Left() );
257 			Fraction aHeight( aRect.Bottom() - aRect.Top() + lHeight, aRect.Bottom() - aRect.Top() );
258 
259 			if( mpView->IsResizeAllowed() )
260 				mpView->ResizeAllMarked( aRect.TopLeft(), aWidth, aHeight );
261 
262 			if( mpView->IsRotateAllowed() )
263 				mpView->RotateAllMarked( aRect.Center(), lAngle * 100 );
264 
265 			if( mpView->IsMoveAllowed() )
266 				mpView->MoveAllMarked( Size( lSizeX, lSizeY ) );
267 
268 			// set protection flags at marked copies to original values
269 			if( nMarkCount == nCopyMarkCount )
270 			{
271 			    for( j = 0; j < nMarkCount; j++ )
272 			    {
273 			        SdrObject* pSrcObj = aMarkList.GetMark( j )->GetMarkedSdrObj();
274 			        SdrObject* pDstObj = aCopyMarkList.GetMark( j )->GetMarkedSdrObj();
275 
276 				    if( pSrcObj && pDstObj &&
277 				        ( pSrcObj->GetObjInventor() == pDstObj->GetObjInventor() ) &&
278 				        ( pSrcObj->GetObjIdentifier() == pDstObj->GetObjIdentifier() ) )
279 				    {
280 					    pDstObj->SetMoveProtect( pSrcObj->IsMoveProtect() );
281 					    pDstObj->SetResizeProtect( pSrcObj->IsResizeProtect() );
282 				    }
283 			    }
284 			}
285 
286 			if( bColor )
287 			{
288 				// Koennte man sicher noch optimieren, wuerde aber u.U.
289 				// zu Rundungsfehlern fuehren
290 				sal_uInt8 nRed = aStartColor.GetRed() + (sal_uInt8) ( ( (long) aEndColor.GetRed() - (long) aStartColor.GetRed() ) * (long) i / (long) nNumber  );
291 				sal_uInt8 nGreen = aStartColor.GetGreen() + (sal_uInt8) ( ( (long) aEndColor.GetGreen() - (long) aStartColor.GetGreen() ) *  (long) i / (long) nNumber );
292 				sal_uInt8 nBlue = aStartColor.GetBlue() + (sal_uInt8) ( ( (long) aEndColor.GetBlue() - (long) aStartColor.GetBlue() ) * (long) i / (long) nNumber );
293 				Color aNewColor( nRed, nGreen, nBlue );
294 				SfxItemSet aNewSet( mpViewShell->GetPool(), XATTR_FILLSTYLE, XATTR_FILLCOLOR, 0L );
295 				aNewSet.Put( XFillStyleItem( XFILL_SOLID ) );
296 				aNewSet.Put( XFillColorItem( String(), aNewColor ) );
297 				mpView->SetAttributes( aNewSet );
298 			}
299 		}
300 
301 		if ( pProgress )
302 			delete pProgress;
303 
304 		if ( bWaiting )
305 			mpDocSh->SetWaitCursor( sal_False );
306 
307 		// Handles zeigen
308 		mpView->AdjustMarkHdl(); //HMH sal_True );
309 		//HMHpView->ShowMarkHdl();
310 
311 		mpView->EndUndo();
312 	}
313 }
314 
315 } // end of namespace
316