bump product version to 4.1.6.2
[LibreOffice.git] / sc / source / ui / view / viewfun5.cxx
blob1611c7f37433ee164e826a361e08a443a2741e5e
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 //------------------------------------------------------------------
30 #include <svx/fmmodel.hxx>
31 #include <svx/svdetc.hxx>
32 #include <svx/svditer.hxx>
33 #include <svx/svdobj.hxx>
34 #include <svx/svdogrp.hxx>
35 #include <svx/svdouno.hxx>
36 #include <svx/svdoole2.hxx>
37 #include <svx/svdpage.hxx>
38 #include <sfx2/dispatch.hxx>
39 #include <sfx2/docfile.hxx>
40 #include <comphelper/classids.hxx>
41 #include <sot/formats.hxx>
42 #include <sot/filelist.hxx>
43 #include <unotools/pathoptions.hxx>
44 #include <svl/ptitem.hxx>
45 #include <svl/stritem.hxx>
46 #include <svtools/transfer.hxx>
47 #include <vcl/graph.hxx>
49 #include <comphelper/processfactory.hxx>
50 #include <comphelper/storagehelper.hxx>
51 #include <comphelper/string.hxx>
53 #include "viewfunc.hxx"
54 #include "docsh.hxx"
55 #include "drawview.hxx"
56 #include "impex.hxx"
57 #include "dbfunc.hxx"
58 #include "dbdata.hxx"
59 #include "sc.hrc"
60 #include "filter.hxx"
61 #include "scextopt.hxx"
62 #include "tabvwsh.hxx" // wegen GetViewFrame
63 #include "compiler.hxx"
65 #include "asciiopt.hxx"
66 #include "scabstdlg.hxx"
67 #include "clipparam.hxx"
68 #include "markdata.hxx"
69 #include <vcl/msgbox.hxx>
70 #include <sfx2/viewfrm.hxx>
71 #include <svx/dbaexchange.hxx>
73 using namespace com::sun::star;
75 //------------------------------------------------------------------
77 sal_Bool ScViewFunc::PasteDataFormat( sal_uLong nFormatId,
78 const uno::Reference<datatransfer::XTransferable>& rxTransferable,
79 SCCOL nPosX, SCROW nPosY, Point* pLogicPos, sal_Bool bLink, sal_Bool bAllowDialogs )
81 ScDocument* pDoc = GetViewData()->GetDocument();
82 pDoc->SetPastingDrawFromOtherDoc( sal_True );
84 Point aPos; // inserting position (1/100 mm)
85 if (pLogicPos)
86 aPos = *pLogicPos;
87 else
89 // inserting position isn't needed for text formats
90 sal_Bool bIsTextFormat = ( ScImportExport::IsFormatSupported( nFormatId ) ||
91 nFormatId == FORMAT_RTF );
92 if ( !bIsTextFormat )
94 // Window MapMode isn't drawing MapMode if DrawingLayer hasn't been created yet
96 SCTAB nTab = GetViewData()->GetTabNo();
97 long nXT = 0;
98 for (SCCOL i=0; i<nPosX; i++)
99 nXT += pDoc->GetColWidth(i,nTab);
100 if (pDoc->IsNegativePage(nTab))
101 nXT = -nXT;
102 sal_uLong nYT = pDoc->GetRowHeight( 0, nPosY-1, nTab);
103 aPos = Point( (long)(nXT * HMM_PER_TWIPS), (long)(nYT * HMM_PER_TWIPS) );
107 TransferableDataHelper aDataHelper( rxTransferable );
108 sal_Bool bRet = false;
111 // handle individual formats
114 if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE ||
115 nFormatId == SOT_FORMATSTR_ID_LINK_SOURCE ||
116 nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ||
117 nFormatId == SOT_FORMATSTR_ID_LINK_SOURCE_OLE ||
118 nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
120 uno::Reference < io::XInputStream > xStm;
121 TransferableObjectDescriptor aObjDesc;
123 if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) &&
124 aDataHelper.GetInputStream( nFormatId, xStm ) )
126 if ( aObjDesc.maClassName == SvGlobalName( SO3_SC_CLASSID_60 ) )
128 uno::Reference < embed::XStorage > xStore = ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm );
130 // mba: BaseURL doesn't make sense for clipboard
131 // #i43716# Medium must be allocated with "new".
132 // DoLoad stores the pointer and deletes it with the SfxObjectShell.
133 SfxMedium* pMedium = new SfxMedium( xStore, String() );
135 // TODO/LATER: is it a problem that we don't support binary formats here?
136 ScDocShellRef xDocShRef = new ScDocShell(SFX_CREATE_MODE_EMBEDDED);
137 if (xDocShRef->DoLoad(pMedium))
139 ScDocument* pSrcDoc = xDocShRef->GetDocument();
140 SCTAB nSrcTab = pSrcDoc->GetVisibleTab();
141 if (!pSrcDoc->HasTable(nSrcTab))
142 nSrcTab = 0;
144 ScMarkData aSrcMark;
145 aSrcMark.SelectOneTable( nSrcTab ); // for CopyToClip
146 ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
148 SCCOL nFirstCol, nLastCol;
149 SCROW nFirstRow, nLastRow;
150 if ( pSrcDoc->GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
151 pSrcDoc->GetCellArea( nSrcTab, nLastCol, nLastRow );
152 else
154 nFirstCol = nLastCol = 0;
155 nFirstRow = nLastRow = 0;
157 ScClipParam aClipParam(ScRange(nFirstCol, nFirstRow, nSrcTab, nLastCol, nLastRow, nSrcTab), false);
158 pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aSrcMark);
159 ScGlobal::SetClipDocName( xDocShRef->GetTitle( SFX_TITLE_FULLNAME ) );
161 SetCursor( nPosX, nPosY );
162 Unmark();
163 PasteFromClip( IDF_ALL, pClipDoc,
164 PASTE_NOFUNC, false, false, false, INS_NONE, IDF_NONE,
165 bAllowDialogs );
166 delete pClipDoc;
167 bRet = sal_True;
170 xDocShRef->DoClose();
171 xDocShRef.Clear();
173 else
175 OUString aName;
176 uno::Reference < embed::XEmbeddedObject > xObj = GetViewData()->GetViewShell()->GetObjectShell()->
177 GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
178 if ( xObj.is() )
180 // try to get the replacement image from the clipboard
181 Graphic aGraphic;
182 sal_uLong nGrFormat = 0;
184 // insert replacement image ( if there is one ) into the object helper
185 if ( nGrFormat )
187 datatransfer::DataFlavor aDataFlavor;
188 SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
189 PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
191 else
192 PasteObject( aPos, xObj, &aObjDesc.maSize );
194 bRet = sal_True;
196 else
198 OSL_FAIL("Error in CreateAndLoad");
202 else
204 if ( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR_OLE, aObjDesc ) )
206 OUString aName;
207 uno::Reference < embed::XEmbeddedObject > xObj;
209 if ( aDataHelper.GetInputStream( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, xStm )
210 || aDataHelper.GetInputStream( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, xStm ) )
212 xObj = GetViewData()->GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
214 else
218 uno::Reference< embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
219 uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator =
220 embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
222 embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard(
223 xTmpStor,
224 OUString( "DummyName" ),
225 uno::Sequence< beans::PropertyValue >() );
227 // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
228 // for example whether the object should be an iconified one
229 xObj = aInfo.Object;
230 if ( xObj.is() )
231 GetViewData()->GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName );
233 catch( uno::Exception& )
237 if ( xObj.is() )
239 // try to get the replacement image from the clipboard
240 Graphic aGraphic;
241 sal_uLong nGrFormat = 0;
243 // (wg. Selection Manager bei Trustet Solaris)
244 #ifndef SOLARIS
245 if( aDataHelper.GetGraphic( SOT_FORMATSTR_ID_SVXB, aGraphic ) )
246 nGrFormat = SOT_FORMATSTR_ID_SVXB;
247 else if( aDataHelper.GetGraphic( FORMAT_GDIMETAFILE, aGraphic ) )
248 nGrFormat = SOT_FORMAT_GDIMETAFILE;
249 else if( aDataHelper.GetGraphic( FORMAT_BITMAP, aGraphic ) )
250 nGrFormat = SOT_FORMAT_BITMAP;
251 #endif
253 // insert replacement image ( if there is one ) into the object helper
254 if ( nGrFormat )
256 datatransfer::DataFlavor aDataFlavor;
257 SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
258 PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
260 else
261 PasteObject( aPos, xObj, &aObjDesc.maSize );
263 // let object stay in loaded state after insertion
264 SdrOle2Obj::Unload( xObj, embed::Aspects::MSOLE_CONTENT );
265 bRet = sal_True;
267 else
269 OSL_FAIL("Error creating external OLE object");
272 //TODO/LATER: if format is not available, create picture
275 else if ( nFormatId == SOT_FORMATSTR_ID_LINK ) // LINK is also in ScImportExport
277 bRet = PasteLink( rxTransferable );
279 else if ( ScImportExport::IsFormatSupported( nFormatId ) || nFormatId == SOT_FORMAT_RTF )
281 if ( nFormatId == SOT_FORMAT_RTF && aDataHelper.HasFormat( SOT_FORMATSTR_ID_EDITENGINE ) )
283 // use EditView's PasteSpecial / Drop
284 PasteRTF( nPosX, nPosY, rxTransferable );
285 bRet = sal_True;
287 else
289 ScAddress aCellPos( nPosX, nPosY, GetViewData()->GetTabNo() );
290 ScImportExport aObj( GetViewData()->GetDocument(), aCellPos );
292 OUString aStr;
293 SotStorageStreamRef xStream;
294 if ( aDataHelper.GetSotStorageStream( nFormatId, xStream ) && xStream.Is() )
296 if (nFormatId == SOT_FORMATSTR_ID_HTML)
298 // Launch the text import options dialog. For now, we do
299 // this for html pasting only, but in the future it may
300 // make sense to do it for other data types too.
301 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
302 boost::scoped_ptr<AbstractScTextImportOptionsDlg> pDlg(
303 pFact->CreateScTextImportOptionsDlg(NULL));
305 if (pDlg->Execute() == RET_OK)
307 ScAsciiOptions aOptions;
308 aOptions.SetLanguage(pDlg->GetLanguageType());
309 aOptions.SetDetectSpecialNumber(pDlg->IsDateConversionSet());
310 aObj.SetExtOptions(aOptions);
312 else
314 // prevent error dialog for user cancel action
315 bRet = true;
318 if(!bRet)
319 bRet = aObj.ImportStream( *xStream, String(), nFormatId );
320 // mba: clipboard always must contain absolute URLs (could be from alien source)
322 else if (nFormatId == FORMAT_STRING && aDataHelper.GetString( nFormatId, aStr ))
324 // Do CSV dialog if more than one line.
325 sal_Int32 nDelim = aStr.indexOf('\n');
326 if (nDelim >= 0 && nDelim != aStr.getLength () - 1)
328 ScImportStringStream aStrm( aStr);
329 ScAbstractDialogFactory* pFact =
330 ScAbstractDialogFactory::Create();
331 AbstractScImportAsciiDlg *pDlg =
332 pFact->CreateScImportAsciiDlg( NULL, String(), &aStrm,
333 SC_PASTETEXT);
335 if (pDlg->Execute() == RET_OK)
337 ScAsciiOptions aOptions;
338 pDlg->GetOptions( aOptions );
339 pDlg->SaveParameters();
340 aObj.SetExtOptions( aOptions );
342 bRet = aObj.ImportString( aStr, nFormatId );
344 // TODO: what if (aObj.IsOverflow())
345 // Content was partially pasted, which can be undone by
346 // the user though.
347 if (aObj.IsOverflow())
348 bRet = false;
350 else
351 bRet = sal_True;
352 // Yes, no failure, don't raise a "couldn't paste"
353 // dialog if user cancelled.
354 delete pDlg;
356 else
357 bRet = aObj.ImportString( aStr, nFormatId );
359 else if (nFormatId != FORMAT_STRING && aDataHelper.GetString( nFormatId, aStr ))
360 bRet = aObj.ImportString( aStr, nFormatId );
362 InvalidateAttribs();
363 GetViewData()->UpdateInputHandler();
366 else if (nFormatId == SOT_FORMATSTR_ID_SBA_DATAEXCHANGE)
368 // import of database data into table
370 const DataFlavorExVector& rVector = aDataHelper.GetDataFlavorExVector();
371 if ( svx::ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector) )
373 // transport the whole ODataAccessDescriptor as slot parameter
374 svx::ODataAccessDescriptor aDesc = svx::ODataAccessObjectTransferable::extractObjectDescriptor(aDataHelper);
375 uno::Any aDescAny;
376 uno::Sequence<beans::PropertyValue> aProperties = aDesc.createPropertyValueSequence();
377 aDescAny <<= aProperties;
378 SfxUsrAnyItem aDataDesc(SID_SBA_IMPORT, aDescAny);
380 ScDocShell* pDocSh = GetViewData()->GetDocShell();
381 SCTAB nTab = GetViewData()->GetTabNo();
383 ClickCursor(nPosX, nPosY, false); // set cursor position
385 // Creation of database area "Import1" isn't here, but in the DocShell
386 // slot execute, so it can be added to the undo action
388 ScDBData* pDBData = pDocSh->GetDBData( ScRange(nPosX,nPosY,nTab), SC_DB_OLD, SC_DBSEL_KEEP );
389 String sTarget;
390 if (pDBData)
391 sTarget = pDBData->GetName();
392 else
394 ScAddress aCellPos( nPosX,nPosY,nTab );
395 aCellPos.Format( sTarget, SCA_ABS_3D, pDoc, pDoc->GetAddressConvention() );
397 SfxStringItem aTarget(FN_PARAM_1, sTarget);
399 sal_Bool bAreaIsNew = !pDBData;
400 SfxBoolItem aAreaNew(FN_PARAM_2, bAreaIsNew);
402 // asynchronous, to avoid doing the whole import in drop handler
403 SfxDispatcher& rDisp = GetViewData()->GetDispatcher();
404 rDisp.Execute(SID_SBA_IMPORT, SFX_CALLMODE_ASYNCHRON,
405 &aDataDesc, &aTarget, &aAreaNew, (void*)0 );
407 bRet = sal_True;
410 else if (nFormatId == SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE)
412 // insert database field control
414 if ( ::svx::OColumnTransferable::canExtractColumnDescriptor( aDataHelper.GetDataFlavorExVector(), CTF_COLUMN_DESCRIPTOR | CTF_CONTROL_EXCHANGE ) )
416 MakeDrawLayer();
417 ScDrawView* pScDrawView = GetScDrawView();
418 SdrObject* pObj = pScDrawView->CreateFieldControl( ::svx::OColumnTransferable::extractColumnDescriptor( aDataHelper ) );
419 if (pObj)
421 Point aInsPos = aPos;
422 Rectangle aRect(pObj->GetLogicRect());
423 aInsPos.X() -= aRect.GetSize().Width() / 2;
424 aInsPos.Y() -= aRect.GetSize().Height() / 2;
425 if ( aInsPos.X() < 0 ) aInsPos.X() = 0;
426 if ( aInsPos.Y() < 0 ) aInsPos.Y() = 0;
427 aRect.SetPos(aInsPos);
428 pObj->SetLogicRect(aRect);
430 if ( pObj->ISA(SdrUnoObj) )
431 pObj->NbcSetLayer(SC_LAYER_CONTROLS);
432 else
433 pObj->NbcSetLayer(SC_LAYER_FRONT);
434 if (pObj->ISA(SdrObjGroup))
436 SdrObjListIter aIter( *pObj, IM_DEEPWITHGROUPS );
437 SdrObject* pSubObj = aIter.Next();
438 while (pSubObj)
440 if ( pSubObj->ISA(SdrUnoObj) )
441 pSubObj->NbcSetLayer(SC_LAYER_CONTROLS);
442 else
443 pSubObj->NbcSetLayer(SC_LAYER_FRONT);
444 pSubObj = aIter.Next();
448 pScDrawView->InsertObjectSafe(pObj, *pScDrawView->GetSdrPageView());
450 GetViewData()->GetViewShell()->SetDrawShell( sal_True );
451 bRet = sal_True;
455 else if (nFormatId == SOT_FORMAT_BITMAP)
457 Bitmap aBmp;
458 if( aDataHelper.GetBitmap( FORMAT_BITMAP, aBmp ) )
459 bRet = PasteBitmap( aPos, aBmp );
461 else if (nFormatId == SOT_FORMAT_GDIMETAFILE)
463 GDIMetaFile aMtf;
464 if( aDataHelper.GetGDIMetaFile( FORMAT_GDIMETAFILE, aMtf ) )
465 bRet = PasteMetaFile( aPos, aMtf );
467 else if (nFormatId == SOT_FORMATSTR_ID_SVXB)
469 SotStorageStreamRef xStm;
470 if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_SVXB, xStm ) )
472 Graphic aGraphic;
473 *xStm >> aGraphic;
474 bRet = PasteGraphic( aPos, aGraphic, EMPTY_STRING, EMPTY_STRING );
477 else if ( nFormatId == SOT_FORMATSTR_ID_DRAWING )
479 SotStorageStreamRef xStm;
480 if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_DRAWING, xStm ) )
482 MakeDrawLayer(); // before loading model, so 3D factory has been created
484 SvtPathOptions aPathOpt;
485 String aPath = aPathOpt.GetPalettePath();
487 ScDocShellRef aDragShellRef( new ScDocShell );
488 aDragShellRef->DoInitNew(NULL);
489 FmFormModel* pModel = new FmFormModel( aPath, NULL, aDragShellRef );
491 pModel->GetItemPool().FreezeIdRanges();
492 xStm->Seek(0);
494 com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm ) );
495 SvxDrawingLayerImport( pModel, xInputStream );
497 // set everything to right layer:
498 sal_uLong nObjCount = 0;
499 sal_uInt16 nPages = pModel->GetPageCount();
500 for (sal_uInt16 i=0; i<nPages; i++)
502 SdrPage* pPage = pModel->GetPage(i);
503 SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
504 SdrObject* pObject = aIter.Next();
505 while (pObject)
507 if ( pObject->ISA(SdrUnoObj) )
508 pObject->NbcSetLayer(SC_LAYER_CONTROLS);
509 else
510 pObject->NbcSetLayer(SC_LAYER_FRONT);
511 pObject = aIter.Next();
514 nObjCount += pPage->GetObjCount(); // count group object only once
517 PasteDraw( aPos, pModel, (nObjCount > 1) ); // grouped if more than 1 object
518 delete pModel;
519 aDragShellRef->DoClose();
520 bRet = sal_True;
523 else if ( (nFormatId == SOT_FORMATSTR_ID_BIFF_5) || (nFormatId == SOT_FORMATSTR_ID_BIFF_8) )
525 // do excel import into a clipboard document
526 //TODO/MBA: testing
527 uno::Reference < io::XInputStream > xStm;
528 if( aDataHelper.GetInputStream( nFormatId, xStm ) )
530 ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
531 SCTAB nSrcTab = 0; // Biff5 in clipboard: always sheet 0
532 pInsDoc->ResetClip( pDoc, nSrcTab );
534 SfxMedium aMed;
535 aMed.GetItemSet()->Put( SfxUsrAnyItem( SID_INPUTSTREAM, uno::makeAny( xStm ) ) );
536 FltError eErr = ScFormatFilter::Get().ScImportExcel( aMed, pInsDoc, EIF_AUTO );
537 if ( eErr == eERR_OK )
539 ScRange aSource;
540 const ScExtDocOptions* pExtOpt = pInsDoc->GetExtDocOptions();
541 const ScExtTabSettings* pTabSett = pExtOpt ? pExtOpt->GetTabSettings( nSrcTab ) : 0;
542 if( pTabSett && pTabSett->maUsedArea.IsValid() )
544 aSource = pTabSett->maUsedArea;
545 // ensure correct sheet indexes
546 aSource.aStart.SetTab( nSrcTab );
547 aSource.aEnd.SetTab( nSrcTab );
548 // don't use selection area: if cursor is moved in Excel after Copy, selection
549 // represents the new cursor position and not the copied area
551 else
553 OSL_FAIL("no dimension"); //! possible?
554 SCCOL nFirstCol, nLastCol;
555 SCROW nFirstRow, nLastRow;
556 if ( pInsDoc->GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
557 pInsDoc->GetCellArea( nSrcTab, nLastCol, nLastRow );
558 else
560 nFirstCol = nLastCol = 0;
561 nFirstRow = nLastRow = 0;
563 aSource = ScRange( nFirstCol, nFirstRow, nSrcTab,
564 nLastCol, nLastRow, nSrcTab );
567 if ( pLogicPos )
569 // position specified (Drag&Drop) - change selection
570 MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, false, false );
571 Unmark();
574 pInsDoc->SetClipArea( aSource );
575 PasteFromClip( IDF_ALL, pInsDoc,
576 PASTE_NOFUNC, false, false, false, INS_NONE, IDF_NONE,
577 bAllowDialogs );
578 delete pInsDoc;
580 bRet = sal_True;
584 else if ( nFormatId == SOT_FORMAT_FILE )
586 String aFile;
587 if ( aDataHelper.GetString( nFormatId, aFile ) )
588 bRet = PasteFile( aPos, aFile, bLink );
590 else if ( nFormatId == SOT_FORMAT_FILE_LIST )
592 FileList aFileList;
593 if ( aDataHelper.GetFileList( nFormatId, aFileList ) )
595 sal_uLong nCount = aFileList.Count();
596 for( sal_uLong i = 0; i < nCount ; i++ )
598 String aFile = aFileList.GetFile( i );
600 PasteFile( aPos, aFile, bLink );
602 aPos.X() += 400;
603 aPos.Y() += 400;
605 bRet = sal_True;
608 else if ( nFormatId == SOT_FORMATSTR_ID_SOLK ||
609 nFormatId == SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ||
610 nFormatId == SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ||
611 nFormatId == SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR )
613 bRet = PasteBookmark( nFormatId, rxTransferable, nPosX, nPosY );
616 pDoc->SetPastingDrawFromOtherDoc( false );
618 return bRet;
621 bool ScViewFunc::PasteLink( const uno::Reference<datatransfer::XTransferable>& rxTransferable )
623 TransferableDataHelper aDataHelper( rxTransferable );
625 // get link data from transferable before string data,
626 // so the source knows it will be used for a link
628 uno::Sequence<sal_Int8> aSequence;
629 if ( !aDataHelper.GetSequence( SOT_FORMATSTR_ID_LINK, aSequence ) )
631 OSL_FAIL("DDE Data not found.");
632 return false;
635 // check size (only if string is available in transferable)
637 sal_uInt16 nCols = 1;
638 sal_uInt16 nRows = 1;
639 if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) )
641 String aDataStr;
642 if ( aDataHelper.GetString( SOT_FORMAT_STRING, aDataStr ) )
644 // get size from string the same way as in ScDdeLink::DataChanged
646 aDataStr = convertLineEnd(aDataStr, LINEEND_LF);
647 xub_StrLen nLen = aDataStr.Len();
648 if (nLen && aDataStr.GetChar(nLen-1) == '\n')
649 aDataStr.Erase(nLen-1);
651 if (aDataStr.Len())
653 nRows = comphelper::string::getTokenCount(aDataStr, '\n');
654 String aLine = aDataStr.GetToken( 0, '\n' );
655 if (aLine.Len())
656 nCols = comphelper::string::getTokenCount(aLine, '\t');
661 // create formula
663 sal_Int32 nSeqLen = aSequence.getLength();
664 const char* p = reinterpret_cast<const char*>(aSequence.getConstArray());
666 rtl_TextEncoding eSysEnc = osl_getThreadTextEncoding();
668 // char array delimited by \0.
669 // app \0 topic \0 item \0 (extra \0) where the extra is optional.
670 ::std::vector<OUString> aStrs;
671 const char* pStart = p;
672 sal_Int32 nStart = 0;
673 for (sal_Int32 i = 0; i < nSeqLen; ++i, ++p)
675 if (*p == '\0')
677 sal_Int32 nLen = i - nStart;
678 aStrs.push_back(OUString(pStart, nLen, eSysEnc));
679 nStart = ++i;
680 pStart = ++p;
684 if (aStrs.size() < 3)
685 return false;
687 const OUString* pApp = &aStrs[0];
688 const OUString* pTopic = &aStrs[1];
689 const OUString* pItem = &aStrs[2];
690 const OUString* pExtra = NULL;
691 if (aStrs.size() > 3)
692 pExtra = &aStrs[3];
694 if ( pExtra && *pExtra == "calc:extref" )
696 // Paste this as an external reference. Note that paste link always
697 // uses Calc A1 syntax even when another formula syntax is specified
698 // in the UI.
699 OUStringBuffer aBuf;
700 aBuf.appendAscii("='");
701 OUString aPath = ScGlobal::GetAbsDocName(
702 *pTopic, GetViewData()->GetDocument()->GetDocumentShell());
703 aBuf.append(aPath);
704 aBuf.appendAscii("'#");
705 aBuf.append(*pItem);
706 EnterMatrix(aBuf.makeStringAndClear(), ::formula::FormulaGrammar::GRAM_NATIVE);
707 return true;
709 else
711 // DDE in all other cases.
713 // TODO: we could define ocQuote for "
714 OUStringBuffer aBuf;
715 aBuf.append(sal_Unicode('='));
716 aBuf.append(ScCompiler::GetNativeSymbol(ocDde));
717 aBuf.append(ScCompiler::GetNativeSymbol(ocOpen));
718 aBuf.append(sal_Unicode('"'));
719 aBuf.append(*pApp);
720 aBuf.append(sal_Unicode('"'));
721 aBuf.append(ScCompiler::GetNativeSymbol(ocSep));
722 aBuf.append(sal_Unicode('"'));
723 aBuf.append(*pTopic);
724 aBuf.append(sal_Unicode('"'));
725 aBuf.append(ScCompiler::GetNativeSymbol(ocSep));
726 aBuf.append(sal_Unicode('"'));
727 aBuf.append(*pItem);
728 aBuf.append(sal_Unicode('"'));
729 aBuf.append(ScCompiler::GetNativeSymbol(ocClose));
731 EnterMatrix(aBuf.makeStringAndClear(), ::formula::FormulaGrammar::GRAM_NATIVE);
734 // mark range
736 SCTAB nTab = GetViewData()->GetTabNo();
737 SCCOL nCurX = GetViewData()->GetCurX();
738 SCROW nCurY = GetViewData()->GetCurY();
739 HideAllCursors();
740 DoneBlockMode();
741 InitBlockMode( nCurX, nCurY, nTab );
742 MarkCursor( nCurX+static_cast<SCCOL>(nCols)-1, nCurY+static_cast<SCROW>(nRows)-1, nTab );
743 ShowAllCursors();
744 CursorPosChanged();
746 return true;
750 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */