Bump version to 4.3-4
[LibreOffice.git] / sc / source / ui / view / viewfun5.cxx
blob36b4053f681d3212727900369ecf817d2bad52f6
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>
25 #include <svx/unomodel.hxx>
26 #include <unotools/streamwrap.hxx>
28 #include <svx/fmmodel.hxx>
29 #include <svx/svdetc.hxx>
30 #include <svx/svditer.hxx>
31 #include <svx/svdobj.hxx>
32 #include <svx/svdogrp.hxx>
33 #include <svx/svdouno.hxx>
34 #include <svx/svdoole2.hxx>
35 #include <svx/svdpage.hxx>
36 #include <sfx2/dispatch.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <comphelper/classids.hxx>
39 #include <sot/formats.hxx>
40 #include <sot/filelist.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( sal_uLong 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 == FORMAT_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;
108 // handle individual formats
111 if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE ||
112 nFormatId == SOT_FORMATSTR_ID_LINK_SOURCE ||
113 nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ||
114 nFormatId == SOT_FORMATSTR_ID_LINK_SOURCE_OLE ||
115 nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
117 uno::Reference < io::XInputStream > xStm;
118 TransferableObjectDescriptor aObjDesc;
120 if (aDataHelper.GetTransferableObjectDescriptor(SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc))
121 xStm = aDataHelper.GetInputStream(nFormatId, OUString());
123 if (xStm.is())
125 if ( aObjDesc.maClassName == SvGlobalName( SO3_SC_CLASSID_60 ) )
127 uno::Reference < embed::XStorage > xStore = ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm );
129 // mba: BaseURL doesn't make sense for clipboard
130 // #i43716# Medium must be allocated with "new".
131 // DoLoad stores the pointer and deletes it with the SfxObjectShell.
132 SfxMedium* pMedium = new SfxMedium( xStore, OUString() );
134 // TODO/LATER: is it a problem that we don't support binary formats here?
135 ScDocShellRef xDocShRef = new ScDocShell(SFX_CREATE_MODE_EMBEDDED);
136 if (xDocShRef->DoLoad(pMedium))
138 ScDocument* pSrcDoc = xDocShRef->GetDocument();
139 SCTAB nSrcTab = pSrcDoc->GetVisibleTab();
140 if (!pSrcDoc->HasTable(nSrcTab))
141 nSrcTab = 0;
143 ScMarkData aSrcMark;
144 aSrcMark.SelectOneTable( nSrcTab ); // for CopyToClip
145 boost::scoped_ptr<ScDocument> pClipDoc(new ScDocument( SCDOCMODE_CLIP ));
147 SCCOL nFirstCol, nLastCol;
148 SCROW nFirstRow, nLastRow;
149 if ( pSrcDoc->GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
150 pSrcDoc->GetCellArea( nSrcTab, nLastCol, nLastRow );
151 else
153 nFirstCol = nLastCol = 0;
154 nFirstRow = nLastRow = 0;
156 ScClipParam aClipParam(ScRange(nFirstCol, nFirstRow, nSrcTab, nLastCol, nLastRow, nSrcTab), false);
157 pSrcDoc->CopyToClip(aClipParam, pClipDoc.get(), &aSrcMark);
158 ScGlobal::SetClipDocName( xDocShRef->GetTitle( SFX_TITLE_FULLNAME ) );
160 SetCursor( nPosX, nPosY );
161 Unmark();
162 PasteFromClip( IDF_ALL, pClipDoc.get(),
163 PASTE_NOFUNC, false, false, false, INS_NONE, IDF_NONE,
164 bAllowDialogs );
165 bRet = true;
168 xDocShRef->DoClose();
169 xDocShRef.Clear();
171 else
173 OUString aName;
174 uno::Reference < embed::XEmbeddedObject > xObj = GetViewData()->GetViewShell()->GetObjectShell()->
175 GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
176 if ( xObj.is() )
178 // try to get the replacement image from the clipboard
179 Graphic aGraphic;
180 sal_uLong nGrFormat = 0;
182 // limit the size of the preview metafile to 100000 actions
183 GDIMetaFile aMetafile;
184 if (aDataHelper.GetGDIMetaFile(FORMAT_GDIMETAFILE, aMetafile, 100000))
186 nGrFormat = SOT_FORMAT_GDIMETAFILE;
187 aGraphic = aMetafile;
190 // insert replacement image ( if there is one ) into the object helper
191 if ( nGrFormat )
193 datatransfer::DataFlavor aDataFlavor;
194 SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
195 PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
197 else
198 PasteObject( aPos, xObj, &aObjDesc.maSize );
200 bRet = true;
202 else
204 OSL_FAIL("Error in CreateAndLoad");
208 else
210 if ( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR_OLE, aObjDesc ) )
212 OUString aName;
213 uno::Reference < embed::XEmbeddedObject > xObj;
214 xStm = aDataHelper.GetInputStream(SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, OUString());
215 if (!xStm.is())
216 aDataHelper.GetInputStream(SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, OUString());
218 if (xStm.is())
220 xObj = GetViewData()->GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
222 else
226 uno::Reference< embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
227 uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator =
228 embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
230 embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard(
231 xTmpStor,
232 OUString( "DummyName" ),
233 uno::Sequence< beans::PropertyValue >() );
235 // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
236 // for example whether the object should be an iconified one
237 xObj = aInfo.Object;
238 if ( xObj.is() )
239 GetViewData()->GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName );
241 catch( uno::Exception& )
245 if ( xObj.is() )
247 // try to get the replacement image from the clipboard
248 Graphic aGraphic;
249 sal_uLong nGrFormat = 0;
251 // (wg. Selection Manager bei Trustet Solaris)
252 #ifndef SOLARIS
253 if( aDataHelper.GetGraphic( SOT_FORMATSTR_ID_SVXB, aGraphic ) )
254 nGrFormat = SOT_FORMATSTR_ID_SVXB;
255 else if( aDataHelper.GetGraphic( FORMAT_GDIMETAFILE, aGraphic ) )
256 nGrFormat = SOT_FORMAT_GDIMETAFILE;
257 else if( aDataHelper.GetGraphic( FORMAT_BITMAP, aGraphic ) )
258 nGrFormat = SOT_FORMAT_BITMAP;
259 #endif
261 // insert replacement image ( if there is one ) into the object helper
262 if ( nGrFormat )
264 datatransfer::DataFlavor aDataFlavor;
265 SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
266 PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
268 else
269 PasteObject( aPos, xObj, &aObjDesc.maSize );
271 // let object stay in loaded state after insertion
272 SdrOle2Obj::Unload( xObj, embed::Aspects::MSOLE_CONTENT );
273 bRet = true;
275 else
277 OSL_FAIL("Error creating external OLE object");
280 //TODO/LATER: if format is not available, create picture
283 else if ( nFormatId == SOT_FORMATSTR_ID_LINK ) // LINK is also in ScImportExport
285 bRet = PasteLink( rxTransferable );
287 else if ( ScImportExport::IsFormatSupported( nFormatId ) || nFormatId == SOT_FORMAT_RTF )
289 if ( nFormatId == SOT_FORMAT_RTF && aDataHelper.HasFormat( SOT_FORMATSTR_ID_EDITENGINE ) )
291 // use EditView's PasteSpecial / Drop
292 PasteRTF( nPosX, nPosY, rxTransferable );
293 bRet = true;
295 else
297 ScAddress aCellPos( nPosX, nPosY, GetViewData()->GetTabNo() );
298 ScImportExport aObj( GetViewData()->GetDocument(), aCellPos );
299 aObj.SetOverwriting( true );
301 OUString aStr;
302 SotStorageStreamRef xStream;
303 if ( aDataHelper.GetSotStorageStream( nFormatId, xStream ) && xStream.Is() )
305 if (nFormatId == SOT_FORMATSTR_ID_HTML)
307 // Launch the text import options dialog. For now, we do
308 // this for html pasting only, but in the future it may
309 // make sense to do it for other data types too.
310 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
311 boost::scoped_ptr<AbstractScTextImportOptionsDlg> pDlg(
312 pFact->CreateScTextImportOptionsDlg(NULL));
314 if (pDlg->Execute() == RET_OK)
316 ScAsciiOptions aOptions;
317 aOptions.SetLanguage(pDlg->GetLanguageType());
318 aOptions.SetDetectSpecialNumber(pDlg->IsDateConversionSet());
319 aObj.SetExtOptions(aOptions);
321 else
323 // prevent error dialog for user cancel action
324 bRet = true;
327 if(!bRet)
328 bRet = aObj.ImportStream( *xStream, OUString(), nFormatId );
329 // mba: clipboard always must contain absolute URLs (could be from alien source)
331 else if (nFormatId == FORMAT_STRING && aDataHelper.GetString( nFormatId, aStr ))
333 // Do CSV dialog if more than one line.
334 sal_Int32 nDelim = aStr.indexOf('\n');
335 if (nDelim >= 0 && nDelim != aStr.getLength () - 1)
337 ScImportStringStream aStrm( aStr);
338 ScAbstractDialogFactory* pFact =
339 ScAbstractDialogFactory::Create();
340 boost::scoped_ptr<AbstractScImportAsciiDlg> pDlg(
341 pFact->CreateScImportAsciiDlg( NULL, OUString(), &aStrm,
342 SC_PASTETEXT));
344 if (pDlg->Execute() == RET_OK)
346 ScAsciiOptions aOptions;
347 pDlg->GetOptions( aOptions );
348 pDlg->SaveParameters();
349 aObj.SetExtOptions( aOptions );
351 bRet = aObj.ImportString( aStr, nFormatId );
353 // TODO: what if (aObj.IsOverflow())
354 // Content was partially pasted, which can be undone by
355 // the user though.
356 if (aObj.IsOverflow())
357 bRet = false;
359 else
360 bRet = true;
361 // Yes, no failure, don't raise a "couldn't paste"
362 // dialog if user cancelled.
364 else
365 bRet = aObj.ImportString( aStr, nFormatId );
367 else if (nFormatId != FORMAT_STRING && aDataHelper.GetString( nFormatId, aStr ))
368 bRet = aObj.ImportString( aStr, nFormatId );
370 InvalidateAttribs();
371 GetViewData()->UpdateInputHandler();
374 else if (nFormatId == SOT_FORMATSTR_ID_SBA_DATAEXCHANGE)
376 // import of database data into table
378 const DataFlavorExVector& rVector = aDataHelper.GetDataFlavorExVector();
379 if ( svx::ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector) )
381 // transport the whole ODataAccessDescriptor as slot parameter
382 svx::ODataAccessDescriptor aDesc = svx::ODataAccessObjectTransferable::extractObjectDescriptor(aDataHelper);
383 uno::Any aDescAny;
384 uno::Sequence<beans::PropertyValue> aProperties = aDesc.createPropertyValueSequence();
385 aDescAny <<= aProperties;
386 SfxUsrAnyItem aDataDesc(SID_SBA_IMPORT, aDescAny);
388 ScDocShell* pDocSh = GetViewData()->GetDocShell();
389 SCTAB nTab = GetViewData()->GetTabNo();
391 ClickCursor(nPosX, nPosY, false); // set cursor position
393 // Creation of database area "Import1" isn't here, but in the DocShell
394 // slot execute, so it can be added to the undo action
396 ScDBData* pDBData = pDocSh->GetDBData( ScRange(nPosX,nPosY,nTab), SC_DB_OLD, SC_DBSEL_KEEP );
397 OUString sTarget;
398 if (pDBData)
399 sTarget = pDBData->GetName();
400 else
402 ScAddress aCellPos( nPosX,nPosY,nTab );
403 sTarget = aCellPos.Format(SCA_ABS_3D, pDoc, pDoc->GetAddressConvention());
405 SfxStringItem aTarget(FN_PARAM_1, sTarget);
407 bool bAreaIsNew = !pDBData;
408 SfxBoolItem aAreaNew(FN_PARAM_2, bAreaIsNew);
410 // asynchronous, to avoid doing the whole import in drop handler
411 SfxDispatcher& rDisp = GetViewData()->GetDispatcher();
412 rDisp.Execute(SID_SBA_IMPORT, SFX_CALLMODE_ASYNCHRON,
413 &aDataDesc, &aTarget, &aAreaNew, (void*)0 );
415 bRet = true;
418 else if (nFormatId == SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE)
420 // insert database field control
422 if ( ::svx::OColumnTransferable::canExtractColumnDescriptor( aDataHelper.GetDataFlavorExVector(), CTF_COLUMN_DESCRIPTOR | CTF_CONTROL_EXCHANGE ) )
424 MakeDrawLayer();
425 ScDrawView* pScDrawView = GetScDrawView();
426 SdrObject* pObj = pScDrawView->CreateFieldControl( ::svx::OColumnTransferable::extractColumnDescriptor( aDataHelper ) );
427 if (pObj)
429 Point aInsPos = aPos;
430 Rectangle aRect(pObj->GetLogicRect());
431 aInsPos.X() -= aRect.GetSize().Width() / 2;
432 aInsPos.Y() -= aRect.GetSize().Height() / 2;
433 if ( aInsPos.X() < 0 ) aInsPos.X() = 0;
434 if ( aInsPos.Y() < 0 ) aInsPos.Y() = 0;
435 aRect.SetPos(aInsPos);
436 pObj->SetLogicRect(aRect);
438 if ( pObj->ISA(SdrUnoObj) )
439 pObj->NbcSetLayer(SC_LAYER_CONTROLS);
440 else
441 pObj->NbcSetLayer(SC_LAYER_FRONT);
442 if (pObj->ISA(SdrObjGroup))
444 SdrObjListIter aIter( *pObj, IM_DEEPWITHGROUPS );
445 SdrObject* pSubObj = aIter.Next();
446 while (pSubObj)
448 if ( pSubObj->ISA(SdrUnoObj) )
449 pSubObj->NbcSetLayer(SC_LAYER_CONTROLS);
450 else
451 pSubObj->NbcSetLayer(SC_LAYER_FRONT);
452 pSubObj = aIter.Next();
456 pScDrawView->InsertObjectSafe(pObj, *pScDrawView->GetSdrPageView());
458 GetViewData()->GetViewShell()->SetDrawShell( true );
459 bRet = true;
463 else if (nFormatId == SOT_FORMAT_BITMAP || nFormatId == SOT_FORMATSTR_ID_PNG)
465 BitmapEx aBmpEx;
466 if( aDataHelper.GetBitmapEx( FORMAT_BITMAP, aBmpEx ) )
467 bRet = PasteBitmapEx( aPos, aBmpEx );
469 else if (nFormatId == SOT_FORMAT_GDIMETAFILE)
471 GDIMetaFile aMtf;
472 if( aDataHelper.GetGDIMetaFile( FORMAT_GDIMETAFILE, aMtf ) )
473 bRet = PasteMetaFile( aPos, aMtf );
475 else if (nFormatId == SOT_FORMATSTR_ID_SVXB)
477 SotStorageStreamRef xStm;
478 if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_SVXB, xStm ) )
480 Graphic aGraphic;
481 ReadGraphic( *xStm, aGraphic );
482 bRet = PasteGraphic( aPos, aGraphic, EMPTY_OUSTRING, EMPTY_OUSTRING );
485 else if ( nFormatId == SOT_FORMATSTR_ID_DRAWING )
487 SotStorageStreamRef xStm;
488 if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_DRAWING, xStm ) )
490 MakeDrawLayer(); // before loading model, so 3D factory has been created
492 SvtPathOptions aPathOpt;
493 OUString aPath = aPathOpt.GetPalettePath();
495 ScDocShellRef aDragShellRef( new ScDocShell );
496 aDragShellRef->DoInitNew(NULL);
497 boost::scoped_ptr<FmFormModel> pModel(new FmFormModel( aPath, NULL, aDragShellRef ));
499 pModel->GetItemPool().FreezeIdRanges();
500 xStm->Seek(0);
502 com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm ) );
503 SvxDrawingLayerImport( pModel.get(), xInputStream );
505 // set everything to right layer:
506 sal_uLong nObjCount = 0;
507 sal_uInt16 nPages = pModel->GetPageCount();
508 for (sal_uInt16 i=0; i<nPages; i++)
510 SdrPage* pPage = pModel->GetPage(i);
511 SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
512 SdrObject* pObject = aIter.Next();
513 while (pObject)
515 if ( pObject->ISA(SdrUnoObj) )
516 pObject->NbcSetLayer(SC_LAYER_CONTROLS);
517 else
518 pObject->NbcSetLayer(SC_LAYER_FRONT);
519 pObject = aIter.Next();
522 nObjCount += pPage->GetObjCount(); // count group object only once
525 PasteDraw(aPos, pModel.get(), (nObjCount > 1), "A", "B"); // grouped if more than 1 object
526 pModel.reset();
527 aDragShellRef->DoClose();
528 bRet = true;
531 else if ( (nFormatId == SOT_FORMATSTR_ID_BIFF_5) || (nFormatId == SOT_FORMATSTR_ID_BIFF_8) )
533 // do excel import into a clipboard document
534 //TODO/MBA: testing
535 uno::Reference <io::XInputStream> xStm = aDataHelper.GetInputStream(nFormatId, OUString());
536 if (xStm.is())
538 ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
539 SCTAB nSrcTab = 0; // Biff5 in clipboard: always sheet 0
540 pInsDoc->ResetClip( pDoc, nSrcTab );
542 SfxMedium aMed;
543 aMed.GetItemSet()->Put( SfxUsrAnyItem( SID_INPUTSTREAM, uno::makeAny( xStm ) ) );
544 FltError eErr = ScFormatFilter::Get().ScImportExcel( aMed, pInsDoc, EIF_AUTO );
545 if ( eErr == eERR_OK )
547 ScRange aSource;
548 const ScExtDocOptions* pExtOpt = pInsDoc->GetExtDocOptions();
549 const ScExtTabSettings* pTabSett = pExtOpt ? pExtOpt->GetTabSettings( nSrcTab ) : 0;
550 if( pTabSett && pTabSett->maUsedArea.IsValid() )
552 aSource = pTabSett->maUsedArea;
553 // ensure correct sheet indexes
554 aSource.aStart.SetTab( nSrcTab );
555 aSource.aEnd.SetTab( nSrcTab );
556 // don't use selection area: if cursor is moved in Excel after Copy, selection
557 // represents the new cursor position and not the copied area
559 else
561 OSL_FAIL("no dimension"); //! possible?
562 SCCOL nFirstCol, nLastCol;
563 SCROW nFirstRow, nLastRow;
564 if ( pInsDoc->GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
565 pInsDoc->GetCellArea( nSrcTab, nLastCol, nLastRow );
566 else
568 nFirstCol = nLastCol = 0;
569 nFirstRow = nLastRow = 0;
571 aSource = ScRange( nFirstCol, nFirstRow, nSrcTab,
572 nLastCol, nLastRow, nSrcTab );
575 if ( pLogicPos )
577 // position specified (Drag&Drop) - change selection
578 MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, false, false );
579 Unmark();
582 pInsDoc->SetClipArea( aSource );
583 PasteFromClip( IDF_ALL, pInsDoc,
584 PASTE_NOFUNC, false, false, false, INS_NONE, IDF_NONE,
585 bAllowDialogs );
586 delete pInsDoc;
588 bRet = true;
592 else if ( nFormatId == SOT_FORMAT_FILE )
594 OUString aFile;
595 if ( aDataHelper.GetString( nFormatId, aFile ) )
596 bRet = PasteFile( aPos, aFile, bLink );
598 else if ( nFormatId == SOT_FORMAT_FILE_LIST )
600 FileList aFileList;
601 if ( aDataHelper.GetFileList( nFormatId, aFileList ) )
603 sal_uLong nCount = aFileList.Count();
604 for( sal_uLong i = 0; i < nCount ; i++ )
606 OUString aFile = aFileList.GetFile( i );
608 PasteFile( aPos, aFile, bLink );
610 aPos.X() += 400;
611 aPos.Y() += 400;
613 bRet = true;
616 else if ( nFormatId == SOT_FORMATSTR_ID_SOLK ||
617 nFormatId == SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ||
618 nFormatId == SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ||
619 nFormatId == SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR )
621 bRet = PasteBookmark( nFormatId, rxTransferable, nPosX, nPosY );
624 pDoc->SetPastingDrawFromOtherDoc( false );
626 return bRet;
629 bool ScViewFunc::PasteLink( const uno::Reference<datatransfer::XTransferable>& rxTransferable )
631 TransferableDataHelper aDataHelper( rxTransferable );
633 // get link data from transferable before string data,
634 // so the source knows it will be used for a link
636 uno::Sequence<sal_Int8> aSequence = aDataHelper.GetSequence(SOT_FORMATSTR_ID_LINK, OUString());
637 if (!aSequence.getLength())
639 OSL_FAIL("DDE Data not found.");
640 return false;
643 // check size (only if string is available in transferable)
645 sal_uInt16 nCols = 1;
646 sal_uInt16 nRows = 1;
647 if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) )
649 OUString aDataStr;
650 if ( aDataHelper.GetString( SOT_FORMAT_STRING, aDataStr ) )
652 // get size from string the same way as in ScDdeLink::DataChanged
654 aDataStr = convertLineEnd(aDataStr, LINEEND_LF);
655 sal_Int32 nLen = aDataStr.getLength();
656 if (nLen && aDataStr[nLen-1] == '\n')
657 aDataStr = aDataStr.copy(0, nLen-1);
659 if (!aDataStr.isEmpty())
661 nRows = comphelper::string::getTokenCount(aDataStr, '\n');
662 OUString aLine = aDataStr.getToken( 0, '\n' );
663 if (!aLine.isEmpty())
664 nCols = comphelper::string::getTokenCount(aLine, '\t');
669 // create formula
671 sal_Int32 nSeqLen = aSequence.getLength();
672 const char* p = reinterpret_cast<const char*>(aSequence.getConstArray());
674 rtl_TextEncoding eSysEnc = osl_getThreadTextEncoding();
676 // char array delimited by \0.
677 // app \0 topic \0 item \0 (extra \0) where the extra is optional.
678 ::std::vector<OUString> aStrs;
679 const char* pStart = p;
680 sal_Int32 nStart = 0;
681 for (sal_Int32 i = 0; i < nSeqLen; ++i, ++p)
683 if (*p == '\0')
685 sal_Int32 nLen = i - nStart;
686 aStrs.push_back(OUString(pStart, nLen, eSysEnc));
687 nStart = ++i;
688 pStart = ++p;
692 if (aStrs.size() < 3)
693 return false;
695 const OUString* pApp = &aStrs[0];
696 const OUString* pTopic = &aStrs[1];
697 const OUString* pItem = &aStrs[2];
698 const OUString* pExtra = NULL;
699 if (aStrs.size() > 3)
700 pExtra = &aStrs[3];
702 if ( pExtra && *pExtra == "calc:extref" )
704 // Paste this as an external reference. Note that paste link always
705 // uses Calc A1 syntax even when another formula syntax is specified
706 // in the UI.
707 EnterMatrix("='"
708 + OUString(ScGlobal::GetAbsDocName(*pTopic, GetViewData()->GetDocument()->GetDocumentShell()))
709 + "'#" + *pItem
710 , ::formula::FormulaGrammar::GRAM_NATIVE);
711 return true;
713 else
715 // DDE in all other cases.
717 // TODO: we could define ocQuote for "
718 EnterMatrix("=" + OUString(ScCompiler::GetNativeSymbol(ocDde))
719 + ScCompiler::GetNativeSymbol(ocOpen)
720 + "\"" + *pApp + "\""
721 + ScCompiler::GetNativeSymbol(ocSep)
722 + "\"" + *pTopic + "\""
723 + ScCompiler::GetNativeSymbol(ocSep)
724 + "\"" + *pItem + "\""
725 + ScCompiler::GetNativeSymbol(ocClose)
726 , ::formula::FormulaGrammar::GRAM_NATIVE);
729 // mark range
731 SCTAB nTab = GetViewData()->GetTabNo();
732 SCCOL nCurX = GetViewData()->GetCurX();
733 SCROW nCurY = GetViewData()->GetCurY();
734 HideAllCursors();
735 DoneBlockMode();
736 InitBlockMode( nCurX, nCurY, nTab );
737 MarkCursor( nCurX+static_cast<SCCOL>(nCols)-1, nCurY+static_cast<SCROW>(nRows)-1, nTab );
738 ShowAllCursors();
739 CursorPosChanged();
741 return true;
745 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */