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 "scitems.hxx"
21 : #include <editeng/eeitem.hxx>
22 : #include <editeng/justifyitem.hxx>
23 :
24 :
25 : #include <com/sun/star/uno/Sequence.hxx>
26 : #include <com/sun/star/embed/XTransactedObject.hpp>
27 :
28 : #include <unotools/tempfile.hxx>
29 : #include <unotools/ucbstreamhelper.hxx>
30 : #include <comphelper/storagehelper.hxx>
31 : #include <comphelper/servicehelper.hxx>
32 : #include <sot/storage.hxx>
33 : #include <vcl/svapp.hxx>
34 : #include <vcl/virdev.hxx>
35 : #include <osl/mutex.hxx>
36 : #include <sfx2/app.hxx>
37 : #include <sfx2/docfile.hxx>
38 :
39 : #include "transobj.hxx"
40 : #include "document.hxx"
41 : #include "viewopti.hxx"
42 : #include "editutil.hxx"
43 : #include "impex.hxx"
44 : #include "cell.hxx"
45 : #include "printfun.hxx"
46 : #include "docfunc.hxx"
47 : #include "scmod.hxx"
48 : #include "dragdata.hxx"
49 : #include "clipdata.hxx"
50 : #include "clipparam.hxx"
51 :
52 : // for InitDocShell
53 : #include <editeng/paperinf.hxx>
54 : #include <editeng/sizeitem.hxx>
55 : #include <svx/algitem.hxx>
56 : #include <svl/intitem.hxx>
57 : #include <svl/zforlist.hxx>
58 : #include "docsh.hxx"
59 : #include "markdata.hxx"
60 : #include "stlpool.hxx"
61 : #include "viewdata.hxx"
62 : #include "dociter.hxx"
63 : #include "cellsuno.hxx"
64 :
65 : using namespace com::sun::star;
66 :
67 : // -----------------------------------------------------------------------
68 :
69 : #define SCTRANS_TYPE_IMPEX 1
70 : #define SCTRANS_TYPE_EDIT_RTF 2
71 : #define SCTRANS_TYPE_EDIT_BIN 3
72 : #define SCTRANS_TYPE_EMBOBJ 4
73 :
74 : // -----------------------------------------------------------------------
75 :
76 0 : void ScTransferObj::GetAreaSize( ScDocument* pDoc, SCTAB nTab1, SCTAB nTab2, SCROW& nRow, SCCOL& nCol )
77 : {
78 0 : SCCOL nMaxCol = 0;
79 0 : SCROW nMaxRow = 0;
80 0 : for( SCTAB nTab = nTab1; nTab <= nTab2; nTab++ )
81 : {
82 0 : SCCOL nLastCol = 0;
83 0 : SCROW nLastRow = 0;
84 : // GetPrintArea instead of GetCellArea - include drawing objects
85 0 : if( pDoc->GetPrintArea( nTab, nLastCol, nLastRow ) )
86 : {
87 0 : if( nLastCol > nMaxCol )
88 0 : nMaxCol = nLastCol;
89 0 : if( nLastRow > nMaxRow )
90 0 : nMaxRow = nLastRow;
91 : }
92 : }
93 0 : nRow = nMaxRow;
94 0 : nCol = nMaxCol;
95 0 : }
96 :
97 0 : void ScTransferObj::PaintToDev( OutputDevice* pDev, ScDocument* pDoc, double nPrintFactor,
98 : const ScRange& rBlock, sal_Bool bMetaFile )
99 : {
100 0 : if (!pDoc)
101 0 : return;
102 :
103 0 : Point aPoint;
104 0 : Rectangle aBound( aPoint, pDev->GetOutputSize() ); //! use size from clip area?
105 :
106 0 : ScViewData aViewData(NULL,NULL);
107 0 : aViewData.InitData( pDoc );
108 :
109 0 : aViewData.SetTabNo( rBlock.aEnd.Tab() );
110 0 : aViewData.SetScreen( rBlock.aStart.Col(), rBlock.aStart.Row(),
111 0 : rBlock.aEnd.Col(), rBlock.aEnd.Row() );
112 :
113 0 : ScPrintFunc::DrawToDev( pDoc, pDev, nPrintFactor, aBound, &aViewData, bMetaFile );
114 : }
115 :
116 : // -----------------------------------------------------------------------
117 :
118 0 : ScTransferObj::ScTransferObj( ScDocument* pClipDoc, const TransferableObjectDescriptor& rDesc ) :
119 : pDoc( pClipDoc ),
120 : aObjDesc( rDesc ),
121 : nDragHandleX( 0 ),
122 : nDragHandleY( 0 ),
123 : nDragSourceFlags( 0 ),
124 : bDragWasInternal( false ),
125 : bUsedForLink( false ),
126 0 : bUseInApi( false )
127 : {
128 : OSL_ENSURE(pDoc->IsClipboard(), "wrong document");
129 :
130 : //
131 : // get aBlock from clipboard doc
132 : //
133 :
134 : SCCOL nCol1;
135 : SCROW nRow1;
136 : SCCOL nCol2;
137 : SCROW nRow2;
138 0 : pDoc->GetClipStart( nCol1, nRow1 );
139 0 : pDoc->GetClipArea( nCol2, nRow2, true ); // real source area - include filtered rows
140 0 : nCol2 = sal::static_int_cast<SCCOL>( nCol2 + nCol1 );
141 0 : nRow2 = sal::static_int_cast<SCROW>( nRow2 + nRow1 );
142 :
143 : SCCOL nDummy;
144 0 : pDoc->GetClipArea( nDummy, nNonFiltered, false );
145 0 : bHasFiltered = (nNonFiltered < (nRow2 - nRow1));
146 0 : ++nNonFiltered; // to get count instead of diff
147 :
148 0 : SCTAB nTab1=0;
149 0 : SCTAB nTab2=0;
150 0 : bool bFirst = true;
151 0 : for (SCTAB i=0; i< pDoc->GetTableCount(); i++)
152 0 : if (pDoc->HasTable(i))
153 : {
154 0 : if (bFirst)
155 0 : nTab1 = i;
156 0 : nTab2 = i;
157 0 : bFirst = false;
158 : }
159 : OSL_ENSURE(!bFirst, "no sheet selected");
160 :
161 : // only limit to used cells if whole sheet was marked
162 : // (so empty cell areas can be copied)
163 0 : if ( nCol2>=MAXCOL && nRow2>=MAXROW )
164 : {
165 : SCROW nMaxRow;
166 : SCCOL nMaxCol;
167 0 : GetAreaSize( pDoc, nTab1, nTab2, nMaxRow, nMaxCol );
168 0 : if( nMaxRow < nRow2 )
169 0 : nRow2 = nMaxRow;
170 0 : if( nMaxCol < nCol2 )
171 0 : nCol2 = nMaxCol;
172 : }
173 :
174 0 : aBlock = ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
175 0 : nVisibleTab = nTab1; // valid table as default
176 :
177 0 : Rectangle aMMRect = pDoc->GetMMRect( nCol1,nRow1, nCol2,nRow2, nTab1 );
178 0 : aObjDesc.maSize = aMMRect.GetSize();
179 0 : PrepareOLE( aObjDesc );
180 0 : }
181 :
182 0 : ScTransferObj::~ScTransferObj()
183 : {
184 0 : SolarMutexGuard aSolarGuard;
185 :
186 0 : ScModule* pScMod = SC_MOD();
187 0 : if ( pScMod->GetClipData().pCellClipboard == this )
188 : {
189 : OSL_FAIL("ScTransferObj wasn't released");
190 0 : pScMod->SetClipObject( NULL, NULL );
191 : }
192 0 : if ( pScMod->GetDragData().pCellTransfer == this )
193 : {
194 : OSL_FAIL("ScTransferObj wasn't released");
195 0 : pScMod->ResetDragObject();
196 : }
197 :
198 0 : delete pDoc; // ScTransferObj is owner of clipboard document
199 :
200 0 : aDocShellRef.Clear(); // before releasing the mutex
201 :
202 0 : aDrawPersistRef.Clear(); // after the model
203 :
204 0 : }
205 :
206 30 : ScTransferObj* ScTransferObj::GetOwnClipboard( Window* pUIWin )
207 : {
208 30 : ScTransferObj* pObj = SC_MOD()->GetClipData().pCellClipboard;
209 30 : if ( pObj && pUIWin )
210 : {
211 : // check formats to see if pObj is really in the system clipboard
212 :
213 : // pUIWin is NULL when called from core (IsClipboardSource),
214 : // in that case don't access the system clipboard, because the call
215 : // may be from other clipboard operations (like flushing, #86059#)
216 :
217 0 : TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pUIWin ) );
218 0 : if ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_DIF ) )
219 : {
220 : // OSL_FAIL("ScTransferObj wasn't released");
221 0 : pObj = NULL;
222 0 : }
223 : }
224 30 : return pObj;
225 : }
226 :
227 0 : void ScTransferObj::AddSupportedFormats()
228 : {
229 0 : AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
230 0 : AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
231 0 : AddFormat( SOT_FORMAT_GDIMETAFILE );
232 0 : AddFormat( SOT_FORMAT_BITMAP );
233 :
234 : // ScImportExport formats
235 0 : AddFormat( SOT_FORMATSTR_ID_HTML );
236 0 : AddFormat( SOT_FORMATSTR_ID_SYLK );
237 0 : AddFormat( SOT_FORMATSTR_ID_LINK );
238 0 : AddFormat( SOT_FORMATSTR_ID_DIF );
239 0 : AddFormat( SOT_FORMAT_STRING );
240 :
241 0 : AddFormat( SOT_FORMAT_RTF );
242 0 : if ( aBlock.aStart == aBlock.aEnd )
243 0 : AddFormat( SOT_FORMATSTR_ID_EDITENGINE );
244 0 : }
245 :
246 0 : sal_Bool ScTransferObj::GetData( const datatransfer::DataFlavor& rFlavor )
247 : {
248 0 : sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
249 0 : bool bOK = false;
250 :
251 0 : if( HasFormat( nFormat ) )
252 : {
253 0 : if ( nFormat == SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR || nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR )
254 : {
255 0 : bOK = SetTransferableObjectDescriptor( aObjDesc, rFlavor );
256 : }
257 0 : else if ( ( nFormat == SOT_FORMAT_RTF || nFormat == SOT_FORMATSTR_ID_EDITENGINE ) &&
258 0 : aBlock.aStart == aBlock.aEnd )
259 : {
260 : // RTF from a single cell is handled by EditEngine
261 :
262 0 : SCCOL nCol = aBlock.aStart.Col();
263 0 : SCROW nRow = aBlock.aStart.Row();
264 0 : SCTAB nTab = aBlock.aStart.Tab();
265 :
266 0 : const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
267 0 : ScTabEditEngine aEngine( *pPattern, pDoc->GetEditPool() );
268 0 : ScBaseCell* pCell = NULL;
269 0 : pDoc->GetCell( nCol, nRow, nTab, pCell );
270 0 : if (pCell)
271 : {
272 0 : if (pCell->GetCellType() == CELLTYPE_EDIT)
273 : {
274 : const EditTextObject* pObj;
275 0 : ((ScEditCell*)pCell)->GetData(pObj);
276 0 : aEngine.SetText( *pObj );
277 : }
278 : else
279 : {
280 0 : String aText;
281 0 : pDoc->GetString( nCol, nRow, nTab, aText );
282 0 : aEngine.SetText(aText);
283 : }
284 : }
285 :
286 : bOK = SetObject( &aEngine,
287 : (nFormat == FORMAT_RTF) ? SCTRANS_TYPE_EDIT_RTF : SCTRANS_TYPE_EDIT_BIN,
288 0 : rFlavor );
289 : }
290 0 : else if ( ScImportExport::IsFormatSupported( nFormat ) || nFormat == SOT_FORMAT_RTF )
291 : {
292 : // if this transfer object was used to create a DDE link, filtered rows
293 : // have to be included for subsequent calls (to be consistent with link data)
294 0 : if ( nFormat == SOT_FORMATSTR_ID_LINK )
295 0 : bUsedForLink = true;
296 :
297 0 : bool bIncludeFiltered = pDoc->IsCutMode() || bUsedForLink;
298 :
299 0 : ScRange aReducedBlock = aBlock;
300 0 : if ( nFormat == SOT_FORMATSTR_ID_HTML && (aBlock.aEnd.Col() == MAXCOL || aBlock.aEnd.Row() == MAXROW) && aBlock.aStart.Tab() == aBlock.aEnd.Tab() )
301 : {
302 0 : bool bShrunk = false;
303 : //shrink the area to allow pasting to external applications
304 0 : SCCOL aStartCol = aReducedBlock.aStart.Col();
305 0 : SCROW aStartRow = aReducedBlock.aStart.Row();
306 0 : SCCOL aEndCol = aReducedBlock.aEnd.Col();
307 0 : SCROW aEndRow = aReducedBlock.aEnd.Row();
308 0 : pDoc->ShrinkToUsedDataArea( bShrunk, aReducedBlock.aStart.Tab(), aStartCol, aStartRow, aEndCol, aEndRow, false);
309 0 : aReducedBlock = ScRange(aStartCol, aStartRow, aReducedBlock.aStart.Tab(), aEndCol, aEndRow, aReducedBlock.aEnd.Tab());
310 : }
311 :
312 0 : ScImportExport aObj( pDoc, aReducedBlock );
313 0 : ScExportTextOptions aTextOptions(ScExportTextOptions::None, 0, true);
314 0 : if ( bUsedForLink )
315 : {
316 : // For a DDE link, convert line breaks and separators to space.
317 0 : aTextOptions.meNewlineConversion = ScExportTextOptions::ToSpace;
318 0 : aTextOptions.mcSeparatorConvertTo = ' ';
319 0 : aTextOptions.mbAddQuotes = false;
320 : }
321 0 : aObj.SetExportTextOptions(aTextOptions);
322 0 : aObj.SetFormulas( pDoc->GetViewOptions().GetOption( VOPT_FORMULAS ) );
323 0 : aObj.SetIncludeFiltered( bIncludeFiltered );
324 :
325 : // DataType depends on format type:
326 :
327 0 : if ( rFlavor.DataType.equals( ::getCppuType( (const ::rtl::OUString*) 0 ) ) )
328 : {
329 0 : rtl::OUString aString;
330 0 : if ( aObj.ExportString( aString, nFormat ) )
331 0 : bOK = SetString( aString, rFlavor );
332 : }
333 0 : else if ( rFlavor.DataType.equals( ::getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) ) )
334 : {
335 : // SetObject converts a stream into a Int8-Sequence
336 0 : bOK = SetObject( &aObj, SCTRANS_TYPE_IMPEX, rFlavor );
337 : }
338 : else
339 : {
340 : OSL_FAIL("unknown DataType");
341 0 : }
342 : }
343 0 : else if ( nFormat == SOT_FORMAT_BITMAP )
344 : {
345 0 : Rectangle aMMRect = pDoc->GetMMRect( aBlock.aStart.Col(), aBlock.aStart.Row(),
346 0 : aBlock.aEnd.Col(), aBlock.aEnd.Row(),
347 0 : aBlock.aStart.Tab() );
348 0 : VirtualDevice aVirtDev;
349 0 : aVirtDev.SetOutputSizePixel( aVirtDev.LogicToPixel( aMMRect.GetSize(), MAP_100TH_MM ) );
350 :
351 0 : PaintToDev( &aVirtDev, pDoc, 1.0, aBlock, false );
352 :
353 0 : aVirtDev.SetMapMode( MapMode( MAP_PIXEL ) );
354 0 : Bitmap aBmp = aVirtDev.GetBitmap( Point(), aVirtDev.GetOutputSize() );
355 0 : bOK = SetBitmap( aBmp, rFlavor );
356 : }
357 0 : else if ( nFormat == SOT_FORMAT_GDIMETAFILE )
358 : {
359 0 : InitDocShell();
360 0 : SfxObjectShell* pEmbObj = aDocShellRef;
361 :
362 : // like SvEmbeddedTransfer::GetData:
363 :
364 0 : GDIMetaFile aMtf;
365 0 : VirtualDevice aVDev;
366 0 : MapMode aMapMode( pEmbObj->GetMapUnit() );
367 0 : Rectangle aVisArea( pEmbObj->GetVisArea( ASPECT_CONTENT ) );
368 :
369 0 : aVDev.EnableOutput( false );
370 0 : aVDev.SetMapMode( aMapMode );
371 0 : aMtf.SetPrefSize( aVisArea.GetSize() );
372 0 : aMtf.SetPrefMapMode( aMapMode );
373 0 : aMtf.Record( &aVDev );
374 :
375 0 : pEmbObj->DoDraw( &aVDev, Point(), aVisArea.GetSize(), JobSetup(), ASPECT_CONTENT );
376 :
377 0 : aMtf.Stop();
378 0 : aMtf.WindStart();
379 :
380 0 : bOK = SetGDIMetaFile( aMtf, rFlavor );
381 : }
382 0 : else if ( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
383 : {
384 : //TODO/LATER: differentiate between formats?!
385 0 : InitDocShell(); // set aDocShellRef
386 :
387 0 : SfxObjectShell* pEmbObj = aDocShellRef;
388 0 : bOK = SetObject( pEmbObj, SCTRANS_TYPE_EMBOBJ, rFlavor );
389 : }
390 : }
391 0 : return bOK;
392 : }
393 :
394 0 : sal_Bool ScTransferObj::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId,
395 : const datatransfer::DataFlavor& rFlavor )
396 : {
397 : // called from SetObject, put data into stream
398 :
399 0 : bool bRet = false;
400 0 : switch (nUserObjectId)
401 : {
402 : case SCTRANS_TYPE_IMPEX:
403 : {
404 0 : ScImportExport* pImpEx = (ScImportExport*)pUserObject;
405 :
406 0 : sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
407 : // mba: no BaseURL for data exchange
408 0 : if ( pImpEx->ExportStream( *rxOStm, String(), nFormat ) )
409 0 : bRet = ( rxOStm->GetError() == ERRCODE_NONE );
410 : }
411 0 : break;
412 :
413 : case SCTRANS_TYPE_EDIT_RTF:
414 : case SCTRANS_TYPE_EDIT_BIN:
415 : {
416 0 : ScTabEditEngine* pEngine = (ScTabEditEngine*)pUserObject;
417 0 : if ( nUserObjectId == SCTRANS_TYPE_EDIT_RTF )
418 : {
419 0 : pEngine->Write( *rxOStm, EE_FORMAT_RTF );
420 0 : bRet = ( rxOStm->GetError() == ERRCODE_NONE );
421 : }
422 : else
423 : {
424 : // can't use Write for EditEngine format because that would
425 : // write old format without support for unicode characters.
426 : // Get the data from the EditEngine's transferable instead.
427 :
428 0 : sal_uInt16 nParCnt = pEngine->GetParagraphCount();
429 0 : if ( nParCnt == 0 )
430 0 : nParCnt = 1;
431 0 : ESelection aSel( 0, 0, nParCnt-1, pEngine->GetTextLen(nParCnt-1) );
432 :
433 0 : uno::Reference<datatransfer::XTransferable> xEditTrans = pEngine->CreateTransferable( aSel );
434 0 : TransferableDataHelper aEditHelper( xEditTrans );
435 :
436 0 : bRet = aEditHelper.GetSotStorageStream( rFlavor, rxOStm );
437 : }
438 : }
439 0 : break;
440 :
441 : case SCTRANS_TYPE_EMBOBJ:
442 : {
443 : // TODO/MBA: testing
444 0 : SfxObjectShell* pEmbObj = (SfxObjectShell*) pUserObject;
445 0 : ::utl::TempFile aTempFile;
446 0 : aTempFile.EnableKillingFile();
447 : uno::Reference< embed::XStorage > xWorkStore =
448 0 : ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
449 :
450 : // write document storage
451 0 : pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false );
452 :
453 : // mba: no relative ULRs for clipboard!
454 0 : SfxMedium aMedium( xWorkStore, String() );
455 0 : bRet = pEmbObj->DoSaveObjectAs( aMedium, false );
456 0 : pEmbObj->DoSaveCompleted();
457 :
458 0 : uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
459 0 : if ( xTransact.is() )
460 0 : xTransact->commit();
461 :
462 0 : SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), STREAM_READ );
463 0 : if( pSrcStm )
464 : {
465 0 : rxOStm->SetBufferSize( 0xff00 );
466 0 : *rxOStm << *pSrcStm;
467 0 : delete pSrcStm;
468 : }
469 :
470 0 : bRet = true;
471 :
472 0 : xWorkStore->dispose();
473 0 : xWorkStore = uno::Reference < embed::XStorage >();
474 0 : rxOStm->Commit();
475 : }
476 0 : break;
477 :
478 : default:
479 : OSL_FAIL("unknown object id");
480 : }
481 0 : return bRet;
482 : }
483 :
484 0 : void ScTransferObj::ObjectReleased()
485 : {
486 0 : ScModule* pScMod = SC_MOD();
487 0 : if ( pScMod->GetClipData().pCellClipboard == this )
488 0 : pScMod->SetClipObject( NULL, NULL );
489 :
490 0 : TransferableHelper::ObjectReleased();
491 0 : }
492 :
493 0 : void ScTransferObj::DragFinished( sal_Int8 nDropAction )
494 : {
495 0 : if ( nDropAction == DND_ACTION_MOVE && !bDragWasInternal && !(nDragSourceFlags & SC_DROP_NAVIGATOR) )
496 : {
497 : // move: delete source data
498 0 : ScDocShell* pSourceSh = GetSourceDocShell();
499 0 : if (pSourceSh)
500 : {
501 0 : ScMarkData aMarkData = GetSourceMarkData();
502 : // external drag&drop doesn't copy objects, so they also aren't deleted:
503 : // bApi=TRUE, don't show error messages from drag&drop
504 0 : pSourceSh->GetDocFunc().DeleteContents( aMarkData, IDF_ALL & ~IDF_OBJECTS, true, true );
505 : }
506 : }
507 :
508 0 : ScModule* pScMod = SC_MOD();
509 0 : if ( pScMod->GetDragData().pCellTransfer == this )
510 0 : pScMod->ResetDragObject();
511 :
512 0 : xDragSourceRanges = NULL; // don't keep source after dropping
513 :
514 0 : TransferableHelper::DragFinished( nDropAction );
515 0 : }
516 :
517 0 : void ScTransferObj::SetDragHandlePos( SCCOL nX, SCROW nY )
518 : {
519 0 : nDragHandleX = nX;
520 0 : nDragHandleY = nY;
521 0 : }
522 :
523 0 : void ScTransferObj::SetVisibleTab( SCTAB nNew )
524 : {
525 0 : nVisibleTab = nNew;
526 0 : }
527 :
528 0 : void ScTransferObj::SetDrawPersist( const SfxObjectShellRef& rRef )
529 : {
530 0 : aDrawPersistRef = rRef;
531 0 : }
532 :
533 0 : void ScTransferObj::SetDragSource( ScDocShell* pSourceShell, const ScMarkData& rMark )
534 : {
535 0 : ScRangeList aRanges;
536 0 : rMark.FillRangeListWithMarks( &aRanges, false );
537 0 : xDragSourceRanges = new ScCellRangesObj( pSourceShell, aRanges );
538 0 : }
539 :
540 0 : void ScTransferObj::SetDragSourceFlags( sal_uInt16 nFlags )
541 : {
542 0 : nDragSourceFlags = nFlags;
543 0 : }
544 :
545 0 : void ScTransferObj::SetDragWasInternal()
546 : {
547 0 : bDragWasInternal = true;
548 0 : }
549 :
550 0 : void ScTransferObj::SetUseInApi( bool bSet )
551 : {
552 0 : bUseInApi = bSet;
553 0 : }
554 :
555 0 : ScDocument* ScTransferObj::GetSourceDocument()
556 : {
557 0 : ScDocShell* pSourceDocSh = GetSourceDocShell();
558 0 : if (pSourceDocSh)
559 0 : return pSourceDocSh->GetDocument();
560 0 : return NULL;
561 : }
562 :
563 0 : ScDocShell* ScTransferObj::GetSourceDocShell()
564 : {
565 0 : ScCellRangesBase* pRangesObj = ScCellRangesBase::getImplementation( xDragSourceRanges );
566 0 : if (pRangesObj)
567 0 : return pRangesObj->GetDocShell();
568 :
569 0 : return NULL; // none set
570 : }
571 :
572 0 : ScMarkData ScTransferObj::GetSourceMarkData()
573 : {
574 0 : ScMarkData aMarkData;
575 0 : ScCellRangesBase* pRangesObj = ScCellRangesBase::getImplementation( xDragSourceRanges );
576 0 : if (pRangesObj)
577 : {
578 0 : const ScRangeList& rRanges = pRangesObj->GetRangeList();
579 0 : aMarkData.MarkFromRangeList( rRanges, false );
580 : }
581 0 : return aMarkData;
582 : }
583 :
584 : //
585 : // initialize aDocShellRef with a live document from the ClipDoc
586 : //
587 :
588 0 : void ScTransferObj::InitDocShell()
589 : {
590 0 : if ( !aDocShellRef.Is() )
591 : {
592 0 : ScDocShell* pDocSh = new ScDocShell;
593 0 : aDocShellRef = pDocSh; // ref must be there before InitNew
594 :
595 0 : pDocSh->DoInitNew(NULL);
596 :
597 0 : ScDocument* pDestDoc = pDocSh->GetDocument();
598 0 : ScMarkData aDestMark;
599 0 : aDestMark.SelectTable( 0, true );
600 :
601 0 : pDestDoc->SetDocOptions( pDoc->GetDocOptions() ); // #i42666#
602 :
603 0 : rtl::OUString aTabName;
604 0 : pDoc->GetName( aBlock.aStart.Tab(), aTabName );
605 0 : pDestDoc->RenameTab( 0, aTabName, false ); // no UpdateRef (empty)
606 :
607 0 : pDestDoc->CopyStdStylesFrom( pDoc );
608 :
609 0 : SCCOL nStartX = aBlock.aStart.Col();
610 0 : SCROW nStartY = aBlock.aStart.Row();
611 0 : SCCOL nEndX = aBlock.aEnd.Col();
612 0 : SCROW nEndY = aBlock.aEnd.Row();
613 :
614 : // widths / heights
615 : // (must be copied before CopyFromClip, for drawing objects)
616 :
617 : SCCOL nCol;
618 0 : SCTAB nSrcTab = aBlock.aStart.Tab();
619 0 : pDestDoc->SetLayoutRTL(0, pDoc->IsLayoutRTL(nSrcTab));
620 0 : for (nCol=nStartX; nCol<=nEndX; nCol++)
621 0 : if ( pDoc->ColHidden(nCol, nSrcTab) )
622 0 : pDestDoc->ShowCol( nCol, 0, false );
623 : else
624 0 : pDestDoc->SetColWidth( nCol, 0, pDoc->GetColWidth( nCol, nSrcTab ) );
625 :
626 0 : for (SCROW nRow = nStartY; nRow <= nEndY; ++nRow)
627 : {
628 0 : if ( pDoc->RowHidden(nRow, nSrcTab) )
629 0 : pDestDoc->ShowRow( nRow, 0, false );
630 : else
631 : {
632 0 : pDestDoc->SetRowHeight( nRow, 0, pDoc->GetOriginalHeight( nRow, nSrcTab ) );
633 :
634 : // if height was set manually, that flag has to be copied, too
635 0 : bool bManual = pDoc->IsManualRowHeight(nRow, nSrcTab);
636 0 : pDestDoc->SetManualHeight(nRow, nRow, 0, bManual);
637 : }
638 : }
639 :
640 0 : if ( pDoc->GetDrawLayer() )
641 0 : pDocSh->MakeDrawLayer();
642 :
643 : // cell range is copied to the original position, but on the first sheet
644 : // -> bCutMode must be set
645 : // pDoc is always a Clipboard-document
646 :
647 0 : ScRange aDestRange( nStartX,nStartY,0, nEndX,nEndY,0 );
648 0 : bool bWasCut = pDoc->IsCutMode();
649 0 : if (!bWasCut)
650 0 : pDoc->SetClipArea( aDestRange, true ); // Cut
651 0 : pDestDoc->CopyFromClip( aDestRange, aDestMark, IDF_ALL, NULL, pDoc, false );
652 0 : pDoc->SetClipArea( aDestRange, bWasCut );
653 :
654 0 : StripRefs( pDoc, nStartX,nStartY, nEndX,nEndY, pDestDoc, 0,0 );
655 :
656 0 : ScRange aMergeRange = aDestRange;
657 0 : pDestDoc->ExtendMerge( aMergeRange, true );
658 :
659 0 : pDoc->CopyDdeLinks( pDestDoc ); // copy values of DDE Links
660 :
661 : // page format (grid etc) and page size (maximum size for ole object)
662 :
663 0 : Size aPaperSize = SvxPaperInfo::GetPaperSize( PAPER_A4 ); // Twips
664 0 : ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
665 0 : String aStyleName = pDoc->GetPageStyle( aBlock.aStart.Tab() );
666 0 : SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
667 0 : if (pStyleSheet)
668 : {
669 0 : const SfxItemSet& rSourceSet = pStyleSheet->GetItemSet();
670 0 : aPaperSize = ((const SvxSizeItem&) rSourceSet.Get(ATTR_PAGE_SIZE)).GetSize();
671 :
672 : // CopyStyleFrom kopiert SetItems mit richtigem Pool
673 0 : ScStyleSheetPool* pDestPool = pDestDoc->GetStyleSheetPool();
674 0 : pDestPool->CopyStyleFrom( pStylePool, aStyleName, SFX_STYLE_FAMILY_PAGE );
675 : }
676 :
677 0 : ScViewData aViewData( pDocSh, NULL );
678 0 : aViewData.SetScreen( nStartX,nStartY, nEndX,nEndY );
679 0 : aViewData.SetCurX( nStartX );
680 0 : aViewData.SetCurY( nStartY );
681 :
682 0 : pDestDoc->SetViewOptions( pDoc->GetViewOptions() );
683 :
684 : // Size
685 : //! get while copying sizes
686 :
687 0 : long nPosX = 0;
688 0 : long nPosY = 0;
689 :
690 0 : for (nCol=0; nCol<nStartX; nCol++)
691 0 : nPosX += pDestDoc->GetColWidth( nCol, 0 );
692 0 : nPosY += pDestDoc->GetRowHeight( 0, nStartY-1, 0 );
693 0 : nPosX = (long) ( nPosX * HMM_PER_TWIPS );
694 0 : nPosY = (long) ( nPosY * HMM_PER_TWIPS );
695 :
696 :
697 0 : aPaperSize.Width() *= 2; // limit OLE object to double of page size
698 0 : aPaperSize.Height() *= 2;
699 :
700 0 : long nSizeX = 0;
701 0 : long nSizeY = 0;
702 0 : for (nCol=nStartX; nCol<=nEndX; nCol++)
703 : {
704 0 : long nAdd = pDestDoc->GetColWidth( nCol, 0 );
705 0 : if ( nSizeX+nAdd > aPaperSize.Width() && nSizeX ) // above limit?
706 0 : break;
707 0 : nSizeX += nAdd;
708 : }
709 0 : for (SCROW nRow=nStartY; nRow<=nEndY; nRow++)
710 : {
711 0 : long nAdd = pDestDoc->GetRowHeight( nRow, 0 );
712 0 : if ( nSizeY+nAdd > aPaperSize.Height() && nSizeY ) // above limit?
713 0 : break;
714 0 : nSizeY += nAdd;
715 : }
716 0 : nSizeX = (long) ( nSizeX * HMM_PER_TWIPS );
717 0 : nSizeY = (long) ( nSizeY * HMM_PER_TWIPS );
718 :
719 : // pDocSh->SetVisAreaSize( Size(nSizeX,nSizeY) );
720 :
721 0 : Rectangle aNewArea( Point(nPosX,nPosY), Size(nSizeX,nSizeY) );
722 : //TODO/LATER: why twice?!
723 : //pDocSh->SvInPlaceObject::SetVisArea( aNewArea );
724 0 : pDocSh->SetVisArea( aNewArea );
725 :
726 0 : pDocSh->UpdateOle(&aViewData, true);
727 :
728 : //! SetDocumentModified?
729 0 : if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
730 0 : pDestDoc->UpdateChartListenerCollection();
731 : }
732 0 : }
733 :
734 0 : SfxObjectShell* ScTransferObj::SetDrawClipDoc( sal_Bool bAnyOle )
735 : {
736 : // update ScGlobal::pDrawClipDocShellRef
737 :
738 0 : delete ScGlobal::pDrawClipDocShellRef;
739 0 : if (bAnyOle)
740 : {
741 : ScGlobal::pDrawClipDocShellRef =
742 0 : new ScDocShellRef(new ScDocShell(SFX_CREATE_MODE_INTERNAL)); // there must be a ref
743 0 : (*ScGlobal::pDrawClipDocShellRef)->DoInitNew(NULL);
744 0 : return *ScGlobal::pDrawClipDocShellRef;
745 : }
746 : else
747 : {
748 0 : ScGlobal::pDrawClipDocShellRef = NULL;
749 0 : return NULL;
750 : }
751 : }
752 :
753 0 : void ScTransferObj::StripRefs( ScDocument* pDoc,
754 : SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
755 : ScDocument* pDestDoc, SCCOL nSubX, SCROW nSubY )
756 : {
757 0 : if (!pDestDoc)
758 : {
759 0 : pDestDoc = pDoc;
760 : OSL_ENSURE(nSubX==0&&nSubY==0, "can't move within the document");
761 : }
762 :
763 : // In a clipboard doc the data don't have to be on the first sheet
764 :
765 0 : SCTAB nSrcTab = 0;
766 0 : while (nSrcTab<pDoc->GetTableCount() && !pDoc->HasTable(nSrcTab))
767 0 : ++nSrcTab;
768 0 : SCTAB nDestTab = 0;
769 0 : while (nDestTab<pDestDoc->GetTableCount() && !pDestDoc->HasTable(nDestTab))
770 0 : ++nDestTab;
771 :
772 0 : if (!pDoc->HasTable(nSrcTab) || !pDestDoc->HasTable(nDestTab))
773 : {
774 : OSL_FAIL("Sheet not found in ScTransferObj::StripRefs");
775 0 : return;
776 : }
777 :
778 0 : SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
779 0 : ScRange aRef;
780 :
781 0 : ScCellIterator aIter( pDoc, nStartX, nStartY, nSrcTab, nEndX, nEndY, nSrcTab );
782 0 : ScBaseCell* pCell = aIter.GetFirst();
783 0 : while (pCell)
784 : {
785 0 : if (pCell->GetCellType() == CELLTYPE_FORMULA)
786 : {
787 0 : ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
788 0 : bool bOut = false;
789 0 : ScDetectiveRefIter aRefIter( pFCell );
790 0 : while ( !bOut && aRefIter.GetNextRef( aRef ) )
791 : {
792 0 : if ( aRef.aStart.Tab() != nSrcTab || aRef.aEnd.Tab() != nSrcTab ||
793 0 : aRef.aStart.Col() < nStartX || aRef.aEnd.Col() > nEndX ||
794 0 : aRef.aStart.Row() < nStartY || aRef.aEnd.Row() > nEndY )
795 0 : bOut = true;
796 : }
797 0 : if (bOut)
798 : {
799 0 : SCCOL nCol = aIter.GetCol() - nSubX;
800 0 : SCROW nRow = aIter.GetRow() - nSubY;
801 :
802 0 : ScBaseCell* pNew = 0;
803 0 : sal_uInt16 nErrCode = pFCell->GetErrCode();
804 0 : if (nErrCode)
805 : {
806 0 : pNew = new ScStringCell( ScGlobal::GetErrorString(nErrCode) );
807 0 : if ( ((const SvxHorJustifyItem*) pDestDoc->GetAttr(
808 0 : nCol,nRow,nDestTab, ATTR_HOR_JUSTIFY))->GetValue() ==
809 : SVX_HOR_JUSTIFY_STANDARD )
810 : pDestDoc->ApplyAttr( nCol,nRow,nDestTab,
811 0 : SvxHorJustifyItem(SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY) );
812 : }
813 0 : else if (pFCell->IsValue())
814 : {
815 0 : double fVal = pFCell->GetValue();
816 0 : pNew = new ScValueCell( fVal );
817 : }
818 : else
819 : {
820 0 : String aStr = pFCell->GetString();
821 0 : if ( pFCell->IsMultilineResult() )
822 0 : pNew = new ScEditCell( aStr, pDestDoc );
823 : else
824 0 : pNew = new ScStringCell( aStr );
825 : }
826 0 : pDestDoc->PutCell( nCol,nRow,nDestTab, pNew );
827 :
828 : // number formats
829 :
830 : sal_uLong nOldFormat = ((const SfxUInt32Item*)
831 0 : pDestDoc->GetAttr(nCol,nRow,nDestTab, ATTR_VALUE_FORMAT))->GetValue();
832 0 : if ( (nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
833 : {
834 : sal_uLong nNewFormat = pFCell->GetStandardFormat( *pFormatter,
835 0 : nOldFormat );
836 : pDestDoc->ApplyAttr( nCol,nRow,nDestTab,
837 0 : SfxUInt32Item(ATTR_VALUE_FORMAT, nNewFormat) );
838 : }
839 : }
840 : }
841 0 : pCell = aIter.GetNext();
842 : }
843 : }
844 :
845 : namespace
846 : {
847 : class theScTransferUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScTransferUnoTunnelId> {};
848 : }
849 :
850 0 : const com::sun::star::uno::Sequence< sal_Int8 >& ScTransferObj::getUnoTunnelId()
851 : {
852 0 : return theScTransferUnoTunnelId::get().getSeq();
853 : }
854 :
855 0 : sal_Int64 SAL_CALL ScTransferObj::getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( com::sun::star::uno::RuntimeException )
856 : {
857 : sal_Int64 nRet;
858 0 : if( ( rId.getLength() == 16 ) &&
859 0 : ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
860 : {
861 0 : nRet = reinterpret_cast< sal_Int64 >( this );
862 : }
863 : else
864 0 : nRet = TransferableHelper::getSomething(rId);
865 0 : return nRet;
866 15 : }
867 :
868 :
869 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|