Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <com/sun/star/embed/XEmbedObjectClipboardCreator.hpp>
21 : #include <com/sun/star/embed/Aspects.hpp>
22 : #include <com/sun/star/embed/MSOLEObjectSystemCreator.hpp>
23 :
24 : #include <svx/unomodel.hxx>
25 : #include <unotools/streamwrap.hxx>
26 :
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>
46 :
47 : #include <comphelper/processfactory.hxx>
48 : #include <comphelper/storagehelper.hxx>
49 : #include <comphelper/string.hxx>
50 :
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"
62 :
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>
71 :
72 : using namespace com::sun::star;
73 :
74 0 : bool ScViewFunc::PasteDataFormat( SotClipboardFormatId nFormatId,
75 : const uno::Reference<datatransfer::XTransferable>& rxTransferable,
76 : SCCOL nPosX, SCROW nPosY, Point* pLogicPos, bool bLink, bool bAllowDialogs )
77 : {
78 0 : ScDocument* pDoc = GetViewData().GetDocument();
79 0 : pDoc->SetPastingDrawFromOtherDoc( true );
80 :
81 0 : Point aPos; // inserting position (1/100 mm)
82 0 : if (pLogicPos)
83 0 : aPos = *pLogicPos;
84 : else
85 : {
86 : // inserting position isn't needed for text formats
87 0 : bool bIsTextFormat = ( ScImportExport::IsFormatSupported( nFormatId ) ||
88 0 : nFormatId == SotClipboardFormatId::RTF );
89 0 : if ( !bIsTextFormat )
90 : {
91 : // Window MapMode isn't drawing MapMode if DrawingLayer hasn't been created yet
92 :
93 0 : SCTAB nTab = GetViewData().GetTabNo();
94 0 : long nXT = 0;
95 0 : for (SCCOL i=0; i<nPosX; i++)
96 0 : nXT += pDoc->GetColWidth(i,nTab);
97 0 : if (pDoc->IsNegativePage(nTab))
98 0 : nXT = -nXT;
99 0 : sal_uLong nYT = pDoc->GetRowHeight( 0, nPosY-1, nTab);
100 0 : aPos = Point( (long)(nXT * HMM_PER_TWIPS), (long)(nYT * HMM_PER_TWIPS) );
101 : }
102 : }
103 :
104 0 : TransferableDataHelper aDataHelper( rxTransferable );
105 0 : bool bRet = false;
106 :
107 : // handle individual formats
108 :
109 0 : if ( nFormatId == SotClipboardFormatId::EMBED_SOURCE ||
110 0 : nFormatId == SotClipboardFormatId::LINK_SOURCE ||
111 0 : nFormatId == SotClipboardFormatId::EMBED_SOURCE_OLE ||
112 0 : nFormatId == SotClipboardFormatId::LINK_SOURCE_OLE ||
113 : nFormatId == SotClipboardFormatId::EMBEDDED_OBJ_OLE )
114 : {
115 0 : uno::Reference < io::XInputStream > xStm;
116 0 : TransferableObjectDescriptor aObjDesc;
117 :
118 0 : if (aDataHelper.GetTransferableObjectDescriptor(SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc))
119 0 : xStm = aDataHelper.GetInputStream(nFormatId, OUString());
120 :
121 0 : if (xStm.is())
122 : {
123 0 : if ( aObjDesc.maClassName == SvGlobalName( SO3_SC_CLASSID_60 ) )
124 : {
125 0 : uno::Reference < embed::XStorage > xStore = ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm );
126 :
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 0 : SfxMedium* pMedium = new SfxMedium( xStore, OUString() );
131 :
132 : // TODO/LATER: is it a problem that we don't support binary formats here?
133 0 : ScDocShellRef xDocShRef = new ScDocShell(SfxModelFlags::EMBEDDED_OBJECT);
134 0 : if (xDocShRef->DoLoad(pMedium))
135 : {
136 0 : ScDocument& rSrcDoc = xDocShRef->GetDocument();
137 0 : SCTAB nSrcTab = rSrcDoc.GetVisibleTab();
138 0 : if (!rSrcDoc.HasTable(nSrcTab))
139 0 : nSrcTab = 0;
140 :
141 0 : ScMarkData aSrcMark;
142 0 : aSrcMark.SelectOneTable( nSrcTab ); // for CopyToClip
143 0 : boost::scoped_ptr<ScDocument> pClipDoc(new ScDocument( SCDOCMODE_CLIP ));
144 :
145 : SCCOL nFirstCol, nLastCol;
146 : SCROW nFirstRow, nLastRow;
147 0 : if ( rSrcDoc.GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
148 0 : rSrcDoc.GetCellArea( nSrcTab, nLastCol, nLastRow );
149 : else
150 : {
151 0 : nFirstCol = nLastCol = 0;
152 0 : nFirstRow = nLastRow = 0;
153 : }
154 0 : ScClipParam aClipParam(ScRange(nFirstCol, nFirstRow, nSrcTab, nLastCol, nLastRow, nSrcTab), false);
155 0 : rSrcDoc.CopyToClip(aClipParam, pClipDoc.get(), &aSrcMark);
156 0 : ScGlobal::SetClipDocName( xDocShRef->GetTitle( SFX_TITLE_FULLNAME ) );
157 :
158 0 : SetCursor( nPosX, nPosY );
159 0 : Unmark();
160 : PasteFromClip( IDF_ALL, pClipDoc.get(),
161 : PASTE_NOFUNC, false, false, false, INS_NONE, IDF_NONE,
162 0 : bAllowDialogs );
163 0 : bRet = true;
164 : }
165 :
166 0 : xDocShRef->DoClose();
167 0 : xDocShRef.Clear();
168 : }
169 : else
170 : {
171 0 : OUString aName;
172 0 : uno::Reference < embed::XEmbeddedObject > xObj = GetViewData().GetViewShell()->GetObjectShell()->
173 0 : GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
174 0 : if ( xObj.is() )
175 : {
176 : // try to get the replacement image from the clipboard
177 0 : Graphic aGraphic;
178 0 : SotClipboardFormatId nGrFormat = SotClipboardFormatId::NONE;
179 :
180 : // limit the size of the preview metafile to 100000 actions
181 0 : GDIMetaFile aMetafile;
182 0 : if (aDataHelper.GetGDIMetaFile(SotClipboardFormatId::GDIMETAFILE, aMetafile, 100000))
183 : {
184 0 : nGrFormat = SotClipboardFormatId::GDIMETAFILE;
185 0 : aGraphic = aMetafile;
186 : }
187 :
188 : // insert replacement image ( if there is one ) into the object helper
189 0 : if ( nGrFormat != SotClipboardFormatId::NONE )
190 : {
191 0 : datatransfer::DataFlavor aDataFlavor;
192 0 : SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
193 0 : PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
194 : }
195 : else
196 0 : PasteObject( aPos, xObj, &aObjDesc.maSize );
197 :
198 0 : bRet = true;
199 : }
200 : else
201 : {
202 : OSL_FAIL("Error in CreateAndLoad");
203 0 : }
204 : }
205 : }
206 : else
207 : {
208 0 : if ( aDataHelper.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE, aObjDesc ) )
209 : {
210 0 : OUString aName;
211 0 : uno::Reference < embed::XEmbeddedObject > xObj;
212 0 : xStm = aDataHelper.GetInputStream(SotClipboardFormatId::EMBED_SOURCE_OLE, OUString());
213 0 : if (!xStm.is())
214 0 : aDataHelper.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ_OLE, OUString());
215 :
216 0 : if (xStm.is())
217 : {
218 0 : xObj = GetViewData().GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
219 : }
220 : else
221 : {
222 : try
223 : {
224 0 : uno::Reference< embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
225 : uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator =
226 0 : embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
227 :
228 0 : embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard(
229 : xTmpStor,
230 : OUString( "DummyName" ),
231 0 : uno::Sequence< beans::PropertyValue >() );
232 :
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 0 : xObj = aInfo.Object;
236 0 : if ( xObj.is() )
237 0 : GetViewData().GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName );
238 : }
239 0 : catch( uno::Exception& )
240 : {}
241 : }
242 :
243 0 : if ( xObj.is() )
244 : {
245 : // try to get the replacement image from the clipboard
246 0 : Graphic aGraphic;
247 0 : SotClipboardFormatId nGrFormat = SotClipboardFormatId::NONE;
248 :
249 : // (wg. Selection Manager bei Trustet Solaris)
250 : #ifndef SOLARIS
251 0 : if( aDataHelper.GetGraphic( SotClipboardFormatId::SVXB, aGraphic ) )
252 0 : nGrFormat = SotClipboardFormatId::SVXB;
253 0 : else if( aDataHelper.GetGraphic( SotClipboardFormatId::GDIMETAFILE, aGraphic ) )
254 0 : nGrFormat = SotClipboardFormatId::GDIMETAFILE;
255 0 : else if( aDataHelper.GetGraphic( SotClipboardFormatId::BITMAP, aGraphic ) )
256 0 : nGrFormat = SotClipboardFormatId::BITMAP;
257 : #endif
258 :
259 : // insert replacement image ( if there is one ) into the object helper
260 0 : if ( nGrFormat != SotClipboardFormatId::NONE )
261 : {
262 0 : datatransfer::DataFlavor aDataFlavor;
263 0 : SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
264 0 : PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
265 : }
266 : else
267 0 : PasteObject( aPos, xObj, &aObjDesc.maSize );
268 :
269 : // let object stay in loaded state after insertion
270 0 : SdrOle2Obj::Unload( xObj, embed::Aspects::MSOLE_CONTENT );
271 0 : bRet = true;
272 : }
273 : else
274 : {
275 : OSL_FAIL("Error creating external OLE object");
276 0 : }
277 : }
278 : //TODO/LATER: if format is not available, create picture
279 0 : }
280 : }
281 0 : else if ( nFormatId == SotClipboardFormatId::LINK ) // LINK is also in ScImportExport
282 : {
283 0 : bRet = PasteLink( rxTransferable );
284 : }
285 0 : else if ( ScImportExport::IsFormatSupported( nFormatId ) || nFormatId == SotClipboardFormatId::RTF )
286 : {
287 0 : if ( nFormatId == SotClipboardFormatId::RTF && aDataHelper.HasFormat( SotClipboardFormatId::EDITENGINE ) )
288 : {
289 : // use EditView's PasteSpecial / Drop
290 0 : PasteRTF( nPosX, nPosY, rxTransferable );
291 0 : bRet = true;
292 : }
293 : else
294 : {
295 0 : ScAddress aCellPos( nPosX, nPosY, GetViewData().GetTabNo() );
296 0 : ScImportExport aObj( GetViewData().GetDocument(), aCellPos );
297 0 : aObj.SetOverwriting( true );
298 :
299 0 : OUString aStr;
300 0 : tools::SvRef<SotStorageStream> xStream;
301 0 : if ( aDataHelper.GetSotStorageStream( nFormatId, xStream ) && xStream.Is() )
302 : {
303 0 : if (nFormatId == SotClipboardFormatId::HTML)
304 : {
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 0 : ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
309 : boost::scoped_ptr<AbstractScTextImportOptionsDlg> pDlg(
310 0 : pFact->CreateScTextImportOptionsDlg(NULL));
311 :
312 0 : if (pDlg->Execute() == RET_OK)
313 : {
314 0 : ScAsciiOptions aOptions;
315 0 : aOptions.SetLanguage(pDlg->GetLanguageType());
316 0 : aOptions.SetDetectSpecialNumber(pDlg->IsDateConversionSet());
317 0 : aObj.SetExtOptions(aOptions);
318 : }
319 : else
320 : {
321 : // prevent error dialog for user cancel action
322 0 : bRet = true;
323 0 : }
324 : }
325 0 : if(!bRet)
326 0 : bRet = aObj.ImportStream( *xStream, OUString(), nFormatId );
327 : // mba: clipboard always must contain absolute URLs (could be from alien source)
328 : }
329 0 : else if (nFormatId == SotClipboardFormatId::STRING && aDataHelper.GetString( nFormatId, aStr ))
330 : {
331 : // Do CSV dialog if more than one line.
332 0 : sal_Int32 nDelim = aStr.indexOf('\n');
333 0 : if (nDelim >= 0 && nDelim != aStr.getLength () - 1)
334 : {
335 0 : ScImportStringStream aStrm( aStr);
336 : ScAbstractDialogFactory* pFact =
337 0 : ScAbstractDialogFactory::Create();
338 : boost::scoped_ptr<AbstractScImportAsciiDlg> pDlg(
339 : pFact->CreateScImportAsciiDlg( NULL, OUString(), &aStrm,
340 0 : SC_PASTETEXT));
341 :
342 0 : if (pDlg->Execute() == RET_OK)
343 : {
344 0 : ScAsciiOptions aOptions;
345 0 : pDlg->GetOptions( aOptions );
346 0 : pDlg->SaveParameters();
347 0 : aObj.SetExtOptions( aOptions );
348 :
349 0 : bRet = aObj.ImportString( aStr, nFormatId );
350 :
351 : // TODO: what if (aObj.IsOverflow())
352 : // Content was partially pasted, which can be undone by
353 : // the user though.
354 0 : if (aObj.IsOverflow())
355 0 : bRet = false;
356 : }
357 : else
358 0 : bRet = true;
359 : // Yes, no failure, don't raise a "couldn't paste"
360 : // dialog if user cancelled.
361 : }
362 : else
363 0 : bRet = aObj.ImportString( aStr, nFormatId );
364 : }
365 0 : else if (nFormatId != SotClipboardFormatId::STRING && aDataHelper.GetString( nFormatId, aStr ))
366 0 : bRet = aObj.ImportString( aStr, nFormatId );
367 :
368 0 : InvalidateAttribs();
369 0 : GetViewData().UpdateInputHandler();
370 : }
371 : }
372 0 : else if (nFormatId == SotClipboardFormatId::SBA_DATAEXCHANGE)
373 : {
374 : // import of database data into table
375 :
376 0 : const DataFlavorExVector& rVector = aDataHelper.GetDataFlavorExVector();
377 0 : if ( svx::ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector) )
378 : {
379 : // transport the whole ODataAccessDescriptor as slot parameter
380 0 : svx::ODataAccessDescriptor aDesc = svx::ODataAccessObjectTransferable::extractObjectDescriptor(aDataHelper);
381 0 : uno::Any aDescAny;
382 0 : uno::Sequence<beans::PropertyValue> aProperties = aDesc.createPropertyValueSequence();
383 0 : aDescAny <<= aProperties;
384 0 : SfxUsrAnyItem aDataDesc(SID_SBA_IMPORT, aDescAny);
385 :
386 0 : ScDocShell* pDocSh = GetViewData().GetDocShell();
387 0 : SCTAB nTab = GetViewData().GetTabNo();
388 :
389 0 : ClickCursor(nPosX, nPosY, false); // set cursor position
390 :
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
393 :
394 0 : ScDBData* pDBData = pDocSh->GetDBData( ScRange(nPosX,nPosY,nTab), SC_DB_OLD, SC_DBSEL_KEEP );
395 0 : OUString sTarget;
396 0 : if (pDBData)
397 0 : sTarget = pDBData->GetName();
398 : else
399 : {
400 0 : ScAddress aCellPos( nPosX,nPosY,nTab );
401 0 : sTarget = aCellPos.Format(SCA_ABS_3D, pDoc, pDoc->GetAddressConvention());
402 : }
403 0 : SfxStringItem aTarget(FN_PARAM_1, sTarget);
404 :
405 0 : bool bAreaIsNew = !pDBData;
406 0 : SfxBoolItem aAreaNew(FN_PARAM_2, bAreaIsNew);
407 :
408 : // asynchronous, to avoid doing the whole import in drop handler
409 0 : SfxDispatcher& rDisp = GetViewData().GetDispatcher();
410 : rDisp.Execute(SID_SBA_IMPORT, SfxCallMode::ASYNCHRON,
411 0 : &aDataDesc, &aTarget, &aAreaNew, nullptr );
412 :
413 0 : bRet = true;
414 : }
415 : }
416 0 : else if (nFormatId == SotClipboardFormatId::SBA_FIELDDATAEXCHANGE)
417 : {
418 : // insert database field control
419 :
420 0 : if ( svx::OColumnTransferable::canExtractColumnDescriptor( aDataHelper.GetDataFlavorExVector(), ColumnTransferFormatFlags::COLUMN_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE ) )
421 : {
422 0 : MakeDrawLayer();
423 0 : ScDrawView* pScDrawView = GetScDrawView();
424 0 : SdrObject* pObj = pScDrawView->CreateFieldControl( svx::OColumnTransferable::extractColumnDescriptor( aDataHelper ) );
425 0 : if (pObj)
426 : {
427 0 : Point aInsPos = aPos;
428 0 : Rectangle aRect(pObj->GetLogicRect());
429 0 : aInsPos.X() -= aRect.GetSize().Width() / 2;
430 0 : aInsPos.Y() -= aRect.GetSize().Height() / 2;
431 0 : if ( aInsPos.X() < 0 ) aInsPos.X() = 0;
432 0 : if ( aInsPos.Y() < 0 ) aInsPos.Y() = 0;
433 0 : aRect.SetPos(aInsPos);
434 0 : pObj->SetLogicRect(aRect);
435 :
436 0 : if ( pObj->ISA(SdrUnoObj) )
437 0 : pObj->NbcSetLayer(SC_LAYER_CONTROLS);
438 : else
439 0 : pObj->NbcSetLayer(SC_LAYER_FRONT);
440 0 : if (pObj->ISA(SdrObjGroup))
441 : {
442 0 : SdrObjListIter aIter( *pObj, IM_DEEPWITHGROUPS );
443 0 : SdrObject* pSubObj = aIter.Next();
444 0 : while (pSubObj)
445 : {
446 0 : if ( pSubObj->ISA(SdrUnoObj) )
447 0 : pSubObj->NbcSetLayer(SC_LAYER_CONTROLS);
448 : else
449 0 : pSubObj->NbcSetLayer(SC_LAYER_FRONT);
450 0 : pSubObj = aIter.Next();
451 0 : }
452 : }
453 :
454 0 : pScDrawView->InsertObjectSafe(pObj, *pScDrawView->GetSdrPageView());
455 :
456 0 : GetViewData().GetViewShell()->SetDrawShell( true );
457 0 : bRet = true;
458 : }
459 : }
460 : }
461 0 : else if (nFormatId == SotClipboardFormatId::BITMAP || nFormatId == SotClipboardFormatId::PNG)
462 : {
463 0 : BitmapEx aBmpEx;
464 0 : if( aDataHelper.GetBitmapEx( SotClipboardFormatId::BITMAP, aBmpEx ) )
465 0 : bRet = PasteBitmapEx( aPos, aBmpEx );
466 : }
467 0 : else if (nFormatId == SotClipboardFormatId::GDIMETAFILE)
468 : {
469 0 : GDIMetaFile aMtf;
470 0 : if( aDataHelper.GetGDIMetaFile( SotClipboardFormatId::GDIMETAFILE, aMtf ) )
471 0 : bRet = PasteMetaFile( aPos, aMtf );
472 : }
473 0 : else if (nFormatId == SotClipboardFormatId::SVXB)
474 : {
475 0 : tools::SvRef<SotStorageStream> xStm;
476 0 : if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::SVXB, xStm ) )
477 : {
478 0 : Graphic aGraphic;
479 0 : ReadGraphic( *xStm, aGraphic );
480 0 : bRet = PasteGraphic( aPos, aGraphic, EMPTY_OUSTRING, EMPTY_OUSTRING );
481 0 : }
482 : }
483 0 : else if ( nFormatId == SotClipboardFormatId::DRAWING )
484 : {
485 0 : tools::SvRef<SotStorageStream> xStm;
486 0 : if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::DRAWING, xStm ) )
487 : {
488 0 : MakeDrawLayer(); // before loading model, so 3D factory has been created
489 :
490 0 : SvtPathOptions aPathOpt;
491 0 : OUString aPath = aPathOpt.GetPalettePath();
492 :
493 0 : ScDocShellRef aDragShellRef( new ScDocShell );
494 0 : aDragShellRef->DoInitNew(NULL);
495 0 : boost::scoped_ptr<FmFormModel> pModel(new FmFormModel( aPath, NULL, aDragShellRef ));
496 :
497 0 : pModel->GetItemPool().FreezeIdRanges();
498 0 : xStm->Seek(0);
499 :
500 0 : com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm ) );
501 0 : SvxDrawingLayerImport( pModel.get(), xInputStream );
502 :
503 : // set everything to right layer:
504 0 : size_t nObjCount = 0;
505 0 : sal_uInt16 nPages = pModel->GetPageCount();
506 0 : for (sal_uInt16 i=0; i<nPages; i++)
507 : {
508 0 : SdrPage* pPage = pModel->GetPage(i);
509 0 : SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
510 0 : SdrObject* pObject = aIter.Next();
511 0 : while (pObject)
512 : {
513 0 : if ( pObject->ISA(SdrUnoObj) )
514 0 : pObject->NbcSetLayer(SC_LAYER_CONTROLS);
515 : else
516 0 : pObject->NbcSetLayer(SC_LAYER_FRONT);
517 0 : pObject = aIter.Next();
518 : }
519 :
520 0 : nObjCount += pPage->GetObjCount(); // count group object only once
521 0 : }
522 :
523 0 : PasteDraw(aPos, pModel.get(), (nObjCount > 1), "A", "B"); // grouped if more than 1 object
524 0 : pModel.reset();
525 0 : aDragShellRef->DoClose();
526 0 : bRet = true;
527 0 : }
528 : }
529 0 : else if ( (nFormatId == SotClipboardFormatId::BIFF_5) || (nFormatId == SotClipboardFormatId::BIFF_8) )
530 : {
531 : // do excel import into a clipboard document
532 : //TODO/MBA: testing
533 0 : uno::Reference <io::XInputStream> xStm = aDataHelper.GetInputStream(nFormatId, OUString());
534 0 : if (xStm.is())
535 : {
536 0 : ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
537 0 : SCTAB nSrcTab = 0; // Biff5 in clipboard: always sheet 0
538 0 : pInsDoc->ResetClip( pDoc, nSrcTab );
539 :
540 0 : SfxMedium aMed;
541 0 : aMed.GetItemSet()->Put( SfxUsrAnyItem( SID_INPUTSTREAM, uno::makeAny( xStm ) ) );
542 0 : FltError eErr = ScFormatFilter::Get().ScImportExcel( aMed, pInsDoc, EIF_AUTO );
543 0 : if ( eErr == eERR_OK )
544 : {
545 0 : ScRange aSource;
546 0 : const ScExtDocOptions* pExtOpt = pInsDoc->GetExtDocOptions();
547 0 : const ScExtTabSettings* pTabSett = pExtOpt ? pExtOpt->GetTabSettings( nSrcTab ) : 0;
548 0 : if( pTabSett && pTabSett->maUsedArea.IsValid() )
549 : {
550 0 : aSource = pTabSett->maUsedArea;
551 : // ensure correct sheet indexes
552 0 : aSource.aStart.SetTab( nSrcTab );
553 0 : 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
556 : }
557 : else
558 : {
559 : OSL_FAIL("no dimension"); //! possible?
560 : SCCOL nFirstCol, nLastCol;
561 : SCROW nFirstRow, nLastRow;
562 0 : if ( pInsDoc->GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
563 0 : pInsDoc->GetCellArea( nSrcTab, nLastCol, nLastRow );
564 : else
565 : {
566 0 : nFirstCol = nLastCol = 0;
567 0 : nFirstRow = nLastRow = 0;
568 : }
569 0 : aSource = ScRange( nFirstCol, nFirstRow, nSrcTab,
570 0 : nLastCol, nLastRow, nSrcTab );
571 : }
572 :
573 0 : if ( pLogicPos )
574 : {
575 : // position specified (Drag&Drop) - change selection
576 0 : MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, false, false );
577 0 : Unmark();
578 : }
579 :
580 0 : pInsDoc->SetClipArea( aSource );
581 : PasteFromClip( IDF_ALL, pInsDoc,
582 : PASTE_NOFUNC, false, false, false, INS_NONE, IDF_NONE,
583 0 : bAllowDialogs );
584 0 : delete pInsDoc;
585 :
586 0 : bRet = true;
587 0 : }
588 0 : }
589 : }
590 0 : else if ( nFormatId == SotClipboardFormatId::SIMPLE_FILE )
591 : {
592 0 : OUString aFile;
593 0 : if ( aDataHelper.GetString( nFormatId, aFile ) )
594 0 : bRet = PasteFile( aPos, aFile, bLink );
595 : }
596 0 : else if ( nFormatId == SotClipboardFormatId::FILE_LIST )
597 : {
598 0 : FileList aFileList;
599 0 : if ( aDataHelper.GetFileList( nFormatId, aFileList ) )
600 : {
601 0 : sal_uLong nCount = aFileList.Count();
602 0 : for( sal_uLong i = 0; i < nCount ; i++ )
603 : {
604 0 : OUString aFile = aFileList.GetFile( i );
605 :
606 0 : PasteFile( aPos, aFile, bLink );
607 :
608 0 : aPos.X() += 400;
609 0 : aPos.Y() += 400;
610 0 : }
611 0 : bRet = true;
612 0 : }
613 : }
614 0 : else if ( nFormatId == SotClipboardFormatId::SOLK ||
615 0 : nFormatId == SotClipboardFormatId::UNIFORMRESOURCELOCATOR ||
616 0 : nFormatId == SotClipboardFormatId::NETSCAPE_BOOKMARK ||
617 : nFormatId == SotClipboardFormatId::FILEGRPDESCRIPTOR )
618 : {
619 0 : bRet = PasteBookmark( nFormatId, rxTransferable, nPosX, nPosY );
620 : }
621 :
622 0 : pDoc->SetPastingDrawFromOtherDoc( false );
623 :
624 0 : return bRet;
625 : }
626 :
627 0 : bool ScViewFunc::PasteLink( const uno::Reference<datatransfer::XTransferable>& rxTransferable )
628 : {
629 0 : TransferableDataHelper aDataHelper( rxTransferable );
630 :
631 : // get link data from transferable before string data,
632 : // so the source knows it will be used for a link
633 :
634 0 : uno::Sequence<sal_Int8> aSequence = aDataHelper.GetSequence(SotClipboardFormatId::LINK, OUString());
635 0 : if (!aSequence.getLength())
636 : {
637 : OSL_FAIL("DDE Data not found.");
638 0 : return false;
639 : }
640 :
641 : // check size (only if string is available in transferable)
642 :
643 0 : sal_uInt16 nCols = 1;
644 0 : sal_uInt16 nRows = 1;
645 0 : if ( aDataHelper.HasFormat( SotClipboardFormatId::STRING ) )
646 : {
647 0 : OUString aDataStr;
648 0 : if ( aDataHelper.GetString( SotClipboardFormatId::STRING, aDataStr ) )
649 : {
650 : // get size from string the same way as in ScDdeLink::DataChanged
651 :
652 0 : aDataStr = convertLineEnd(aDataStr, LINEEND_LF);
653 0 : sal_Int32 nLen = aDataStr.getLength();
654 0 : if (nLen && aDataStr[nLen-1] == '\n')
655 0 : aDataStr = aDataStr.copy(0, nLen-1);
656 :
657 0 : if (!aDataStr.isEmpty())
658 : {
659 0 : nRows = comphelper::string::getTokenCount(aDataStr, '\n');
660 0 : OUString aLine = aDataStr.getToken( 0, '\n' );
661 0 : if (!aLine.isEmpty())
662 0 : nCols = comphelper::string::getTokenCount(aLine, '\t');
663 : }
664 0 : }
665 : }
666 :
667 : // create formula
668 :
669 0 : sal_Int32 nSeqLen = aSequence.getLength();
670 0 : const char* p = reinterpret_cast<const char*>(aSequence.getConstArray());
671 :
672 0 : rtl_TextEncoding eSysEnc = osl_getThreadTextEncoding();
673 :
674 : // char array delimited by \0.
675 : // app \0 topic \0 item \0 (extra \0) where the extra is optional.
676 0 : ::std::vector<OUString> aStrs;
677 0 : const char* pStart = p;
678 0 : sal_Int32 nStart = 0;
679 0 : for (sal_Int32 i = 0; i < nSeqLen; ++i, ++p)
680 : {
681 0 : if (*p == '\0')
682 : {
683 0 : sal_Int32 nLen = i - nStart;
684 0 : aStrs.push_back(OUString(pStart, nLen, eSysEnc));
685 0 : nStart = ++i;
686 0 : pStart = ++p;
687 : }
688 : }
689 :
690 0 : if (aStrs.size() < 3)
691 0 : return false;
692 :
693 0 : const OUString* pApp = &aStrs[0];
694 0 : const OUString* pTopic = &aStrs[1];
695 0 : const OUString* pItem = &aStrs[2];
696 0 : const OUString* pExtra = NULL;
697 0 : if (aStrs.size() > 3)
698 0 : pExtra = &aStrs[3];
699 :
700 0 : if ( pExtra && *pExtra == "calc:extref" )
701 : {
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 0 : + OUString(ScGlobal::GetAbsDocName(*pTopic, GetViewData().GetDocument()->GetDocumentShell()))
707 0 : + "'#" + *pItem
708 0 : , ::formula::FormulaGrammar::GRAM_NATIVE);
709 0 : return true;
710 : }
711 : else
712 : {
713 : // DDE in all other cases.
714 :
715 : // TODO: we could define ocQuote for "
716 0 : EnterMatrix("=" + OUString(ScCompiler::GetNativeSymbol(ocDde))
717 0 : + ScCompiler::GetNativeSymbol(ocOpen)
718 0 : + "\"" + *pApp + "\""
719 0 : + ScCompiler::GetNativeSymbol(ocSep)
720 0 : + "\"" + *pTopic + "\""
721 0 : + ScCompiler::GetNativeSymbol(ocSep)
722 0 : + "\"" + *pItem + "\""
723 0 : + ScCompiler::GetNativeSymbol(ocClose)
724 0 : , ::formula::FormulaGrammar::GRAM_NATIVE);
725 : }
726 :
727 : // mark range
728 :
729 0 : SCTAB nTab = GetViewData().GetTabNo();
730 0 : SCCOL nCurX = GetViewData().GetCurX();
731 0 : SCROW nCurY = GetViewData().GetCurY();
732 0 : HideAllCursors();
733 0 : DoneBlockMode();
734 0 : InitBlockMode( nCurX, nCurY, nTab );
735 0 : MarkCursor( nCurX+static_cast<SCCOL>(nCols)-1, nCurY+static_cast<SCROW>(nRows)-1, nTab );
736 0 : ShowAllCursors();
737 0 : CursorPosChanged();
738 :
739 0 : return true;
740 156 : }
741 :
742 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|