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 27 // INCLUDE --------------------------------------------------------------- 28 29 30 31 #include <com/sun/star/beans/XPropertySet.hpp> 32 #include <com/sun/star/beans/XPropertySetInfo.hpp> 33 #include <com/sun/star/form/FormButtonType.hpp> 34 35 #include <tools/urlobj.hxx> 36 #include <sfx2/docfile.hxx> 37 #include <svx/fmglob.hxx> 38 #include <svx/svdograf.hxx> 39 #include <svx/svdouno.hxx> 40 41 #include "seltrans.hxx" 42 #include "transobj.hxx" 43 #include "drwtrans.hxx" 44 #include "scmod.hxx" 45 #include "dbfunc.hxx" // for CopyToClip 46 #include "docsh.hxx" 47 #include "drawview.hxx" 48 #include "drwlayer.hxx" 49 50 using namespace com::sun::star; 51 52 // ----------------------------------------------------------------------- 53 54 sal_Bool lcl_IsURLButton( SdrObject* pObject ) 55 { 56 sal_Bool bRet = sal_False; 57 58 SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObject); 59 if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor()) 60 { 61 uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel(); 62 DBG_ASSERT( xControlModel.is(), "uno control without model" ); 63 if ( xControlModel.is() ) 64 { 65 uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY ); 66 uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo(); 67 68 rtl::OUString sPropButtonType = rtl::OUString::createFromAscii( "ButtonType" ); 69 if(xInfo->hasPropertyByName( sPropButtonType )) 70 { 71 uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType ); 72 form::FormButtonType eTmp; 73 if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL ) 74 bRet = sal_True; 75 } 76 } 77 } 78 79 return bRet; 80 } 81 82 // static 83 84 ScSelectionTransferObj* ScSelectionTransferObj::CreateFromView( ScTabView* pView ) 85 { 86 ScSelectionTransferObj* pRet = NULL; 87 88 if ( pView ) 89 { 90 ScSelectionTransferMode eMode = SC_SELTRANS_INVALID; 91 92 SdrView* pSdrView = pView->GetSdrView(); 93 if ( pSdrView ) 94 { 95 // handle selection on drawing layer 96 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); 97 sal_uLong nMarkCount = rMarkList.GetMarkCount(); 98 if ( nMarkCount ) 99 { 100 if ( nMarkCount == 1 ) 101 { 102 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); 103 sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier(); 104 105 if ( nSdrObjKind == OBJ_GRAF ) 106 { 107 if ( ((SdrGrafObj*)pObj)->GetGraphic().GetType() == GRAPHIC_BITMAP ) 108 eMode = SC_SELTRANS_DRAW_BITMAP; 109 else 110 eMode = SC_SELTRANS_DRAW_GRAPHIC; 111 } 112 else if ( nSdrObjKind == OBJ_OLE2 ) 113 eMode = SC_SELTRANS_DRAW_OLE; 114 else if ( lcl_IsURLButton( pObj ) ) 115 eMode = SC_SELTRANS_DRAW_BOOKMARK; 116 } 117 118 if ( eMode == SC_SELTRANS_INVALID ) 119 eMode = SC_SELTRANS_DRAW_OTHER; // something selected but no special selection 120 } 121 } 122 if ( eMode == SC_SELTRANS_INVALID ) // no drawing object selected 123 { 124 ScRange aRange; 125 ScViewData* pViewData = pView->GetViewData(); 126 const ScMarkData& rMark = pViewData->GetMarkData(); 127 // allow MultiMarked because GetSimpleArea may be able to merge into a simple range 128 // (GetSimpleArea modifies a local copy of MarkData) 129 // Also allow simple filtered area. 130 ScMarkType eMarkType; 131 if ( ( rMark.IsMarked() || rMark.IsMultiMarked() ) && 132 (((eMarkType = pViewData->GetSimpleArea( aRange )) == SC_MARK_SIMPLE) || 133 (eMarkType == SC_MARK_SIMPLE_FILTERED)) ) 134 { 135 // only for "real" selection, cursor alone isn't used 136 if ( aRange.aStart == aRange.aEnd ) 137 eMode = SC_SELTRANS_CELL; 138 else 139 eMode = SC_SELTRANS_CELLS; 140 } 141 } 142 143 if ( eMode != SC_SELTRANS_INVALID ) 144 pRet = new ScSelectionTransferObj( pView, eMode ); 145 } 146 147 return pRet; 148 } 149 150 151 ScSelectionTransferObj::ScSelectionTransferObj( ScTabView* pSource, ScSelectionTransferMode eNewMode ) : 152 pView( pSource ), 153 eMode( eNewMode ), 154 pCellData( NULL ), 155 pDrawData( NULL ) 156 { 157 //! store range for StillValid 158 } 159 160 ScSelectionTransferObj::~ScSelectionTransferObj() 161 { 162 ScModule* pScMod = SC_MOD(); 163 if ( pScMod->GetSelectionTransfer() == this ) 164 { 165 // this is reached when the object wasn't really copied to the selection 166 // (CopyToSelection has no effect under Windows) 167 168 ForgetView(); 169 pScMod->SetSelectionTransfer( NULL ); 170 } 171 172 DBG_ASSERT( !pView, "ScSelectionTransferObj dtor: ForgetView not called" ); 173 } 174 175 sal_Bool ScSelectionTransferObj::StillValid() 176 { 177 //! check if view still has same cell selection 178 //! (but return sal_False if data has changed inbetween) 179 return sal_False; 180 } 181 182 void ScSelectionTransferObj::ForgetView() 183 { 184 pView = NULL; 185 eMode = SC_SELTRANS_INVALID; 186 187 if (pCellData) 188 { 189 pCellData->release(); 190 pCellData = NULL; 191 } 192 if (pDrawData) 193 { 194 pDrawData->release(); 195 pDrawData = NULL; 196 } 197 } 198 199 void ScSelectionTransferObj::AddSupportedFormats() 200 { 201 // AddSupportedFormats must work without actually creating the 202 // "real" transfer object 203 204 switch (eMode) 205 { 206 case SC_SELTRANS_CELL: 207 case SC_SELTRANS_CELLS: 208 // same formats as in ScTransferObj::AddSupportedFormats 209 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); 210 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 211 AddFormat( SOT_FORMAT_GDIMETAFILE ); 212 AddFormat( SOT_FORMATSTR_ID_PNG ); 213 AddFormat( SOT_FORMAT_BITMAP ); 214 AddFormat( SOT_FORMATSTR_ID_HTML ); 215 AddFormat( SOT_FORMATSTR_ID_SYLK ); 216 AddFormat( SOT_FORMATSTR_ID_LINK ); 217 AddFormat( SOT_FORMATSTR_ID_DIF ); 218 AddFormat( SOT_FORMAT_STRING ); 219 AddFormat( SOT_FORMAT_RTF ); 220 if ( eMode == SC_SELTRANS_CELL ) 221 AddFormat( SOT_FORMATSTR_ID_EDITENGINE ); 222 break; 223 224 // different graphic formats as in ScDrawTransferObj::AddSupportedFormats: 225 226 case SC_SELTRANS_DRAW_BITMAP: 227 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 228 AddFormat( SOT_FORMATSTR_ID_SVXB ); 229 AddFormat( SOT_FORMATSTR_ID_PNG ); 230 AddFormat( SOT_FORMAT_BITMAP ); 231 AddFormat( SOT_FORMAT_GDIMETAFILE ); 232 break; 233 234 case SC_SELTRANS_DRAW_GRAPHIC: 235 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 236 AddFormat( SOT_FORMATSTR_ID_SVXB ); 237 AddFormat( SOT_FORMAT_GDIMETAFILE ); 238 AddFormat( SOT_FORMATSTR_ID_PNG ); 239 AddFormat( SOT_FORMAT_BITMAP ); 240 break; 241 242 case SC_SELTRANS_DRAW_BOOKMARK: 243 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 244 AddFormat( SOT_FORMATSTR_ID_SOLK ); 245 AddFormat( SOT_FORMAT_STRING ); 246 AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ); 247 AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ); 248 AddFormat( SOT_FORMATSTR_ID_DRAWING ); 249 break; 250 251 case SC_SELTRANS_DRAW_OLE: 252 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); 253 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 254 AddFormat( SOT_FORMAT_GDIMETAFILE ); 255 break; 256 257 case SC_SELTRANS_DRAW_OTHER: 258 // other drawing objects 259 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); 260 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 261 AddFormat( SOT_FORMATSTR_ID_DRAWING ); 262 AddFormat( SOT_FORMATSTR_ID_PNG ); 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