xref: /trunk/main/sd/source/ui/func/fucopy.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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