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