fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / view / drawvie4.cxx
blob108d714815c95ee809b4ea95b56ff91dd9899ddc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
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 #include <gridwin.hxx>
44 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
45 #include <com/sun/star/embed/Aspects.hpp>
46 #include <com/sun/star/embed/XEmbeddedObject.hpp>
47 #include <com/sun/star/embed/XComponentSupplier.hpp>
48 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
49 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
50 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
52 using namespace com::sun::star;
54 // STATIC DATA -----------------------------------------------------------
56 Point aDragStartDiff;
58 void ScDrawView::CheckOle( const SdrMarkList& rMarkList, bool& rAnyOle, bool& rOneOle )
60 rAnyOle = rOneOle = false;
61 const size_t nCount = rMarkList.GetMarkCount();
62 for (size_t i=0; i<nCount; ++i)
64 SdrMark* pMark = rMarkList.GetMark(i);
65 SdrObject* pObj = pMark->GetMarkedSdrObj();
66 sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier();
67 if (nSdrObjKind == OBJ_OLE2)
69 rAnyOle = true;
70 rOneOle = (nCount == 1);
71 break;
73 else if ( pObj->ISA(SdrObjGroup) )
75 SdrObjListIter aIter( *pObj, IM_DEEPNOGROUPS );
76 SdrObject* pSubObj = aIter.Next();
77 while (pSubObj)
79 if ( pSubObj->GetObjIdentifier() == OBJ_OLE2 )
81 rAnyOle = true;
82 // rOneOle remains sal_False - a group isn't treated like a single OLE object
83 return;
85 pSubObj = aIter.Next();
91 bool ScDrawView::BeginDrag( vcl::Window* pWindow, const Point& rStartPos )
93 bool bReturn = false;
95 if ( AreObjectsMarked() )
97 BrkAction();
99 Rectangle aMarkedRect = GetAllMarkedRect();
100 vcl::Region aRegion( aMarkedRect );
102 aDragStartDiff = rStartPos - aMarkedRect.TopLeft();
104 bool bAnyOle, bOneOle;
105 const SdrMarkList& rMarkList = GetMarkedObjectList();
106 CheckOle( rMarkList, bAnyOle, bOneOle );
108 ScDocShellRef aDragShellRef;
109 if (bAnyOle)
111 aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately
112 aDragShellRef->DoInitNew(NULL);
114 ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
115 SdrModel* pModel = GetMarkedObjModel();
116 ScDrawLayer::SetGlobalDrawPersist(NULL);
118 // Charts now always copy their data in addition to the source reference, so
119 // there's no need to call SchDLL::Update for the charts in the clipboard doc.
120 // Update with the data (including NumberFormatter) from the live document would
121 // also store the NumberFormatter in the clipboard chart (#88749#)
122 // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
124 ScDocShell* pDocSh = pViewData->GetDocShell();
126 TransferableObjectDescriptor aObjDesc;
127 pDocSh->FillTransferableObjectDescriptor( aObjDesc );
128 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
129 // maSize is set in ScDrawTransferObj ctor
131 ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
132 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
134 pTransferObj->SetDrawPersist( &aDragShellRef ); // keep persist for ole objects alive
135 pTransferObj->SetDragSource( this ); // copies selection
137 SC_MOD()->SetDragObject( NULL, pTransferObj ); // for internal D&D
138 pTransferObj->StartDrag( pWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
141 return bReturn;
144 namespace {
146 void getRangeFromDataSource( uno::Reference< chart2::data::XDataSource > xDataSource, std::vector<OUString>& rRangeRep)
148 uno::Sequence<uno::Reference<chart2::data::XLabeledDataSequence> > xSeqs = xDataSource->getDataSequences();
149 for (sal_Int32 i = 0, n = xSeqs.getLength(); i < n; ++i)
151 uno::Reference<chart2::data::XLabeledDataSequence> xLS = xSeqs[i];
152 uno::Reference<chart2::data::XDataSequence> xSeq = xLS->getValues();
153 if (xSeq.is())
155 OUString aRep = xSeq->getSourceRangeRepresentation();
156 rRangeRep.push_back(aRep);
158 xSeq = xLS->getLabel();
159 if (xSeq.is())
161 OUString aRep = xSeq->getSourceRangeRepresentation();
162 rRangeRep.push_back(aRep);
167 void getRangeFromErrorBar(const uno::Reference< chart2::XChartDocument >& rChartDoc, std::vector<OUString>& rRangeRep)
169 uno::Reference <chart2::XDiagram > xDiagram = rChartDoc->getFirstDiagram();
170 if(!xDiagram.is())
171 return;
173 uno::Reference< chart2::XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY);
174 if(!xCooSysContainer.is())
175 return;
177 uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > xCooSysSequence( xCooSysContainer->getCoordinateSystems());
178 for(sal_Int32 i = 0; i < xCooSysSequence.getLength(); ++i)
180 uno::Reference< chart2::XChartTypeContainer > xChartTypeContainer( xCooSysSequence[i], uno::UNO_QUERY);
181 if(!xChartTypeContainer.is())
182 continue;
184 uno::Sequence< uno::Reference< chart2::XChartType > > xChartTypeSequence( xChartTypeContainer->getChartTypes() );
185 for(sal_Int32 nChartType = 0; nChartType < xChartTypeSequence.getLength(); ++nChartType)
187 uno::Reference< chart2::XDataSeriesContainer > xDataSequenceContainer( xChartTypeSequence[nChartType], uno::UNO_QUERY);
188 if(!xDataSequenceContainer.is())
189 continue;
191 uno::Sequence< uno::Reference< chart2::XDataSeries > > xSeriesSequence( xDataSequenceContainer->getDataSeries() );
192 for(sal_Int32 nDataSeries = 0; nDataSeries < xSeriesSequence.getLength(); ++nDataSeries)
194 uno::Reference< chart2::XDataSeries > xSeries = xSeriesSequence[nDataSeries];
195 uno::Reference< beans::XPropertySet > xPropSet( xSeries, uno::UNO_QUERY);
196 uno::Reference< chart2::data::XDataSource > xErrorBarY;
197 xPropSet->getPropertyValue("ErrorBarY") >>= xErrorBarY;
198 if(xErrorBarY.is())
199 getRangeFromDataSource(xErrorBarY, rRangeRep);
200 uno::Reference< chart2::data::XDataSource > xErrorBarX;
201 xPropSet->getPropertyValue("ErrorBarX") >>= xErrorBarX;
202 if(xErrorBarX.is())
203 getRangeFromDataSource(xErrorBarX, rRangeRep);
209 void getRangeFromOle2Object(const SdrOle2Obj& rObj, std::vector<OUString>& rRangeRep)
211 if (!rObj.IsChart())
212 // not a chart object.
213 return;
215 uno::Reference<embed::XEmbeddedObject> xObj = rObj.GetObjRef();
216 if (!xObj.is())
217 return;
219 uno::Reference<embed::XComponentSupplier> xCompSupp(xObj, uno::UNO_QUERY);
220 if (!xCompSupp.is())
221 return;
223 uno::Reference<chart2::XChartDocument> xChartDoc(xCompSupp->getComponent(), uno::UNO_QUERY);
224 if (!xChartDoc.is())
225 return;
227 if(xChartDoc->hasInternalDataProvider())
228 return;
230 getRangeFromErrorBar(xChartDoc, rRangeRep);
232 uno::Reference<chart2::data::XDataSource> xDataSource(xChartDoc, uno::UNO_QUERY);
233 if (!xDataSource.is())
234 return;
236 // Get all data sources used in this chart.
237 getRangeFromDataSource(xDataSource, rRangeRep);
241 * Get all cell ranges that are referenced by the selected chart objects.
243 void getChartSourceRanges(ScDocument* pDoc, const SdrMarkList& rObjs, std::vector<ScRange>& rRanges)
245 std::vector<OUString> aRangeReps;
246 for (size_t i = 0, n = rObjs.GetMarkCount(); i < n; ++i)
248 const SdrMark* pMark = rObjs.GetMark(i);
249 if (!pMark)
250 continue;
252 const SdrObject* pObj = pMark->GetMarkedSdrObj();
253 if (!pObj)
254 continue;
256 switch (pObj->GetObjIdentifier())
258 case OBJ_OLE2:
259 getRangeFromOle2Object(static_cast<const SdrOle2Obj&>(*pObj), aRangeReps);
260 break;
261 case OBJ_GRUP:
263 SdrObjListIter aIter(*pObj, IM_DEEPNOGROUPS);
264 for (SdrObject* pSubObj = aIter.Next(); pSubObj; pSubObj = aIter.Next())
266 if (pSubObj->GetObjIdentifier() != OBJ_OLE2)
267 continue;
269 getRangeFromOle2Object(static_cast<const SdrOle2Obj&>(*pSubObj), aRangeReps);
273 break;
274 default:
279 // Compile all range representation strings into ranges.
280 std::vector<OUString>::const_iterator it = aRangeReps.begin(), itEnd = aRangeReps.end();
281 for (; it != itEnd; ++it)
283 ScRangeList aRange;
284 ScAddress aAddr;
285 if (aRange.Parse(*it, pDoc, pDoc->GetAddressConvention()) & SCA_VALID)
287 for(size_t i = 0; i < aRange.size(); ++i)
288 rRanges.push_back(*aRange[i]);
290 else if (aAddr.Parse(*it, pDoc, pDoc->GetAddressConvention()) & SCA_VALID)
291 rRanges.push_back(aAddr);
295 class InsertTabIndex : std::unary_function<ScRange, void>
297 std::vector<SCTAB>& mrTabs;
298 public:
299 InsertTabIndex(std::vector<SCTAB>& rTabs) : mrTabs(rTabs) {}
300 void operator() (const ScRange& rRange)
302 mrTabs.push_back(rRange.aStart.Tab());
306 class CopyRangeData : std::unary_function<ScRange, void>
308 ScDocument* mpSrc;
309 ScDocument* mpDest;
310 public:
311 CopyRangeData(ScDocument* pSrc, ScDocument* pDest) : mpSrc(pSrc), mpDest(pDest) {}
313 void operator() (const ScRange& rRange)
315 OUString aTabName;
316 mpSrc->GetName(rRange.aStart.Tab(), aTabName);
318 SCTAB nTab;
319 if (!mpDest->GetTable(aTabName, nTab))
320 // Sheet by this name doesn't exist.
321 return;
323 mpSrc->CopyStaticToDocument(rRange, nTab, mpDest);
327 void copyChartRefDataToClipDoc(ScDocument* pSrcDoc, ScDocument* pClipDoc, const std::vector<ScRange>& rRanges)
329 // Get a list of referenced table indices.
330 std::vector<SCTAB> aTabs;
331 std::for_each(rRanges.begin(), rRanges.end(), InsertTabIndex(aTabs));
332 std::sort(aTabs.begin(), aTabs.end());
333 aTabs.erase(std::unique(aTabs.begin(), aTabs.end()), aTabs.end());
335 // Get table names.
336 if (aTabs.empty())
337 return;
339 // Create sheets only for referenced source sheets.
340 OUString aName;
341 std::vector<SCTAB>::const_iterator it = aTabs.begin(), itEnd = aTabs.end();
342 if (!pSrcDoc->GetName(*it, aName))
343 return;
345 pClipDoc->SetTabNameOnLoad(0, aName); // document initially has one sheet.
347 for (++it; it != itEnd; ++it)
349 if (!pSrcDoc->GetName(*it, aName))
350 return;
352 pClipDoc->AppendTabOnLoad(aName);
355 std::for_each(rRanges.begin(), rRanges.end(), CopyRangeData(pSrcDoc, pClipDoc));
360 void ScDrawView::DoCopy()
362 const SdrMarkList& rMarkList = GetMarkedObjectList();
363 std::vector<ScRange> aRanges;
364 getChartSourceRanges(pDoc, rMarkList, aRanges);
366 // update ScGlobal::pDrawClipDocShellRef
367 ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc(!aRanges.empty()) );
368 if (ScGlobal::pDrawClipDocShellRef)
370 // Copy data referenced by the chart objects to the draw clip
371 // document. We need to do this before GetMarkedObjModel() below.
372 ScDocShellRef xDocSh = *ScGlobal::pDrawClipDocShellRef;
373 ScDocument& rClipDoc = xDocSh->GetDocument();
374 copyChartRefDataToClipDoc(pDoc, &rClipDoc, aRanges);
376 SdrModel* pModel = GetMarkedObjModel();
377 ScDrawLayer::SetGlobalDrawPersist(NULL);
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#)
384 ScDocShell* pDocSh = pViewData->GetDocShell();
386 TransferableObjectDescriptor aObjDesc;
387 pDocSh->FillTransferableObjectDescriptor( aObjDesc );
388 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
389 // maSize is set in ScDrawTransferObj ctor
391 ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
392 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
394 if ( ScGlobal::pDrawClipDocShellRef )
396 pTransferObj->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef) ); // keep persist for ole objects alive
399 pTransferObj->CopyToClipboard( pViewData->GetActiveWin() ); // system clipboard
400 SC_MOD()->SetClipObject( NULL, pTransferObj ); // internal clipboard
403 uno::Reference<datatransfer::XTransferable> ScDrawView::CopyToTransferable()
405 bool bAnyOle, bOneOle;
406 const SdrMarkList& rMarkList = GetMarkedObjectList();
407 CheckOle( rMarkList, bAnyOle, bOneOle );
409 // update ScGlobal::pDrawClipDocShellRef
410 ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
411 SdrModel* pModel = GetMarkedObjModel();
412 ScDrawLayer::SetGlobalDrawPersist(NULL);
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() );
420 ScDocShell* pDocSh = pViewData->GetDocShell();
422 TransferableObjectDescriptor aObjDesc;
423 pDocSh->FillTransferableObjectDescriptor( aObjDesc );
424 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
425 // maSize is set in ScDrawTransferObj ctor
427 ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
428 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
430 if ( ScGlobal::pDrawClipDocShellRef )
432 pTransferObj->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef) ); // keep persist for ole objects alive
435 return xTransferable;
438 // Korrektur fuer 100% berechnen, unabhaengig von momentanen Einstellungen
440 void ScDrawView::CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const
442 double nPPTX = ScGlobal::nScreenPPTX;
443 double nPPTY = ScGlobal::nScreenPPTY;
445 if (pViewData)
446 nPPTX /= pViewData->GetDocShell()->GetOutputFactor();
448 SCCOL nEndCol = 0;
449 SCROW nEndRow = 0;
450 pDoc->GetTableArea( nTab, nEndCol, nEndRow );
451 if (nEndCol<20)
452 nEndCol = 20;
453 if (nEndRow<20)
454 nEndRow = 1000;
456 Fraction aZoom(1,1);
457 ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev, aZoom,aZoom,
458 nPPTX, nPPTY, rFractX,rFractY );
461 void ScDrawView::SetMarkedOriginalSize()
463 SdrUndoGroup* pUndoGroup = new SdrUndoGroup(*GetModel());
465 const SdrMarkList& rMarkList = GetMarkedObjectList();
466 long nDone = 0;
467 const size_t nCount = rMarkList.GetMarkCount();
468 for (size_t i=0; i<nCount; ++i)
470 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
471 sal_uInt16 nIdent = pObj->GetObjIdentifier();
472 bool bDo = false;
473 Size aOriginalSize;
474 if (nIdent == OBJ_OLE2)
476 // TODO/LEAN: working with visual area can switch object to running state
477 uno::Reference < embed::XEmbeddedObject > xObj( static_cast<SdrOle2Obj*>(pObj)->GetObjRef(), uno::UNO_QUERY );
478 if ( xObj.is() ) // NULL for an invalid object that couldn't be loaded
480 sal_Int64 nAspect = static_cast<SdrOle2Obj*>(pObj)->GetAspect();
482 if ( nAspect == embed::Aspects::MSOLE_ICON )
484 MapMode aMapMode( MAP_100TH_MM );
485 aOriginalSize = static_cast<SdrOle2Obj*>(pObj)->GetOrigObjSize( &aMapMode );
486 bDo = true;
488 else
490 MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( static_cast<SdrOle2Obj*>(pObj)->GetAspect() ) );
491 awt::Size aSz;
494 aSz = xObj->getVisualAreaSize( static_cast<SdrOle2Obj*>(pObj)->GetAspect() );
495 aOriginalSize = OutputDevice::LogicToLogic(
496 Size( aSz.Width, aSz.Height ),
497 aUnit, MAP_100TH_MM );
498 bDo = true;
499 } catch( embed::NoVisualAreaSizeException& )
501 OSL_ENSURE( false, "Can't get the original size of the object!" );
506 else if (nIdent == OBJ_GRAF)
508 const Graphic& rGraphic = static_cast<SdrGrafObj*>(pObj)->GetGraphic();
510 MapMode aSourceMap = rGraphic.GetPrefMapMode();
511 MapMode aDestMap( MAP_100TH_MM );
512 if (aSourceMap.GetMapUnit() == MAP_PIXEL)
514 // Pixel-Korrektur beruecksichtigen, damit Bitmap auf dem Bildschirm stimmt
516 Fraction aNormScaleX, aNormScaleY;
517 CalcNormScale( aNormScaleX, aNormScaleY );
518 aDestMap.SetScaleX(aNormScaleX);
519 aDestMap.SetScaleY(aNormScaleY);
521 if (pViewData)
523 vcl::Window* pActWin = pViewData->GetActiveWin();
524 if (pActWin)
526 aOriginalSize = pActWin->LogicToLogic(
527 rGraphic.GetPrefSize(), &aSourceMap, &aDestMap );
528 bDo = true;
533 if ( bDo )
535 Rectangle aDrawRect = pObj->GetLogicRect();
537 pUndoGroup->AddAction( new SdrUndoGeoObj( *pObj ) );
538 pObj->Resize( aDrawRect.TopLeft(), Fraction( aOriginalSize.Width(), aDrawRect.GetWidth() ),
539 Fraction( aOriginalSize.Height(), aDrawRect.GetHeight() ) );
540 ++nDone;
544 if (nDone && pViewData)
546 pUndoGroup->SetComment(ScGlobal::GetRscString( STR_UNDO_ORIGINALSIZE ));
547 ScDocShell* pDocSh = pViewData->GetDocShell();
548 pDocSh->GetUndoManager()->AddUndoAction(pUndoGroup);
549 pDocSh->SetDrawModified();
551 else
552 delete pUndoGroup;
555 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */