xref: /trunk/main/sc/source/ui/view/drawvie4.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_sc.hxx"
30 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
31 
32 
33 
34 // INCLUDE ---------------------------------------------------------------
35 #include <svx/svditer.hxx>
36 #include <svx/svdograf.hxx>
37 #include <svx/svdogrp.hxx>
38 #include <svx/svdoole2.hxx>
39 #include <svx/svdpage.hxx>
40 #include <svx/svdundo.hxx>
41 #include <sfx2/docfile.hxx>
42 #include <tools/urlobj.hxx>
43 #include <toolkit/helper/vclunohelper.hxx>
44 
45 #include "drawview.hxx"
46 #include "global.hxx"
47 #include "drwlayer.hxx"
48 #include "viewdata.hxx"
49 #include "document.hxx"
50 #include "docsh.hxx"
51 #include "drwtrans.hxx"
52 #include "transobj.hxx"     // SetDrawClipDoc
53 #include "drawutil.hxx"
54 #include "scmod.hxx"
55 #include "globstr.hrc"
56 #include "chartarr.hxx"
57 
58 using namespace com::sun::star;
59 
60 // STATIC DATA -----------------------------------------------------------
61 
62 Point aDragStartDiff;
63 
64 // -----------------------------------------------------------------------
65 
66 //! welche Funktionen aus drawview/drawvie4 muessen wirklich ohne Optimierung sein?
67 
68 #ifdef _MSC_VER
69 #pragma optimize ( "", off )
70 #endif
71 
72 // -----------------------------------------------------------------------
73 
74 void lcl_CheckOle( const SdrMarkList& rMarkList, sal_Bool& rAnyOle, sal_Bool& rOneOle )
75 {
76     rAnyOle = rOneOle = sal_False;
77     sal_uLong nCount = rMarkList.GetMarkCount();
78     for (sal_uLong i=0; i<nCount; i++)
79     {
80         SdrMark* pMark = rMarkList.GetMark(i);
81         SdrObject* pObj = pMark->GetMarkedSdrObj();
82         sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier();
83         if (nSdrObjKind == OBJ_OLE2)
84         {
85             rAnyOle = sal_True;
86             rOneOle = (nCount == 1);
87             break;
88         }
89         else if ( pObj->ISA(SdrObjGroup) )
90         {
91             SdrObjListIter aIter( *pObj, IM_DEEPNOGROUPS );
92             SdrObject* pSubObj = aIter.Next();
93             while (pSubObj)
94             {
95                 if ( pSubObj->GetObjIdentifier() == OBJ_OLE2 )
96                 {
97                     rAnyOle = sal_True;
98                     // rOneOle remains sal_False - a group isn't treated like a single OLE object
99                     return;
100                 }
101                 pSubObj = aIter.Next();
102             }
103         }
104     }
105 }
106 
107 #if 0
108 void lcl_RefreshChartData( SdrModel* pModel, ScDocument* pSourceDoc )
109 {
110     sal_uInt16 nPages = pModel->GetPageCount();
111     for (SCTAB nTab=0; nTab<nPages; nTab++)
112     {
113         SdrPage* pPage = pModel->GetPage(nTab);
114         SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
115         SdrObject* pObject = aIter.Next();
116         while (pObject)
117         {
118             if ( pObject->GetObjIdentifier() == OBJ_OLE2 )
119             {
120                 SvInPlaceObjectRef aIPObj = ((SdrOle2Obj*)pObject)->GetObjRef();
121                 if ( aIPObj.Is() && SotExchange::IsChart( aIPObj->GetStorage()->GetClassName() ) )
122                 {
123                     SchMemChart* pOldData = SchDLL::GetChartData(aIPObj);
124                     if ( pOldData )
125                     {
126                         //  create data from source document
127                         ScChartArray aArray( pSourceDoc, *pOldData );
128                         if ( aArray.IsValid() )
129                         {
130                             SchMemChart* pNewData = aArray.CreateMemChart();
131                             SchDLL::Update( aIPObj, pNewData );
132                             delete pNewData;
133                             ((SdrOle2Obj*)pObject)->GetNewReplacement();
134                         }
135                     }
136                 }
137             }
138             pObject = aIter.Next();
139         }
140     }
141 }
142 #endif
143 
144 
145 sal_Bool ScDrawView::BeginDrag( Window* pWindow, const Point& rStartPos )
146 {
147     sal_Bool bReturn = sal_False;
148 
149     if ( AreObjectsMarked() )
150     {
151         BrkAction();
152 
153         Rectangle aMarkedRect = GetAllMarkedRect();
154         Region aRegion( aMarkedRect );
155 
156         aDragStartDiff = rStartPos - aMarkedRect.TopLeft();
157 
158         sal_Bool bAnyOle, bOneOle;
159         const SdrMarkList& rMarkList = GetMarkedObjectList();
160         lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
161 
162         ScDocShellRef aDragShellRef;
163         if (bAnyOle)
164         {
165             aDragShellRef = new ScDocShell;     // DocShell needs a Ref immediately
166             aDragShellRef->DoInitNew(NULL);
167         }
168         ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
169         SdrModel* pModel = GetAllMarkedModel();
170         ScDrawLayer::SetGlobalDrawPersist(NULL);
171 
172         //  Charts now always copy their data in addition to the source reference, so
173         //  there's no need to call SchDLL::Update for the charts in the clipboard doc.
174         //  Update with the data (including NumberFormatter) from the live document would
175         //  also store the NumberFormatter in the clipboard chart (#88749#)
176         // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
177 
178         ScDocShell* pDocSh = pViewData->GetDocShell();
179 
180         TransferableObjectDescriptor aObjDesc;
181         pDocSh->FillTransferableObjectDescriptor( aObjDesc );
182         aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
183         // maSize is set in ScDrawTransferObj ctor
184 
185         ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
186         uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
187 
188         pTransferObj->SetDrawPersist( &aDragShellRef );    // keep persist for ole objects alive
189         pTransferObj->SetDragSource( this );            // copies selection
190 
191         SC_MOD()->SetDragObject( NULL, pTransferObj );      // for internal D&D
192         pTransferObj->StartDrag( pWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
193     }
194 
195     return bReturn;
196 }
197 
198 void ScDrawView::DoCopy()
199 {
200     sal_Bool bAnyOle, bOneOle;
201     const SdrMarkList& rMarkList = GetMarkedObjectList();
202     lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
203 
204     // update ScGlobal::pDrawClipDocShellRef
205     ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
206     SdrModel* pModel = GetAllMarkedModel();
207     ScDrawLayer::SetGlobalDrawPersist(NULL);
208 
209     //  Charts now always copy their data in addition to the source reference, so
210     //  there's no need to call SchDLL::Update for the charts in the clipboard doc.
211     //  Update with the data (including NumberFormatter) from the live document would
212     //  also store the NumberFormatter in the clipboard chart (#88749#)
213     // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
214 
215     ScDocShell* pDocSh = pViewData->GetDocShell();
216 
217     TransferableObjectDescriptor aObjDesc;
218     pDocSh->FillTransferableObjectDescriptor( aObjDesc );
219     aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
220     // maSize is set in ScDrawTransferObj ctor
221 
222     ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
223     uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
224 
225     if ( ScGlobal::pDrawClipDocShellRef )
226     {
227         pTransferObj->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef) );    // keep persist for ole objects alive
228     }
229 
230     pTransferObj->CopyToClipboard( pViewData->GetActiveWin() );     // system clipboard
231     SC_MOD()->SetClipObject( NULL, pTransferObj );                  // internal clipboard
232 }
233 
234 uno::Reference<datatransfer::XTransferable> ScDrawView::CopyToTransferable()
235 {
236     sal_Bool bAnyOle, bOneOle;
237     const SdrMarkList& rMarkList = GetMarkedObjectList();
238     lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
239 
240     // update ScGlobal::pDrawClipDocShellRef
241     ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
242     SdrModel* pModel = GetAllMarkedModel();
243     ScDrawLayer::SetGlobalDrawPersist(NULL);
244 
245     //  Charts now always copy their data in addition to the source reference, so
246     //  there's no need to call SchDLL::Update for the charts in the clipboard doc.
247     //  Update with the data (including NumberFormatter) from the live document would
248     //  also store the NumberFormatter in the clipboard chart (#88749#)
249     // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
250 
251     ScDocShell* pDocSh = pViewData->GetDocShell();
252 
253     TransferableObjectDescriptor aObjDesc;
254     pDocSh->FillTransferableObjectDescriptor( aObjDesc );
255     aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
256     // maSize is set in ScDrawTransferObj ctor
257 
258     ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
259     uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
260 
261     if ( ScGlobal::pDrawClipDocShellRef )
262     {
263         pTransferObj->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef) );    // keep persist for ole objects alive
264     }
265 
266     return xTransferable;
267 }
268 
269 //  Korrektur fuer 100% berechnen, unabhaengig von momentanen Einstellungen
270 
271 void ScDrawView::CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const
272 {
273     Point aLogic = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
274     double nPPTX = ScGlobal::nScreenPPTX;
275     double nPPTY = ScGlobal::nScreenPPTY;
276 
277     if (pViewData)
278         nPPTX /= pViewData->GetDocShell()->GetOutputFactor();
279 
280     SCCOL nEndCol = 0;
281     SCROW nEndRow = 0;
282     pDoc->GetTableArea( nTab, nEndCol, nEndRow );
283     if (nEndCol<20)
284         nEndCol = 20;
285     if (nEndRow<20)
286         nEndRow = 20;
287 
288     Fraction aZoom(1,1);
289     ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev, aZoom,aZoom,
290                             nPPTX, nPPTY, rFractX,rFractY );
291 }
292 
293 void ScDrawView::SetMarkedOriginalSize()
294 {
295     SdrUndoGroup* pUndoGroup = new SdrUndoGroup(*GetModel());
296 
297     const SdrMarkList& rMarkList = GetMarkedObjectList();
298     long nDone = 0;
299     sal_uLong nCount = rMarkList.GetMarkCount();
300     for (sal_uLong i=0; i<nCount; i++)
301     {
302         SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
303         sal_uInt16 nIdent = pObj->GetObjIdentifier();
304         sal_Bool bDo = sal_False;
305         Size aOriginalSize;
306         if (nIdent == OBJ_OLE2)
307         {
308             // TODO/LEAN: working with visual area can switch object to running state
309             uno::Reference < embed::XEmbeddedObject > xObj( ((SdrOle2Obj*)pObj)->GetObjRef(), uno::UNO_QUERY );
310             if ( xObj.is() )    // #121612# NULL for an invalid object that couldn't be loaded
311             {
312                 sal_Int64 nAspect = ((SdrOle2Obj*)pObj)->GetAspect();
313 
314                 if ( nAspect == embed::Aspects::MSOLE_ICON )
315                 {
316                     MapMode aMapMode( MAP_100TH_MM );
317                     aOriginalSize = ((SdrOle2Obj*)pObj)->GetOrigObjSize( &aMapMode );
318                     bDo = sal_True;
319                 }
320                 else
321                 {
322                     MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( ((SdrOle2Obj*)pObj)->GetAspect() ) );
323                     awt::Size aSz;
324                     try
325                     {
326                         aSz = xObj->getVisualAreaSize( ((SdrOle2Obj*)pObj)->GetAspect() );
327                         aOriginalSize = OutputDevice::LogicToLogic(
328                                             Size( aSz.Width, aSz.Height ),
329                                             aUnit, MAP_100TH_MM );
330                         bDo = sal_True;
331                     } catch( embed::NoVisualAreaSizeException& )
332                     {
333                         OSL_ENSURE( sal_False, "Can't get the original size of the object!" );
334                     }
335                 }
336             }
337         }
338         else if (nIdent == OBJ_GRAF)
339         {
340             const Graphic& rGraphic = ((SdrGrafObj*)pObj)->GetGraphic();
341 
342             MapMode aSourceMap = rGraphic.GetPrefMapMode();
343             MapMode aDestMap( MAP_100TH_MM );
344             if (aSourceMap.GetMapUnit() == MAP_PIXEL)
345             {
346                 //  Pixel-Korrektur beruecksichtigen, damit Bitmap auf dem Bildschirm stimmt
347 
348                 Fraction aNormScaleX, aNormScaleY;
349                 CalcNormScale( aNormScaleX, aNormScaleY );
350                 aDestMap.SetScaleX(aNormScaleX);
351                 aDestMap.SetScaleY(aNormScaleY);
352             }
353             if (pViewData)
354             {
355                 Window* pActWin = pViewData->GetActiveWin();
356                 if (pActWin)
357                 {
358                     aOriginalSize = pActWin->LogicToLogic(
359                                     rGraphic.GetPrefSize(), &aSourceMap, &aDestMap );
360                     bDo = sal_True;
361                 }
362             }
363         }
364 
365         if ( bDo )
366         {
367             Rectangle aDrawRect = pObj->GetLogicRect();
368 
369             pUndoGroup->AddAction( new SdrUndoGeoObj( *pObj ) );
370             pObj->Resize( aDrawRect.TopLeft(), Fraction( aOriginalSize.Width(), aDrawRect.GetWidth() ),
371                                                  Fraction( aOriginalSize.Height(), aDrawRect.GetHeight() ) );
372             ++nDone;
373         }
374     }
375 
376     if (nDone)
377     {
378         pUndoGroup->SetComment(ScGlobal::GetRscString( STR_UNDO_ORIGINALSIZE ));
379         ScDocShell* pDocSh = pViewData->GetDocShell();
380         pDocSh->GetUndoManager()->AddUndoAction(pUndoGroup);
381         pDocSh->SetDrawModified();
382     }
383     else
384         delete pUndoGroup;
385 }
386 
387 
388 #ifdef _MSC_VER
389 #pragma optimize ( "", on )
390 #endif
391 
392 
393 
394 
395