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