1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: drawvie4.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
33 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
37 // INCLUDE ---------------------------------------------------------------
38 #include <svx/svditer.hxx>
39 #include <svx/svdograf.hxx>
40 #include <svx/svdogrp.hxx>
41 #include <svx/svdoole2.hxx>
42 #include <svx/svdpage.hxx>
43 #include <svx/svdundo.hxx>
44 #include <sfx2/docfile.hxx>
45 #include <tools/urlobj.hxx>
46 #include <toolkit/helper/vclunohelper.hxx>
48 #include "drawview.hxx"
50 #include "drwlayer.hxx"
51 #include "viewdata.hxx"
52 #include "document.hxx"
54 #include "drwtrans.hxx"
55 #include "transobj.hxx" // SetDrawClipDoc
56 #include "drawutil.hxx"
58 #include "globstr.hrc"
59 #include "chartarr.hxx"
61 using namespace com::sun::star
;
63 // STATIC DATA -----------------------------------------------------------
67 // -----------------------------------------------------------------------
69 //! welche Funktionen aus drawview/drawvie4 muessen wirklich ohne Optimierung sein?
72 #pragma optimize ( "", off )
75 // -----------------------------------------------------------------------
77 void lcl_CheckOle( const SdrMarkList
& rMarkList
, BOOL
& rAnyOle
, BOOL
& rOneOle
)
79 rAnyOle
= rOneOle
= FALSE
;
80 ULONG nCount
= rMarkList
.GetMarkCount();
81 for (ULONG i
=0; i
<nCount
; i
++)
83 SdrMark
* pMark
= rMarkList
.GetMark(i
);
84 SdrObject
* pObj
= pMark
->GetMarkedSdrObj();
85 UINT16 nSdrObjKind
= pObj
->GetObjIdentifier();
86 if (nSdrObjKind
== OBJ_OLE2
)
89 rOneOle
= (nCount
== 1);
92 else if ( pObj
->ISA(SdrObjGroup
) )
94 SdrObjListIter
aIter( *pObj
, IM_DEEPNOGROUPS
);
95 SdrObject
* pSubObj
= aIter
.Next();
98 if ( pSubObj
->GetObjIdentifier() == OBJ_OLE2
)
101 // rOneOle remains FALSE - a group isn't treated like a single OLE object
104 pSubObj
= aIter
.Next();
111 void lcl_RefreshChartData( SdrModel
* pModel
, ScDocument
* pSourceDoc
)
113 USHORT nPages
= pModel
->GetPageCount();
114 for (SCTAB nTab
=0; nTab
<nPages
; nTab
++)
116 SdrPage
* pPage
= pModel
->GetPage(nTab
);
117 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
118 SdrObject
* pObject
= aIter
.Next();
121 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
)
123 SvInPlaceObjectRef aIPObj
= ((SdrOle2Obj
*)pObject
)->GetObjRef();
124 if ( aIPObj
.Is() && SotExchange::IsChart( aIPObj
->GetStorage()->GetClassName() ) )
126 SchMemChart
* pOldData
= SchDLL::GetChartData(aIPObj
);
129 // create data from source document
130 ScChartArray
aArray( pSourceDoc
, *pOldData
);
131 if ( aArray
.IsValid() )
133 SchMemChart
* pNewData
= aArray
.CreateMemChart();
134 SchDLL::Update( aIPObj
, pNewData
);
136 ((SdrOle2Obj
*)pObject
)->GetNewReplacement();
141 pObject
= aIter
.Next();
148 BOOL
ScDrawView::BeginDrag( Window
* pWindow
, const Point
& rStartPos
)
150 BOOL bReturn
= FALSE
;
152 if ( AreObjectsMarked() )
156 Rectangle aMarkedRect
= GetAllMarkedRect();
157 Region
aRegion( aMarkedRect
);
159 aDragStartDiff
= rStartPos
- aMarkedRect
.TopLeft();
161 BOOL bAnyOle
, bOneOle
;
162 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
163 lcl_CheckOle( rMarkList
, bAnyOle
, bOneOle
);
165 ScDocShellRef aDragShellRef
;
168 aDragShellRef
= new ScDocShell
; // DocShell needs a Ref immediately
169 aDragShellRef
->DoInitNew(NULL
);
171 ScDrawLayer::SetGlobalDrawPersist(aDragShellRef
);
172 SdrModel
* pModel
= GetAllMarkedModel();
173 ScDrawLayer::SetGlobalDrawPersist(NULL
);
175 // Charts now always copy their data in addition to the source reference, so
176 // there's no need to call SchDLL::Update for the charts in the clipboard doc.
177 // Update with the data (including NumberFormatter) from the live document would
178 // also store the NumberFormatter in the clipboard chart (#88749#)
179 // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
181 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
183 TransferableObjectDescriptor aObjDesc
;
184 pDocSh
->FillTransferableObjectDescriptor( aObjDesc
);
185 aObjDesc
.maDisplayName
= pDocSh
->GetMedium()->GetURLObject().GetURLNoPass();
186 // maSize is set in ScDrawTransferObj ctor
188 ScDrawTransferObj
* pTransferObj
= new ScDrawTransferObj( pModel
, pDocSh
, aObjDesc
);
189 uno::Reference
<datatransfer::XTransferable
> xTransferable( pTransferObj
);
191 pTransferObj
->SetDrawPersist( &aDragShellRef
); // keep persist for ole objects alive
192 pTransferObj
->SetDragSource( this ); // copies selection
194 SC_MOD()->SetDragObject( NULL
, pTransferObj
); // for internal D&D
195 pTransferObj
->StartDrag( pWindow
, DND_ACTION_COPYMOVE
| DND_ACTION_LINK
);
201 void ScDrawView::DoCopy()
203 BOOL bAnyOle
, bOneOle
;
204 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
205 lcl_CheckOle( rMarkList
, bAnyOle
, bOneOle
);
207 // update ScGlobal::pDrawClipDocShellRef
208 ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle
) );
209 SdrModel
* pModel
= GetAllMarkedModel();
210 ScDrawLayer::SetGlobalDrawPersist(NULL
);
212 // Charts now always copy their data in addition to the source reference, so
213 // there's no need to call SchDLL::Update for the charts in the clipboard doc.
214 // Update with the data (including NumberFormatter) from the live document would
215 // also store the NumberFormatter in the clipboard chart (#88749#)
216 // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
218 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
220 TransferableObjectDescriptor aObjDesc
;
221 pDocSh
->FillTransferableObjectDescriptor( aObjDesc
);
222 aObjDesc
.maDisplayName
= pDocSh
->GetMedium()->GetURLObject().GetURLNoPass();
223 // maSize is set in ScDrawTransferObj ctor
225 ScDrawTransferObj
* pTransferObj
= new ScDrawTransferObj( pModel
, pDocSh
, aObjDesc
);
226 uno::Reference
<datatransfer::XTransferable
> xTransferable( pTransferObj
);
228 if ( ScGlobal::pDrawClipDocShellRef
)
230 pTransferObj
->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef
) ); // keep persist for ole objects alive
233 pTransferObj
->CopyToClipboard( pViewData
->GetActiveWin() ); // system clipboard
234 SC_MOD()->SetClipObject( NULL
, pTransferObj
); // internal clipboard
237 uno::Reference
<datatransfer::XTransferable
> ScDrawView::CopyToTransferable()
239 BOOL bAnyOle
, bOneOle
;
240 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
241 lcl_CheckOle( rMarkList
, bAnyOle
, bOneOle
);
243 // update ScGlobal::pDrawClipDocShellRef
244 ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle
) );
245 SdrModel
* pModel
= GetAllMarkedModel();
246 ScDrawLayer::SetGlobalDrawPersist(NULL
);
248 // Charts now always copy their data in addition to the source reference, so
249 // there's no need to call SchDLL::Update for the charts in the clipboard doc.
250 // Update with the data (including NumberFormatter) from the live document would
251 // also store the NumberFormatter in the clipboard chart (#88749#)
252 // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
254 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
256 TransferableObjectDescriptor aObjDesc
;
257 pDocSh
->FillTransferableObjectDescriptor( aObjDesc
);
258 aObjDesc
.maDisplayName
= pDocSh
->GetMedium()->GetURLObject().GetURLNoPass();
259 // maSize is set in ScDrawTransferObj ctor
261 ScDrawTransferObj
* pTransferObj
= new ScDrawTransferObj( pModel
, pDocSh
, aObjDesc
);
262 uno::Reference
<datatransfer::XTransferable
> xTransferable( pTransferObj
);
264 if ( ScGlobal::pDrawClipDocShellRef
)
266 pTransferObj
->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef
) ); // keep persist for ole objects alive
269 return xTransferable
;
272 // Korrektur fuer 100% berechnen, unabhaengig von momentanen Einstellungen
274 void ScDrawView::CalcNormScale( Fraction
& rFractX
, Fraction
& rFractY
) const
276 Point aLogic
= pDev
->LogicToPixel( Point(1000,1000), MAP_TWIP
);
277 double nPPTX
= ScGlobal::nScreenPPTX
;
278 double nPPTY
= ScGlobal::nScreenPPTY
;
281 nPPTX
/= pViewData
->GetDocShell()->GetOutputFactor();
285 pDoc
->GetTableArea( nTab
, nEndCol
, nEndRow
);
292 ScDrawUtil::CalcScale( pDoc
, nTab
, 0,0, nEndCol
,nEndRow
, pDev
, aZoom
,aZoom
,
293 nPPTX
, nPPTY
, rFractX
,rFractY
);
296 void ScDrawView::SetMarkedOriginalSize()
298 SdrUndoGroup
* pUndoGroup
= new SdrUndoGroup(*GetModel());
300 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
302 ULONG nCount
= rMarkList
.GetMarkCount();
303 for (ULONG i
=0; i
<nCount
; i
++)
305 SdrObject
* pObj
= rMarkList
.GetMark(i
)->GetMarkedSdrObj();
306 USHORT nIdent
= pObj
->GetObjIdentifier();
309 if (nIdent
== OBJ_OLE2
)
311 // TODO/LEAN: working with visual area can switch object to running state
312 uno::Reference
< embed::XEmbeddedObject
> xObj( ((SdrOle2Obj
*)pObj
)->GetObjRef(), uno::UNO_QUERY
);
313 if ( xObj
.is() ) // #121612# NULL for an invalid object that couldn't be loaded
315 sal_Int64 nAspect
= ((SdrOle2Obj
*)pObj
)->GetAspect();
317 if ( nAspect
== embed::Aspects::MSOLE_ICON
)
319 MapMode
aMapMode( MAP_100TH_MM
);
320 aOriginalSize
= ((SdrOle2Obj
*)pObj
)->GetOrigObjSize( &aMapMode
);
325 MapUnit aUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj
->getMapUnit( ((SdrOle2Obj
*)pObj
)->GetAspect() ) );
329 aSz
= xObj
->getVisualAreaSize( ((SdrOle2Obj
*)pObj
)->GetAspect() );
330 aOriginalSize
= OutputDevice::LogicToLogic(
331 Size( aSz
.Width
, aSz
.Height
),
332 aUnit
, MAP_100TH_MM
);
334 } catch( embed::NoVisualAreaSizeException
& )
336 OSL_ENSURE( sal_False
, "Can't get the original size of the object!" );
341 else if (nIdent
== OBJ_GRAF
)
343 const Graphic
& rGraphic
= ((SdrGrafObj
*)pObj
)->GetGraphic();
345 MapMode aSourceMap
= rGraphic
.GetPrefMapMode();
346 MapMode
aDestMap( MAP_100TH_MM
);
347 if (aSourceMap
.GetMapUnit() == MAP_PIXEL
)
349 // Pixel-Korrektur beruecksichtigen, damit Bitmap auf dem Bildschirm stimmt
351 Fraction aNormScaleX
, aNormScaleY
;
352 CalcNormScale( aNormScaleX
, aNormScaleY
);
353 aDestMap
.SetScaleX(aNormScaleX
);
354 aDestMap
.SetScaleY(aNormScaleY
);
358 Window
* pActWin
= pViewData
->GetActiveWin();
361 aOriginalSize
= pActWin
->LogicToLogic(
362 rGraphic
.GetPrefSize(), &aSourceMap
, &aDestMap
);
370 Rectangle aDrawRect
= pObj
->GetLogicRect();
372 pUndoGroup
->AddAction( new SdrUndoGeoObj( *pObj
) );
373 pObj
->Resize( aDrawRect
.TopLeft(), Fraction( aOriginalSize
.Width(), aDrawRect
.GetWidth() ),
374 Fraction( aOriginalSize
.Height(), aDrawRect
.GetHeight() ) );
381 pUndoGroup
->SetComment(ScGlobal::GetRscString( STR_UNDO_ORIGINALSIZE
));
382 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
383 pDocSh
->GetUndoManager()->AddUndoAction(pUndoGroup
);
384 pDocSh
->SetDrawModified();
392 #pragma optimize ( "", on )