Line data Source code
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 <svx/svditer.hxx>
21 : #include <svx/svdograf.hxx>
22 : #include <svx/svdogrp.hxx>
23 : #include <svx/svdoole2.hxx>
24 : #include <svx/svdpage.hxx>
25 : #include <svx/svdundo.hxx>
26 : #include <sfx2/docfile.hxx>
27 : #include <tools/urlobj.hxx>
28 : #include <toolkit/helper/vclunohelper.hxx>
29 :
30 : #include "drawview.hxx"
31 : #include "global.hxx"
32 : #include "drwlayer.hxx"
33 : #include "viewdata.hxx"
34 : #include "document.hxx"
35 : #include "docsh.hxx"
36 : #include "drwtrans.hxx"
37 : #include "transobj.hxx"
38 : #include "drawutil.hxx"
39 : #include "scmod.hxx"
40 : #include "globstr.hrc"
41 : #include "chartarr.hxx"
42 :
43 : #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
44 : #include <com/sun/star/embed/Aspects.hpp>
45 : #include <com/sun/star/embed/XEmbeddedObject.hpp>
46 : #include <com/sun/star/embed/XComponentSupplier.hpp>
47 : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
48 : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
49 : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
50 :
51 : using namespace com::sun::star;
52 :
53 : // STATIC DATA -----------------------------------------------------------
54 :
55 0 : Point aDragStartDiff;
56 :
57 0 : void ScDrawView::CheckOle( const SdrMarkList& rMarkList, bool& rAnyOle, bool& rOneOle )
58 : {
59 0 : rAnyOle = rOneOle = false;
60 0 : sal_uLong nCount = rMarkList.GetMarkCount();
61 0 : for (sal_uLong i=0; i<nCount; i++)
62 : {
63 0 : SdrMark* pMark = rMarkList.GetMark(i);
64 0 : SdrObject* pObj = pMark->GetMarkedSdrObj();
65 0 : sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier();
66 0 : if (nSdrObjKind == OBJ_OLE2)
67 : {
68 0 : rAnyOle = true;
69 0 : rOneOle = (nCount == 1);
70 0 : break;
71 : }
72 0 : else if ( pObj->ISA(SdrObjGroup) )
73 : {
74 0 : SdrObjListIter aIter( *pObj, IM_DEEPNOGROUPS );
75 0 : SdrObject* pSubObj = aIter.Next();
76 0 : while (pSubObj)
77 : {
78 0 : if ( pSubObj->GetObjIdentifier() == OBJ_OLE2 )
79 : {
80 0 : rAnyOle = true;
81 : // rOneOle remains sal_False - a group isn't treated like a single OLE object
82 0 : return;
83 : }
84 0 : pSubObj = aIter.Next();
85 0 : }
86 : }
87 : }
88 : }
89 :
90 0 : bool ScDrawView::BeginDrag( Window* pWindow, const Point& rStartPos )
91 : {
92 0 : bool bReturn = false;
93 :
94 0 : if ( AreObjectsMarked() )
95 : {
96 0 : BrkAction();
97 :
98 0 : Rectangle aMarkedRect = GetAllMarkedRect();
99 0 : Region aRegion( aMarkedRect );
100 :
101 0 : aDragStartDiff = rStartPos - aMarkedRect.TopLeft();
102 :
103 : bool bAnyOle, bOneOle;
104 0 : const SdrMarkList& rMarkList = GetMarkedObjectList();
105 0 : CheckOle( rMarkList, bAnyOle, bOneOle );
106 :
107 0 : ScDocShellRef aDragShellRef;
108 0 : if (bAnyOle)
109 : {
110 0 : aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately
111 0 : aDragShellRef->DoInitNew(NULL);
112 : }
113 0 : ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
114 0 : SdrModel* pModel = GetMarkedObjModel();
115 0 : ScDrawLayer::SetGlobalDrawPersist(NULL);
116 :
117 : // Charts now always copy their data in addition to the source reference, so
118 : // there's no need to call SchDLL::Update for the charts in the clipboard doc.
119 : // Update with the data (including NumberFormatter) from the live document would
120 : // also store the NumberFormatter in the clipboard chart (#88749#)
121 : // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
122 :
123 0 : ScDocShell* pDocSh = pViewData->GetDocShell();
124 :
125 0 : TransferableObjectDescriptor aObjDesc;
126 0 : pDocSh->FillTransferableObjectDescriptor( aObjDesc );
127 0 : aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
128 : // maSize is set in ScDrawTransferObj ctor
129 :
130 0 : ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
131 0 : uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
132 :
133 0 : pTransferObj->SetDrawPersist( &aDragShellRef ); // keep persist for ole objects alive
134 0 : pTransferObj->SetDragSource( this ); // copies selection
135 :
136 0 : SC_MOD()->SetDragObject( NULL, pTransferObj ); // for internal D&D
137 0 : pTransferObj->StartDrag( pWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
138 : }
139 :
140 0 : return bReturn;
141 : }
142 :
143 : namespace {
144 :
145 0 : void getRangeFromDataSource( uno::Reference< chart2::data::XDataSource > xDataSource, std::vector<OUString>& rRangeRep)
146 : {
147 0 : uno::Sequence<uno::Reference<chart2::data::XLabeledDataSequence> > xSeqs = xDataSource->getDataSequences();
148 0 : for (sal_Int32 i = 0, n = xSeqs.getLength(); i < n; ++i)
149 : {
150 0 : uno::Reference<chart2::data::XLabeledDataSequence> xLS = xSeqs[i];
151 0 : uno::Reference<chart2::data::XDataSequence> xSeq = xLS->getValues();
152 0 : if (xSeq.is())
153 : {
154 0 : OUString aRep = xSeq->getSourceRangeRepresentation();
155 0 : rRangeRep.push_back(aRep);
156 : }
157 0 : xSeq = xLS->getLabel();
158 0 : if (xSeq.is())
159 : {
160 0 : OUString aRep = xSeq->getSourceRangeRepresentation();
161 0 : rRangeRep.push_back(aRep);
162 : }
163 0 : }
164 0 : }
165 :
166 :
167 0 : void getRangeFromErrorBar(const uno::Reference< chart2::XChartDocument > xChartDoc, std::vector<OUString>& rRangeRep)
168 : {
169 0 : uno::Reference <chart2::XDiagram > xDiagram = xChartDoc->getFirstDiagram();
170 0 : if(!xDiagram.is())
171 0 : return;
172 :
173 0 : uno::Reference< chart2::XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY);
174 0 : if(!xCooSysContainer.is())
175 0 : return;
176 :
177 0 : uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > xCooSysSequence( xCooSysContainer->getCoordinateSystems());
178 0 : for(sal_Int32 i = 0; i < xCooSysSequence.getLength(); ++i)
179 : {
180 0 : uno::Reference< chart2::XChartTypeContainer > xChartTypeContainer( xCooSysSequence[i], uno::UNO_QUERY);
181 0 : if(!xChartTypeContainer.is())
182 0 : continue;
183 :
184 0 : uno::Sequence< uno::Reference< chart2::XChartType > > xChartTypeSequence( xChartTypeContainer->getChartTypes() );
185 0 : for(sal_Int32 nChartType = 0; nChartType < xChartTypeSequence.getLength(); ++nChartType)
186 : {
187 0 : uno::Reference< chart2::XDataSeriesContainer > xDataSequenceContainer( xChartTypeSequence[nChartType], uno::UNO_QUERY);
188 0 : if(!xDataSequenceContainer.is())
189 0 : continue;
190 :
191 0 : uno::Sequence< uno::Reference< chart2::XDataSeries > > xSeriesSequence( xDataSequenceContainer->getDataSeries() );
192 0 : for(sal_Int32 nDataSeries = 0; nDataSeries < xSeriesSequence.getLength(); ++nDataSeries)
193 : {
194 0 : uno::Reference< chart2::XDataSeries > xSeries = xSeriesSequence[nDataSeries];
195 0 : uno::Reference< beans::XPropertySet > xPropSet( xSeries, uno::UNO_QUERY);
196 0 : uno::Reference< chart2::data::XDataSource > xErrorBarY;
197 0 : xPropSet->getPropertyValue("ErrorBarY") >>= xErrorBarY;
198 0 : if(xErrorBarY.is())
199 0 : getRangeFromDataSource(xErrorBarY, rRangeRep);
200 0 : uno::Reference< chart2::data::XDataSource > xErrorBarX;
201 0 : xPropSet->getPropertyValue("ErrorBarX") >>= xErrorBarX;
202 0 : if(xErrorBarX.is())
203 0 : getRangeFromDataSource(xErrorBarX, rRangeRep);
204 0 : }
205 0 : }
206 0 : }
207 : }
208 :
209 0 : void getRangeFromOle2Object(const SdrOle2Obj& rObj, std::vector<OUString>& rRangeRep)
210 : {
211 0 : if (!rObj.IsChart())
212 : // not a chart object.
213 0 : return;
214 :
215 0 : uno::Reference<embed::XEmbeddedObject> xObj = rObj.GetObjRef();
216 0 : if (!xObj.is())
217 0 : return;
218 :
219 0 : uno::Reference<embed::XComponentSupplier> xCompSupp(xObj, uno::UNO_QUERY);
220 0 : if (!xCompSupp.is())
221 0 : return;
222 :
223 0 : uno::Reference<chart2::XChartDocument> xChartDoc(xCompSupp->getComponent(), uno::UNO_QUERY);
224 0 : if (!xChartDoc.is())
225 0 : return;
226 :
227 0 : if(xChartDoc->hasInternalDataProvider())
228 0 : return;
229 :
230 0 : getRangeFromErrorBar(xChartDoc, rRangeRep);
231 :
232 0 : uno::Reference<chart2::data::XDataSource> xDataSource(xChartDoc, uno::UNO_QUERY);
233 0 : if (!xDataSource.is())
234 0 : return;
235 :
236 : // Get all data sources used in this chart.
237 0 : getRangeFromDataSource(xDataSource, rRangeRep);
238 : }
239 :
240 : /**
241 : * Get all cell ranges that are referenced by the selected chart objects.
242 : */
243 0 : void getChartSourceRanges(ScDocument* pDoc, const SdrMarkList& rObjs, std::vector<ScRange>& rRanges)
244 : {
245 0 : std::vector<OUString> aRangeReps;
246 0 : for (size_t i = 0, n = rObjs.GetMarkCount(); i < n; ++i)
247 : {
248 0 : const SdrMark* pMark = rObjs.GetMark(i);
249 0 : if (!pMark)
250 0 : continue;
251 :
252 0 : const SdrObject* pObj = pMark->GetMarkedSdrObj();
253 0 : if (!pObj)
254 0 : continue;
255 :
256 0 : switch (pObj->GetObjIdentifier())
257 : {
258 : case OBJ_OLE2:
259 0 : getRangeFromOle2Object(static_cast<const SdrOle2Obj&>(*pObj), aRangeReps);
260 0 : break;
261 : case OBJ_GRUP:
262 : {
263 0 : SdrObjListIter aIter(*pObj, IM_DEEPNOGROUPS);
264 0 : for (SdrObject* pSubObj = aIter.Next(); pSubObj; pSubObj = aIter.Next())
265 : {
266 0 : if (pSubObj->GetObjIdentifier() != OBJ_OLE2)
267 0 : continue;
268 :
269 0 : getRangeFromOle2Object(static_cast<const SdrOle2Obj&>(*pSubObj), aRangeReps);
270 0 : }
271 :
272 : }
273 0 : break;
274 : default:
275 : ;
276 : }
277 : }
278 :
279 : // Compile all range representation strings into ranges.
280 0 : std::vector<OUString>::const_iterator it = aRangeReps.begin(), itEnd = aRangeReps.end();
281 0 : for (; it != itEnd; ++it)
282 : {
283 0 : ScRangeList aRange;
284 0 : ScAddress aAddr;
285 0 : if (aRange.Parse(*it, pDoc, pDoc->GetAddressConvention()) & SCA_VALID)
286 : {
287 0 : for(size_t i = 0; i < aRange.size(); ++i)
288 0 : rRanges.push_back(*aRange[i]);
289 : }
290 0 : else if (aAddr.Parse(*it, pDoc, pDoc->GetAddressConvention()) & SCA_VALID)
291 0 : rRanges.push_back(aAddr);
292 0 : }
293 0 : }
294 :
295 : class InsertTabIndex : std::unary_function<ScRange, void>
296 : {
297 : std::vector<SCTAB>& mrTabs;
298 : public:
299 0 : InsertTabIndex(std::vector<SCTAB>& rTabs) : mrTabs(rTabs) {}
300 0 : void operator() (const ScRange& rRange)
301 : {
302 0 : mrTabs.push_back(rRange.aStart.Tab());
303 0 : }
304 : };
305 :
306 : class CopyRangeData : std::unary_function<ScRange, void>
307 : {
308 : ScDocument* mpSrc;
309 : ScDocument* mpDest;
310 : public:
311 0 : CopyRangeData(ScDocument* pSrc, ScDocument* pDest) : mpSrc(pSrc), mpDest(pDest) {}
312 :
313 0 : void operator() (const ScRange& rRange)
314 : {
315 0 : OUString aTabName;
316 0 : mpSrc->GetName(rRange.aStart.Tab(), aTabName);
317 :
318 : SCTAB nTab;
319 0 : if (!mpDest->GetTable(aTabName, nTab))
320 : // Sheet by this name doesn't exist.
321 0 : return;
322 :
323 0 : mpSrc->CopyStaticToDocument(rRange, nTab, mpDest);
324 : }
325 : };
326 :
327 0 : void copyChartRefDataToClipDoc(ScDocument* pSrcDoc, ScDocument* pClipDoc, const std::vector<ScRange>& rRanges)
328 : {
329 : // Get a list of referenced table indices.
330 0 : std::vector<SCTAB> aTabs;
331 0 : std::for_each(rRanges.begin(), rRanges.end(), InsertTabIndex(aTabs));
332 0 : std::sort(aTabs.begin(), aTabs.end());
333 0 : aTabs.erase(std::unique(aTabs.begin(), aTabs.end()), aTabs.end());
334 :
335 : // Get table names.
336 0 : if (aTabs.empty())
337 0 : return;
338 :
339 : // Create sheets only for referenced source sheets.
340 0 : OUString aName;
341 0 : std::vector<SCTAB>::const_iterator it = aTabs.begin(), itEnd = aTabs.end();
342 0 : if (!pSrcDoc->GetName(*it, aName))
343 0 : return;
344 :
345 0 : pClipDoc->SetTabNameOnLoad(0, aName); // document initially has one sheet.
346 :
347 0 : for (++it; it != itEnd; ++it)
348 : {
349 0 : if (!pSrcDoc->GetName(*it, aName))
350 0 : return;
351 :
352 0 : pClipDoc->AppendTabOnLoad(aName);
353 : }
354 :
355 0 : std::for_each(rRanges.begin(), rRanges.end(), CopyRangeData(pSrcDoc, pClipDoc));
356 : }
357 :
358 : }
359 :
360 0 : void ScDrawView::DoCopy()
361 : {
362 0 : const SdrMarkList& rMarkList = GetMarkedObjectList();
363 0 : std::vector<ScRange> aRanges;
364 0 : getChartSourceRanges(pDoc, rMarkList, aRanges);
365 :
366 : // update ScGlobal::pDrawClipDocShellRef
367 0 : ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc(!aRanges.empty()) );
368 0 : if (ScGlobal::pDrawClipDocShellRef)
369 : {
370 : // Copy data referenced by the chart objects to the draw clip
371 : // document. We need to do this before GetMarkedObjModel() below.
372 0 : ScDocShellRef xDocSh = *ScGlobal::pDrawClipDocShellRef;
373 0 : ScDocument* pClipDoc = xDocSh->GetDocument();
374 0 : copyChartRefDataToClipDoc(pDoc, pClipDoc, aRanges);
375 : }
376 0 : SdrModel* pModel = GetMarkedObjModel();
377 0 : ScDrawLayer::SetGlobalDrawPersist(NULL);
378 :
379 : // Charts now always copy their data in addition to the source reference, so
380 : // there's no need to call SchDLL::Update for the charts in the clipboard doc.
381 : // Update with the data (including NumberFormatter) from the live document would
382 : // also store the NumberFormatter in the clipboard chart (#88749#)
383 :
384 0 : ScDocShell* pDocSh = pViewData->GetDocShell();
385 :
386 0 : TransferableObjectDescriptor aObjDesc;
387 0 : pDocSh->FillTransferableObjectDescriptor( aObjDesc );
388 0 : aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
389 : // maSize is set in ScDrawTransferObj ctor
390 :
391 0 : ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
392 0 : uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
393 :
394 0 : if ( ScGlobal::pDrawClipDocShellRef )
395 : {
396 0 : pTransferObj->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef) ); // keep persist for ole objects alive
397 : }
398 :
399 0 : pTransferObj->CopyToClipboard( pViewData->GetActiveWin() ); // system clipboard
400 0 : SC_MOD()->SetClipObject( NULL, pTransferObj ); // internal clipboard
401 0 : }
402 :
403 0 : uno::Reference<datatransfer::XTransferable> ScDrawView::CopyToTransferable()
404 : {
405 : bool bAnyOle, bOneOle;
406 0 : const SdrMarkList& rMarkList = GetMarkedObjectList();
407 0 : CheckOle( rMarkList, bAnyOle, bOneOle );
408 :
409 : // update ScGlobal::pDrawClipDocShellRef
410 0 : ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
411 0 : SdrModel* pModel = GetMarkedObjModel();
412 0 : ScDrawLayer::SetGlobalDrawPersist(NULL);
413 :
414 : // Charts now always copy their data in addition to the source reference, so
415 : // there's no need to call SchDLL::Update for the charts in the clipboard doc.
416 : // Update with the data (including NumberFormatter) from the live document would
417 : // also store the NumberFormatter in the clipboard chart (#88749#)
418 : // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
419 :
420 0 : ScDocShell* pDocSh = pViewData->GetDocShell();
421 :
422 0 : TransferableObjectDescriptor aObjDesc;
423 0 : pDocSh->FillTransferableObjectDescriptor( aObjDesc );
424 0 : aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
425 : // maSize is set in ScDrawTransferObj ctor
426 :
427 0 : ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
428 0 : uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
429 :
430 0 : if ( ScGlobal::pDrawClipDocShellRef )
431 : {
432 0 : pTransferObj->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef) ); // keep persist for ole objects alive
433 : }
434 :
435 0 : return xTransferable;
436 : }
437 :
438 : // Korrektur fuer 100% berechnen, unabhaengig von momentanen Einstellungen
439 :
440 0 : void ScDrawView::CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const
441 : {
442 0 : double nPPTX = ScGlobal::nScreenPPTX;
443 0 : double nPPTY = ScGlobal::nScreenPPTY;
444 :
445 0 : if (pViewData)
446 0 : nPPTX /= pViewData->GetDocShell()->GetOutputFactor();
447 :
448 0 : SCCOL nEndCol = 0;
449 0 : SCROW nEndRow = 0;
450 0 : pDoc->GetTableArea( nTab, nEndCol, nEndRow );
451 0 : if (nEndCol<20)
452 0 : nEndCol = 20;
453 0 : if (nEndRow<20)
454 0 : nEndRow = 1000;
455 :
456 0 : Fraction aZoom(1,1);
457 : ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev, aZoom,aZoom,
458 0 : nPPTX, nPPTY, rFractX,rFractY );
459 0 : }
460 :
461 0 : void ScDrawView::SetMarkedOriginalSize()
462 : {
463 0 : SdrUndoGroup* pUndoGroup = new SdrUndoGroup(*GetModel());
464 :
465 0 : const SdrMarkList& rMarkList = GetMarkedObjectList();
466 0 : long nDone = 0;
467 0 : sal_uLong nCount = rMarkList.GetMarkCount();
468 0 : for (sal_uLong i=0; i<nCount; i++)
469 : {
470 0 : SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
471 0 : sal_uInt16 nIdent = pObj->GetObjIdentifier();
472 0 : sal_Bool bDo = false;
473 0 : Size aOriginalSize;
474 0 : if (nIdent == OBJ_OLE2)
475 : {
476 : // TODO/LEAN: working with visual area can switch object to running state
477 0 : uno::Reference < embed::XEmbeddedObject > xObj( ((SdrOle2Obj*)pObj)->GetObjRef(), uno::UNO_QUERY );
478 0 : if ( xObj.is() ) // NULL for an invalid object that couldn't be loaded
479 : {
480 0 : sal_Int64 nAspect = ((SdrOle2Obj*)pObj)->GetAspect();
481 :
482 0 : if ( nAspect == embed::Aspects::MSOLE_ICON )
483 : {
484 0 : MapMode aMapMode( MAP_100TH_MM );
485 0 : aOriginalSize = ((SdrOle2Obj*)pObj)->GetOrigObjSize( &aMapMode );
486 0 : bDo = sal_True;
487 : }
488 : else
489 : {
490 0 : MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( ((SdrOle2Obj*)pObj)->GetAspect() ) );
491 0 : awt::Size aSz;
492 : try
493 : {
494 0 : aSz = xObj->getVisualAreaSize( ((SdrOle2Obj*)pObj)->GetAspect() );
495 : aOriginalSize = OutputDevice::LogicToLogic(
496 : Size( aSz.Width, aSz.Height ),
497 0 : aUnit, MAP_100TH_MM );
498 0 : bDo = sal_True;
499 0 : } catch( embed::NoVisualAreaSizeException& )
500 : {
501 : OSL_ENSURE( false, "Can't get the original size of the object!" );
502 : }
503 : }
504 0 : }
505 : }
506 0 : else if (nIdent == OBJ_GRAF)
507 : {
508 0 : const Graphic& rGraphic = ((SdrGrafObj*)pObj)->GetGraphic();
509 :
510 0 : MapMode aSourceMap = rGraphic.GetPrefMapMode();
511 0 : MapMode aDestMap( MAP_100TH_MM );
512 0 : if (aSourceMap.GetMapUnit() == MAP_PIXEL)
513 : {
514 : // Pixel-Korrektur beruecksichtigen, damit Bitmap auf dem Bildschirm stimmt
515 :
516 0 : Fraction aNormScaleX, aNormScaleY;
517 0 : CalcNormScale( aNormScaleX, aNormScaleY );
518 0 : aDestMap.SetScaleX(aNormScaleX);
519 0 : aDestMap.SetScaleY(aNormScaleY);
520 : }
521 0 : if (pViewData)
522 : {
523 0 : Window* pActWin = pViewData->GetActiveWin();
524 0 : if (pActWin)
525 : {
526 : aOriginalSize = pActWin->LogicToLogic(
527 0 : rGraphic.GetPrefSize(), &aSourceMap, &aDestMap );
528 0 : bDo = sal_True;
529 : }
530 0 : }
531 : }
532 :
533 0 : if ( bDo )
534 : {
535 0 : Rectangle aDrawRect = pObj->GetLogicRect();
536 :
537 0 : pUndoGroup->AddAction( new SdrUndoGeoObj( *pObj ) );
538 0 : pObj->Resize( aDrawRect.TopLeft(), Fraction( aOriginalSize.Width(), aDrawRect.GetWidth() ),
539 0 : Fraction( aOriginalSize.Height(), aDrawRect.GetHeight() ) );
540 0 : ++nDone;
541 : }
542 : }
543 :
544 0 : if (nDone && pViewData)
545 : {
546 0 : pUndoGroup->SetComment(ScGlobal::GetRscString( STR_UNDO_ORIGINALSIZE ));
547 0 : ScDocShell* pDocSh = pViewData->GetDocShell();
548 0 : pDocSh->GetUndoManager()->AddUndoAction(pUndoGroup);
549 0 : pDocSh->SetDrawModified();
550 : }
551 : else
552 0 : delete pUndoGroup;
553 0 : }
554 :
555 :
556 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|