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