2006/05/24 12:33:22 nn 1.31.174.1: #129384# keep a reference of clipboard object during PasteFromClip
1191 lines
40 KiB
C++
1191 lines
40 KiB
C++
/*************************************************************************
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* $RCSfile: viewfun3.cxx,v $
|
|
*
|
|
* $Revision: 1.32 $
|
|
*
|
|
* last change: $Author: obo $ $Date: 2006-07-10 14:11:39 $
|
|
*
|
|
* The Contents of this file are made available subject to
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
|
*
|
|
*
|
|
* GNU Lesser General Public License Version 2.1
|
|
* =============================================
|
|
* Copyright 2005 by Sun Microsystems, Inc.
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307 USA
|
|
*
|
|
************************************************************************/
|
|
|
|
#ifdef PCH
|
|
#include "ui_pch.hxx"
|
|
#endif
|
|
|
|
#pragma hdrstop
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
#define _SV_NOXSOUND
|
|
|
|
#ifdef WIN
|
|
#define _MENUBTN_HXX
|
|
#endif
|
|
|
|
#define _BASE_DLGS_HXX
|
|
#define _BIGINT_HXX
|
|
#define _CACHESTR_HXX
|
|
#define _CONFIG_HXX
|
|
#define _CURSOR_HXX
|
|
#define _CTRLTOOL_HXX
|
|
#define _DLGCFG_HXX
|
|
#define _DYNARR_HXX
|
|
#define _EXTATTR_HXX
|
|
#define _FILDLG_HXX
|
|
#define _FONTDLG_HXX
|
|
#define _FRM3D_HXX
|
|
#define _INTRO_HXX
|
|
#define _ISETBWR_HXX
|
|
#define _NO_SVRTF_PARSER_HXX
|
|
#define _MACRODLG_HXX
|
|
#define _MODALDLG_HXX
|
|
#define _MOREBUTTON_HXX
|
|
#define _OUTLINER_HXX
|
|
//#define _PRNDLG_HXX
|
|
//#define _POLY_HXX
|
|
#define _PVRWIN_HXX
|
|
//#define _QUEUE_HXX
|
|
#define _RULER_HXX
|
|
#define _SCRWIN_HXX
|
|
#define _SETBRW_HXX
|
|
//#define _STACK_HXX
|
|
//#define _STATUS_HXX ***
|
|
#define _STDCTRL_HXX
|
|
#define _STDMENU_HXX
|
|
//#define _TAB_HXX
|
|
#define _TABBAR_HXX
|
|
#define _TREELIST_HXX
|
|
#define _VALUESET_HXX
|
|
#define _VCATTR_HXX
|
|
#define _VCBRW_HXX
|
|
#define _VCTRLS_HXX
|
|
#define _VCSBX_HXX
|
|
#define _VCONT_HXX
|
|
#define _VDRWOBJ_HXX
|
|
|
|
//#define _SELENG_HXX
|
|
//#define _SOUND_HXX
|
|
//#define _SYSDLG_HXX
|
|
|
|
|
|
|
|
|
|
#define _PASSWD_HXX
|
|
|
|
#define _SFX_DOCFILE_HXX
|
|
//#define _SFX_DOCFILT_HXX
|
|
#define _SFX_DOCINF_HXX
|
|
#define _SFX_DOCSH_HXX
|
|
//#define _SFXDOCFILT_HXX
|
|
//#define _SFXDOCINF_HXX
|
|
//#define _SFXDOCSH_HXX
|
|
#define _SFX_PRNMON_HXX
|
|
#define _SFX_RESMGR_HXX
|
|
#define _SFX_TEMPLDLG_HXX
|
|
//#define _SFXAPPWIN_HXX
|
|
#define _SFXBASIC_HXX
|
|
#define _SFXCTRLITEM
|
|
#define _SFXDLGCFG_HXX
|
|
//#define _SFXDISPATCH_HXX
|
|
#define _SFXFILEDLG_HXX
|
|
//#define _SFXIMGMGR_HXX
|
|
#define _SFXIPFRM_HXX
|
|
#define _SFX_MACRO_HXX
|
|
#define _SFXMNUITEM_HXX
|
|
#define _SFXMNUMGR_HXX
|
|
#define _SFXMULTISEL_HXX
|
|
//#define _SFXMSG_HXX
|
|
#define _SFXMSGDESCR_HXX
|
|
#define _SFXMSGPOOL_HXX
|
|
#define _SFX_MINFITEM_HXX
|
|
#define _SFXOBJFACE_HXX
|
|
#define _SFXOBJFAC_HXX
|
|
#define _SFX_SAVEOPT_HXX
|
|
#define _SFXSTBITEM_HXX
|
|
#define _SFXSTBMGR_HXX
|
|
#define _SFXTBXCTRL_HXX
|
|
#define _SFXTBXMGR_HXX
|
|
|
|
#define _SI_HXX
|
|
//#define _SI_DLL_HXX
|
|
//#define _SIDLL_HXX
|
|
//#define _SI_NOITEMS
|
|
//#define _SI_NOOTHERFORMS
|
|
//#define _SI_NOSBXCONTROLS
|
|
//#define _SINOSBXCONTROLS
|
|
//#define _SI_NODRW
|
|
//#define _SI_NOCONTROL
|
|
|
|
#define _SVBOXITM_HXX
|
|
#define _SVCONTNR_HXX //
|
|
|
|
#define _SDR_NOTRANSFORM
|
|
|
|
#define _SVDRAG_HXX
|
|
#define _SVINCVW_HXX
|
|
#define _SV_MULTISEL_HXX
|
|
#define _SVRTV_HXX
|
|
#define _SVTABBX_HXX
|
|
#define _SVTREEBOX_HXX
|
|
#define _SVTREELIST_HXX
|
|
|
|
#define _SVX_DAILDLL_HXX
|
|
#define _SVX_HYPHEN_HXX
|
|
#define _SVX_IMPGRF_HXX
|
|
#define _SVX_LAYCTRL_HXX
|
|
#define _SVX_OPTITEMS_HXX
|
|
#define _SVX_OPTGERL_HXX
|
|
#define _SVX_OPTSAVE_HXX
|
|
#define _SVX_OPTSPELL_HXX
|
|
#define _SVX_OPTPATH_HXX
|
|
#define _SVX_OPTLINGU_HXX
|
|
#define _SVX_RULER_HXX
|
|
#define _SVX_RULRITEM_HXX
|
|
#define _SVX_SELCTRL_HXX
|
|
#define _SVX_SPLWRAP_HXX
|
|
#define _SVX_SPLDLG_HXX
|
|
#define _SVX_STDDLG_HXX
|
|
#define _SVX_THESDLG_HXX
|
|
|
|
// INCLUDE -------------------------------------------------------------------
|
|
|
|
#include "scitems.hxx"
|
|
#include <svx/dbexch.hrc>
|
|
#include <svx/svdetc.hxx>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <sfx2/docfile.hxx>
|
|
#include <svtools/stritem.hxx>
|
|
#include <svtools/ptitem.hxx>
|
|
#include <svtools/urlbmk.hxx>
|
|
#include <sot/clsids.hxx>
|
|
#include <sot/formats.hxx>
|
|
#include <vcl/graph.hxx>
|
|
#include <vcl/virdev.hxx>
|
|
#include <vcl/msgbox.hxx>
|
|
#include <tools/urlobj.hxx>
|
|
#ifndef _SOT_EXCHANGE_HXX
|
|
#include <sot/exchange.hxx>
|
|
#endif
|
|
|
|
#include "viewfunc.hxx"
|
|
#include "tabvwsh.hxx"
|
|
#include "docsh.hxx"
|
|
#include "docfunc.hxx"
|
|
#include "undoblk.hxx"
|
|
#include "refundo.hxx"
|
|
#include "globstr.hrc"
|
|
#include "global.hxx"
|
|
#include "transobj.hxx"
|
|
#include "drwtrans.hxx"
|
|
#include "rangenam.hxx"
|
|
#include "dbcolect.hxx"
|
|
#include "impex.hxx" // Sylk-ID fuer CB
|
|
#include "chgtrack.hxx"
|
|
#include "waitoff.hxx"
|
|
#include "scmod.hxx"
|
|
#include "sc.hrc"
|
|
#include "inputopt.hxx"
|
|
#include "warnbox.hxx"
|
|
#include "drwlayer.hxx"
|
|
#include "editable.hxx"
|
|
|
|
using namespace com::sun::star;
|
|
|
|
// STATIC DATA ---------------------------------------------------------------
|
|
|
|
|
|
//============================================================================
|
|
|
|
// GlobalName der Writer-DocShell kommt jetzt aus so3/clsids.hxx
|
|
|
|
//----------------------------------------------------------------------------
|
|
// C U T
|
|
|
|
void ScViewFunc::CutToClip( ScDocument* pClipDoc, BOOL bIncludeObjects )
|
|
{
|
|
UpdateInputLine();
|
|
|
|
ScEditableTester aTester( this );
|
|
if (!aTester.IsEditable()) // selection editable?
|
|
{
|
|
ErrorMessage( aTester.GetMessageId() );
|
|
return;
|
|
}
|
|
|
|
ScRange aRange; // zu loeschender Bereich
|
|
if ( GetViewData()->GetSimpleArea( aRange ) )
|
|
{
|
|
ScDocument* pDoc = GetViewData()->GetDocument();
|
|
ScDocShell* pDocSh = GetViewData()->GetDocShell();
|
|
ScMarkData& rMark = GetViewData()->GetMarkData();
|
|
const BOOL bRecord(pDoc->IsUndoEnabled()); // Undo/Redo
|
|
|
|
ScDocShellModificator aModificator( *pDocSh );
|
|
|
|
if ( !rMark.IsMarked() && !rMark.IsMultiMarked() ) // mark the range if not marked yet
|
|
{
|
|
DoneBlockMode();
|
|
InitOwnBlockMode();
|
|
rMark.SetMarkArea( aRange );
|
|
}
|
|
|
|
CopyToClip( pClipDoc, TRUE, FALSE, bIncludeObjects ); // Ab ins Clipboard
|
|
|
|
ScAddress aOldEnd( aRange.aEnd ); // Zusammengefasste Zellen im Bereich?
|
|
pDoc->ExtendMerge( aRange, TRUE );
|
|
|
|
ScDocument* pUndoDoc = NULL;
|
|
if ( bRecord )
|
|
{
|
|
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
|
|
pUndoDoc->InitUndoSelected( pDoc, rMark );
|
|
// all sheets - CopyToDocument skips those that don't exist in pUndoDoc
|
|
ScRange aCopyRange = aRange;
|
|
aCopyRange.aStart.SetTab(0);
|
|
aCopyRange.aEnd.SetTab(pDoc->GetTableCount()-1);
|
|
pDoc->CopyToDocument( aCopyRange, IDF_ALL, FALSE, pUndoDoc );
|
|
pDoc->BeginDrawUndo();
|
|
}
|
|
|
|
USHORT nExtFlags = 0;
|
|
pDocSh->UpdatePaintExt( nExtFlags, aRange );
|
|
|
|
HideCursor(); // Cursor aendert sich !
|
|
|
|
rMark.MarkToMulti();
|
|
pDoc->DeleteSelection( IDF_ALL, rMark );
|
|
if ( bIncludeObjects )
|
|
pDoc->DeleteObjectsInSelection( rMark );
|
|
rMark.MarkToSimple();
|
|
|
|
if ( !AdjustRowHeight( aRange.aStart.Row(), aRange.aEnd.Row() ) )
|
|
pDocSh->PostPaint( aRange, PAINT_GRID, nExtFlags );
|
|
|
|
if ( bRecord ) // erst jetzt ist Draw-Undo verfuegbar
|
|
pDocSh->GetUndoManager()->AddUndoAction(
|
|
new ScUndoCut( pDocSh, aRange, aOldEnd, rMark, pUndoDoc ) );
|
|
|
|
aModificator.SetDocumentModified();
|
|
ShowCursor(); // Cursor aendert sich !
|
|
pDocSh->UpdateOle(GetViewData());
|
|
|
|
CellContentChanged();
|
|
}
|
|
else
|
|
ErrorMessage( STR_NOMULTISELECT );
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// C O P Y
|
|
|
|
BOOL ScViewFunc::CopyToClip( ScDocument* pClipDoc, BOOL bCut, BOOL bApi, BOOL bIncludeObjects, BOOL bStopEdit )
|
|
{
|
|
BOOL bDone = FALSE;
|
|
if ( bStopEdit )
|
|
UpdateInputLine();
|
|
|
|
ScRange aRange;
|
|
if ( GetViewData()->GetSimpleArea( aRange ) )
|
|
{
|
|
ScDocument* pDoc = GetViewData()->GetDocument();
|
|
ScMarkData& rMark = GetViewData()->GetMarkData();
|
|
if ( !pDoc->HasSelectedBlockMatrixFragment(
|
|
aRange.aStart.Col(), aRange.aStart.Row(),
|
|
aRange.aEnd.Col(), aRange.aEnd.Row(),
|
|
rMark ) )
|
|
{
|
|
BOOL bSysClip = FALSE;
|
|
if ( !pClipDoc ) // no clip doc specified
|
|
{
|
|
pClipDoc = new ScDocument( SCDOCMODE_CLIP ); // create one (deleted by ScTransferObj)
|
|
bSysClip = TRUE; // and copy into system
|
|
}
|
|
|
|
if ( !bCut )
|
|
{
|
|
ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
|
|
if ( pChangeTrack )
|
|
pChangeTrack->ResetLastCut(); // kein CutMode mehr
|
|
}
|
|
|
|
if ( bSysClip && bIncludeObjects )
|
|
{
|
|
BOOL bAnyOle = pDoc->HasOLEObjectsInArea( aRange, &rMark );
|
|
// update ScGlobal::pDrawClipDocShellRef
|
|
ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
|
|
}
|
|
|
|
pDoc->CopyToClip( aRange.aStart.Col(), aRange.aStart.Row(),
|
|
aRange.aEnd.Col(), aRange.aEnd.Row(),
|
|
bCut, pClipDoc, FALSE, &rMark, FALSE, bIncludeObjects );
|
|
if (bSysClip)
|
|
{
|
|
ScDrawLayer::SetGlobalDrawPersist(NULL);
|
|
|
|
ScGlobal::SetClipDocName( pDoc->GetDocumentShell()->GetTitle( SFX_TITLE_FULLNAME ) );
|
|
}
|
|
pClipDoc->ExtendMerge( aRange, TRUE );
|
|
|
|
if (bSysClip)
|
|
{
|
|
ScDocShell* pDocSh = GetViewData()->GetDocShell();
|
|
TransferableObjectDescriptor aObjDesc;
|
|
pDocSh->FillTransferableObjectDescriptor( aObjDesc );
|
|
aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
|
|
// maSize is set in ScTransferObj ctor
|
|
|
|
ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
|
|
uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
|
|
|
|
if ( ScGlobal::pDrawClipDocShellRef )
|
|
{
|
|
SfxObjectShellRef aPersistRef( &(*ScGlobal::pDrawClipDocShellRef) );
|
|
pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
|
|
}
|
|
|
|
pTransferObj->CopyToClipboard( GetActiveWin() ); // system clipboard
|
|
SC_MOD()->SetClipObject( pTransferObj, NULL ); // internal clipboard
|
|
}
|
|
|
|
bDone = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (!bApi)
|
|
ErrorMessage(STR_MATRIXFRAGMENTERR);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!bApi)
|
|
ErrorMessage(STR_NOMULTISELECT);
|
|
}
|
|
|
|
return bDone;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// P A S T E
|
|
|
|
void ScViewFunc::PasteDraw()
|
|
{
|
|
ScViewData* pViewData = GetViewData();
|
|
SCCOL nPosX = pViewData->GetCurX();
|
|
SCROW nPosY = pViewData->GetCurY();
|
|
Window* pWin = GetActiveWin();
|
|
Point aPos = pWin->PixelToLogic( pViewData->GetScrPos( nPosX, nPosY,
|
|
pViewData->GetActivePart() ) );
|
|
ScDrawTransferObj* pDrawClip = ScDrawTransferObj::GetOwnClipboard( pWin );
|
|
if (pDrawClip)
|
|
PasteDraw( aPos, pDrawClip->GetModel(), FALSE,
|
|
pDrawClip->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() );
|
|
}
|
|
|
|
void ScViewFunc::PasteFromSystem()
|
|
{
|
|
UpdateInputLine();
|
|
|
|
Window* pWin = GetActiveWin();
|
|
ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
|
|
ScDrawTransferObj* pDrawClip = ScDrawTransferObj::GetOwnClipboard( pWin );
|
|
|
|
if (pOwnClip)
|
|
{
|
|
// #129384# keep a reference in case the clipboard is changed during PasteFromClip
|
|
uno::Reference<datatransfer::XTransferable> aOwnClipRef( pOwnClip );
|
|
PasteFromClip( IDF_ALL, pOwnClip->GetDocument(),
|
|
PASTE_NOFUNC, FALSE, FALSE, FALSE, INS_NONE, IDF_NONE,
|
|
TRUE ); // allow warning dialog
|
|
}
|
|
else if (pDrawClip)
|
|
PasteDraw();
|
|
else
|
|
{
|
|
TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
|
|
|
|
// if (pClipObj.Is())
|
|
{
|
|
ULONG nBiff8 = SotExchange::RegisterFormatName(
|
|
String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Biff8")));
|
|
ULONG nBiff5 = SotExchange::RegisterFormatName(
|
|
String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Biff5")));
|
|
|
|
// als erstes SvDraw-Model, dann Grafik
|
|
// (Grafik darf nur bei einzelner Grafik drinstehen)
|
|
|
|
if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ))
|
|
PasteFromSystem( SOT_FORMATSTR_ID_DRAWING );
|
|
else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ))
|
|
PasteFromSystem( SOT_FORMATSTR_ID_SVXB );
|
|
else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ))
|
|
{
|
|
// If it's a Writer object, insert RTF instead of OLE
|
|
|
|
BOOL bDoRtf = FALSE;
|
|
SotStorageStreamRef xStm;
|
|
TransferableObjectDescriptor aObjDesc;
|
|
if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) &&
|
|
aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE, xStm ) )
|
|
{
|
|
SotStorageRef xStore( new SotStorage( *xStm ) );
|
|
bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
|
|
aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) )
|
|
&& aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
|
|
}
|
|
if ( bDoRtf )
|
|
PasteFromSystem( FORMAT_RTF );
|
|
else
|
|
PasteFromSystem( SOT_FORMATSTR_ID_EMBED_SOURCE );
|
|
}
|
|
else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ))
|
|
PasteFromSystem( SOT_FORMATSTR_ID_LINK_SOURCE );
|
|
// the following format can not affect scenario from #89579#
|
|
else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ))
|
|
PasteFromSystem( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE );
|
|
// FORMAT_PRIVATE no longer here (can't work if pOwnClip is NULL)
|
|
else if (aDataHelper.HasFormat(nBiff8)) // before xxx_OLE formats
|
|
PasteFromSystem(nBiff8);
|
|
else if (aDataHelper.HasFormat(nBiff5))
|
|
PasteFromSystem(nBiff5);
|
|
else if (aDataHelper.HasFormat(FORMAT_RTF))
|
|
PasteFromSystem(FORMAT_RTF);
|
|
else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML))
|
|
PasteFromSystem(SOT_FORMATSTR_ID_HTML);
|
|
else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML_SIMPLE))
|
|
PasteFromSystem(SOT_FORMATSTR_ID_HTML_SIMPLE);
|
|
else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_SYLK))
|
|
PasteFromSystem(SOT_FORMATSTR_ID_SYLK);
|
|
else if (aDataHelper.HasFormat(FORMAT_STRING))
|
|
PasteFromSystem(FORMAT_STRING);
|
|
else if (aDataHelper.HasFormat(FORMAT_GDIMETAFILE))
|
|
PasteFromSystem(FORMAT_GDIMETAFILE);
|
|
else if (aDataHelper.HasFormat(FORMAT_BITMAP))
|
|
PasteFromSystem(FORMAT_BITMAP);
|
|
// #89579# xxx_OLE formats come last, like in SotExchange tables
|
|
else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ))
|
|
PasteFromSystem( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE );
|
|
else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ))
|
|
PasteFromSystem( SOT_FORMATSTR_ID_LINK_SOURCE_OLE );
|
|
// else
|
|
// ErrorMessage(STR_PASTE_ERROR);
|
|
}
|
|
// else
|
|
// ErrorMessage(STR_PASTE_ERROR);
|
|
}
|
|
|
|
// keine Fehlermeldung, weil SID_PASTE in der idl das FastCall-Flag hat,
|
|
// also auch gerufen wird, wenn nichts im Clipboard steht (#42531#)
|
|
}
|
|
|
|
BOOL ScViewFunc::PasteFromSystem( ULONG nFormatId, BOOL bApi )
|
|
{
|
|
UpdateInputLine();
|
|
|
|
BOOL bRet = TRUE;
|
|
Window* pWin = GetActiveWin();
|
|
ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
|
|
if ( nFormatId == 0 && pOwnClip )
|
|
{
|
|
// #129384# keep a reference in case the clipboard is changed during PasteFromClip
|
|
uno::Reference<datatransfer::XTransferable> aOwnClipRef( pOwnClip );
|
|
PasteFromClip( IDF_ALL, pOwnClip->GetDocument(),
|
|
PASTE_NOFUNC, FALSE, FALSE, FALSE, INS_NONE, IDF_NONE,
|
|
!bApi ); // allow warning dialog
|
|
}
|
|
else
|
|
{
|
|
TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
|
|
if ( !aDataHelper.GetTransferable().is() )
|
|
return FALSE;
|
|
|
|
bRet = PasteDataFormat( nFormatId, aDataHelper.GetTransferable(),
|
|
GetViewData()->GetCurX(), GetViewData()->GetCurY(),
|
|
NULL, FALSE, !bApi ); // allow warning dialog
|
|
|
|
if ( !bRet && !bApi )
|
|
ErrorMessage(STR_PASTE_ERROR);
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// P A S T E
|
|
|
|
BOOL ScViewFunc::PasteOnDrawObject( const uno::Reference<datatransfer::XTransferable>& rxTransferable,
|
|
SdrObject* pHitObj, BOOL bLink )
|
|
{
|
|
BOOL bRet = FALSE;
|
|
if ( bLink )
|
|
{
|
|
TransferableDataHelper aDataHelper( rxTransferable );
|
|
if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) )
|
|
{
|
|
SotStorageStreamRef xStm;
|
|
if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_SVXB, xStm ) )
|
|
{
|
|
Graphic aGraphic;
|
|
*xStm >> aGraphic;
|
|
bRet = ApplyGraphicToObject( pHitObj, aGraphic );
|
|
}
|
|
}
|
|
else if ( aDataHelper.HasFormat( SOT_FORMAT_GDIMETAFILE ) )
|
|
{
|
|
GDIMetaFile aMtf;
|
|
if( aDataHelper.GetGDIMetaFile( FORMAT_GDIMETAFILE, aMtf ) )
|
|
bRet = ApplyGraphicToObject( pHitObj, Graphic(aMtf) );
|
|
}
|
|
else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) )
|
|
{
|
|
Bitmap aBmp;
|
|
if( aDataHelper.GetBitmap( FORMAT_BITMAP, aBmp ) )
|
|
bRet = ApplyGraphicToObject( pHitObj, Graphic(aBmp) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// ham' wa noch nich
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
//
|
|
// Einfuegen auf Tabelle:
|
|
//
|
|
|
|
// internes Paste
|
|
|
|
BOOL ScViewFunc::PasteFromClip( USHORT nFlags, ScDocument* pClipDoc,
|
|
USHORT nFunction, BOOL bSkipEmpty,
|
|
BOOL bTranspose, BOOL bAsLink,
|
|
InsCellCmd eMoveMode, USHORT nUndoExtraFlags,
|
|
BOOL bAllowDialogs )
|
|
{
|
|
if (!pClipDoc)
|
|
{
|
|
DBG_ERROR("PasteFromClip: pClipDoc=0 not allowed");
|
|
return FALSE;
|
|
}
|
|
|
|
// fuer Undo etc. immer alle oder keine Inhalte sichern
|
|
USHORT nContFlags = IDF_NONE;
|
|
if (nFlags & IDF_CONTENTS)
|
|
nContFlags |= IDF_CONTENTS;
|
|
if (nFlags & IDF_ATTRIB)
|
|
nContFlags |= IDF_ATTRIB;
|
|
// evtl. Attribute ins Undo ohne sie vom Clip ins Doc zu kopieren
|
|
USHORT nUndoFlags = nContFlags;
|
|
if (nUndoExtraFlags & IDF_ATTRIB)
|
|
nUndoFlags |= IDF_ATTRIB;
|
|
|
|
BOOL bCutMode = pClipDoc->IsCutMode(); // if transposing, take from original clipdoc
|
|
BOOL bIncludeFiltered = bCutMode;
|
|
|
|
BOOL bPasteDraw = ( pClipDoc->GetDrawLayer() && ( nFlags & IDF_OBJECTS ) );
|
|
|
|
ScDocShellRef aTransShellRef; // for objects in pTransClip - must remain valid as long as pTransClip
|
|
ScDocument* pOrigClipDoc = NULL;
|
|
ScDocument* pTransClip = NULL;
|
|
if ( bTranspose )
|
|
{
|
|
SCCOL nX;
|
|
SCROW nY;
|
|
// include filtered rows until TransposeClip can skip them
|
|
bIncludeFiltered = TRUE;
|
|
pClipDoc->GetClipArea( nX, nY, TRUE );
|
|
if ( nY > static_cast<sal_Int32>(MAXCOL) ) // zuviele Zeilen zum Transponieren
|
|
{
|
|
ErrorMessage(STR_PASTE_FULL);
|
|
return FALSE;
|
|
}
|
|
pOrigClipDoc = pClipDoc; // fuer Referenzen
|
|
|
|
if ( bPasteDraw )
|
|
{
|
|
aTransShellRef = new ScDocShell; // DocShell needs a Ref immediately
|
|
aTransShellRef->DoInitNew(NULL);
|
|
}
|
|
ScDrawLayer::SetGlobalDrawPersist(aTransShellRef);
|
|
|
|
pTransClip = new ScDocument( SCDOCMODE_CLIP );
|
|
pClipDoc->TransposeClip( pTransClip, nFlags, bAsLink );
|
|
pClipDoc = pTransClip;
|
|
|
|
ScDrawLayer::SetGlobalDrawPersist(NULL);
|
|
}
|
|
|
|
SCCOL nStartCol;
|
|
SCROW nStartRow;
|
|
SCTAB nStartTab;
|
|
SCCOL nEndCol;
|
|
SCROW nEndRow;
|
|
SCTAB nEndTab;
|
|
SCCOL nClipSizeX;
|
|
SCROW nClipSizeY;
|
|
pClipDoc->GetClipArea( nClipSizeX, nClipSizeY, TRUE ); // size in clipboard doc
|
|
|
|
// size in target doc: include filtered rows only if CutMode is set
|
|
SCCOL nDestSizeX;
|
|
SCROW nDestSizeY;
|
|
pClipDoc->GetClipArea( nDestSizeX, nDestSizeY, bIncludeFiltered );
|
|
|
|
ScDocument* pDoc = GetViewData()->GetDocument();
|
|
ScDocShell* pDocSh = GetViewData()->GetDocShell();
|
|
ScMarkData& rMark = GetViewData()->GetMarkData();
|
|
SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager();
|
|
const BOOL bRecord(pDoc->IsUndoEnabled());
|
|
|
|
ScDocShellModificator aModificator( *pDocSh );
|
|
|
|
if ( rMark.IsMultiMarked() )
|
|
{
|
|
rMark.MarkToSimple();
|
|
if ( rMark.IsMultiMarked() )
|
|
{ // "Einfuegen auf Mehrfachselektion nicht moeglich"
|
|
ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
|
|
delete pTransClip;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
SCCOL nMarkAddX = 0;
|
|
SCROW nMarkAddY = 0;
|
|
|
|
if ( rMark.IsMarked() )
|
|
{
|
|
ScRange aMarkRange;
|
|
rMark.GetMarkArea( aMarkRange );
|
|
nStartCol = aMarkRange.aStart.Col();
|
|
nStartRow = aMarkRange.aStart.Row();
|
|
nStartTab = aMarkRange.aStart.Tab();
|
|
nEndCol = aMarkRange.aEnd.Col();
|
|
nEndRow = aMarkRange.aEnd.Row();
|
|
nEndTab = aMarkRange.aEnd.Tab();
|
|
SCCOL nBlockAddX = nEndCol-nStartCol;
|
|
SCROW nBlockAddY = nEndRow-nStartRow;
|
|
|
|
// #58422# Nachfrage, wenn die Selektion groesser als 1 Zeile/Spalte, aber kleiner
|
|
// als das Clipboard ist (dann wird ueber die Selektion hinaus eingefuegt)
|
|
|
|
// ClipSize ist nicht Groesse, sondern Differenz
|
|
if ( ( nBlockAddX != 0 && nBlockAddX < nDestSizeX ) ||
|
|
( nBlockAddY != 0 && nBlockAddY < nDestSizeY ) )
|
|
{
|
|
ScWaitCursorOff aWaitOff( GetFrameWin() );
|
|
String aMessage = ScGlobal::GetRscString( STR_PASTE_BIGGER );
|
|
QueryBox aBox( GetViewData()->GetDialogParent(),
|
|
WinBits(WB_YES_NO | WB_DEF_NO), aMessage );
|
|
if ( aBox.Execute() != RET_YES )
|
|
{
|
|
delete pTransClip;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if (nBlockAddX > nDestSizeX)
|
|
nMarkAddX = nBlockAddX - nDestSizeX; // fuer Merge-Test
|
|
else
|
|
nEndCol = nStartCol + nDestSizeX;
|
|
|
|
if (nBlockAddY > nDestSizeY)
|
|
nMarkAddY = nBlockAddY - nDestSizeY; // fuer Merge-Test
|
|
else
|
|
nEndRow = nStartRow + nDestSizeY;
|
|
}
|
|
else
|
|
{
|
|
nStartCol = GetViewData()->GetCurX();
|
|
nStartRow = GetViewData()->GetCurY();
|
|
nStartTab = GetViewData()->GetTabNo();
|
|
nEndCol = nStartCol + nDestSizeX;
|
|
nEndRow = nStartRow + nDestSizeY;
|
|
nEndTab = nStartTab;
|
|
}
|
|
|
|
bool bOffLimits = !ValidCol(nEndCol) || !ValidRow(nEndRow);
|
|
|
|
// Zielbereich, wie er angezeigt wird:
|
|
ScRange aUserRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab );
|
|
|
|
// Sollen Zellen eingefuegt werden?
|
|
// (zu grosse nEndCol/nEndRow werden weiter unten erkannt)
|
|
BOOL bInsertCells = ( eMoveMode != INS_NONE && !bOffLimits );
|
|
if ( bInsertCells )
|
|
{
|
|
// #94115# Instead of EnterListAction, the paste undo action is merged into the
|
|
// insert action, so Repeat can insert the right cells
|
|
|
|
MarkRange( aUserRange ); // wird vor CopyFromClip sowieso gesetzt
|
|
|
|
// #72930# CutMode is reset on insertion of cols/rows but needed again on cell move
|
|
BOOL bCut = pClipDoc->IsCutMode();
|
|
if (!InsertCells( eMoveMode, bRecord, TRUE )) // is inserting possible?
|
|
{
|
|
delete pTransClip; // cancel
|
|
return FALSE;
|
|
// #i21036# EnterListAction isn't used, and InsertCells doesn't insert
|
|
// its undo action on failure, so no undo handling is needed here
|
|
}
|
|
if ( bCut )
|
|
pClipDoc->SetCutMode( bCut );
|
|
}
|
|
else if (!bOffLimits)
|
|
{
|
|
BOOL bAskIfNotEmpty = bAllowDialogs &&
|
|
( nFlags & IDF_CONTENTS ) &&
|
|
nFunction == PASTE_NOFUNC &&
|
|
SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
|
|
if ( bAskIfNotEmpty )
|
|
{
|
|
BOOL bIsEmpty = TRUE;
|
|
SCTAB nTabCount = pDoc->GetTableCount();
|
|
for (SCTAB nTab=0; nTab<nTabCount && bIsEmpty; nTab++)
|
|
if ( rMark.GetTableSelect(nTab) &&
|
|
!pDoc->IsBlockEmpty( nTab, aUserRange.aStart.Col(), aUserRange.aStart.Row(),
|
|
aUserRange.aEnd.Col(), aUserRange.aEnd.Row() ) )
|
|
bIsEmpty = FALSE;
|
|
|
|
if ( !bIsEmpty )
|
|
{
|
|
ScReplaceWarnBox aBox( GetViewData()->GetDialogParent() );
|
|
if ( aBox.Execute() != RET_YES )
|
|
{
|
|
// changing the configuration is within the ScReplaceWarnBox
|
|
delete pTransClip;
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SCCOL nClipStartX; // Clipboard-Bereich erweitern
|
|
SCROW nClipStartY;
|
|
pClipDoc->GetClipStart( nClipStartX, nClipStartY );
|
|
SCCOL nUndoEndCol = nClipStartX + nClipSizeX;
|
|
SCROW nUndoEndRow = nClipStartY + nClipSizeY; // end of source area in clipboard document
|
|
BOOL bClipOver = pClipDoc->
|
|
ExtendMerge( nClipStartX,nClipStartY, nUndoEndCol,nUndoEndRow, nStartTab, FALSE );
|
|
nUndoEndCol -= nClipStartX + nClipSizeX;
|
|
nUndoEndRow -= nClipStartY + nClipSizeY; // now contains only the difference added by ExtendMerge
|
|
nUndoEndCol += nEndCol;
|
|
nUndoEndRow += nEndRow; // destination area, expanded for merged cells
|
|
|
|
// if (nUndoEndCol < nEndCol) nUndoEndCol = nEndCol;
|
|
// if (nUndoEndRow < nEndRow) nUndoEndRow = nEndRow;
|
|
|
|
// nUndoEndCol += nMarkAddX;
|
|
// nUndoEndRow += nMarkAddY;
|
|
|
|
if (nUndoEndCol>MAXCOL || nUndoEndRow>MAXROW)
|
|
{
|
|
ErrorMessage(STR_PASTE_FULL);
|
|
delete pTransClip;
|
|
return FALSE;
|
|
}
|
|
|
|
pDoc->ExtendMerge( nStartCol,nStartRow, nUndoEndCol,nUndoEndRow, nStartTab, FALSE );
|
|
|
|
// Test auf Zellschutz
|
|
|
|
ScEditableTester aTester( pDoc, nStartTab, nStartCol,nStartRow, nUndoEndCol,nUndoEndRow );
|
|
if (!aTester.IsEditable())
|
|
{
|
|
ErrorMessage(aTester.GetMessageId());
|
|
delete pTransClip;
|
|
return FALSE;
|
|
}
|
|
|
|
//! Test auf Ueberlappung
|
|
//! nur wirkliche Schnittmenge testen !!!!!!!
|
|
|
|
// pDoc->HasCommonAttr( StartCol,nStartRow, nUndoEndCol,nUndoEndRow, nStartTab,
|
|
// pClipDoc, nClipStartX, nClipStartY );
|
|
|
|
if (bClipOver)
|
|
if (pDoc->HasAttrib( nStartCol,nStartRow,nStartTab, nUndoEndCol,nUndoEndRow,nStartTab,
|
|
HASATTR_OVERLAPPED ))
|
|
{ // "Zusammenfassen nicht verschachteln !"
|
|
ErrorMessage(STR_MSSG_PASTEFROMCLIP_1);
|
|
delete pTransClip;
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !bCutMode )
|
|
{
|
|
ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
|
|
if ( pChangeTrack )
|
|
pChangeTrack->ResetLastCut(); // kein CutMode mehr
|
|
}
|
|
|
|
BOOL bColInfo = ( nStartRow==0 && nEndRow==MAXROW );
|
|
BOOL bRowInfo = ( nStartCol==0 && nEndCol==MAXCOL );
|
|
|
|
ScDocument* pUndoDoc = NULL;
|
|
ScDocument* pRefUndoDoc = NULL;
|
|
ScDocument* pRedoDoc = NULL;
|
|
ScRefUndoData* pUndoData = NULL;
|
|
|
|
if ( bRecord )
|
|
{
|
|
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
|
|
pUndoDoc->InitUndoSelected( pDoc, rMark, bColInfo, bRowInfo );
|
|
|
|
// all sheets - CopyToDocument skips those that don't exist in pUndoDoc
|
|
SCTAB nTabCount = pDoc->GetTableCount();
|
|
pDoc->CopyToDocument( nStartCol, nStartRow, 0, nUndoEndCol, nUndoEndRow, nTabCount-1,
|
|
nUndoFlags, FALSE, pUndoDoc );
|
|
|
|
if ( bCutMode )
|
|
{
|
|
pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
|
|
pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, FALSE, FALSE );
|
|
|
|
pUndoData = new ScRefUndoData( pDoc );
|
|
}
|
|
}
|
|
|
|
USHORT nExtFlags = 0;
|
|
pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab,
|
|
nEndCol, nEndRow, nEndTab ); // content before the change
|
|
|
|
if (GetViewData()->IsActive())
|
|
{
|
|
DoneBlockMode();
|
|
InitOwnBlockMode();
|
|
}
|
|
rMark.SetMarkArea( aUserRange );
|
|
|
|
HideCursor(); // Cursor aendert sich !
|
|
|
|
//
|
|
// Aus Clipboard kopieren,
|
|
// wenn gerechnet werden soll, Originaldaten merken
|
|
//
|
|
|
|
ScDocument* pMixDoc = NULL;
|
|
if ( bSkipEmpty || nFunction )
|
|
{
|
|
if ( nFlags & IDF_CONTENTS )
|
|
{
|
|
pMixDoc = new ScDocument( SCDOCMODE_UNDO );
|
|
pMixDoc->InitUndo( pDoc, nStartTab, nEndTab );
|
|
pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
|
|
IDF_CONTENTS, FALSE, pMixDoc );
|
|
}
|
|
}
|
|
|
|
USHORT nNoObjFlags = nFlags & ~IDF_OBJECTS;
|
|
if (!bAsLink)
|
|
{
|
|
// copy normally (original range)
|
|
pDoc->CopyFromClip( aUserRange, rMark, nNoObjFlags, pRefUndoDoc, pClipDoc,
|
|
TRUE, FALSE, bIncludeFiltered, bSkipEmpty );
|
|
|
|
// bei Transpose Referenzen per Hand anpassen
|
|
if ( bTranspose && bCutMode && (nFlags & IDF_CONTENTS) )
|
|
pDoc->UpdateTranspose( aUserRange.aStart, pOrigClipDoc, rMark, pRefUndoDoc );
|
|
}
|
|
else if (!bTranspose)
|
|
{
|
|
// copy with bAsLink=TRUE
|
|
pDoc->CopyFromClip( aUserRange, rMark, nNoObjFlags, pRefUndoDoc, pClipDoc,
|
|
TRUE, TRUE, bIncludeFiltered, bSkipEmpty );
|
|
}
|
|
else
|
|
{
|
|
// alle Inhalte kopieren (im TransClipDoc stehen nur Formeln)
|
|
pDoc->CopyFromClip( aUserRange, rMark, nContFlags, pRefUndoDoc, pClipDoc );
|
|
}
|
|
|
|
// skipped rows and merged cells don't mix
|
|
if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
|
|
pDocSh->GetDocFunc().UnmergeCells( aUserRange, FALSE, TRUE );
|
|
|
|
pDoc->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nStartTab, TRUE ); // Refresh
|
|
// und Bereich neu
|
|
|
|
if ( pMixDoc ) // Rechenfunktionen mit Original-Daten auszufuehren ?
|
|
{
|
|
pDoc->MixDocument( aUserRange, nFunction, bSkipEmpty, pMixDoc );
|
|
}
|
|
delete pMixDoc;
|
|
|
|
if ( bPasteDraw )
|
|
pDocSh->MakeDrawLayer(); // before AdjustBlockHeight, so BeginDrawUndo can be called
|
|
|
|
if ( bRecord )
|
|
pDoc->BeginDrawUndo();
|
|
AdjustBlockHeight(); // update row heights before pasting objects
|
|
|
|
if ( bPasteDraw )
|
|
{
|
|
// Paste the drawing objects after the row heights have been updated.
|
|
|
|
pDoc->CopyFromClip( aUserRange, rMark, IDF_OBJECTS, pRefUndoDoc, pClipDoc,
|
|
TRUE, FALSE, bIncludeFiltered );
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab,
|
|
nEndCol, nEndRow, nEndTab ); // content after the change
|
|
|
|
|
|
// ggf. Autofilter-Koepfe loeschen
|
|
if (bCutMode)
|
|
if (pDoc->RefreshAutoFilter( nClipStartX,nClipStartY, nClipStartX+nClipSizeX,
|
|
nClipStartY+nClipSizeY, nStartTab ))
|
|
pDocSh->PostPaint( nClipStartX,nClipStartY,nStartTab,
|
|
nClipStartX+nClipSizeX,nClipStartY,nStartTab,
|
|
PAINT_GRID );
|
|
|
|
ShowCursor(); // Cursor aendert sich !
|
|
|
|
//! Block-Bereich bei RefUndoDoc weglassen !!!
|
|
|
|
if ( bRecord )
|
|
{
|
|
// Redo-Daten werden erst beim ersten Undo kopiert
|
|
// ohne RefUndoDoc muss das Redo-Doc noch nicht angelegt werden
|
|
|
|
if (pRefUndoDoc)
|
|
{
|
|
pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
|
|
pRedoDoc->InitUndo( pDoc, nStartTab, nEndTab, bColInfo, bRowInfo );
|
|
|
|
// angepasste Referenzen ins Redo-Doc
|
|
|
|
SCTAB nTabCount = pDoc->GetTableCount();
|
|
pRedoDoc->AddUndoTab( 0, nTabCount-1 );
|
|
pDoc->CopyUpdated( pRefUndoDoc, pRedoDoc );
|
|
|
|
// alte Referenzen ins Undo-Doc
|
|
|
|
//! Tabellen selektieren ?
|
|
pUndoDoc->AddUndoTab( 0, nTabCount-1 );
|
|
pRefUndoDoc->DeleteArea( nStartCol, nStartRow, nEndCol, nEndRow, rMark, IDF_ALL );
|
|
pRefUndoDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1,
|
|
IDF_FORMULA, FALSE, pUndoDoc );
|
|
delete pRefUndoDoc;
|
|
}
|
|
|
|
// DeleteUnchanged for pUndoData is in ScUndoPaste ctor,
|
|
// UndoData for redo is made during first undo
|
|
|
|
ScUndoPasteOptions aOptions; // store options for repeat
|
|
aOptions.nFunction = nFunction;
|
|
aOptions.bSkipEmpty = bSkipEmpty;
|
|
aOptions.bTranspose = bTranspose;
|
|
aOptions.bAsLink = bAsLink;
|
|
aOptions.eMoveMode = eMoveMode;
|
|
|
|
SfxUndoAction* pUndo = new ScUndoPaste( pDocSh,
|
|
nStartCol, nStartRow, nStartTab,
|
|
nUndoEndCol, nUndoEndRow, nEndTab, rMark,
|
|
pUndoDoc, pRedoDoc, nFlags | nUndoFlags,
|
|
pUndoData, NULL, NULL, NULL,
|
|
FALSE, &aOptions ); // FALSE = Redo data not yet copied
|
|
|
|
if ( bInsertCells )
|
|
{
|
|
// Merge the paste undo action into the insert action.
|
|
// Use ScUndoWrapper so the ScUndoPaste pointer can be stored in the insert action.
|
|
|
|
pUndoMgr->AddUndoAction( new ScUndoWrapper( pUndo ), TRUE );
|
|
}
|
|
else
|
|
pUndoMgr->AddUndoAction( pUndo );
|
|
}
|
|
|
|
USHORT nPaint = PAINT_GRID;
|
|
if (bColInfo)
|
|
{
|
|
nPaint |= PAINT_TOP;
|
|
nUndoEndCol = MAXCOL; // nur zum Zeichnen !
|
|
}
|
|
if (bRowInfo)
|
|
{
|
|
nPaint |= PAINT_LEFT;
|
|
nUndoEndRow = MAXROW; // nur zum Zeichnen !
|
|
}
|
|
pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
|
|
nUndoEndCol, nUndoEndRow, nEndTab, nPaint, nExtFlags );
|
|
// AdjustBlockHeight has already been called above
|
|
|
|
aModificator.SetDocumentModified();
|
|
pDocSh->UpdateOle(GetViewData());
|
|
|
|
SelectionChanged();
|
|
|
|
delete pTransClip;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// D R A G A N D D R O P
|
|
//
|
|
// innerhalb des Dokuments
|
|
|
|
BOOL ScViewFunc::MoveBlockTo( const ScRange& rSource, const ScAddress& rDestPos,
|
|
BOOL bCut, BOOL bRecord, BOOL bPaint, BOOL bApi )
|
|
{
|
|
ScDocShell* pDocSh = GetViewData()->GetDocShell();
|
|
HideAllCursors(); // wegen zusammengefassten
|
|
|
|
BOOL bSuccess = TRUE;
|
|
SCTAB nDestTab = rDestPos.Tab();
|
|
const ScMarkData& rMark = GetViewData()->GetMarkData();
|
|
if ( rSource.aStart.Tab() == nDestTab && rSource.aEnd.Tab() == nDestTab && rMark.GetSelectCount() > 1 )
|
|
{
|
|
// moving within one table and several tables selected -> apply to all selected tables
|
|
|
|
if ( bRecord )
|
|
{
|
|
String aUndo = ScGlobal::GetRscString( bCut ? STR_UNDO_MOVE : STR_UNDO_COPY );
|
|
pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
|
|
}
|
|
|
|
// collect ranges of consecutive selected tables
|
|
|
|
ScRange aLocalSource = rSource;
|
|
ScAddress aLocalDest = rDestPos;
|
|
SCTAB nTabCount = pDocSh->GetDocument()->GetTableCount();
|
|
SCTAB nStartTab = 0;
|
|
while ( nStartTab < nTabCount && bSuccess )
|
|
{
|
|
while ( nStartTab < nTabCount && !rMark.GetTableSelect(nStartTab) )
|
|
++nStartTab;
|
|
if ( nStartTab < nTabCount )
|
|
{
|
|
SCTAB nEndTab = nStartTab;
|
|
while ( nEndTab+1 < nTabCount && rMark.GetTableSelect(nEndTab+1) )
|
|
++nEndTab;
|
|
|
|
aLocalSource.aStart.SetTab( nStartTab );
|
|
aLocalSource.aEnd.SetTab( nEndTab );
|
|
aLocalDest.SetTab( nStartTab );
|
|
|
|
bSuccess = pDocSh->GetDocFunc().MoveBlock(
|
|
aLocalSource, aLocalDest, bCut, bRecord, bPaint, bApi );
|
|
|
|
nStartTab = nEndTab + 1;
|
|
}
|
|
}
|
|
|
|
if ( bRecord )
|
|
pDocSh->GetUndoManager()->LeaveListAction();
|
|
}
|
|
else
|
|
{
|
|
// move the block as specified
|
|
bSuccess = pDocSh->GetDocFunc().MoveBlock(
|
|
rSource, rDestPos, bCut, bRecord, bPaint, bApi );
|
|
}
|
|
|
|
ShowAllCursors();
|
|
if (bSuccess)
|
|
{
|
|
// Zielbereich markieren
|
|
ScAddress aDestEnd(
|
|
rDestPos.Col() + rSource.aEnd.Col() - rSource.aStart.Col(),
|
|
rDestPos.Row() + rSource.aEnd.Row() - rSource.aStart.Row(),
|
|
nDestTab );
|
|
|
|
BOOL bIncludeFiltered = bCut;
|
|
if ( !bIncludeFiltered )
|
|
{
|
|
// manually find number of non-filtered rows
|
|
SCROW nPastedCount = pDocSh->GetDocument()->GetRowFlagsArray(
|
|
rSource.aStart.Tab()).CountForCondition(
|
|
rSource.aStart.Row(), rSource.aEnd.Row(), CR_FILTERED, 0);
|
|
if ( nPastedCount == 0 )
|
|
nPastedCount = 1;
|
|
aDestEnd.SetRow( rDestPos.Row() + nPastedCount - 1 );
|
|
}
|
|
|
|
MarkRange( ScRange( rDestPos, aDestEnd ), FALSE ); //! FALSE ???
|
|
|
|
pDocSh->UpdateOle(GetViewData());
|
|
SelectionChanged();
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
// Link innerhalb des Dokuments
|
|
|
|
BOOL ScViewFunc::LinkBlock( const ScRange& rSource, const ScAddress& rDestPos, BOOL bApi )
|
|
{
|
|
// Test auf Ueberlappung
|
|
|
|
if ( rSource.aStart.Tab() == rDestPos.Tab() )
|
|
{
|
|
SCCOL nDestEndCol = rDestPos.Col() + ( rSource.aEnd.Col() - rSource.aStart.Col() );
|
|
SCROW nDestEndRow = rDestPos.Row() + ( rSource.aEnd.Row() - rSource.aStart.Row() );
|
|
|
|
if ( rSource.aStart.Col() <= nDestEndCol && rDestPos.Col() <= rSource.aEnd.Col() &&
|
|
rSource.aStart.Row() <= nDestEndRow && rDestPos.Row() <= rSource.aEnd.Row() )
|
|
{
|
|
if (!bApi)
|
|
ErrorMessage( STR_ERR_LINKOVERLAP );
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// Ausfuehren per Paste
|
|
|
|
ScDocument* pDoc = GetViewData()->GetDocument();
|
|
ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
|
|
pDoc->CopyTabToClip( rSource.aStart.Col(), rSource.aStart.Row(),
|
|
rSource.aEnd.Col(), rSource.aEnd.Row(),
|
|
rSource.aStart.Tab(), pClipDoc );
|
|
|
|
// Zielbereich markieren (Cursor setzen, keine Markierung)
|
|
|
|
if ( GetViewData()->GetTabNo() != rDestPos.Tab() )
|
|
SetTabNo( rDestPos.Tab() );
|
|
|
|
MoveCursorAbs( rDestPos.Col(), rDestPos.Row(), SC_FOLLOW_NONE, FALSE, FALSE );
|
|
|
|
// Paste
|
|
|
|
PasteFromClip( IDF_ALL, pClipDoc, PASTE_NOFUNC, FALSE, FALSE, TRUE ); // als Link
|
|
|
|
delete pClipDoc;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|