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 : #define _OUTLINER_HXX
21 :
22 : #include "scitems.hxx"
23 : #include <svx/svdetc.hxx>
24 : #include <svx/svditer.hxx>
25 : #include <svx/svdoole2.hxx>
26 : #include <svx/svdpage.hxx>
27 : #include <sfx2/dispatch.hxx>
28 : #include <sfx2/docfile.hxx>
29 : #include <svl/stritem.hxx>
30 : #include <svl/ptitem.hxx>
31 : #include <svl/urlbmk.hxx>
32 : #include <comphelper/classids.hxx>
33 : #include <sot/formats.hxx>
34 : #include <vcl/graph.hxx>
35 : #include <vcl/virdev.hxx>
36 : #include <vcl/msgbox.hxx>
37 : #include <tools/urlobj.hxx>
38 : #include <sot/exchange.hxx>
39 : #include <memory>
40 :
41 : #include "attrib.hxx"
42 : #include "patattr.hxx"
43 : #include "dociter.hxx"
44 : #include "viewfunc.hxx"
45 : #include "tabvwsh.hxx"
46 : #include "docsh.hxx"
47 : #include "docfunc.hxx"
48 : #include "undoblk.hxx"
49 : #include "refundo.hxx"
50 : #include "globstr.hrc"
51 : #include "global.hxx"
52 : #include "transobj.hxx"
53 : #include "drwtrans.hxx"
54 : #include "rangenam.hxx"
55 : #include "dbdata.hxx"
56 : #include "impex.hxx" // Sylk-ID fuer CB
57 : #include "chgtrack.hxx"
58 : #include "waitoff.hxx"
59 : #include "scmod.hxx"
60 : #include "sc.hrc"
61 : #include "inputopt.hxx"
62 : #include "warnbox.hxx"
63 : #include "drwlayer.hxx"
64 : #include "editable.hxx"
65 : #include "docuno.hxx"
66 : #include "clipparam.hxx"
67 : #include "undodat.hxx"
68 : #include "drawview.hxx"
69 : #include "cliputil.hxx"
70 :
71 : using namespace com::sun::star;
72 :
73 : // STATIC DATA ---------------------------------------------------------------
74 :
75 :
76 : //============================================================================
77 :
78 : // GlobalName der Writer-DocShell kommt jetzt aus comphelper/classids.hxx
79 :
80 : //----------------------------------------------------------------------------
81 : // C U T
82 :
83 0 : void ScViewFunc::CutToClip( ScDocument* pClipDoc, sal_Bool bIncludeObjects )
84 : {
85 0 : UpdateInputLine();
86 :
87 0 : ScEditableTester aTester( this );
88 0 : if (!aTester.IsEditable()) // selection editable?
89 : {
90 0 : ErrorMessage( aTester.GetMessageId() );
91 0 : return;
92 : }
93 :
94 0 : ScRange aRange; // zu loeschender Bereich
95 0 : if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
96 : {
97 0 : ScDocument* pDoc = GetViewData()->GetDocument();
98 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
99 0 : ScMarkData& rMark = GetViewData()->GetMarkData();
100 0 : const sal_Bool bRecord(pDoc->IsUndoEnabled()); // Undo/Redo
101 :
102 0 : ScDocShellModificator aModificator( *pDocSh );
103 :
104 0 : if ( !rMark.IsMarked() && !rMark.IsMultiMarked() ) // mark the range if not marked yet
105 : {
106 0 : DoneBlockMode();
107 0 : InitOwnBlockMode();
108 0 : rMark.SetMarkArea( aRange );
109 0 : MarkDataChanged();
110 : }
111 :
112 0 : CopyToClip( pClipDoc, sal_True, false, bIncludeObjects ); // Ab ins Clipboard
113 :
114 0 : ScAddress aOldEnd( aRange.aEnd ); // Zusammengefasste Zellen im Bereich?
115 0 : pDoc->ExtendMerge( aRange, sal_True );
116 :
117 0 : ScDocument* pUndoDoc = NULL;
118 0 : if ( bRecord )
119 : {
120 0 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
121 0 : pUndoDoc->InitUndoSelected( pDoc, rMark );
122 : // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
123 0 : ScRange aCopyRange = aRange;
124 0 : aCopyRange.aStart.SetTab(0);
125 0 : aCopyRange.aEnd.SetTab(pDoc->GetTableCount()-1);
126 0 : pDoc->CopyToDocument( aCopyRange, (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS, false, pUndoDoc );
127 0 : pDoc->BeginDrawUndo();
128 : }
129 :
130 0 : sal_uInt16 nExtFlags = 0;
131 0 : pDocSh->UpdatePaintExt( nExtFlags, aRange );
132 :
133 0 : rMark.MarkToMulti();
134 0 : pDoc->DeleteSelection( IDF_ALL, rMark );
135 0 : if ( bIncludeObjects )
136 0 : pDoc->DeleteObjectsInSelection( rMark );
137 0 : rMark.MarkToSimple();
138 :
139 0 : if ( !AdjustRowHeight( aRange.aStart.Row(), aRange.aEnd.Row() ) )
140 0 : pDocSh->PostPaint( aRange, PAINT_GRID, nExtFlags );
141 :
142 0 : if ( bRecord ) // erst jetzt ist Draw-Undo verfuegbar
143 0 : pDocSh->GetUndoManager()->AddUndoAction(
144 0 : new ScUndoCut( pDocSh, aRange, aOldEnd, rMark, pUndoDoc ) );
145 :
146 0 : aModificator.SetDocumentModified();
147 0 : pDocSh->UpdateOle(GetViewData());
148 :
149 0 : CellContentChanged();
150 : }
151 : else
152 0 : ErrorMessage( STR_NOMULTISELECT );
153 : }
154 :
155 :
156 : //----------------------------------------------------------------------------
157 : // C O P Y
158 :
159 11 : sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, sal_Bool bCut, sal_Bool bApi, sal_Bool bIncludeObjects, sal_Bool bStopEdit )
160 : {
161 11 : ScRange aRange;
162 11 : ScMarkType eMarkType = GetViewData()->GetSimpleArea( aRange );
163 11 : ScMarkData& rMark = GetViewData()->GetMarkData();
164 11 : sal_Bool bDone = sal_False;
165 :
166 11 : if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED )
167 : {
168 11 : ScRangeList aRangeList;
169 11 : aRangeList.Append( aRange );
170 11 : bDone = CopyToClip( pClipDoc, aRangeList, bCut, bApi, bIncludeObjects, bStopEdit, sal_False );
171 : }
172 0 : else if (eMarkType == SC_MARK_MULTI)
173 : {
174 0 : ScRangeList aRangeList;
175 0 : rMark.MarkToSimple();
176 0 : rMark.FillRangeListWithMarks(&aRangeList, false);
177 0 : bDone = CopyToClip( pClipDoc, aRangeList, bCut, bApi, bIncludeObjects, bStopEdit, sal_False );
178 : }
179 : else
180 : {
181 0 : if (!bApi)
182 0 : ErrorMessage(STR_NOMULTISELECT);
183 : }
184 :
185 11 : return bDone;
186 : }
187 :
188 : // Copy the content of the Range into clipboard.
189 11 : sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, const ScRangeList& rRanges, sal_Bool bCut, sal_Bool bApi, sal_Bool bIncludeObjects, sal_Bool bStopEdit, sal_Bool bUseRangeForVBA )
190 : {
191 11 : if ( rRanges.empty() )
192 0 : return false;
193 11 : sal_Bool bDone = false;
194 11 : if ( bStopEdit )
195 11 : UpdateInputLine();
196 :
197 11 : ScRange aRange = *rRanges[0];
198 11 : ScClipParam aClipParam( aRange, bCut );
199 11 : aClipParam.maRanges = rRanges;
200 :
201 11 : ScDocument* pDoc = GetViewData()->GetDocument();
202 11 : ScMarkData& rMark = GetViewData()->GetMarkData();
203 :
204 11 : if ( !aClipParam.isMultiRange() )
205 : {
206 11 : if ( pDoc && ( !pDoc->HasSelectedBlockMatrixFragment( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), rMark ) ) )
207 : {
208 11 : sal_Bool bSysClip = false;
209 11 : if ( !pClipDoc ) // no clip doc specified
210 : {
211 : // Create one (deleted by ScTransferObj).
212 11 : pClipDoc = new ScDocument( SCDOCMODE_CLIP );
213 11 : bSysClip = sal_True; // and copy into system
214 : }
215 11 : if ( !bCut )
216 : {
217 11 : ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
218 11 : if ( pChangeTrack )
219 0 : pChangeTrack->ResetLastCut();
220 : }
221 :
222 11 : if ( bSysClip && bIncludeObjects )
223 : {
224 11 : sal_Bool bAnyOle = pDoc->HasOLEObjectsInArea( aRange );
225 : // Update ScGlobal::pDrawClipDocShellRef.
226 11 : ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
227 : }
228 :
229 11 : if ( !bUseRangeForVBA )
230 : // is this necessary?, will setting the doc id upset the
231 : // following paste operation with range? would be nicer to just set this always
232 : // and lose the 'if' above
233 11 : aClipParam.setSourceDocID( pDoc->GetDocumentID() );
234 :
235 11 : pDoc->CopyToClip( aClipParam, pClipDoc, &rMark, false, false, bIncludeObjects, true, bUseRangeForVBA );
236 11 : if ( !bUseRangeForVBA && pDoc && pClipDoc )
237 : {
238 11 : ScDrawLayer* pDrawLayer = pClipDoc->GetDrawLayer();
239 11 : if ( pDrawLayer )
240 : {
241 0 : ScClipParam& rClipParam = pClipDoc->GetClipParam();
242 0 : ScRangeListVector& rRangesVector = rClipParam.maProtectedChartRangesVector;
243 0 : SCTAB nTabCount = pClipDoc->GetTableCount();
244 0 : for ( SCTAB nTab = 0; nTab < nTabCount; ++nTab )
245 : {
246 0 : SdrPage* pPage = pDrawLayer->GetPage( static_cast< sal_uInt16 >( nTab ) );
247 0 : if ( pPage )
248 : {
249 0 : ScChartHelper::FillProtectedChartRangesVector( rRangesVector, pDoc, pPage );
250 : }
251 : }
252 : }
253 : }
254 :
255 11 : if ( bSysClip )
256 : {
257 11 : ScDrawLayer::SetGlobalDrawPersist(NULL);
258 11 : ScGlobal::SetClipDocName( pDoc->GetDocumentShell()->GetTitle( SFX_TITLE_FULLNAME ) );
259 : }
260 11 : pClipDoc->ExtendMerge( aRange, true );
261 :
262 11 : if ( bSysClip )
263 : {
264 11 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
265 11 : TransferableObjectDescriptor aObjDesc;
266 11 : pDocSh->FillTransferableObjectDescriptor( aObjDesc );
267 11 : aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
268 : // maSize is set in ScTransferObj ctor
269 :
270 11 : ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
271 22 : uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
272 11 : if ( ScGlobal::pDrawClipDocShellRef )
273 : {
274 0 : SfxObjectShellRef aPersistRef( &(*ScGlobal::pDrawClipDocShellRef) );
275 0 : pTransferObj->SetDrawPersist( aPersistRef );// keep persist for ole objects alive
276 :
277 : }
278 11 : pTransferObj->CopyToClipboard( GetActiveWin() );
279 22 : SC_MOD()->SetClipObject( pTransferObj, NULL );
280 : }
281 :
282 11 : bDone = true;
283 : }
284 : }
285 : else
286 : {
287 0 : bool bSuccess = false;
288 0 : aClipParam.mbCutMode = false;
289 :
290 : do
291 : {
292 0 : if (bCut)
293 : // We con't support cutting of multi-selections.
294 0 : break;
295 :
296 0 : if (pClipDoc)
297 : // TODO: What's this for?
298 0 : break;
299 :
300 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
301 0 : ::std::auto_ptr<ScDocument> pDocClip(new ScDocument(SCDOCMODE_CLIP));
302 : SAL_WNODEPRECATED_DECLARATIONS_POP
303 :
304 : // Check for geometrical feasibility of the ranges.
305 0 : bool bValidRanges = true;
306 0 : ScRange* p = aClipParam.maRanges.front();
307 0 : SCCOL nPrevColDelta = 0;
308 0 : SCROW nPrevRowDelta = 0;
309 0 : SCCOL nPrevCol = p->aStart.Col();
310 0 : SCROW nPrevRow = p->aStart.Row();
311 0 : SCCOL nPrevColSize = p->aEnd.Col() - p->aStart.Col() + 1;
312 0 : SCROW nPrevRowSize = p->aEnd.Row() - p->aStart.Row() + 1;
313 0 : for ( size_t i = 1; i < aClipParam.maRanges.size(); ++i )
314 : {
315 0 : p = aClipParam.maRanges[i];
316 0 : if ( pDoc->HasSelectedBlockMatrixFragment(
317 0 : p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), rMark) )
318 : {
319 0 : if (!bApi)
320 0 : ErrorMessage(STR_MATRIXFRAGMENTERR);
321 0 : return false;
322 : }
323 :
324 0 : SCCOL nColDelta = p->aStart.Col() - nPrevCol;
325 0 : SCROW nRowDelta = p->aStart.Row() - nPrevRow;
326 :
327 0 : if ((nColDelta && nRowDelta) || (nPrevColDelta && nRowDelta) || (nPrevRowDelta && nColDelta))
328 : {
329 0 : bValidRanges = false;
330 0 : break;
331 : }
332 :
333 0 : if (aClipParam.meDirection == ScClipParam::Unspecified)
334 : {
335 0 : if (nColDelta)
336 0 : aClipParam.meDirection = ScClipParam::Column;
337 0 : if (nRowDelta)
338 0 : aClipParam.meDirection = ScClipParam::Row;
339 : }
340 :
341 0 : SCCOL nColSize = p->aEnd.Col() - p->aStart.Col() + 1;
342 0 : SCROW nRowSize = p->aEnd.Row() - p->aStart.Row() + 1;
343 :
344 0 : if (aClipParam.meDirection == ScClipParam::Column && nRowSize != nPrevRowSize)
345 : {
346 : // column-oriented ranges must have identical row size.
347 0 : bValidRanges = false;
348 0 : break;
349 : }
350 0 : if (aClipParam.meDirection == ScClipParam::Row && nColSize != nPrevColSize)
351 : {
352 : // likewise, row-oriented ranges must have identical
353 : // column size.
354 0 : bValidRanges = false;
355 0 : break;
356 : }
357 :
358 0 : nPrevCol = p->aStart.Col();
359 0 : nPrevRow = p->aStart.Row();
360 0 : nPrevColDelta = nColDelta;
361 0 : nPrevRowDelta = nRowDelta;
362 0 : nPrevColSize = nColSize;
363 0 : nPrevRowSize = nRowSize;
364 : }
365 0 : if (!bValidRanges)
366 0 : break;
367 0 : pDoc->CopyToClip(aClipParam, pDocClip.get(), &rMark, false, false, bIncludeObjects, true, bUseRangeForVBA );
368 :
369 0 : ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
370 0 : if ( pChangeTrack )
371 0 : pChangeTrack->ResetLastCut(); // kein CutMode mehr
372 :
373 : {
374 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
375 0 : TransferableObjectDescriptor aObjDesc;
376 0 : pDocSh->FillTransferableObjectDescriptor( aObjDesc );
377 0 : aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
378 : // maSize is set in ScTransferObj ctor
379 :
380 0 : ScTransferObj* pTransferObj = new ScTransferObj( pDocClip.release(), aObjDesc );
381 0 : uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
382 :
383 0 : if ( ScGlobal::pDrawClipDocShellRef )
384 : {
385 0 : SfxObjectShellRef aPersistRef( &(*ScGlobal::pDrawClipDocShellRef) );
386 0 : pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
387 : }
388 :
389 0 : pTransferObj->CopyToClipboard( GetActiveWin() ); // system clipboard
390 0 : SC_MOD()->SetClipObject( pTransferObj, NULL ); // internal clipboard
391 : }
392 :
393 0 : bSuccess = true;
394 : }
395 : while (false);
396 :
397 0 : if (!bSuccess && !bApi)
398 0 : ErrorMessage(STR_NOMULTISELECT);
399 :
400 0 : bDone = bSuccess;
401 : }
402 :
403 11 : return bDone;
404 : }
405 :
406 0 : ScTransferObj* ScViewFunc::CopyToTransferable()
407 : {
408 0 : ScRange aRange;
409 0 : if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
410 : {
411 0 : ScDocument* pDoc = GetViewData()->GetDocument();
412 0 : ScMarkData& rMark = GetViewData()->GetMarkData();
413 0 : if ( !pDoc->HasSelectedBlockMatrixFragment(
414 0 : aRange.aStart.Col(), aRange.aStart.Row(),
415 0 : aRange.aEnd.Col(), aRange.aEnd.Row(),
416 0 : rMark ) )
417 : {
418 0 : ScDocument *pClipDoc = new ScDocument( SCDOCMODE_CLIP ); // create one (deleted by ScTransferObj)
419 :
420 0 : sal_Bool bAnyOle = pDoc->HasOLEObjectsInArea( aRange, &rMark );
421 0 : ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
422 :
423 0 : ScClipParam aClipParam(aRange, false);
424 0 : pDoc->CopyToClip(aClipParam, pClipDoc, &rMark, false, false, true);
425 :
426 0 : ScDrawLayer::SetGlobalDrawPersist(NULL);
427 0 : pClipDoc->ExtendMerge( aRange, sal_True );
428 :
429 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
430 0 : TransferableObjectDescriptor aObjDesc;
431 0 : pDocSh->FillTransferableObjectDescriptor( aObjDesc );
432 0 : aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
433 0 : ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
434 0 : return pTransferObj;
435 : }
436 : }
437 :
438 0 : return NULL;
439 : }
440 :
441 : //----------------------------------------------------------------------------
442 : // P A S T E
443 :
444 0 : void ScViewFunc::PasteDraw()
445 : {
446 0 : ScViewData* pViewData = GetViewData();
447 0 : SCCOL nPosX = pViewData->GetCurX();
448 0 : SCROW nPosY = pViewData->GetCurY();
449 0 : Window* pWin = GetActiveWin();
450 : Point aPos = pWin->PixelToLogic( pViewData->GetScrPos( nPosX, nPosY,
451 0 : pViewData->GetActivePart() ) );
452 0 : ScDrawTransferObj* pDrawClip = ScDrawTransferObj::GetOwnClipboard( pWin );
453 0 : if (pDrawClip)
454 : PasteDraw( aPos, pDrawClip->GetModel(), false,
455 0 : pDrawClip->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() );
456 0 : }
457 :
458 3 : void ScViewFunc::PasteFromSystem()
459 : {
460 3 : UpdateInputLine();
461 :
462 3 : Window* pWin = GetActiveWin();
463 3 : ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
464 3 : ScDrawTransferObj* pDrawClip = ScDrawTransferObj::GetOwnClipboard( pWin );
465 :
466 3 : if (pOwnClip)
467 : {
468 : // keep a reference in case the clipboard is changed during PasteFromClip
469 0 : uno::Reference<datatransfer::XTransferable> aOwnClipRef( pOwnClip );
470 : PasteFromClip( IDF_ALL, pOwnClip->GetDocument(),
471 : PASTE_NOFUNC, false, false, false, INS_NONE, IDF_NONE,
472 0 : sal_True ); // allow warning dialog
473 : }
474 3 : else if (pDrawClip)
475 0 : PasteDraw();
476 : else
477 : {
478 3 : TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
479 :
480 : {
481 3 : sal_uLong nBiff8 = SotExchange::RegisterFormatName(OUString("Biff8"));
482 3 : sal_uLong nBiff5 = SotExchange::RegisterFormatName(OUString("Biff5"));
483 :
484 : // als erstes SvDraw-Model, dann Grafik
485 : // (Grafik darf nur bei einzelner Grafik drinstehen)
486 :
487 3 : if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ))
488 : {
489 : // special case for tables from drawing
490 0 : if( aDataHelper.HasFormat( SOT_FORMAT_RTF ) )
491 : {
492 0 : PasteFromSystem( FORMAT_RTF );
493 : }
494 : else
495 : {
496 0 : PasteFromSystem( SOT_FORMATSTR_ID_DRAWING );
497 : }
498 : }
499 3 : else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ))
500 0 : PasteFromSystem( SOT_FORMATSTR_ID_SVXB );
501 3 : else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ))
502 : {
503 : // If it's a Writer object, insert RTF instead of OLE
504 :
505 : // Else, if the class id is all-zero, and SYLK is available,
506 : // it probably is spreadsheet cells that have been put
507 : // on the clipboard by OOo, so use the SYLK. (fdo#31077)
508 :
509 0 : sal_Bool bDoRtf = false;
510 0 : TransferableObjectDescriptor aObjDesc;
511 0 : if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) )
512 : {
513 0 : bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
514 0 : aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) )
515 0 : && aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
516 : }
517 0 : if ( bDoRtf )
518 0 : PasteFromSystem( FORMAT_RTF );
519 0 : else if ( aObjDesc.maClassName == SvGlobalName( 0,0,0,0,0,0,0,0,0,0,0 )
520 0 : && aDataHelper.HasFormat( SOT_FORMATSTR_ID_SYLK ))
521 0 : PasteFromSystem( SOT_FORMATSTR_ID_SYLK );
522 : else
523 0 : PasteFromSystem( SOT_FORMATSTR_ID_EMBED_SOURCE );
524 : }
525 3 : else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ))
526 0 : PasteFromSystem( SOT_FORMATSTR_ID_LINK_SOURCE );
527 : // the following format can not affect scenario from #89579#
528 3 : else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ))
529 0 : PasteFromSystem( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE );
530 : // FORMAT_PRIVATE no longer here (can't work if pOwnClip is NULL)
531 3 : else if (aDataHelper.HasFormat(nBiff8)) // before xxx_OLE formats
532 0 : PasteFromSystem(nBiff8);
533 3 : else if (aDataHelper.HasFormat(nBiff5))
534 0 : PasteFromSystem(nBiff5);
535 3 : else if (aDataHelper.HasFormat(FORMAT_RTF))
536 0 : PasteFromSystem(FORMAT_RTF);
537 3 : else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML))
538 0 : PasteFromSystem(SOT_FORMATSTR_ID_HTML);
539 3 : else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML_SIMPLE))
540 0 : PasteFromSystem(SOT_FORMATSTR_ID_HTML_SIMPLE);
541 3 : else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_SYLK))
542 0 : PasteFromSystem(SOT_FORMATSTR_ID_SYLK);
543 3 : else if (aDataHelper.HasFormat(FORMAT_STRING))
544 0 : PasteFromSystem(FORMAT_STRING);
545 3 : else if (aDataHelper.HasFormat(FORMAT_GDIMETAFILE))
546 0 : PasteFromSystem(FORMAT_GDIMETAFILE);
547 3 : else if (aDataHelper.HasFormat(FORMAT_BITMAP))
548 0 : PasteFromSystem(FORMAT_BITMAP);
549 : // xxx_OLE formats come last, like in SotExchange tables
550 3 : else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ))
551 0 : PasteFromSystem( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE );
552 3 : else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ))
553 0 : PasteFromSystem( SOT_FORMATSTR_ID_LINK_SOURCE_OLE );
554 3 : }
555 : }
556 : // keine Fehlermeldung, weil SID_PASTE in der idl das FastCall-Flag hat,
557 : // also auch gerufen wird, wenn nichts im Clipboard steht (#42531#)
558 3 : }
559 :
560 0 : void ScViewFunc::PasteFromTransferable( const uno::Reference<datatransfer::XTransferable>& rxTransferable )
561 : {
562 0 : ScTransferObj *pOwnClip=0;
563 0 : ScDrawTransferObj *pDrawClip=0;
564 0 : uno::Reference<lang::XUnoTunnel> xTunnel( rxTransferable, uno::UNO_QUERY );
565 0 : if ( xTunnel.is() )
566 : {
567 0 : sal_Int64 nHandle = xTunnel->getSomething( ScTransferObj::getUnoTunnelId() );
568 0 : if ( nHandle )
569 0 : pOwnClip = (ScTransferObj*) (sal_IntPtr) nHandle;
570 : else
571 : {
572 0 : nHandle = xTunnel->getSomething( ScDrawTransferObj::getUnoTunnelId() );
573 0 : if ( nHandle )
574 0 : pDrawClip = (ScDrawTransferObj*) (sal_IntPtr) nHandle;
575 : }
576 : }
577 :
578 0 : if (pOwnClip)
579 : {
580 : PasteFromClip( IDF_ALL, pOwnClip->GetDocument(),
581 : PASTE_NOFUNC, false, false, false, INS_NONE, IDF_NONE,
582 0 : sal_True ); // allow warning dialog
583 : }
584 0 : else if (pDrawClip)
585 : {
586 0 : ScViewData* pViewData = GetViewData();
587 0 : SCCOL nPosX = pViewData->GetCurX();
588 0 : SCROW nPosY = pViewData->GetCurY();
589 0 : Window* pWin = GetActiveWin();
590 0 : Point aPos = pWin->PixelToLogic( pViewData->GetScrPos( nPosX, nPosY, pViewData->GetActivePart() ) );
591 0 : PasteDraw( aPos, pDrawClip->GetModel(), false, pDrawClip->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() );
592 : }
593 : else
594 : {
595 0 : TransferableDataHelper aDataHelper( rxTransferable );
596 : {
597 0 : sal_uLong nBiff8 = SotExchange::RegisterFormatName(OUString("Biff8"));
598 0 : sal_uLong nBiff5 = SotExchange::RegisterFormatName(OUString("Biff5"));
599 0 : sal_uLong nFormatId = 0;
600 : // als erstes SvDraw-Model, dann Grafik
601 : // (Grafik darf nur bei einzelner Grafik drinstehen)
602 :
603 0 : if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ))
604 0 : nFormatId = SOT_FORMATSTR_ID_DRAWING;
605 0 : else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ))
606 0 : nFormatId = SOT_FORMATSTR_ID_SVXB;
607 0 : else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ))
608 : {
609 : // If it's a Writer object, insert RTF instead of OLE
610 0 : sal_Bool bDoRtf = false;
611 0 : TransferableObjectDescriptor aObjDesc;
612 0 : if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) )
613 : {
614 0 : bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
615 0 : aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) )
616 0 : && aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
617 : }
618 0 : if ( bDoRtf )
619 0 : nFormatId = FORMAT_RTF;
620 : else
621 0 : nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE;
622 : }
623 0 : else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ))
624 0 : nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
625 : // the following format can not affect scenario from #89579#
626 0 : else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ))
627 0 : nFormatId = SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE;
628 : // FORMAT_PRIVATE no longer here (can't work if pOwnClip is NULL)
629 0 : else if (aDataHelper.HasFormat(nBiff8)) // before xxx_OLE formats
630 0 : nFormatId = nBiff8;
631 0 : else if (aDataHelper.HasFormat(nBiff5))
632 0 : nFormatId = nBiff5;
633 0 : else if (aDataHelper.HasFormat(FORMAT_RTF))
634 0 : nFormatId = FORMAT_RTF;
635 0 : else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML))
636 0 : nFormatId = SOT_FORMATSTR_ID_HTML;
637 0 : else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML_SIMPLE))
638 0 : nFormatId = SOT_FORMATSTR_ID_HTML_SIMPLE;
639 0 : else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_SYLK))
640 0 : nFormatId = SOT_FORMATSTR_ID_SYLK;
641 0 : else if (aDataHelper.HasFormat(FORMAT_STRING))
642 0 : nFormatId = FORMAT_STRING;
643 0 : else if (aDataHelper.HasFormat(FORMAT_GDIMETAFILE))
644 0 : nFormatId = FORMAT_GDIMETAFILE;
645 0 : else if (aDataHelper.HasFormat(FORMAT_BITMAP))
646 0 : nFormatId = FORMAT_BITMAP;
647 : // xxx_OLE formats come last, like in SotExchange tables
648 0 : else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ))
649 0 : nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE;
650 0 : else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ))
651 0 : nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
652 : else
653 0 : return;
654 :
655 0 : PasteDataFormat( nFormatId, aDataHelper.GetTransferable(),
656 0 : GetViewData()->GetCurX(), GetViewData()->GetCurY(),
657 0 : NULL, false, false );
658 0 : }
659 0 : }
660 : }
661 :
662 0 : sal_Bool ScViewFunc::PasteFromSystem( sal_uLong nFormatId, sal_Bool bApi )
663 : {
664 0 : UpdateInputLine();
665 :
666 0 : sal_Bool bRet = sal_True;
667 0 : Window* pWin = GetActiveWin();
668 0 : ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
669 0 : if ( nFormatId == 0 && pOwnClip )
670 : {
671 : // keep a reference in case the clipboard is changed during PasteFromClip
672 0 : uno::Reference<datatransfer::XTransferable> aOwnClipRef( pOwnClip );
673 : PasteFromClip( IDF_ALL, pOwnClip->GetDocument(),
674 : PASTE_NOFUNC, false, false, false, INS_NONE, IDF_NONE,
675 0 : !bApi ); // allow warning dialog
676 : }
677 : else
678 : {
679 0 : TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
680 0 : if ( !aDataHelper.GetTransferable().is() )
681 0 : return false;
682 :
683 0 : bRet = PasteDataFormat( nFormatId, aDataHelper.GetTransferable(),
684 0 : GetViewData()->GetCurX(), GetViewData()->GetCurY(),
685 0 : NULL, false, !bApi ); // allow warning dialog
686 :
687 0 : if ( !bRet && !bApi )
688 0 : ErrorMessage(STR_PASTE_ERROR);
689 : }
690 0 : return bRet;
691 : }
692 :
693 :
694 : //----------------------------------------------------------------------------
695 : // P A S T E
696 :
697 0 : sal_Bool ScViewFunc::PasteOnDrawObject( const uno::Reference<datatransfer::XTransferable>& rxTransferable,
698 : SdrObject* pHitObj, sal_Bool bLink )
699 : {
700 0 : sal_Bool bRet = false;
701 0 : if ( bLink )
702 : {
703 0 : TransferableDataHelper aDataHelper( rxTransferable );
704 0 : if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) )
705 : {
706 0 : SotStorageStreamRef xStm;
707 0 : if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_SVXB, xStm ) )
708 : {
709 0 : Graphic aGraphic;
710 0 : *xStm >> aGraphic;
711 0 : bRet = ApplyGraphicToObject( pHitObj, aGraphic );
712 0 : }
713 : }
714 0 : else if ( aDataHelper.HasFormat( SOT_FORMAT_GDIMETAFILE ) )
715 : {
716 0 : GDIMetaFile aMtf;
717 0 : if( aDataHelper.GetGDIMetaFile( FORMAT_GDIMETAFILE, aMtf ) )
718 0 : bRet = ApplyGraphicToObject( pHitObj, Graphic(aMtf) );
719 : }
720 0 : else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) )
721 : {
722 0 : BitmapEx aBmpEx;
723 0 : if( aDataHelper.GetBitmapEx( FORMAT_BITMAP, aBmpEx ) )
724 0 : bRet = ApplyGraphicToObject( pHitObj, Graphic(aBmpEx) );
725 0 : }
726 : }
727 : else
728 : {
729 : // ham' wa noch nich
730 : }
731 0 : return bRet;
732 : }
733 :
734 0 : static sal_Bool lcl_SelHasAttrib( ScDocument* pDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
735 : const ScMarkData& rTabSelection, sal_uInt16 nMask )
736 : {
737 0 : ScMarkData::const_iterator itr = rTabSelection.begin(), itrEnd = rTabSelection.end();
738 0 : for (; itr != itrEnd; ++itr)
739 0 : if ( pDoc->HasAttrib( nCol1, nRow1, *itr, nCol2, nRow2, *itr, nMask ) )
740 0 : return sal_True;
741 0 : return false;
742 : }
743 :
744 : //
745 : // Einfuegen auf Tabelle:
746 : //
747 :
748 : // internes Paste
749 :
750 : namespace {
751 :
752 0 : bool checkDestRangeForOverwrite(const ScRangeList& rDestRanges, const ScDocument* pDoc, const ScMarkData& rMark, Window* pParentWnd)
753 : {
754 0 : bool bIsEmpty = true;
755 0 : ScMarkData::const_iterator itrTab = rMark.begin(), itrTabEnd = rMark.end();
756 0 : size_t nRangeSize = rDestRanges.size();
757 0 : for (; itrTab != itrTabEnd && bIsEmpty; ++itrTab)
758 : {
759 0 : for (size_t i = 0; i < nRangeSize && bIsEmpty; ++i)
760 : {
761 0 : const ScRange& rRange = *rDestRanges[i];
762 : bIsEmpty = pDoc->IsBlockEmpty(
763 0 : *itrTab, rRange.aStart.Col(), rRange.aStart.Row(),
764 0 : rRange.aEnd.Col(), rRange.aEnd.Row());
765 : }
766 : }
767 :
768 0 : if (!bIsEmpty)
769 : {
770 0 : ScReplaceWarnBox aBox(pParentWnd);
771 0 : if (aBox.Execute() != RET_YES)
772 : {
773 : // changing the configuration is within the ScReplaceWarnBox
774 0 : return false;
775 0 : }
776 : }
777 0 : return true;
778 : }
779 :
780 : }
781 :
782 28 : bool ScViewFunc::PasteFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc,
783 : sal_uInt16 nFunction, bool bSkipEmpty,
784 : bool bTranspose, bool bAsLink,
785 : InsCellCmd eMoveMode, sal_uInt16 nUndoExtraFlags,
786 : bool bAllowDialogs )
787 : {
788 28 : if (!pClipDoc)
789 : {
790 : OSL_FAIL("PasteFromClip: pClipDoc=0 not allowed");
791 12 : return false;
792 : }
793 :
794 : // fuer Undo etc. immer alle oder keine Inhalte sichern
795 16 : sal_uInt16 nContFlags = IDF_NONE;
796 16 : if (nFlags & IDF_CONTENTS)
797 16 : nContFlags |= IDF_CONTENTS;
798 16 : if (nFlags & IDF_ATTRIB)
799 16 : nContFlags |= IDF_ATTRIB;
800 : // evtl. Attribute ins Undo ohne sie vom Clip ins Doc zu kopieren
801 16 : sal_uInt16 nUndoFlags = nContFlags;
802 16 : if (nUndoExtraFlags & IDF_ATTRIB)
803 0 : nUndoFlags |= IDF_ATTRIB;
804 : // do not copy note captions into undo document
805 16 : nUndoFlags |= IDF_NOCAPTIONS;
806 :
807 16 : ScClipParam& rClipParam = pClipDoc->GetClipParam();
808 16 : if (rClipParam.isMultiRange())
809 : {
810 : // Source data is multi-range.
811 : return PasteMultiRangesFromClip(
812 : nFlags, pClipDoc, nFunction, bSkipEmpty, bTranspose, bAsLink, bAllowDialogs,
813 0 : eMoveMode, nUndoFlags);
814 : }
815 :
816 16 : ScMarkData& rMark = GetViewData()->GetMarkData();
817 16 : if (rMark.IsMultiMarked())
818 : {
819 : // Source data is single-range but destination is multi-range.
820 : return PasteFromClipToMultiRanges(
821 : nFlags, pClipDoc, nFunction, bSkipEmpty, bTranspose, bAsLink, bAllowDialogs,
822 0 : eMoveMode, nUndoFlags);
823 : }
824 :
825 16 : bool bCutMode = pClipDoc->IsCutMode(); // if transposing, take from original clipdoc
826 16 : bool bIncludeFiltered = bCutMode;
827 :
828 : // paste drawing: also if IDF_NOTE is set (to create drawing layer for note captions)
829 16 : bool bPasteDraw = ( pClipDoc->GetDrawLayer() && ( nFlags & (IDF_OBJECTS|IDF_NOTE) ) );
830 :
831 16 : ScDocShellRef aTransShellRef; // for objects in xTransClip - must remain valid as long as xTransClip
832 16 : ScDocument* pOrigClipDoc = NULL;
833 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
834 32 : ::std::auto_ptr< ScDocument > xTransClip;
835 : SAL_WNODEPRECATED_DECLARATIONS_POP
836 16 : if ( bTranspose )
837 : {
838 : SCCOL nX;
839 : SCROW nY;
840 : // include filtered rows until TransposeClip can skip them
841 0 : bIncludeFiltered = true;
842 0 : pClipDoc->GetClipArea( nX, nY, true );
843 0 : if ( nY > static_cast<sal_Int32>(MAXCOL) ) // zuviele Zeilen zum Transponieren
844 : {
845 0 : ErrorMessage(STR_PASTE_FULL);
846 0 : return false;
847 : }
848 0 : pOrigClipDoc = pClipDoc; // fuer Referenzen
849 :
850 0 : if ( bPasteDraw )
851 : {
852 0 : aTransShellRef = new ScDocShell; // DocShell needs a Ref immediately
853 0 : aTransShellRef->DoInitNew(NULL);
854 : }
855 0 : ScDrawLayer::SetGlobalDrawPersist(aTransShellRef);
856 :
857 0 : xTransClip.reset( new ScDocument( SCDOCMODE_CLIP ));
858 0 : pClipDoc->TransposeClip( xTransClip.get(), nFlags, bAsLink );
859 0 : pClipDoc = xTransClip.get();
860 :
861 0 : ScDrawLayer::SetGlobalDrawPersist(NULL);
862 : }
863 :
864 : SCCOL nStartCol;
865 : SCROW nStartRow;
866 : SCTAB nStartTab;
867 : SCCOL nEndCol;
868 : SCROW nEndRow;
869 : SCTAB nEndTab;
870 : SCCOL nClipSizeX;
871 : SCROW nClipSizeY;
872 16 : pClipDoc->GetClipArea( nClipSizeX, nClipSizeY, true ); // size in clipboard doc
873 :
874 : // size in target doc: include filtered rows only if CutMode is set
875 : SCCOL nDestSizeX;
876 : SCROW nDestSizeY;
877 16 : pClipDoc->GetClipArea( nDestSizeX, nDestSizeY, bIncludeFiltered );
878 :
879 16 : ScDocument* pDoc = GetViewData()->GetDocument();
880 16 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
881 16 : ::svl::IUndoManager* pUndoMgr = pDocSh->GetUndoManager();
882 16 : const bool bRecord(pDoc->IsUndoEnabled());
883 :
884 32 : ScDocShellModificator aModificator( *pDocSh );
885 :
886 16 : ScRange aMarkRange;
887 32 : ScMarkData aFilteredMark( rMark); // local copy for all modifications
888 16 : ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange, aFilteredMark);
889 16 : bool bMarkIsFiltered = (eMarkType == SC_MARK_SIMPLE_FILTERED);
890 16 : bool bNoPaste = ((eMarkType != SC_MARK_SIMPLE && !bMarkIsFiltered) ||
891 16 : (bMarkIsFiltered && (eMoveMode != INS_NONE || bAsLink)));
892 :
893 16 : if (!bNoPaste)
894 : {
895 16 : if (!rMark.IsMarked())
896 : {
897 : // Create a selection with clipboard row count and check that for
898 : // filtered.
899 16 : nStartCol = GetViewData()->GetCurX();
900 16 : nStartRow = GetViewData()->GetCurY();
901 16 : nStartTab = GetViewData()->GetTabNo();
902 16 : nEndCol = nStartCol + nDestSizeX;
903 16 : nEndRow = nStartRow + nDestSizeY;
904 16 : nEndTab = nStartTab;
905 16 : aMarkRange = ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
906 16 : if (ScViewUtil::HasFiltered( aMarkRange, pDoc))
907 : {
908 0 : bMarkIsFiltered = true;
909 : // Fit to clipboard's row count unfiltered rows. If there is no
910 : // fit assume that pasting is not possible. Note that nDestSizeY is
911 : // size-1 (difference).
912 0 : if (!ScViewUtil::FitToUnfilteredRows( aMarkRange, pDoc, nDestSizeY+1))
913 0 : bNoPaste = true;
914 : }
915 16 : aFilteredMark.SetMarkArea( aMarkRange);
916 : }
917 : else
918 : {
919 : // Expand the marked area when the destination area is larger than the
920 : // current selection, to get the undo do the right thing. (i#106711)
921 0 : ScRange aRange;
922 0 : aFilteredMark.GetMarkArea( aRange );
923 0 : if( (aRange.aEnd.Col() - aRange.aStart.Col()) < nDestSizeX )
924 : {
925 0 : aRange.aEnd.SetCol(aRange.aStart.Col() + nDestSizeX);
926 0 : aFilteredMark.SetMarkArea(aRange);
927 : }
928 : }
929 : }
930 :
931 16 : if (bNoPaste)
932 : {
933 0 : ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
934 0 : return false;
935 : }
936 :
937 16 : SCROW nUnfilteredRows = aMarkRange.aEnd.Row() - aMarkRange.aStart.Row() + 1;
938 32 : ScRangeList aRangeList;
939 16 : if (bMarkIsFiltered)
940 : {
941 0 : ScViewUtil::UnmarkFiltered( aFilteredMark, pDoc);
942 0 : aFilteredMark.FillRangeListWithMarks( &aRangeList, false);
943 0 : nUnfilteredRows = 0;
944 0 : size_t ListSize = aRangeList.size();
945 0 : for ( size_t i = 0; i < ListSize; ++i )
946 : {
947 0 : ScRange* p = aRangeList[i];
948 0 : nUnfilteredRows += p->aEnd.Row() - p->aStart.Row() + 1;
949 : }
950 : #if 0
951 : /* This isn't needed but could be a desired restriction. */
952 : // For filtered, destination rows have to be an exact multiple of
953 : // source rows. Note that nDestSizeY is size-1 (difference), so
954 : // nDestSizeY==0 fits always.
955 : if ((nUnfilteredRows % (nDestSizeY+1)) != 0)
956 : {
957 : /* FIXME: this should be a more descriptive error message then. */
958 : ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
959 : return false;
960 : }
961 : #endif
962 : }
963 :
964 : // Also for a filtered selection the area is used, for undo et al.
965 16 : if ( aFilteredMark.IsMarked() || bMarkIsFiltered )
966 : {
967 16 : aMarkRange.GetVars( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
968 16 : SCCOL nBlockAddX = nEndCol-nStartCol;
969 16 : SCROW nBlockAddY = nEndRow-nStartRow;
970 :
971 : // Nachfrage, wenn die Selektion groesser als 1 Zeile/Spalte, aber kleiner
972 : // als das Clipboard ist (dann wird ueber die Selektion hinaus eingefuegt)
973 :
974 : // ClipSize is not size, but difference
975 16 : if ( ( nBlockAddX != 0 && nBlockAddX < nDestSizeX ) ||
976 16 : ( nBlockAddY != 0 && nBlockAddY < nDestSizeY ) ||
977 0 : ( bMarkIsFiltered && nUnfilteredRows < nDestSizeY+1 ) )
978 : {
979 0 : ScWaitCursorOff aWaitOff( GetFrameWin() );
980 0 : String aMessage = ScGlobal::GetRscString( STR_PASTE_BIGGER );
981 : QueryBox aBox( GetViewData()->GetDialogParent(),
982 0 : WinBits(WB_YES_NO | WB_DEF_NO), aMessage );
983 0 : if ( aBox.Execute() != RET_YES )
984 : {
985 0 : return false;
986 0 : }
987 : }
988 :
989 16 : if (nBlockAddX <= nDestSizeX)
990 16 : nEndCol = nStartCol + nDestSizeX;
991 :
992 16 : if (nBlockAddY <= nDestSizeY)
993 : {
994 16 : nEndRow = nStartRow + nDestSizeY;
995 16 : if (bMarkIsFiltered || nEndRow > aMarkRange.aEnd.Row())
996 : {
997 : // Same as above if nothing was marked: re-fit selection to
998 : // unfiltered rows. Extending the selection actually may
999 : // introduce filtered rows where there weren't any before, so
1000 : // we also need to test for that.
1001 0 : aMarkRange = ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
1002 0 : if (bMarkIsFiltered || ScViewUtil::HasFiltered( aMarkRange, pDoc))
1003 : {
1004 0 : bMarkIsFiltered = true;
1005 : // Worst case: all rows up to the end of the sheet are filtered.
1006 0 : if (!ScViewUtil::FitToUnfilteredRows( aMarkRange, pDoc, nDestSizeY+1))
1007 : {
1008 0 : ErrorMessage(STR_PASTE_FULL);
1009 0 : return false;
1010 : }
1011 : }
1012 0 : aMarkRange.GetVars( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
1013 0 : aFilteredMark.SetMarkArea( aMarkRange);
1014 0 : if (bMarkIsFiltered)
1015 : {
1016 0 : ScViewUtil::UnmarkFiltered( aFilteredMark, pDoc);
1017 0 : aFilteredMark.FillRangeListWithMarks( &aRangeList, true);
1018 : }
1019 : }
1020 : }
1021 : }
1022 : else
1023 : {
1024 0 : nStartCol = GetViewData()->GetCurX();
1025 0 : nStartRow = GetViewData()->GetCurY();
1026 0 : nStartTab = GetViewData()->GetTabNo();
1027 0 : nEndCol = nStartCol + nDestSizeX;
1028 0 : nEndRow = nStartRow + nDestSizeY;
1029 0 : nEndTab = nStartTab;
1030 : }
1031 :
1032 16 : bool bOffLimits = !ValidCol(nEndCol) || !ValidRow(nEndRow);
1033 :
1034 : // Zielbereich, wie er angezeigt wird:
1035 16 : ScRange aUserRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab );
1036 :
1037 : // Sollen Zellen eingefuegt werden?
1038 : // (zu grosse nEndCol/nEndRow werden weiter unten erkannt)
1039 16 : bool bInsertCells = ( eMoveMode != INS_NONE && !bOffLimits );
1040 16 : if ( bInsertCells )
1041 : {
1042 : // Instead of EnterListAction, the paste undo action is merged into the
1043 : // insert action, so Repeat can insert the right cells
1044 :
1045 0 : MarkRange( aUserRange ); // wird vor CopyFromClip sowieso gesetzt
1046 :
1047 : // CutMode is reset on insertion of cols/rows but needed again on cell move
1048 0 : bool bCut = pClipDoc->IsCutMode();
1049 0 : if (!InsertCells( eMoveMode, bRecord, true )) // is inserting possible?
1050 : {
1051 0 : return false;
1052 : // #i21036# EnterListAction isn't used, and InsertCells doesn't insert
1053 : // its undo action on failure, so no undo handling is needed here
1054 : }
1055 0 : if ( bCut )
1056 0 : pClipDoc->SetCutMode( bCut );
1057 : }
1058 16 : else if (!bOffLimits)
1059 : {
1060 0 : bool bAskIfNotEmpty = bAllowDialogs &&
1061 0 : ( nFlags & IDF_CONTENTS ) &&
1062 16 : nFunction == PASTE_NOFUNC &&
1063 16 : SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1064 16 : if ( bAskIfNotEmpty )
1065 : {
1066 0 : ScRangeList aTestRanges;
1067 0 : aTestRanges.Append(aUserRange);
1068 0 : if (!checkDestRangeForOverwrite(aTestRanges, pDoc, aFilteredMark, GetViewData()->GetDialogParent()))
1069 0 : return false;
1070 : }
1071 : }
1072 :
1073 : SCCOL nClipStartX; // Clipboard-Bereich erweitern
1074 : SCROW nClipStartY;
1075 16 : pClipDoc->GetClipStart( nClipStartX, nClipStartY );
1076 16 : SCCOL nUndoEndCol = nClipStartX + nClipSizeX;
1077 16 : SCROW nUndoEndRow = nClipStartY + nClipSizeY; // end of source area in clipboard document
1078 16 : bool bClipOver = false;
1079 : // #i68690# ExtendMerge for the clip doc must be called with the clipboard's sheet numbers.
1080 : // The same end column/row can be used for all calls because the clip doc doesn't contain
1081 : // content outside the clip area.
1082 32 : for (SCTAB nClipTab=0; nClipTab < pClipDoc->GetTableCount(); nClipTab++)
1083 16 : if ( pClipDoc->HasTable(nClipTab) )
1084 16 : if ( pClipDoc->ExtendMerge( nClipStartX,nClipStartY, nUndoEndCol,nUndoEndRow, nClipTab, false ) )
1085 0 : bClipOver = true;
1086 16 : nUndoEndCol -= nClipStartX + nClipSizeX;
1087 16 : nUndoEndRow -= nClipStartY + nClipSizeY; // now contains only the difference added by ExtendMerge
1088 16 : nUndoEndCol = sal::static_int_cast<SCCOL>( nUndoEndCol + nEndCol );
1089 16 : nUndoEndRow = sal::static_int_cast<SCROW>( nUndoEndRow + nEndRow ); // destination area, expanded for merged cells
1090 :
1091 16 : if (nUndoEndCol>MAXCOL || nUndoEndRow>MAXROW)
1092 : {
1093 0 : ErrorMessage(STR_PASTE_FULL);
1094 0 : return false;
1095 : }
1096 :
1097 16 : pDoc->ExtendMergeSel( nStartCol,nStartRow, nUndoEndCol,nUndoEndRow, aFilteredMark, false );
1098 :
1099 : // Test auf Zellschutz
1100 :
1101 16 : ScEditableTester aTester( pDoc, nStartTab, nStartCol,nStartRow, nUndoEndCol,nUndoEndRow );
1102 16 : if (!aTester.IsEditable())
1103 : {
1104 0 : ErrorMessage(aTester.GetMessageId());
1105 0 : return false;
1106 : }
1107 :
1108 : //! Test auf Ueberlappung
1109 : //! nur wirkliche Schnittmenge testen !!!!!!!
1110 :
1111 16 : ScDocFunc& rDocFunc = pDocSh->GetDocFunc();
1112 16 : if ( bRecord )
1113 : {
1114 16 : String aUndo = ScGlobal::GetRscString( pClipDoc->IsCutMode() ? STR_UNDO_MOVE : STR_UNDO_COPY );
1115 16 : pUndoMgr->EnterListAction( aUndo, aUndo );
1116 : }
1117 :
1118 16 : if (bClipOver)
1119 0 : if (lcl_SelHasAttrib( pDoc, nStartCol,nStartRow, nUndoEndCol,nUndoEndRow, aFilteredMark, HASATTR_OVERLAPPED ))
1120 : { // "Cell merge not possible if cells already merged"
1121 0 : ScDocAttrIterator aIter( pDoc, nStartTab, nStartCol, nStartRow, nUndoEndCol, nUndoEndRow );
1122 0 : const ScPatternAttr* pPattern = NULL;
1123 0 : const ScMergeAttr* pMergeFlag = NULL;
1124 0 : const ScMergeFlagAttr* pMergeFlagAttr = NULL;
1125 0 : SCCOL nCol = -1;
1126 0 : SCROW nRow1 = -1;
1127 0 : SCROW nRow2 = -1;
1128 0 : while ( ( pPattern = aIter.GetNext( nCol, nRow1, nRow2 ) ) != NULL )
1129 : {
1130 0 : pMergeFlag = (const ScMergeAttr*) &pPattern->GetItem(ATTR_MERGE);
1131 0 : pMergeFlagAttr = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
1132 0 : if( ( pMergeFlag && pMergeFlag->IsMerged() ) || ( pMergeFlagAttr && pMergeFlagAttr->IsOverlapped() ) )
1133 : {
1134 0 : ScRange aRange(nCol, nRow1, nStartTab);
1135 0 : pDoc->ExtendOverlapped(aRange);
1136 0 : pDoc->ExtendMerge(aRange, true);
1137 0 : rDocFunc.UnmergeCells(aRange, bRecord);
1138 : }
1139 0 : }
1140 : }
1141 :
1142 16 : if ( !bCutMode )
1143 : {
1144 16 : ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1145 16 : if ( pChangeTrack )
1146 0 : pChangeTrack->ResetLastCut(); // kein CutMode mehr
1147 : }
1148 :
1149 16 : bool bColInfo = ( nStartRow==0 && nEndRow==MAXROW );
1150 16 : bool bRowInfo = ( nStartCol==0 && nEndCol==MAXCOL );
1151 :
1152 16 : ScDocument* pUndoDoc = NULL;
1153 16 : ScDocument* pRefUndoDoc = NULL;
1154 16 : ScRefUndoData* pUndoData = NULL;
1155 :
1156 16 : if ( bRecord )
1157 : {
1158 16 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1159 16 : pUndoDoc->InitUndoSelected( pDoc, aFilteredMark, bColInfo, bRowInfo );
1160 :
1161 : // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
1162 16 : SCTAB nTabCount = pDoc->GetTableCount();
1163 : pDoc->CopyToDocument( nStartCol, nStartRow, 0, nUndoEndCol, nUndoEndRow, nTabCount-1,
1164 16 : nUndoFlags, false, pUndoDoc );
1165 :
1166 16 : if ( bCutMode )
1167 : {
1168 0 : pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1169 0 : pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, false, false );
1170 :
1171 0 : pUndoData = new ScRefUndoData( pDoc );
1172 : }
1173 : }
1174 :
1175 16 : sal_uInt16 nExtFlags = 0;
1176 : pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab,
1177 16 : nEndCol, nEndRow, nEndTab ); // content before the change
1178 :
1179 16 : if (GetViewData()->IsActive())
1180 : {
1181 16 : DoneBlockMode();
1182 16 : InitOwnBlockMode();
1183 : }
1184 16 : rMark.SetMarkArea( aUserRange );
1185 16 : MarkDataChanged();
1186 :
1187 : //
1188 : // Aus Clipboard kopieren,
1189 : // wenn gerechnet werden soll, Originaldaten merken
1190 : //
1191 :
1192 16 : ScDocument* pMixDoc = NULL;
1193 16 : if ( bSkipEmpty || nFunction )
1194 : {
1195 0 : if ( nFlags & IDF_CONTENTS )
1196 : {
1197 0 : pMixDoc = new ScDocument( SCDOCMODE_UNDO );
1198 0 : pMixDoc->InitUndo( pDoc, nStartTab, nEndTab );
1199 : pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
1200 0 : IDF_CONTENTS, false, pMixDoc );
1201 : }
1202 : }
1203 :
1204 : /* Make draw layer and start drawing undo.
1205 : - Needed before AdjustBlockHeight to track moved drawing objects.
1206 : - Needed before pDoc->CopyFromClip to track inserted note caption objects.
1207 : */
1208 16 : if ( bPasteDraw )
1209 0 : pDocSh->MakeDrawLayer();
1210 16 : if ( bRecord )
1211 16 : pDoc->BeginDrawUndo();
1212 :
1213 16 : sal_uInt16 nNoObjFlags = nFlags & ~IDF_OBJECTS;
1214 16 : if (!bAsLink)
1215 : {
1216 : // copy normally (original range)
1217 : pDoc->CopyFromClip( aUserRange, aFilteredMark, nNoObjFlags,
1218 : pRefUndoDoc, pClipDoc, true, false, bIncludeFiltered,
1219 16 : bSkipEmpty, (bMarkIsFiltered ? &aRangeList : NULL) );
1220 :
1221 : // bei Transpose Referenzen per Hand anpassen
1222 16 : if ( bTranspose && bCutMode && (nFlags & IDF_CONTENTS) )
1223 0 : pDoc->UpdateTranspose( aUserRange.aStart, pOrigClipDoc, aFilteredMark, pRefUndoDoc );
1224 : }
1225 0 : else if (!bTranspose)
1226 : {
1227 : // copy with bAsLink=TRUE
1228 : pDoc->CopyFromClip( aUserRange, aFilteredMark, nNoObjFlags, pRefUndoDoc, pClipDoc,
1229 0 : true, true, bIncludeFiltered, bSkipEmpty );
1230 : }
1231 : else
1232 : {
1233 : // alle Inhalte kopieren (im TransClipDoc stehen nur Formeln)
1234 0 : pDoc->CopyFromClip( aUserRange, aFilteredMark, nContFlags, pRefUndoDoc, pClipDoc );
1235 : }
1236 :
1237 : // skipped rows and merged cells don't mix
1238 16 : if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
1239 0 : rDocFunc.UnmergeCells( aUserRange, false );
1240 :
1241 16 : pDoc->ExtendMergeSel( nStartCol, nStartRow, nEndCol, nEndRow, aFilteredMark, true ); // Refresh
1242 : // und Bereich neu
1243 :
1244 16 : if ( pMixDoc ) // Rechenfunktionen mit Original-Daten auszufuehren ?
1245 : {
1246 0 : pDoc->MixDocument( aUserRange, nFunction, bSkipEmpty, pMixDoc );
1247 : }
1248 16 : delete pMixDoc;
1249 :
1250 16 : AdjustBlockHeight(); // update row heights before pasting objects
1251 :
1252 32 : ::std::vector< OUString > aExcludedChartNames;
1253 16 : SdrPage* pPage = NULL;
1254 :
1255 16 : if ( nFlags & IDF_OBJECTS )
1256 : {
1257 16 : ScDrawView* pScDrawView = GetScDrawView();
1258 16 : SdrModel* pModel = ( pScDrawView ? pScDrawView->GetModel() : NULL );
1259 16 : pPage = ( pModel ? pModel->GetPage( static_cast< sal_uInt16 >( nStartTab ) ) : NULL );
1260 16 : if ( pPage )
1261 : {
1262 16 : ScChartHelper::GetChartNames( aExcludedChartNames, pPage );
1263 : }
1264 :
1265 : // Paste the drawing objects after the row heights have been updated.
1266 :
1267 : pDoc->CopyFromClip( aUserRange, aFilteredMark, IDF_OBJECTS, pRefUndoDoc, pClipDoc,
1268 16 : true, false, bIncludeFiltered );
1269 : }
1270 :
1271 :
1272 : pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab,
1273 16 : nEndCol, nEndRow, nEndTab ); // content after the change
1274 :
1275 :
1276 : // ggf. Autofilter-Koepfe loeschen
1277 16 : if (bCutMode)
1278 0 : if (pDoc->RefreshAutoFilter( nClipStartX,nClipStartY, nClipStartX+nClipSizeX,
1279 0 : nClipStartY+nClipSizeY, nStartTab ))
1280 : {
1281 : pDocSh->PostPaint(
1282 : ScRange(nClipStartX, nClipStartY, nStartTab, nClipStartX+nClipSizeX, nClipStartY, nStartTab),
1283 0 : PAINT_GRID );
1284 : }
1285 :
1286 : //! Block-Bereich bei RefUndoDoc weglassen !!!
1287 :
1288 16 : if ( bRecord )
1289 : {
1290 16 : ScDocument* pRedoDoc = NULL;
1291 : // Redo-Daten werden erst beim ersten Undo kopiert
1292 : // ohne RefUndoDoc muss das Redo-Doc noch nicht angelegt werden
1293 :
1294 16 : if (pRefUndoDoc)
1295 : {
1296 0 : pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
1297 0 : pRedoDoc->InitUndo( pDoc, nStartTab, nEndTab, bColInfo, bRowInfo );
1298 :
1299 : // angepasste Referenzen ins Redo-Doc
1300 :
1301 0 : SCTAB nTabCount = pDoc->GetTableCount();
1302 0 : pRedoDoc->AddUndoTab( 0, nTabCount-1 );
1303 0 : pDoc->CopyUpdated( pRefUndoDoc, pRedoDoc );
1304 :
1305 : // alte Referenzen ins Undo-Doc
1306 :
1307 : //! Tabellen selektieren ?
1308 0 : pUndoDoc->AddUndoTab( 0, nTabCount-1 );
1309 0 : pRefUndoDoc->DeleteArea( nStartCol, nStartRow, nEndCol, nEndRow, aFilteredMark, IDF_ALL );
1310 : pRefUndoDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1,
1311 0 : IDF_FORMULA, false, pUndoDoc );
1312 0 : delete pRefUndoDoc;
1313 : }
1314 :
1315 : // DeleteUnchanged for pUndoData is in ScUndoPaste ctor,
1316 : // UndoData for redo is made during first undo
1317 :
1318 16 : ScUndoPasteOptions aOptions; // store options for repeat
1319 16 : aOptions.nFunction = nFunction;
1320 16 : aOptions.bSkipEmpty = bSkipEmpty;
1321 16 : aOptions.bTranspose = bTranspose;
1322 16 : aOptions.bAsLink = bAsLink;
1323 16 : aOptions.eMoveMode = eMoveMode;
1324 :
1325 : SfxUndoAction* pUndo = new ScUndoPaste(
1326 : pDocSh, ScRange(nStartCol, nStartRow, nStartTab, nUndoEndCol, nUndoEndRow, nEndTab),
1327 : aFilteredMark, pUndoDoc, pRedoDoc, nFlags | nUndoFlags, pUndoData,
1328 16 : false, &aOptions ); // false = Redo data not yet copied
1329 :
1330 16 : if ( bInsertCells )
1331 : {
1332 : // Merge the paste undo action into the insert action.
1333 : // Use ScUndoWrapper so the ScUndoPaste pointer can be stored in the insert action.
1334 :
1335 0 : pUndoMgr->AddUndoAction( new ScUndoWrapper( pUndo ), true );
1336 : }
1337 : else
1338 16 : pUndoMgr->AddUndoAction( pUndo );
1339 16 : pUndoMgr->LeaveListAction();
1340 : }
1341 :
1342 16 : sal_uInt16 nPaint = PAINT_GRID;
1343 16 : if (bColInfo)
1344 : {
1345 0 : nPaint |= PAINT_TOP;
1346 0 : nUndoEndCol = MAXCOL; // nur zum Zeichnen !
1347 : }
1348 16 : if (bRowInfo)
1349 : {
1350 0 : nPaint |= PAINT_LEFT;
1351 0 : nUndoEndRow = MAXROW; // nur zum Zeichnen !
1352 : }
1353 : pDocSh->PostPaint(
1354 : ScRange(nStartCol, nStartRow, nStartTab, nUndoEndCol, nUndoEndRow, nEndTab),
1355 16 : nPaint, nExtFlags);
1356 : // AdjustBlockHeight has already been called above
1357 :
1358 16 : aModificator.SetDocumentModified();
1359 16 : PostPasteFromClip(aUserRange, rMark);
1360 :
1361 16 : if ( nFlags & IDF_OBJECTS )
1362 : {
1363 16 : ScModelObj* pModelObj = ( pDocSh ? ScModelObj::getImplementation( pDocSh->GetModel() ) : NULL );
1364 16 : if ( pDoc && pPage && pModelObj )
1365 : {
1366 16 : bool bSameDoc = ( rClipParam.getSourceDocID() == pDoc->GetDocumentID() );
1367 16 : const ScRangeListVector& rProtectedChartRangesVector( rClipParam.maProtectedChartRangesVector );
1368 : ScChartHelper::CreateProtectedChartListenersAndNotify( pDoc, pPage, pModelObj, nStartTab,
1369 16 : rProtectedChartRangesVector, aExcludedChartNames, bSameDoc );
1370 : }
1371 : }
1372 :
1373 32 : return true;
1374 : }
1375 :
1376 0 : bool ScViewFunc::PasteMultiRangesFromClip(
1377 : sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction,
1378 : bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
1379 : InsCellCmd eMoveMode, sal_uInt16 nUndoFlags)
1380 : {
1381 0 : ScViewData& rViewData = *GetViewData();
1382 0 : ScDocument* pDoc = rViewData.GetDocument();
1383 0 : ScDocShell* pDocSh = rViewData.GetDocShell();
1384 0 : ScMarkData aMark(rViewData.GetMarkData());
1385 0 : const ScAddress& rCurPos = rViewData.GetCurPos();
1386 0 : ScClipParam& rClipParam = pClipDoc->GetClipParam();
1387 0 : SCCOL nColSize = rClipParam.getPasteColSize();
1388 0 : SCROW nRowSize = rClipParam.getPasteRowSize();
1389 :
1390 0 : if (bTranspose)
1391 : {
1392 0 : if (static_cast<SCROW>(rCurPos.Col()) + nRowSize-1 > static_cast<SCROW>(MAXCOL))
1393 : {
1394 0 : ErrorMessage(STR_PASTE_FULL);
1395 0 : return false;
1396 : }
1397 :
1398 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1399 0 : ::std::auto_ptr<ScDocument> pTransClip(new ScDocument(SCDOCMODE_CLIP));
1400 : SAL_WNODEPRECATED_DECLARATIONS_POP
1401 0 : pClipDoc->TransposeClip(pTransClip.get(), nFlags, bAsLink);
1402 0 : pClipDoc = pTransClip.release();
1403 0 : SCCOL nTempColSize = nColSize;
1404 0 : nColSize = static_cast<SCCOL>(nRowSize);
1405 0 : nRowSize = static_cast<SCROW>(nTempColSize);
1406 : }
1407 :
1408 0 : if (!ValidCol(rCurPos.Col()+nColSize-1) || !ValidRow(rCurPos.Row()+nRowSize-1))
1409 : {
1410 0 : ErrorMessage(STR_PASTE_FULL);
1411 0 : return false;
1412 : }
1413 :
1414 : // Determine the first and last selected sheet numbers.
1415 0 : SCTAB nTab1 = aMark.GetFirstSelected();
1416 0 : SCTAB nTab2 = aMark.GetLastSelected();
1417 :
1418 0 : ScDocShellModificator aModificator(*pDocSh);
1419 :
1420 : // For multi-selection paste, we don't support cell duplication for larger
1421 : // destination range. In case the destination is marked, we reset it to
1422 : // the clip size.
1423 0 : ScRange aMarkedRange(rCurPos.Col(), rCurPos.Row(), nTab1,
1424 0 : rCurPos.Col()+nColSize-1, rCurPos.Row()+nRowSize-1, nTab2);
1425 :
1426 : // Extend the marked range to account for filtered rows in the destination
1427 : // area.
1428 0 : if (ScViewUtil::HasFiltered(aMarkedRange, pDoc))
1429 : {
1430 0 : if (!ScViewUtil::FitToUnfilteredRows(aMarkedRange, pDoc, nRowSize))
1431 0 : return false;
1432 : }
1433 :
1434 : bool bAskIfNotEmpty =
1435 0 : bAllowDialogs && (nFlags & IDF_CONTENTS) &&
1436 0 : nFunction == PASTE_NOFUNC && SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1437 :
1438 0 : if (bAskIfNotEmpty)
1439 : {
1440 0 : ScRangeList aTestRanges;
1441 0 : aTestRanges.Append(aMarkedRange);
1442 0 : if (!checkDestRangeForOverwrite(aTestRanges, pDoc, aMark, rViewData.GetDialogParent()))
1443 0 : return false;
1444 : }
1445 :
1446 0 : aMark.SetMarkArea(aMarkedRange);
1447 0 : MarkRange(aMarkedRange);
1448 :
1449 0 : bool bInsertCells = (eMoveMode != INS_NONE);
1450 0 : if (bInsertCells)
1451 : {
1452 0 : if (!InsertCells(eMoveMode, pDoc->IsUndoEnabled(), true))
1453 0 : return false;
1454 : }
1455 :
1456 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1457 0 : ::std::auto_ptr<ScDocument> pUndoDoc;
1458 : SAL_WNODEPRECATED_DECLARATIONS_POP
1459 0 : if (pDoc->IsUndoEnabled())
1460 : {
1461 0 : pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1462 0 : pUndoDoc->InitUndoSelected(pDoc, aMark, false, false);
1463 0 : pDoc->CopyToDocument(aMarkedRange, nUndoFlags, false, pUndoDoc.get(), &aMark, true);
1464 : }
1465 :
1466 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1467 0 : ::std::auto_ptr<ScDocument> pMixDoc;
1468 : SAL_WNODEPRECATED_DECLARATIONS_POP
1469 0 : if ( bSkipEmpty || nFunction )
1470 : {
1471 0 : if ( nFlags & IDF_CONTENTS )
1472 : {
1473 0 : pMixDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1474 0 : pMixDoc->InitUndoSelected(pDoc, aMark, false, false);
1475 0 : pDoc->CopyToDocument(aMarkedRange, IDF_CONTENTS, false, pMixDoc.get(), &aMark, true);
1476 : }
1477 : }
1478 :
1479 : /* Make draw layer and start drawing undo.
1480 : - Needed before AdjustBlockHeight to track moved drawing objects.
1481 : - Needed before pDoc->CopyFromClip to track inserted note caption objects.
1482 : */
1483 0 : if (nFlags & IDF_OBJECTS)
1484 0 : pDocSh->MakeDrawLayer();
1485 0 : if (pDoc->IsUndoEnabled())
1486 0 : pDoc->BeginDrawUndo();
1487 :
1488 0 : sal_uInt16 nNoObjFlags = nFlags & ~IDF_OBJECTS;
1489 : pDoc->CopyMultiRangeFromClip(rCurPos, aMark, nNoObjFlags, pClipDoc,
1490 0 : true, bAsLink, false, bSkipEmpty);
1491 :
1492 0 : if (pMixDoc.get())
1493 0 : pDoc->MixDocument(aMarkedRange, nFunction, bSkipEmpty, pMixDoc.get());
1494 :
1495 0 : AdjustBlockHeight(); // update row heights before pasting objects
1496 :
1497 0 : if (nFlags & IDF_OBJECTS)
1498 : {
1499 : // Paste the drawing objects after the row heights have been updated.
1500 : pDoc->CopyMultiRangeFromClip(rCurPos, aMark, IDF_OBJECTS, pClipDoc,
1501 0 : true, false, false, true);
1502 : }
1503 :
1504 0 : ScRange aTmp = aMarkedRange;
1505 0 : aTmp.aStart.SetTab(nTab1);
1506 0 : aTmp.aEnd.SetTab(nTab1);
1507 0 : pDocSh->PostPaint(aTmp, PAINT_GRID);
1508 :
1509 0 : if (pDoc->IsUndoEnabled())
1510 : {
1511 0 : ::svl::IUndoManager* pUndoMgr = pDocSh->GetUndoManager();
1512 : String aUndo = ScGlobal::GetRscString(
1513 0 : pClipDoc->IsCutMode() ? STR_UNDO_CUT : STR_UNDO_COPY);
1514 0 : pUndoMgr->EnterListAction(aUndo, aUndo);
1515 :
1516 0 : ScUndoPasteOptions aOptions; // store options for repeat
1517 0 : aOptions.nFunction = nFunction;
1518 0 : aOptions.bSkipEmpty = bSkipEmpty;
1519 0 : aOptions.bTranspose = bTranspose;
1520 0 : aOptions.bAsLink = bAsLink;
1521 0 : aOptions.eMoveMode = eMoveMode;
1522 :
1523 : ScUndoPaste* pUndo = new ScUndoPaste(pDocSh,
1524 0 : aMarkedRange, aMark, pUndoDoc.release(), NULL, nFlags|nUndoFlags, NULL, false, &aOptions);
1525 :
1526 0 : if (bInsertCells)
1527 0 : pUndoMgr->AddUndoAction(new ScUndoWrapper(pUndo), true);
1528 : else
1529 0 : pUndoMgr->AddUndoAction(pUndo, false);
1530 :
1531 0 : pUndoMgr->LeaveListAction();
1532 : }
1533 0 : aModificator.SetDocumentModified();
1534 0 : PostPasteFromClip(aMarkedRange, aMark);
1535 0 : return true;
1536 : }
1537 :
1538 0 : bool ScViewFunc::PasteFromClipToMultiRanges(
1539 : sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction,
1540 : bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
1541 : InsCellCmd eMoveMode, sal_uInt16 nUndoFlags )
1542 : {
1543 0 : if (bTranspose)
1544 : {
1545 : // We don't allow transpose for this yet.
1546 0 : ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1547 0 : return false;
1548 : }
1549 :
1550 0 : if (eMoveMode != INS_NONE)
1551 : {
1552 : // We don't allow insertion mode either. Too complicated.
1553 0 : ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1554 0 : return false;
1555 : }
1556 :
1557 0 : ScViewData& rViewData = *GetViewData();
1558 0 : ScClipParam& rClipParam = pClipDoc->GetClipParam();
1559 0 : if (rClipParam.mbCutMode)
1560 : {
1561 : // No cut and paste with this, please.
1562 0 : ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1563 0 : return false;
1564 : }
1565 :
1566 0 : const ScAddress& rCurPos = rViewData.GetCurPos();
1567 0 : ScDocument* pDoc = rViewData.GetDocument();
1568 :
1569 0 : ScRange aSrcRange = rClipParam.getWholeRange();
1570 0 : SCROW nRowSize = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1;
1571 0 : SCCOL nColSize = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1;
1572 :
1573 0 : if (!ValidCol(rCurPos.Col()+nColSize-1) || !ValidRow(rCurPos.Row()+nRowSize-1))
1574 : {
1575 0 : ErrorMessage(STR_PASTE_FULL);
1576 0 : return false;
1577 : }
1578 :
1579 0 : ScMarkData aMark(rViewData.GetMarkData());
1580 :
1581 0 : ScRangeList aRanges;
1582 0 : aMark.MarkToSimple();
1583 0 : aMark.FillRangeListWithMarks(&aRanges, false);
1584 0 : if (!ScClipUtil::CheckDestRanges(pDoc, nColSize, nRowSize, aMark, aRanges))
1585 : {
1586 0 : ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
1587 0 : return false;
1588 : }
1589 :
1590 0 : ScDocShell* pDocSh = rViewData.GetDocShell();
1591 :
1592 0 : ScDocShellModificator aModificator(*pDocSh);
1593 :
1594 : bool bAskIfNotEmpty =
1595 0 : bAllowDialogs && (nFlags & IDF_CONTENTS) &&
1596 0 : nFunction == PASTE_NOFUNC && SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
1597 :
1598 0 : if (bAskIfNotEmpty)
1599 : {
1600 0 : if (!checkDestRangeForOverwrite(aRanges, pDoc, aMark, rViewData.GetDialogParent()))
1601 0 : return false;
1602 : }
1603 :
1604 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1605 0 : std::auto_ptr<ScDocument> pUndoDoc;
1606 : SAL_WNODEPRECATED_DECLARATIONS_POP
1607 0 : if (pDoc->IsUndoEnabled())
1608 : {
1609 0 : pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1610 0 : pUndoDoc->InitUndoSelected(pDoc, aMark, false, false);
1611 0 : for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1612 : {
1613 : pDoc->CopyToDocument(
1614 0 : *aRanges[i], nUndoFlags, false, pUndoDoc.get(), &aMark, true);
1615 : }
1616 : }
1617 :
1618 0 : boost::scoped_ptr<ScDocument> pMixDoc;
1619 0 : if (bSkipEmpty || nFunction)
1620 : {
1621 0 : if (nFlags & IDF_CONTENTS)
1622 : {
1623 0 : pMixDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1624 0 : pMixDoc->InitUndoSelected(pDoc, aMark, false, false);
1625 0 : for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1626 : {
1627 : pDoc->CopyToDocument(
1628 0 : *aRanges[i], IDF_CONTENTS, false, pMixDoc.get(), &aMark, true);
1629 : }
1630 : }
1631 : }
1632 :
1633 0 : if (nFlags & IDF_OBJECTS)
1634 0 : pDocSh->MakeDrawLayer();
1635 0 : if (pDoc->IsUndoEnabled())
1636 0 : pDoc->BeginDrawUndo();
1637 :
1638 : // First, paste everything but the drawing objects.
1639 0 : for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1640 : {
1641 : pDoc->CopyFromClip(
1642 0 : *aRanges[i], aMark, (nFlags & ~IDF_OBJECTS), NULL, pClipDoc,
1643 0 : false, false, true, bSkipEmpty, NULL);
1644 : }
1645 :
1646 0 : if (pMixDoc.get())
1647 : {
1648 0 : for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1649 0 : pDoc->MixDocument(*aRanges[i], nFunction, bSkipEmpty, pMixDoc.get());
1650 : }
1651 :
1652 0 : AdjustBlockHeight(); // update row heights before pasting objects
1653 :
1654 : // Then paste the objects.
1655 0 : if (nFlags & IDF_OBJECTS)
1656 : {
1657 0 : for (size_t i = 0, n = aRanges.size(); i < n; ++i)
1658 : {
1659 : pDoc->CopyFromClip(
1660 0 : *aRanges[i], aMark, IDF_OBJECTS, NULL, pClipDoc,
1661 0 : false, false, true, bSkipEmpty, NULL);
1662 : }
1663 : }
1664 :
1665 : // Refresh the range that includes all pasted ranges. We only need to
1666 : // refresh the current sheet.
1667 0 : pDocSh->PostPaint(aRanges, PAINT_GRID);
1668 :
1669 0 : if (pDoc->IsUndoEnabled())
1670 : {
1671 0 : svl::IUndoManager* pUndoMgr = pDocSh->GetUndoManager();
1672 : String aUndo = ScGlobal::GetRscString(
1673 0 : pClipDoc->IsCutMode() ? STR_UNDO_CUT : STR_UNDO_COPY);
1674 0 : pUndoMgr->EnterListAction(aUndo, aUndo);
1675 :
1676 0 : ScUndoPasteOptions aOptions; // store options for repeat
1677 0 : aOptions.nFunction = nFunction;
1678 0 : aOptions.bSkipEmpty = bSkipEmpty;
1679 0 : aOptions.bTranspose = bTranspose;
1680 0 : aOptions.bAsLink = bAsLink;
1681 0 : aOptions.eMoveMode = eMoveMode;
1682 :
1683 : ScUndoPaste* pUndo = new ScUndoPaste(
1684 0 : pDocSh, aRanges, aMark, pUndoDoc.release(), NULL, nFlags|nUndoFlags, NULL, false, &aOptions);
1685 :
1686 0 : pUndoMgr->AddUndoAction(pUndo, false);
1687 0 : pUndoMgr->LeaveListAction();
1688 : }
1689 0 : aModificator.SetDocumentModified();
1690 0 : PostPasteFromClip(aRanges, aMark);
1691 :
1692 0 : return false;
1693 : }
1694 :
1695 16 : void ScViewFunc::PostPasteFromClip(const ScRangeList& rPasteRanges, const ScMarkData& rMark)
1696 : {
1697 16 : ScViewData* pViewData = GetViewData();
1698 16 : ScDocShell* pDocSh = pViewData->GetDocShell();
1699 16 : pDocSh->UpdateOle(pViewData);
1700 :
1701 16 : SelectionChanged();
1702 :
1703 : // #i97876# Spreadsheet data changes are not notified
1704 16 : ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
1705 16 : if (!pModelObj || !pModelObj->HasChangesListeners())
1706 32 : return;
1707 :
1708 0 : ScRangeList aChangeRanges;
1709 0 : for (size_t i = 0, n = rPasteRanges.size(); i < n; ++i)
1710 : {
1711 0 : const ScRange& r = *rPasteRanges[i];
1712 0 : ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
1713 0 : for (; itr != itrEnd; ++itr)
1714 : {
1715 0 : ScRange aChangeRange(r);
1716 0 : aChangeRange.aStart.SetTab(*itr);
1717 0 : aChangeRange.aEnd.SetTab(*itr);
1718 0 : aChangeRanges.Append(aChangeRange);
1719 : }
1720 : }
1721 0 : pModelObj->NotifyChanges( OUString( "cell-change" ), aChangeRanges );
1722 : }
1723 :
1724 :
1725 : //----------------------------------------------------------------------------
1726 : // D R A G A N D D R O P
1727 : //
1728 : // innerhalb des Dokuments
1729 :
1730 0 : sal_Bool ScViewFunc::MoveBlockTo( const ScRange& rSource, const ScAddress& rDestPos,
1731 : sal_Bool bCut, sal_Bool bRecord, sal_Bool bPaint, sal_Bool bApi )
1732 : {
1733 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1734 0 : HideAllCursors(); // wegen zusammengefassten
1735 :
1736 0 : sal_Bool bSuccess = sal_True;
1737 0 : SCTAB nDestTab = rDestPos.Tab();
1738 0 : const ScMarkData& rMark = GetViewData()->GetMarkData();
1739 0 : if ( rSource.aStart.Tab() == nDestTab && rSource.aEnd.Tab() == nDestTab && rMark.GetSelectCount() > 1 )
1740 : {
1741 : // moving within one table and several tables selected -> apply to all selected tables
1742 :
1743 0 : if ( bRecord )
1744 : {
1745 0 : String aUndo = ScGlobal::GetRscString( bCut ? STR_UNDO_MOVE : STR_UNDO_COPY );
1746 0 : pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
1747 : }
1748 :
1749 : // collect ranges of consecutive selected tables
1750 :
1751 0 : ScRange aLocalSource = rSource;
1752 0 : ScAddress aLocalDest = rDestPos;
1753 0 : SCTAB nTabCount = pDocSh->GetDocument()->GetTableCount();
1754 0 : SCTAB nStartTab = 0;
1755 0 : while ( nStartTab < nTabCount && bSuccess )
1756 : {
1757 0 : while ( nStartTab < nTabCount && !rMark.GetTableSelect(nStartTab) )
1758 0 : ++nStartTab;
1759 0 : if ( nStartTab < nTabCount )
1760 : {
1761 0 : SCTAB nEndTab = nStartTab;
1762 0 : while ( nEndTab+1 < nTabCount && rMark.GetTableSelect(nEndTab+1) )
1763 0 : ++nEndTab;
1764 :
1765 0 : aLocalSource.aStart.SetTab( nStartTab );
1766 0 : aLocalSource.aEnd.SetTab( nEndTab );
1767 0 : aLocalDest.SetTab( nStartTab );
1768 :
1769 0 : bSuccess = pDocSh->GetDocFunc().MoveBlock(
1770 0 : aLocalSource, aLocalDest, bCut, bRecord, bPaint, bApi );
1771 :
1772 0 : nStartTab = nEndTab + 1;
1773 : }
1774 : }
1775 :
1776 0 : if ( bRecord )
1777 0 : pDocSh->GetUndoManager()->LeaveListAction();
1778 : }
1779 : else
1780 : {
1781 : // move the block as specified
1782 0 : bSuccess = pDocSh->GetDocFunc().MoveBlock(
1783 0 : rSource, rDestPos, bCut, bRecord, bPaint, bApi );
1784 : }
1785 :
1786 0 : ShowAllCursors();
1787 0 : if (bSuccess)
1788 : {
1789 : // Zielbereich markieren
1790 : ScAddress aDestEnd(
1791 0 : rDestPos.Col() + rSource.aEnd.Col() - rSource.aStart.Col(),
1792 0 : rDestPos.Row() + rSource.aEnd.Row() - rSource.aStart.Row(),
1793 0 : nDestTab );
1794 :
1795 0 : sal_Bool bIncludeFiltered = bCut;
1796 0 : if ( !bIncludeFiltered )
1797 : {
1798 : // find number of non-filtered rows
1799 : SCROW nPastedCount = pDocSh->GetDocument()->CountNonFilteredRows(
1800 0 : rSource.aStart.Row(), rSource.aEnd.Row(), rSource.aStart.Tab());
1801 :
1802 0 : if ( nPastedCount == 0 )
1803 0 : nPastedCount = 1;
1804 0 : aDestEnd.SetRow( rDestPos.Row() + nPastedCount - 1 );
1805 : }
1806 :
1807 0 : MarkRange( ScRange( rDestPos, aDestEnd ), false ); //! sal_False ???
1808 :
1809 0 : pDocSh->UpdateOle(GetViewData());
1810 0 : SelectionChanged();
1811 : }
1812 0 : return bSuccess;
1813 : }
1814 :
1815 : // Link innerhalb des Dokuments
1816 :
1817 0 : sal_Bool ScViewFunc::LinkBlock( const ScRange& rSource, const ScAddress& rDestPos, sal_Bool bApi )
1818 : {
1819 : // Test auf Ueberlappung
1820 :
1821 0 : if ( rSource.aStart.Tab() == rDestPos.Tab() )
1822 : {
1823 0 : SCCOL nDestEndCol = rDestPos.Col() + ( rSource.aEnd.Col() - rSource.aStart.Col() );
1824 0 : SCROW nDestEndRow = rDestPos.Row() + ( rSource.aEnd.Row() - rSource.aStart.Row() );
1825 :
1826 0 : if ( rSource.aStart.Col() <= nDestEndCol && rDestPos.Col() <= rSource.aEnd.Col() &&
1827 0 : rSource.aStart.Row() <= nDestEndRow && rDestPos.Row() <= rSource.aEnd.Row() )
1828 : {
1829 0 : if (!bApi)
1830 0 : ErrorMessage( STR_ERR_LINKOVERLAP );
1831 0 : return false;
1832 : }
1833 : }
1834 :
1835 : // Ausfuehren per Paste
1836 :
1837 0 : ScDocument* pDoc = GetViewData()->GetDocument();
1838 0 : ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
1839 0 : pDoc->CopyTabToClip( rSource.aStart.Col(), rSource.aStart.Row(),
1840 0 : rSource.aEnd.Col(), rSource.aEnd.Row(),
1841 0 : rSource.aStart.Tab(), pClipDoc );
1842 :
1843 : // Zielbereich markieren (Cursor setzen, keine Markierung)
1844 :
1845 0 : if ( GetViewData()->GetTabNo() != rDestPos.Tab() )
1846 0 : SetTabNo( rDestPos.Tab() );
1847 :
1848 0 : MoveCursorAbs( rDestPos.Col(), rDestPos.Row(), SC_FOLLOW_NONE, false, false );
1849 :
1850 : // Paste
1851 :
1852 0 : PasteFromClip( IDF_ALL, pClipDoc, PASTE_NOFUNC, false, false, sal_True ); // als Link
1853 :
1854 0 : delete pClipDoc;
1855 :
1856 0 : return sal_True;
1857 : }
1858 :
1859 0 : void ScViewFunc::DataFormPutData( SCROW nCurrentRow ,
1860 : SCROW nStartRow , SCCOL nStartCol ,
1861 : SCROW nEndRow , SCCOL nEndCol ,
1862 : boost::ptr_vector<boost::nullable<Edit> >& aEdits,
1863 : sal_uInt16 aColLength )
1864 : {
1865 0 : ScDocument* pDoc = GetViewData()->GetDocument();
1866 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1867 0 : ScMarkData& rMark = GetViewData()->GetMarkData();
1868 0 : ScDocShellModificator aModificator( *pDocSh );
1869 0 : ::svl::IUndoManager* pUndoMgr = pDocSh->GetUndoManager();
1870 0 : if ( pDoc )
1871 : {
1872 0 : const sal_Bool bRecord( pDoc->IsUndoEnabled());
1873 0 : ScDocument* pUndoDoc = NULL;
1874 0 : ScDocument* pRedoDoc = NULL;
1875 0 : ScRefUndoData* pUndoData = NULL;
1876 0 : SCTAB nTab = GetViewData()->GetTabNo();
1877 0 : SCTAB nStartTab = nTab;
1878 0 : SCTAB nEndTab = nTab;
1879 :
1880 : {
1881 0 : ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1882 0 : if ( pChangeTrack )
1883 0 : pChangeTrack->ResetLastCut(); // kein CutMode mehr
1884 : }
1885 0 : ScRange aUserRange( nStartCol, nCurrentRow, nStartTab, nEndCol, nCurrentRow, nEndTab );
1886 0 : sal_Bool bColInfo = ( nStartRow==0 && nEndRow==MAXROW );
1887 0 : sal_Bool bRowInfo = ( nStartCol==0 && nEndCol==MAXCOL );
1888 0 : SCCOL nUndoEndCol = nStartCol+aColLength-1;
1889 0 : SCROW nUndoEndRow = nCurrentRow;
1890 0 : sal_uInt16 nUndoFlags = IDF_NONE;
1891 :
1892 0 : if ( bRecord )
1893 : {
1894 0 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1895 0 : pUndoDoc->InitUndoSelected( pDoc , rMark , bColInfo , bRowInfo );
1896 0 : pDoc->CopyToDocument( aUserRange , 1 , false , pUndoDoc );
1897 : }
1898 0 : sal_uInt16 nExtFlags = 0;
1899 0 : pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab , nEndCol, nEndRow, nEndTab ); // content before the change
1900 0 : pDoc->BeginDrawUndo();
1901 :
1902 0 : for(sal_uInt16 i = 0; i < aColLength; i++)
1903 : {
1904 0 : if (!aEdits.is_null(i))
1905 : {
1906 0 : String aFieldName=aEdits[i].GetText();
1907 0 : pDoc->SetString( nStartCol + i, nCurrentRow, nTab, aFieldName );
1908 : }
1909 : }
1910 0 : pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nCurrentRow, nStartTab, nEndCol, nCurrentRow, nEndTab ); // content after the change
1911 : SfxUndoAction* pUndo = new ScUndoDataForm( pDocSh,
1912 : nStartCol, nCurrentRow, nStartTab,
1913 : nUndoEndCol, nUndoEndRow, nEndTab, rMark,
1914 : pUndoDoc, pRedoDoc, nUndoFlags,
1915 : pUndoData, NULL, NULL, NULL,
1916 0 : false ); // FALSE = Redo data not yet copied
1917 0 : pUndoMgr->AddUndoAction( new ScUndoWrapper( pUndo ), true );
1918 :
1919 0 : sal_uInt16 nPaint = PAINT_GRID;
1920 0 : if (bColInfo)
1921 : {
1922 0 : nPaint |= PAINT_TOP;
1923 0 : nUndoEndCol = MAXCOL; // nur zum Zeichnen !
1924 : }
1925 0 : if (bRowInfo)
1926 : {
1927 0 : nPaint |= PAINT_LEFT;
1928 0 : nUndoEndRow = MAXROW; // nur zum Zeichnen !
1929 : }
1930 :
1931 : pDocSh->PostPaint(
1932 : ScRange(nStartCol, nCurrentRow, nStartTab, nUndoEndCol, nUndoEndRow, nEndTab),
1933 0 : nPaint, nExtFlags);
1934 0 : pDocSh->UpdateOle(GetViewData());
1935 0 : }
1936 93 : }
1937 :
1938 :
1939 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|