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