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 31 // INCLUDE --------------------------------------------------------------- 32 33 34 35 #include <com/sun/star/beans/XPropertySet.hpp> 36 #include <com/sun/star/beans/XPropertySetInfo.hpp> 37 #include <com/sun/star/form/FormButtonType.hpp> 38 39 #include <tools/urlobj.hxx> 40 #include <sfx2/docfile.hxx> 41 #include <svx/fmglob.hxx> 42 #include <svx/svdograf.hxx> 43 #include <svx/svdouno.hxx> 44 45 #include "seltrans.hxx" 46 #include "transobj.hxx" 47 #include "drwtrans.hxx" 48 #include "scmod.hxx" 49 #include "dbfunc.hxx" // for CopyToClip 50 #include "docsh.hxx" 51 #include "drawview.hxx" 52 #include "drwlayer.hxx" 53 54 using namespace com::sun::star; 55 56 // ----------------------------------------------------------------------- 57 58 sal_Bool lcl_IsURLButton( SdrObject* pObject ) 59 { 60 sal_Bool bRet = sal_False; 61 62 SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObject); 63 if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor()) 64 { 65 uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel(); 66 DBG_ASSERT( xControlModel.is(), "uno control without model" ); 67 if ( xControlModel.is() ) 68 { 69 uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY ); 70 uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo(); 71 72 rtl::OUString sPropButtonType = rtl::OUString::createFromAscii( "ButtonType" ); 73 if(xInfo->hasPropertyByName( sPropButtonType )) 74 { 75 uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType ); 76 form::FormButtonType eTmp; 77 if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL ) 78 bRet = sal_True; 79 } 80 } 81 } 82 83 return bRet; 84 } 85 86 // static 87 88 ScSelectionTransferObj* ScSelectionTransferObj::CreateFromView( ScTabView* pView ) 89 { 90 ScSelectionTransferObj* pRet = NULL; 91 92 if ( pView ) 93 { 94 ScSelectionTransferMode eMode = SC_SELTRANS_INVALID; 95 96 SdrView* pSdrView = pView->GetSdrView(); 97 if ( pSdrView ) 98 { 99 // handle selection on drawing layer 100 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); 101 sal_uLong nMarkCount = rMarkList.GetMarkCount(); 102 if ( nMarkCount ) 103 { 104 if ( nMarkCount == 1 ) 105 { 106 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); 107 sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier(); 108 109 if ( nSdrObjKind == OBJ_GRAF ) 110 { 111 if ( ((SdrGrafObj*)pObj)->GetGraphic().GetType() == GRAPHIC_BITMAP ) 112 eMode = SC_SELTRANS_DRAW_BITMAP; 113 else 114 eMode = SC_SELTRANS_DRAW_GRAPHIC; 115 } 116 else if ( nSdrObjKind == OBJ_OLE2 ) 117 eMode = SC_SELTRANS_DRAW_OLE; 118 else if ( lcl_IsURLButton( pObj ) ) 119 eMode = SC_SELTRANS_DRAW_BOOKMARK; 120 } 121 122 if ( eMode == SC_SELTRANS_INVALID ) 123 eMode = SC_SELTRANS_DRAW_OTHER; // something selected but no special selection 124 } 125 } 126 if ( eMode == SC_SELTRANS_INVALID ) // no drawing object selected 127 { 128 ScRange aRange; 129 ScViewData* pViewData = pView->GetViewData(); 130 const ScMarkData& rMark = pViewData->GetMarkData(); 131 // allow MultiMarked because GetSimpleArea may be able to merge into a simple range 132 // (GetSimpleArea modifies a local copy of MarkData) 133 // Also allow simple filtered area. 134 ScMarkType eMarkType; 135 if ( ( rMark.IsMarked() || rMark.IsMultiMarked() ) && 136 (((eMarkType = pViewData->GetSimpleArea( aRange )) == SC_MARK_SIMPLE) || 137 (eMarkType == SC_MARK_SIMPLE_FILTERED)) ) 138 { 139 // only for "real" selection, cursor alone isn't used 140 if ( aRange.aStart == aRange.aEnd ) 141 eMode = SC_SELTRANS_CELL; 142 else 143 eMode = SC_SELTRANS_CELLS; 144 } 145 } 146 147 if ( eMode != SC_SELTRANS_INVALID ) 148 pRet = new ScSelectionTransferObj( pView, eMode ); 149 } 150 151 return pRet; 152 } 153 154 155 ScSelectionTransferObj::ScSelectionTransferObj( ScTabView* pSource, ScSelectionTransferMode eNewMode ) : 156 pView( pSource ), 157 eMode( eNewMode ), 158 pCellData( NULL ), 159 pDrawData( NULL ) 160 { 161 //! store range for StillValid 162 } 163 164 ScSelectionTransferObj::~ScSelectionTransferObj() 165 { 166 ScModule* pScMod = SC_MOD(); 167 if ( pScMod->GetSelectionTransfer() == this ) 168 { 169 // this is reached when the object wasn't really copied to the selection 170 // (CopyToSelection has no effect under Windows) 171 172 ForgetView(); 173 pScMod->SetSelectionTransfer( NULL ); 174 } 175 176 DBG_ASSERT( !pView, "ScSelectionTransferObj dtor: ForgetView not called" ); 177 } 178 179 sal_Bool ScSelectionTransferObj::StillValid() 180 { 181 //! check if view still has same cell selection 182 //! (but return sal_False if data has changed inbetween) 183 return sal_False; 184 } 185 186 void ScSelectionTransferObj::ForgetView() 187 { 188 pView = NULL; 189 eMode = SC_SELTRANS_INVALID; 190 191 if (pCellData) 192 { 193 pCellData->release(); 194 pCellData = NULL; 195 } 196 if (pDrawData) 197 { 198 pDrawData->release(); 199 pDrawData = NULL; 200 } 201 } 202 203 void ScSelectionTransferObj::AddSupportedFormats() 204 { 205 // AddSupportedFormats must work without actually creating the 206 // "real" transfer object 207 208 switch (eMode) 209 { 210 case SC_SELTRANS_CELL: 211 case SC_SELTRANS_CELLS: 212 // same formats as in ScTransferObj::AddSupportedFormats 213 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); 214 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 215 AddFormat( SOT_FORMAT_GDIMETAFILE ); 216 AddFormat( SOT_FORMAT_BITMAP ); 217 AddFormat( SOT_FORMATSTR_ID_HTML ); 218 AddFormat( SOT_FORMATSTR_ID_SYLK ); 219 AddFormat( SOT_FORMATSTR_ID_LINK ); 220 AddFormat( SOT_FORMATSTR_ID_DIF ); 221 AddFormat( SOT_FORMAT_STRING ); 222 AddFormat( SOT_FORMAT_RTF ); 223 if ( eMode == SC_SELTRANS_CELL ) 224 AddFormat( SOT_FORMATSTR_ID_EDITENGINE ); 225 break; 226 227 // different graphic formats as in ScDrawTransferObj::AddSupportedFormats: 228 229 case SC_SELTRANS_DRAW_BITMAP: 230 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 231 AddFormat( SOT_FORMATSTR_ID_SVXB ); 232 AddFormat( SOT_FORMAT_BITMAP ); 233 AddFormat( SOT_FORMAT_GDIMETAFILE ); 234 break; 235 236 case SC_SELTRANS_DRAW_GRAPHIC: 237 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 238 AddFormat( SOT_FORMATSTR_ID_SVXB ); 239 AddFormat( SOT_FORMAT_GDIMETAFILE ); 240 AddFormat( SOT_FORMAT_BITMAP ); 241 break; 242 243 case SC_SELTRANS_DRAW_BOOKMARK: 244 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 245 AddFormat( SOT_FORMATSTR_ID_SOLK ); 246 AddFormat( SOT_FORMAT_STRING ); 247 AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ); 248 AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ); 249 AddFormat( SOT_FORMATSTR_ID_DRAWING ); 250 break; 251 252 case SC_SELTRANS_DRAW_OLE: 253 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); 254 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 255 AddFormat( SOT_FORMAT_GDIMETAFILE ); 256 break; 257 258 case SC_SELTRANS_DRAW_OTHER: 259 // other drawing objects 260 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); 261 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 262 AddFormat( SOT_FORMATSTR_ID_DRAWING ); 263 AddFormat( SOT_FORMAT_BITMAP ); 264 AddFormat( SOT_FORMAT_GDIMETAFILE ); 265 break; 266 267 default: 268 { 269 // added to avoid warnings 270 } 271 } 272 } 273 274 void ScSelectionTransferObj::CreateCellData() 275 { 276 DBG_ASSERT( !pCellData, "CreateCellData twice" ); 277 if ( pView ) 278 { 279 ScViewData* pViewData = pView->GetViewData(); 280 ScMarkData aNewMark( pViewData->GetMarkData() ); // use local copy for MarkToSimple 281 aNewMark.MarkToSimple(); 282 283 // similar to ScViewFunctionSet::BeginDrag 284 if ( aNewMark.IsMarked() && !aNewMark.IsMultiMarked() ) 285 { 286 ScDocShell* pDocSh = pViewData->GetDocShell(); 287 288 ScRange aSelRange; 289 aNewMark.GetMarkArea( aSelRange ); 290 ScDocShellRef aDragShellRef; 291 if ( pDocSh->GetDocument()->HasOLEObjectsInArea( aSelRange, &aNewMark ) ) 292 { 293 aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately 294 aDragShellRef->DoInitNew(NULL); 295 } 296 ScDrawLayer::SetGlobalDrawPersist(aDragShellRef); 297 298 ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); 299 // bApi = sal_True -> no error mesages 300 // #i18364# bStopEdit = sal_False -> don't end edit mode 301 // (this may be called from pasting into the edit line) 302 sal_Bool bCopied = pViewData->GetView()->CopyToClip( pClipDoc, sal_False, sal_True, sal_True, sal_False ); 303 304 ScDrawLayer::SetGlobalDrawPersist(NULL); 305 306 if ( bCopied ) 307 { 308 TransferableObjectDescriptor aObjDesc; 309 pDocSh->FillTransferableObjectDescriptor( aObjDesc ); 310 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); 311 // maSize is set in ScTransferObj ctor 312 313 ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc ); 314 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); 315 316 // SetDragHandlePos is not used - there is no mouse position 317 //? pTransferObj->SetVisibleTab( nTab ); 318 319 SfxObjectShellRef aPersistRef( aDragShellRef ); 320 pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive 321 322 pTransferObj->SetDragSource( pDocSh, aNewMark ); 323 324 pCellData = pTransferObj; 325 pCellData->acquire(); // keep ref count up - released in ForgetView 326 } 327 else 328 delete pClipDoc; 329 } 330 } 331 DBG_ASSERT( pCellData, "can't create CellData" ); 332 } 333 334 //! make static member of ScDrawView 335 extern void lcl_CheckOle( const SdrMarkList& rMarkList, sal_Bool& rAnyOle, sal_Bool& rOneOle ); 336 337 void ScSelectionTransferObj::CreateDrawData() 338 { 339 DBG_ASSERT( !pDrawData, "CreateDrawData twice" ); 340 if ( pView ) 341 { 342 // similar to ScDrawView::BeginDrag 343 344 ScDrawView* pDrawView = pView->GetScDrawView(); 345 if ( pDrawView ) 346 { 347 sal_Bool bAnyOle, bOneOle; 348 const SdrMarkList& rMarkList = pDrawView->GetMarkedObjectList(); 349 lcl_CheckOle( rMarkList, bAnyOle, bOneOle ); 350 351 //--------------------------------------------------------- 352 ScDocShellRef aDragShellRef; 353 if (bAnyOle) 354 { 355 aDragShellRef = new ScDocShell; // ohne Ref lebt die DocShell nicht !!! 356 aDragShellRef->DoInitNew(NULL); 357 } 358 //--------------------------------------------------------- 359 360 ScDrawLayer::SetGlobalDrawPersist(aDragShellRef); 361 SdrModel* pModel = pDrawView->GetAllMarkedModel(); 362 ScDrawLayer::SetGlobalDrawPersist(NULL); 363 364 ScViewData* pViewData = pView->GetViewData(); 365 ScDocShell* pDocSh = pViewData->GetDocShell(); 366 367 TransferableObjectDescriptor aObjDesc; 368 pDocSh->FillTransferableObjectDescriptor( aObjDesc ); 369 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); 370 // maSize is set in ScDrawTransferObj ctor 371 372 ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc ); 373 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); 374 375 SfxObjectShellRef aPersistRef( aDragShellRef ); 376 pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive 377 pTransferObj->SetDragSource( pDrawView ); // copies selection 378 379 pDrawData = pTransferObj; 380 pDrawData->acquire(); // keep ref count up - released in ForgetView 381 } 382 } 383 DBG_ASSERT( pDrawData, "can't create DrawData" ); 384 } 385 386 ScTransferObj* ScSelectionTransferObj::GetCellData() 387 { 388 if ( !pCellData && ( eMode == SC_SELTRANS_CELL || eMode == SC_SELTRANS_CELLS ) ) 389 CreateCellData(); 390 return pCellData; 391 } 392 393 ScDrawTransferObj* ScSelectionTransferObj::GetDrawData() 394 { 395 if ( !pDrawData && ( eMode == SC_SELTRANS_DRAW_BITMAP || eMode == SC_SELTRANS_DRAW_GRAPHIC || 396 eMode == SC_SELTRANS_DRAW_BOOKMARK || eMode == SC_SELTRANS_DRAW_OLE || 397 eMode == SC_SELTRANS_DRAW_OTHER ) ) 398 CreateDrawData(); 399 return pDrawData; 400 } 401 402 sal_Bool ScSelectionTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor ) 403 { 404 sal_Bool bOK = sal_False; 405 406 uno::Reference<datatransfer::XTransferable> xSource; 407 switch (eMode) 408 { 409 case SC_SELTRANS_CELL: 410 case SC_SELTRANS_CELLS: 411 xSource = GetCellData(); 412 break; 413 case SC_SELTRANS_DRAW_BITMAP: 414 case SC_SELTRANS_DRAW_GRAPHIC: 415 case SC_SELTRANS_DRAW_BOOKMARK: 416 case SC_SELTRANS_DRAW_OLE: 417 case SC_SELTRANS_DRAW_OTHER: 418 xSource = GetDrawData(); 419 break; 420 default: 421 { 422 // added to avoid warnings 423 } 424 } 425 426 if ( xSource.is() ) 427 { 428 TransferableDataHelper aHelper( xSource ); 429 uno::Any aAny = aHelper.GetAny( rFlavor ); 430 bOK = SetAny( aAny, rFlavor ); 431 } 432 433 return bOK; 434 } 435 436 void ScSelectionTransferObj::ObjectReleased() 437 { 438 // called when another selection is set from outside 439 440 ForgetView(); 441 442 ScModule* pScMod = SC_MOD(); 443 if ( pScMod->GetSelectionTransfer() == this ) 444 pScMod->SetSelectionTransfer( NULL ); 445 446 TransferableHelper::ObjectReleased(); 447 } 448 449 450