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