fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / view / viewfun5.cxx
blob046f01ed808ae593c785bd06f31f42aefc6a9194
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/embed/XEmbedObjectClipboardCreator.hpp>
21 #include <com/sun/star/embed/Aspects.hpp>
22 #include <com/sun/star/embed/MSOLEObjectSystemCreator.hpp>
24 #include <svx/unomodel.hxx>
25 #include <unotools/streamwrap.hxx>
27 #include <svx/fmmodel.hxx>
28 #include <svx/svdetc.hxx>
29 #include <svx/svditer.hxx>
30 #include <svx/svdobj.hxx>
31 #include <svx/svdogrp.hxx>
32 #include <svx/svdouno.hxx>
33 #include <svx/svdoole2.hxx>
34 #include <svx/svdpage.hxx>
35 #include <sfx2/dispatch.hxx>
36 #include <sfx2/docfile.hxx>
37 #include <comphelper/classids.hxx>
38 #include <sot/formats.hxx>
39 #include <sot/filelist.hxx>
40 #include <sot/storage.hxx>
41 #include <unotools/pathoptions.hxx>
42 #include <svl/ptitem.hxx>
43 #include <svl/stritem.hxx>
44 #include <svtools/transfer.hxx>
45 #include <vcl/graph.hxx>
47 #include <comphelper/processfactory.hxx>
48 #include <comphelper/storagehelper.hxx>
49 #include <comphelper/string.hxx>
51 #include "viewfunc.hxx"
52 #include "docsh.hxx"
53 #include "drawview.hxx"
54 #include "impex.hxx"
55 #include "dbfunc.hxx"
56 #include "dbdata.hxx"
57 #include "sc.hrc"
58 #include "filter.hxx"
59 #include "scextopt.hxx"
60 #include "tabvwsh.hxx"
61 #include "compiler.hxx"
63 #include "asciiopt.hxx"
64 #include "scabstdlg.hxx"
65 #include "clipparam.hxx"
66 #include "markdata.hxx"
67 #include <vcl/msgbox.hxx>
68 #include <sfx2/viewfrm.hxx>
69 #include <svx/dbaexchange.hxx>
70 #include <boost/scoped_ptr.hpp>
72 using namespace com::sun::star;
74 bool ScViewFunc::PasteDataFormat( SotClipboardFormatId nFormatId,
75 const uno::Reference<datatransfer::XTransferable>& rxTransferable,
76 SCCOL nPosX, SCROW nPosY, Point* pLogicPos, bool bLink, bool bAllowDialogs )
78 ScDocument* pDoc = GetViewData().GetDocument();
79 pDoc->SetPastingDrawFromOtherDoc( true );
81 Point aPos; // inserting position (1/100 mm)
82 if (pLogicPos)
83 aPos = *pLogicPos;
84 else
86 // inserting position isn't needed for text formats
87 bool bIsTextFormat = ( ScImportExport::IsFormatSupported( nFormatId ) ||
88 nFormatId == SotClipboardFormatId::RTF );
89 if ( !bIsTextFormat )
91 // Window MapMode isn't drawing MapMode if DrawingLayer hasn't been created yet
93 SCTAB nTab = GetViewData().GetTabNo();
94 long nXT = 0;
95 for (SCCOL i=0; i<nPosX; i++)
96 nXT += pDoc->GetColWidth(i,nTab);
97 if (pDoc->IsNegativePage(nTab))
98 nXT = -nXT;
99 sal_uLong nYT = pDoc->GetRowHeight( 0, nPosY-1, nTab);
100 aPos = Point( (long)(nXT * HMM_PER_TWIPS), (long)(nYT * HMM_PER_TWIPS) );
104 TransferableDataHelper aDataHelper( rxTransferable );
105 bool bRet = false;
107 // handle individual formats
109 if ( nFormatId == SotClipboardFormatId::EMBED_SOURCE ||
110 nFormatId == SotClipboardFormatId::LINK_SOURCE ||
111 nFormatId == SotClipboardFormatId::EMBED_SOURCE_OLE ||
112 nFormatId == SotClipboardFormatId::LINK_SOURCE_OLE ||
113 nFormatId == SotClipboardFormatId::EMBEDDED_OBJ_OLE )
115 uno::Reference < io::XInputStream > xStm;
116 TransferableObjectDescriptor aObjDesc;
118 if (aDataHelper.GetTransferableObjectDescriptor(SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc))
119 xStm = aDataHelper.GetInputStream(nFormatId, OUString());
121 if (xStm.is())
123 if ( aObjDesc.maClassName == SvGlobalName( SO3_SC_CLASSID_60 ) )
125 uno::Reference < embed::XStorage > xStore = ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm );
127 // mba: BaseURL doesn't make sense for clipboard
128 // #i43716# Medium must be allocated with "new".
129 // DoLoad stores the pointer and deletes it with the SfxObjectShell.
130 SfxMedium* pMedium = new SfxMedium( xStore, OUString() );
132 // TODO/LATER: is it a problem that we don't support binary formats here?
133 ScDocShellRef xDocShRef = new ScDocShell(SfxModelFlags::EMBEDDED_OBJECT);
134 if (xDocShRef->DoLoad(pMedium))
136 ScDocument& rSrcDoc = xDocShRef->GetDocument();
137 SCTAB nSrcTab = rSrcDoc.GetVisibleTab();
138 if (!rSrcDoc.HasTable(nSrcTab))
139 nSrcTab = 0;
141 ScMarkData aSrcMark;
142 aSrcMark.SelectOneTable( nSrcTab ); // for CopyToClip
143 boost::scoped_ptr<ScDocument> pClipDoc(new ScDocument( SCDOCMODE_CLIP ));
145 SCCOL nFirstCol, nLastCol;
146 SCROW nFirstRow, nLastRow;
147 if ( rSrcDoc.GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
148 rSrcDoc.GetCellArea( nSrcTab, nLastCol, nLastRow );
149 else
151 nFirstCol = nLastCol = 0;
152 nFirstRow = nLastRow = 0;
154 ScClipParam aClipParam(ScRange(nFirstCol, nFirstRow, nSrcTab, nLastCol, nLastRow, nSrcTab), false);
155 rSrcDoc.CopyToClip(aClipParam, pClipDoc.get(), &aSrcMark);
156 ScGlobal::SetClipDocName( xDocShRef->GetTitle( SFX_TITLE_FULLNAME ) );
158 SetCursor( nPosX, nPosY );
159 Unmark();
160 PasteFromClip( IDF_ALL, pClipDoc.get(),
161 PASTE_NOFUNC, false, false, false, INS_NONE, IDF_NONE,
162 bAllowDialogs );
163 bRet = true;
166 xDocShRef->DoClose();
167 xDocShRef.Clear();
169 else
171 OUString aName;
172 uno::Reference < embed::XEmbeddedObject > xObj = GetViewData().GetViewShell()->GetObjectShell()->
173 GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
174 if ( xObj.is() )
176 // try to get the replacement image from the clipboard
177 Graphic aGraphic;
178 SotClipboardFormatId nGrFormat = SotClipboardFormatId::NONE;
180 // limit the size of the preview metafile to 100000 actions
181 GDIMetaFile aMetafile;
182 if (aDataHelper.GetGDIMetaFile(SotClipboardFormatId::GDIMETAFILE, aMetafile, 100000))
184 nGrFormat = SotClipboardFormatId::GDIMETAFILE;
185 aGraphic = aMetafile;
188 // insert replacement image ( if there is one ) into the object helper
189 if ( nGrFormat != SotClipboardFormatId::NONE )
191 datatransfer::DataFlavor aDataFlavor;
192 SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
193 PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
195 else
196 PasteObject( aPos, xObj, &aObjDesc.maSize );
198 bRet = true;
200 else
202 OSL_FAIL("Error in CreateAndLoad");
206 else
208 if ( aDataHelper.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE, aObjDesc ) )
210 OUString aName;
211 uno::Reference < embed::XEmbeddedObject > xObj;
212 xStm = aDataHelper.GetInputStream(SotClipboardFormatId::EMBED_SOURCE_OLE, OUString());
213 if (!xStm.is())
214 aDataHelper.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ_OLE, OUString());
216 if (xStm.is())
218 xObj = GetViewData().GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
220 else
224 uno::Reference< embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
225 uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator =
226 embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
228 embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard(
229 xTmpStor,
230 OUString( "DummyName" ),
231 uno::Sequence< beans::PropertyValue >() );
233 // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
234 // for example whether the object should be an iconified one
235 xObj = aInfo.Object;
236 if ( xObj.is() )
237 GetViewData().GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName );
239 catch( uno::Exception& )
243 if ( xObj.is() )
245 // try to get the replacement image from the clipboard
246 Graphic aGraphic;
247 SotClipboardFormatId nGrFormat = SotClipboardFormatId::NONE;
249 // (wg. Selection Manager bei Trustet Solaris)
250 #ifndef SOLARIS
251 if( aDataHelper.GetGraphic( SotClipboardFormatId::SVXB, aGraphic ) )
252 nGrFormat = SotClipboardFormatId::SVXB;
253 else if( aDataHelper.GetGraphic( SotClipboardFormatId::GDIMETAFILE, aGraphic ) )
254 nGrFormat = SotClipboardFormatId::GDIMETAFILE;
255 else if( aDataHelper.GetGraphic( SotClipboardFormatId::BITMAP, aGraphic ) )
256 nGrFormat = SotClipboardFormatId::BITMAP;
257 #endif
259 // insert replacement image ( if there is one ) into the object helper
260 if ( nGrFormat != SotClipboardFormatId::NONE )
262 datatransfer::DataFlavor aDataFlavor;
263 SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
264 PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
266 else
267 PasteObject( aPos, xObj, &aObjDesc.maSize );
269 // let object stay in loaded state after insertion
270 SdrOle2Obj::Unload( xObj, embed::Aspects::MSOLE_CONTENT );
271 bRet = true;
273 else
275 OSL_FAIL("Error creating external OLE object");
278 //TODO/LATER: if format is not available, create picture
281 else if ( nFormatId == SotClipboardFormatId::LINK ) // LINK is also in ScImportExport
283 bRet = PasteLink( rxTransferable );
285 else if ( ScImportExport::IsFormatSupported( nFormatId ) || nFormatId == SotClipboardFormatId::RTF )
287 if ( nFormatId == SotClipboardFormatId::RTF && aDataHelper.HasFormat( SotClipboardFormatId::EDITENGINE ) )
289 // use EditView's PasteSpecial / Drop
290 PasteRTF( nPosX, nPosY, rxTransferable );
291 bRet = true;
293 else
295 ScAddress aCellPos( nPosX, nPosY, GetViewData().GetTabNo() );
296 ScImportExport aObj( GetViewData().GetDocument(), aCellPos );
297 aObj.SetOverwriting( true );
299 OUString aStr;
300 tools::SvRef<SotStorageStream> xStream;
301 if ( aDataHelper.GetSotStorageStream( nFormatId, xStream ) && xStream.Is() )
303 if (nFormatId == SotClipboardFormatId::HTML)
305 // Launch the text import options dialog. For now, we do
306 // this for html pasting only, but in the future it may
307 // make sense to do it for other data types too.
308 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
309 boost::scoped_ptr<AbstractScTextImportOptionsDlg> pDlg(
310 pFact->CreateScTextImportOptionsDlg(NULL));
312 if (pDlg->Execute() == RET_OK)
314 ScAsciiOptions aOptions;
315 aOptions.SetLanguage(pDlg->GetLanguageType());
316 aOptions.SetDetectSpecialNumber(pDlg->IsDateConversionSet());
317 aObj.SetExtOptions(aOptions);
319 else
321 // prevent error dialog for user cancel action
322 bRet = true;
325 if(!bRet)
326 bRet = aObj.ImportStream( *xStream, OUString(), nFormatId );
327 // mba: clipboard always must contain absolute URLs (could be from alien source)
329 else if (nFormatId == SotClipboardFormatId::STRING && aDataHelper.GetString( nFormatId, aStr ))
331 // Do CSV dialog if more than one line.
332 sal_Int32 nDelim = aStr.indexOf('\n');
333 if (nDelim >= 0 && nDelim != aStr.getLength () - 1)
335 ScImportStringStream aStrm( aStr);
336 ScAbstractDialogFactory* pFact =
337 ScAbstractDialogFactory::Create();
338 boost::scoped_ptr<AbstractScImportAsciiDlg> pDlg(
339 pFact->CreateScImportAsciiDlg( NULL, OUString(), &aStrm,
340 SC_PASTETEXT));
342 if (pDlg->Execute() == RET_OK)
344 ScAsciiOptions aOptions;
345 pDlg->GetOptions( aOptions );
346 pDlg->SaveParameters();
347 aObj.SetExtOptions( aOptions );
349 bRet = aObj.ImportString( aStr, nFormatId );
351 // TODO: what if (aObj.IsOverflow())
352 // Content was partially pasted, which can be undone by
353 // the user though.
354 if (aObj.IsOverflow())
355 bRet = false;
357 else
358 bRet = true;
359 // Yes, no failure, don't raise a "couldn't paste"
360 // dialog if user cancelled.
362 else
363 bRet = aObj.ImportString( aStr, nFormatId );
365 else if (nFormatId != SotClipboardFormatId::STRING && aDataHelper.GetString( nFormatId, aStr ))
366 bRet = aObj.ImportString( aStr, nFormatId );
368 InvalidateAttribs();
369 GetViewData().UpdateInputHandler();
372 else if (nFormatId == SotClipboardFormatId::SBA_DATAEXCHANGE)
374 // import of database data into table
376 const DataFlavorExVector& rVector = aDataHelper.GetDataFlavorExVector();
377 if ( svx::ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector) )
379 // transport the whole ODataAccessDescriptor as slot parameter
380 svx::ODataAccessDescriptor aDesc = svx::ODataAccessObjectTransferable::extractObjectDescriptor(aDataHelper);
381 uno::Any aDescAny;
382 uno::Sequence<beans::PropertyValue> aProperties = aDesc.createPropertyValueSequence();
383 aDescAny <<= aProperties;
384 SfxUsrAnyItem aDataDesc(SID_SBA_IMPORT, aDescAny);
386 ScDocShell* pDocSh = GetViewData().GetDocShell();
387 SCTAB nTab = GetViewData().GetTabNo();
389 ClickCursor(nPosX, nPosY, false); // set cursor position
391 // Creation of database area "Import1" isn't here, but in the DocShell
392 // slot execute, so it can be added to the undo action
394 ScDBData* pDBData = pDocSh->GetDBData( ScRange(nPosX,nPosY,nTab), SC_DB_OLD, SC_DBSEL_KEEP );
395 OUString sTarget;
396 if (pDBData)
397 sTarget = pDBData->GetName();
398 else
400 ScAddress aCellPos( nPosX,nPosY,nTab );
401 sTarget = aCellPos.Format(SCA_ABS_3D, pDoc, pDoc->GetAddressConvention());
403 SfxStringItem aTarget(FN_PARAM_1, sTarget);
405 bool bAreaIsNew = !pDBData;
406 SfxBoolItem aAreaNew(FN_PARAM_2, bAreaIsNew);
408 // asynchronous, to avoid doing the whole import in drop handler
409 SfxDispatcher& rDisp = GetViewData().GetDispatcher();
410 rDisp.Execute(SID_SBA_IMPORT, SfxCallMode::ASYNCHRON,
411 &aDataDesc, &aTarget, &aAreaNew, (void*)0 );
413 bRet = true;
416 else if (nFormatId == SotClipboardFormatId::SBA_FIELDDATAEXCHANGE)
418 // insert database field control
420 if ( svx::OColumnTransferable::canExtractColumnDescriptor( aDataHelper.GetDataFlavorExVector(), ColumnTransferFormatFlags::COLUMN_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE ) )
422 MakeDrawLayer();
423 ScDrawView* pScDrawView = GetScDrawView();
424 SdrObject* pObj = pScDrawView->CreateFieldControl( svx::OColumnTransferable::extractColumnDescriptor( aDataHelper ) );
425 if (pObj)
427 Point aInsPos = aPos;
428 Rectangle aRect(pObj->GetLogicRect());
429 aInsPos.X() -= aRect.GetSize().Width() / 2;
430 aInsPos.Y() -= aRect.GetSize().Height() / 2;
431 if ( aInsPos.X() < 0 ) aInsPos.X() = 0;
432 if ( aInsPos.Y() < 0 ) aInsPos.Y() = 0;
433 aRect.SetPos(aInsPos);
434 pObj->SetLogicRect(aRect);
436 if ( pObj->ISA(SdrUnoObj) )
437 pObj->NbcSetLayer(SC_LAYER_CONTROLS);
438 else
439 pObj->NbcSetLayer(SC_LAYER_FRONT);
440 if (pObj->ISA(SdrObjGroup))
442 SdrObjListIter aIter( *pObj, IM_DEEPWITHGROUPS );
443 SdrObject* pSubObj = aIter.Next();
444 while (pSubObj)
446 if ( pSubObj->ISA(SdrUnoObj) )
447 pSubObj->NbcSetLayer(SC_LAYER_CONTROLS);
448 else
449 pSubObj->NbcSetLayer(SC_LAYER_FRONT);
450 pSubObj = aIter.Next();
454 pScDrawView->InsertObjectSafe(pObj, *pScDrawView->GetSdrPageView());
456 GetViewData().GetViewShell()->SetDrawShell( true );
457 bRet = true;
461 else if (nFormatId == SotClipboardFormatId::BITMAP || nFormatId == SotClipboardFormatId::PNG)
463 BitmapEx aBmpEx;
464 if( aDataHelper.GetBitmapEx( SotClipboardFormatId::BITMAP, aBmpEx ) )
465 bRet = PasteBitmapEx( aPos, aBmpEx );
467 else if (nFormatId == SotClipboardFormatId::GDIMETAFILE)
469 GDIMetaFile aMtf;
470 if( aDataHelper.GetGDIMetaFile( SotClipboardFormatId::GDIMETAFILE, aMtf ) )
471 bRet = PasteMetaFile( aPos, aMtf );
473 else if (nFormatId == SotClipboardFormatId::SVXB)
475 tools::SvRef<SotStorageStream> xStm;
476 if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::SVXB, xStm ) )
478 Graphic aGraphic;
479 ReadGraphic( *xStm, aGraphic );
480 bRet = PasteGraphic( aPos, aGraphic, EMPTY_OUSTRING, EMPTY_OUSTRING );
483 else if ( nFormatId == SotClipboardFormatId::DRAWING )
485 tools::SvRef<SotStorageStream> xStm;
486 if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::DRAWING, xStm ) )
488 MakeDrawLayer(); // before loading model, so 3D factory has been created
490 SvtPathOptions aPathOpt;
491 OUString aPath = aPathOpt.GetPalettePath();
493 ScDocShellRef aDragShellRef( new ScDocShell );
494 aDragShellRef->DoInitNew(NULL);
495 boost::scoped_ptr<FmFormModel> pModel(new FmFormModel( aPath, NULL, aDragShellRef ));
497 pModel->GetItemPool().FreezeIdRanges();
498 xStm->Seek(0);
500 com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm ) );
501 SvxDrawingLayerImport( pModel.get(), xInputStream );
503 // set everything to right layer:
504 size_t nObjCount = 0;
505 sal_uInt16 nPages = pModel->GetPageCount();
506 for (sal_uInt16 i=0; i<nPages; i++)
508 SdrPage* pPage = pModel->GetPage(i);
509 SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
510 SdrObject* pObject = aIter.Next();
511 while (pObject)
513 if ( pObject->ISA(SdrUnoObj) )
514 pObject->NbcSetLayer(SC_LAYER_CONTROLS);
515 else
516 pObject->NbcSetLayer(SC_LAYER_FRONT);
517 pObject = aIter.Next();
520 nObjCount += pPage->GetObjCount(); // count group object only once
523 PasteDraw(aPos, pModel.get(), (nObjCount > 1), "A", "B"); // grouped if more than 1 object
524 pModel.reset();
525 aDragShellRef->DoClose();
526 bRet = true;
529 else if ( (nFormatId == SotClipboardFormatId::BIFF_5) || (nFormatId == SotClipboardFormatId::BIFF_8) )
531 // do excel import into a clipboard document
532 //TODO/MBA: testing
533 uno::Reference <io::XInputStream> xStm = aDataHelper.GetInputStream(nFormatId, OUString());
534 if (xStm.is())
536 ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
537 SCTAB nSrcTab = 0; // Biff5 in clipboard: always sheet 0
538 pInsDoc->ResetClip( pDoc, nSrcTab );
540 SfxMedium aMed;
541 aMed.GetItemSet()->Put( SfxUsrAnyItem( SID_INPUTSTREAM, uno::makeAny( xStm ) ) );
542 FltError eErr = ScFormatFilter::Get().ScImportExcel( aMed, pInsDoc, EIF_AUTO );
543 if ( eErr == eERR_OK )
545 ScRange aSource;
546 const ScExtDocOptions* pExtOpt = pInsDoc->GetExtDocOptions();
547 const ScExtTabSettings* pTabSett = pExtOpt ? pExtOpt->GetTabSettings( nSrcTab ) : 0;
548 if( pTabSett && pTabSett->maUsedArea.IsValid() )
550 aSource = pTabSett->maUsedArea;
551 // ensure correct sheet indexes
552 aSource.aStart.SetTab( nSrcTab );
553 aSource.aEnd.SetTab( nSrcTab );
554 // don't use selection area: if cursor is moved in Excel after Copy, selection
555 // represents the new cursor position and not the copied area
557 else
559 OSL_FAIL("no dimension"); //! possible?
560 SCCOL nFirstCol, nLastCol;
561 SCROW nFirstRow, nLastRow;
562 if ( pInsDoc->GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
563 pInsDoc->GetCellArea( nSrcTab, nLastCol, nLastRow );
564 else
566 nFirstCol = nLastCol = 0;
567 nFirstRow = nLastRow = 0;
569 aSource = ScRange( nFirstCol, nFirstRow, nSrcTab,
570 nLastCol, nLastRow, nSrcTab );
573 if ( pLogicPos )
575 // position specified (Drag&Drop) - change selection
576 MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, false, false );
577 Unmark();
580 pInsDoc->SetClipArea( aSource );
581 PasteFromClip( IDF_ALL, pInsDoc,
582 PASTE_NOFUNC, false, false, false, INS_NONE, IDF_NONE,
583 bAllowDialogs );
584 delete pInsDoc;
586 bRet = true;
590 else if ( nFormatId == SotClipboardFormatId::SIMPLE_FILE )
592 OUString aFile;
593 if ( aDataHelper.GetString( nFormatId, aFile ) )
594 bRet = PasteFile( aPos, aFile, bLink );
596 else if ( nFormatId == SotClipboardFormatId::FILE_LIST )
598 FileList aFileList;
599 if ( aDataHelper.GetFileList( nFormatId, aFileList ) )
601 sal_uLong nCount = aFileList.Count();
602 for( sal_uLong i = 0; i < nCount ; i++ )
604 OUString aFile = aFileList.GetFile( i );
606 PasteFile( aPos, aFile, bLink );
608 aPos.X() += 400;
609 aPos.Y() += 400;
611 bRet = true;
614 else if ( nFormatId == SotClipboardFormatId::SOLK ||
615 nFormatId == SotClipboardFormatId::UNIFORMRESOURCELOCATOR ||
616 nFormatId == SotClipboardFormatId::NETSCAPE_BOOKMARK ||
617 nFormatId == SotClipboardFormatId::FILEGRPDESCRIPTOR )
619 bRet = PasteBookmark( nFormatId, rxTransferable, nPosX, nPosY );
622 pDoc->SetPastingDrawFromOtherDoc( false );
624 return bRet;
627 bool ScViewFunc::PasteLink( const uno::Reference<datatransfer::XTransferable>& rxTransferable )
629 TransferableDataHelper aDataHelper( rxTransferable );
631 // get link data from transferable before string data,
632 // so the source knows it will be used for a link
634 uno::Sequence<sal_Int8> aSequence = aDataHelper.GetSequence(SotClipboardFormatId::LINK, OUString());
635 if (!aSequence.getLength())
637 OSL_FAIL("DDE Data not found.");
638 return false;
641 // check size (only if string is available in transferable)
643 sal_uInt16 nCols = 1;
644 sal_uInt16 nRows = 1;
645 if ( aDataHelper.HasFormat( SotClipboardFormatId::STRING ) )
647 OUString aDataStr;
648 if ( aDataHelper.GetString( SotClipboardFormatId::STRING, aDataStr ) )
650 // get size from string the same way as in ScDdeLink::DataChanged
652 aDataStr = convertLineEnd(aDataStr, LINEEND_LF);
653 sal_Int32 nLen = aDataStr.getLength();
654 if (nLen && aDataStr[nLen-1] == '\n')
655 aDataStr = aDataStr.copy(0, nLen-1);
657 if (!aDataStr.isEmpty())
659 nRows = comphelper::string::getTokenCount(aDataStr, '\n');
660 OUString aLine = aDataStr.getToken( 0, '\n' );
661 if (!aLine.isEmpty())
662 nCols = comphelper::string::getTokenCount(aLine, '\t');
667 // create formula
669 sal_Int32 nSeqLen = aSequence.getLength();
670 const char* p = reinterpret_cast<const char*>(aSequence.getConstArray());
672 rtl_TextEncoding eSysEnc = osl_getThreadTextEncoding();
674 // char array delimited by \0.
675 // app \0 topic \0 item \0 (extra \0) where the extra is optional.
676 ::std::vector<OUString> aStrs;
677 const char* pStart = p;
678 sal_Int32 nStart = 0;
679 for (sal_Int32 i = 0; i < nSeqLen; ++i, ++p)
681 if (*p == '\0')
683 sal_Int32 nLen = i - nStart;
684 aStrs.push_back(OUString(pStart, nLen, eSysEnc));
685 nStart = ++i;
686 pStart = ++p;
690 if (aStrs.size() < 3)
691 return false;
693 const OUString* pApp = &aStrs[0];
694 const OUString* pTopic = &aStrs[1];
695 const OUString* pItem = &aStrs[2];
696 const OUString* pExtra = NULL;
697 if (aStrs.size() > 3)
698 pExtra = &aStrs[3];
700 if ( pExtra && *pExtra == "calc:extref" )
702 // Paste this as an external reference. Note that paste link always
703 // uses Calc A1 syntax even when another formula syntax is specified
704 // in the UI.
705 EnterMatrix("='"
706 + OUString(ScGlobal::GetAbsDocName(*pTopic, GetViewData().GetDocument()->GetDocumentShell()))
707 + "'#" + *pItem
708 , ::formula::FormulaGrammar::GRAM_NATIVE);
709 return true;
711 else
713 // DDE in all other cases.
715 // TODO: we could define ocQuote for "
716 EnterMatrix("=" + OUString(ScCompiler::GetNativeSymbol(ocDde))
717 + ScCompiler::GetNativeSymbol(ocOpen)
718 + "\"" + *pApp + "\""
719 + ScCompiler::GetNativeSymbol(ocSep)
720 + "\"" + *pTopic + "\""
721 + ScCompiler::GetNativeSymbol(ocSep)
722 + "\"" + *pItem + "\""
723 + ScCompiler::GetNativeSymbol(ocClose)
724 , ::formula::FormulaGrammar::GRAM_NATIVE);
727 // mark range
729 SCTAB nTab = GetViewData().GetTabNo();
730 SCCOL nCurX = GetViewData().GetCurX();
731 SCROW nCurY = GetViewData().GetCurY();
732 HideAllCursors();
733 DoneBlockMode();
734 InitBlockMode( nCurX, nCurY, nTab );
735 MarkCursor( nCurX+static_cast<SCCOL>(nCols)-1, nCurY+static_cast<SCROW>(nRows)-1, nTab );
736 ShowAllCursors();
737 CursorPosChanged();
739 return true;
742 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */