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