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_FORMAT_BITMAP ); 213 AddFormat( SOT_FORMATSTR_ID_HTML ); 214 AddFormat( SOT_FORMATSTR_ID_SYLK ); 215 AddFormat( SOT_FORMATSTR_ID_LINK ); 216 AddFormat( SOT_FORMATSTR_ID_DIF ); 217 AddFormat( SOT_FORMAT_STRING ); 218 AddFormat( SOT_FORMAT_RTF ); 219 if ( eMode == SC_SELTRANS_CELL ) 220 AddFormat( SOT_FORMATSTR_ID_EDITENGINE ); 221 break; 222 223 // different graphic formats as in ScDrawTransferObj::AddSupportedFormats: 224 225 case SC_SELTRANS_DRAW_BITMAP: 226 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 227 AddFormat( SOT_FORMATSTR_ID_SVXB ); 228 AddFormat( SOT_FORMAT_BITMAP ); 229 AddFormat( SOT_FORMAT_GDIMETAFILE ); 230 break; 231 232 case SC_SELTRANS_DRAW_GRAPHIC: 233 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 234 AddFormat( SOT_FORMATSTR_ID_SVXB ); 235 AddFormat( SOT_FORMAT_GDIMETAFILE ); 236 AddFormat( SOT_FORMAT_BITMAP ); 237 break; 238 239 case SC_SELTRANS_DRAW_BOOKMARK: 240 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 241 AddFormat( SOT_FORMATSTR_ID_SOLK ); 242 AddFormat( SOT_FORMAT_STRING ); 243 AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ); 244 AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ); 245 AddFormat( SOT_FORMATSTR_ID_DRAWING ); 246 break; 247 248 case SC_SELTRANS_DRAW_OLE: 249 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); 250 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 251 AddFormat( SOT_FORMAT_GDIMETAFILE ); 252 break; 253 254 case SC_SELTRANS_DRAW_OTHER: 255 // other drawing objects 256 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); 257 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 258 AddFormat( SOT_FORMATSTR_ID_DRAWING ); 259 AddFormat( SOT_FORMAT_BITMAP ); 260 AddFormat( SOT_FORMAT_GDIMETAFILE ); 261 break; 262 263 default: 264 { 265 // added to avoid warnings 266 } 267 } 268 } 269 270 void ScSelectionTransferObj::CreateCellData() 271 { 272 DBG_ASSERT( !pCellData, "CreateCellData twice" ); 273 if ( pView ) 274 { 275 ScViewData* pViewData = pView->GetViewData(); 276 ScMarkData aNewMark( pViewData->GetMarkData() ); // use local copy for MarkToSimple 277 aNewMark.MarkToSimple(); 278 279 // similar to ScViewFunctionSet::BeginDrag 280 if ( aNewMark.IsMarked() && !aNewMark.IsMultiMarked() ) 281 { 282 ScDocShell* pDocSh = pViewData->GetDocShell(); 283 284 ScRange aSelRange; 285 aNewMark.GetMarkArea( aSelRange ); 286 ScDocShellRef aDragShellRef; 287 if ( pDocSh->GetDocument()->HasOLEObjectsInArea( aSelRange, &aNewMark ) ) 288 { 289 aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately 290 aDragShellRef->DoInitNew(NULL); 291 } 292 ScDrawLayer::SetGlobalDrawPersist(aDragShellRef); 293 294 ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); 295 // bApi = sal_True -> no error mesages 296 // #i18364# bStopEdit = sal_False -> don't end edit mode 297 // (this may be called from pasting into the edit line) 298 sal_Bool bCopied = pViewData->GetView()->CopyToClip( pClipDoc, sal_False, sal_True, sal_True, sal_False ); 299 300 ScDrawLayer::SetGlobalDrawPersist(NULL); 301 302 if ( bCopied ) 303 { 304 TransferableObjectDescriptor aObjDesc; 305 pDocSh->FillTransferableObjectDescriptor( aObjDesc ); 306 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); 307 // maSize is set in ScTransferObj ctor 308 309 ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc ); 310 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); 311 312 // SetDragHandlePos is not used - there is no mouse position 313 //? pTransferObj->SetVisibleTab( nTab ); 314 315 SfxObjectShellRef aPersistRef( aDragShellRef ); 316 pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive 317 318 pTransferObj->SetDragSource( pDocSh, aNewMark ); 319 320 pCellData = pTransferObj; 321 pCellData->acquire(); // keep ref count up - released in ForgetView 322 } 323 else 324 delete pClipDoc; 325 } 326 } 327 DBG_ASSERT( pCellData, "can't create CellData" ); 328 } 329 330 //! make static member of ScDrawView 331 extern void lcl_CheckOle( const SdrMarkList& rMarkList, sal_Bool& rAnyOle, sal_Bool& rOneOle ); 332 333 void ScSelectionTransferObj::CreateDrawData() 334 { 335 DBG_ASSERT( !pDrawData, "CreateDrawData twice" ); 336 if ( pView ) 337 { 338 // similar to ScDrawView::BeginDrag 339 340 ScDrawView* pDrawView = pView->GetScDrawView(); 341 if ( pDrawView ) 342 { 343 sal_Bool bAnyOle, bOneOle; 344 const SdrMarkList& rMarkList = pDrawView->GetMarkedObjectList(); 345 lcl_CheckOle( rMarkList, bAnyOle, bOneOle ); 346 347 //--------------------------------------------------------- 348 ScDocShellRef aDragShellRef; 349 if (bAnyOle) 350 { 351 aDragShellRef = new ScDocShell; // ohne Ref lebt die DocShell nicht !!! 352 aDragShellRef->DoInitNew(NULL); 353 } 354 //--------------------------------------------------------- 355 356 ScDrawLayer::SetGlobalDrawPersist(aDragShellRef); 357 SdrModel* pModel = pDrawView->GetAllMarkedModel(); 358 ScDrawLayer::SetGlobalDrawPersist(NULL); 359 360 ScViewData* pViewData = pView->GetViewData(); 361 ScDocShell* pDocSh = pViewData->GetDocShell(); 362 363 TransferableObjectDescriptor aObjDesc; 364 pDocSh->FillTransferableObjectDescriptor( aObjDesc ); 365 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); 366 // maSize is set in ScDrawTransferObj ctor 367 368 ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc ); 369 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); 370 371 SfxObjectShellRef aPersistRef( aDragShellRef ); 372 pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive 373 pTransferObj->SetDragSource( pDrawView ); // copies selection 374 375 pDrawData = pTransferObj; 376 pDrawData->acquire(); // keep ref count up - released in ForgetView 377 } 378 } 379 DBG_ASSERT( pDrawData, "can't create DrawData" ); 380 } 381 382 ScTransferObj* ScSelectionTransferObj::GetCellData() 383 { 384 if ( !pCellData && ( eMode == SC_SELTRANS_CELL || eMode == SC_SELTRANS_CELLS ) ) 385 CreateCellData(); 386 return pCellData; 387 } 388 389 ScDrawTransferObj* ScSelectionTransferObj::GetDrawData() 390 { 391 if ( !pDrawData && ( eMode == SC_SELTRANS_DRAW_BITMAP || eMode == SC_SELTRANS_DRAW_GRAPHIC || 392 eMode == SC_SELTRANS_DRAW_BOOKMARK || eMode == SC_SELTRANS_DRAW_OLE || 393 eMode == SC_SELTRANS_DRAW_OTHER ) ) 394 CreateDrawData(); 395 return pDrawData; 396 } 397 398 sal_Bool ScSelectionTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor ) 399 { 400 sal_Bool bOK = sal_False; 401 402 uno::Reference<datatransfer::XTransferable> xSource; 403 switch (eMode) 404 { 405 case SC_SELTRANS_CELL: 406 case SC_SELTRANS_CELLS: 407 xSource = GetCellData(); 408 break; 409 case SC_SELTRANS_DRAW_BITMAP: 410 case SC_SELTRANS_DRAW_GRAPHIC: 411 case SC_SELTRANS_DRAW_BOOKMARK: 412 case SC_SELTRANS_DRAW_OLE: 413 case SC_SELTRANS_DRAW_OTHER: 414 xSource = GetDrawData(); 415 break; 416 default: 417 { 418 // added to avoid warnings 419 } 420 } 421 422 if ( xSource.is() ) 423 { 424 TransferableDataHelper aHelper( xSource ); 425 uno::Any aAny = aHelper.GetAny( rFlavor ); 426 bOK = SetAny( aAny, rFlavor ); 427 } 428 429 return bOK; 430 } 431 432 void ScSelectionTransferObj::ObjectReleased() 433 { 434 // called when another selection is set from outside 435 436 ForgetView(); 437 438 ScModule* pScMod = SC_MOD(); 439 if ( pScMod->GetSelectionTransfer() == this ) 440 pScMod->SetSelectionTransfer( NULL ); 441 442 TransferableHelper::ObjectReleased(); 443 } 444 445 446