/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
// Shrink the area to allow pasting to external applications. // Shrink to real data area for HTML, RTF and RICHTEXT, but include // all objects and top-left area for BITMAP and PNG.
SCCOL nStartCol = aReducedBlock.aStart.Col();
SCROW nStartRow = aReducedBlock.aStart.Row();
SCCOL nEndCol = aReducedBlock.aEnd.Col();
SCROW nEndRow = aReducedBlock.aEnd.Row();
bOK = SetObject(&aEngine,
((nFormat == SotClipboardFormatId::RTF)
? SCTRANS_TYPE_EDIT_RTF
: ((nFormat == SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT)
? SCTRANS_TYPE_EDIT_ODF_TEXT_FLAT
: SCTRANS_TYPE_EDIT_BIN)),
rFlavor);
}
} elseif ( ScImportExport::IsFormatSupported( nFormat ) || nFormat == SotClipboardFormatId::RTF
|| nFormat == SotClipboardFormatId::RICHTEXT )
{ // if this transfer object was used to create a DDE link, filtered rows // have to be included for subsequent calls (to be consistent with link data) if ( nFormat == SotClipboardFormatId::LINK )
m_bUsedForLink = true;
ScImportExport aObj( *m_pDoc, aReducedBlock ); // Plain text ("Unformatted text") may contain embedded tabs and // line breaks but is not enclosed in quotes. Which makes it // unsuitable for multiple cells, especially if one of them is // multi-line, but otherwise is expected behavior for plain text. // For multiple cells replace embedded line breaks (and tabs) with // space character, otherwise pasting would yield odd results. /* XXX: it's debatable whether this is actually expected, but * there's no way to satisfy all possible requirements when
* copy/pasting unformatted text. */ constbool bPlainMulti = (nFormat == SotClipboardFormatId::STRING &&
aReducedBlock.aStart != aReducedBlock.aEnd); // Add quotes only for STRING_TSVC. /* TODO: a possible future STRING_TSV should not contain embedded * line breaks nor tab (separator) characters and not be quoted.
* A possible STRING_CSV should. */
ScExportTextOptions aTextOptions( ScExportTextOptions::None, 0,
(nFormat == SotClipboardFormatId::STRING_TSVC)); if ( bPlainMulti || m_bUsedForLink )
{ // For a DDE link or plain text multiple cells, convert line // breaks and separators to space.
aTextOptions.meNewlineConversion = ScExportTextOptions::ToSpace;
aTextOptions.mcSeparatorConvertTo = ' ';
aTextOptions.mbAddQuotes = false;
}
aObj.SetExportTextOptions(aTextOptions);
aObj.SetFormulas( m_pDoc->GetViewOptions().GetOption( VOPT_FORMULAS ) );
aObj.SetIncludeFiltered( bIncludeFiltered );
// tdf#160855 fix crash due to Skia's internal maximum pixel limit // Somewhere in the tens of thousands of selected fill cells, // the size of the VirtualDevice exceeds 1 GB of pixels. But // Skia, at least on macOS, will fail to create a surface. // Even if there is ample free memory, Skia/Raster will fail. // The second problem is that even if you disable Skia, the // crash is just delayed when a BitmapEx is created from the // VirtualDevice and malloc() fails. // Since this data flavor really triggers one or more system // memory limits, lower the resolution of the bitmap by keeping // the VirtualDevice pixel size within an arbitrary number of // pixels. // Note: the arbitrary "maximum number of pixels" limit that // that Skia can handle may need to be raised or lowered for // platforms other than macOS. static constexpr tools::Long nCopyToImageMaxPixels = 8192 * 8192;
Fraction aScale(1.0);
Size aPixelSize = pVirtDev->LogicToPixel(aMMRect.GetSize(), MapMode(MapUnit::Map100thMM));
tools::Long nPixels(aPixelSize.Width() * aPixelSize.Height()); if (nPixels < 0 || nPixels > nCopyToImageMaxPixels)
{
aScale = Fraction(nCopyToImageMaxPixels, nPixels);
aPixelSize = pVirtDev->LogicToPixel(aMMRect.GetSize(), MapMode(MapUnit::Map100thMM, Point(), aScale, aScale));
nPixels = aPixelSize.Width() * aPixelSize.Height();
}
pVirtDev->SetMapMode( MapMode( MapUnit::MapPixel, Point(), aScale, aScale ) );
BitmapEx aBmp = pVirtDev->GetBitmapEx( Point(), pVirtDev->GetOutputSize() );
bOK = SetBitmapEx( aBmp, rFlavor );
} elseif ( nFormat == SotClipboardFormatId::GDIMETAFILE )
{ // #i123405# Do not limit visual size calculation for metafile creation. // It seems unlikely that removing the limitation causes problems since // metafile creation means that no real pixel device in the needed size is // created.
InitDocShell(false);
bool ScTransferObj::WriteObject( SvStream& rOStm, void* pUserObject, sal_uInt32 nUserObjectId, const datatransfer::DataFlavor& rFlavor )
{ // called from SetObject, put data into stream
SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor ); // mba: no BaseURL for data exchange if ( pImpEx->ExportStream( rOStm, OUString(), nFormat ) )
bRet = ( rOStm.GetError() == ERRCODE_NONE );
} break;
case SCTRANS_TYPE_EDIT_RTF: case SCTRANS_TYPE_EDIT_BIN:
{
ScTabEditEngine* pEngine = static_cast<ScTabEditEngine*>(pUserObject); if ( nUserObjectId == SCTRANS_TYPE_EDIT_RTF )
{
pEngine->Write( rOStm, EETextFormat::Rtf );
bRet = ( rOStm.GetError() == ERRCODE_NONE );
} else
{ // can't use Write for EditEngine format because that would // write old format without support for unicode characters. // Get the data from the EditEngine's transferable instead.
if (nStartY > 0)
{ // Set manual height for all previous rows so we can ensure // that visible area will not change due to autoheight
rDestDoc.SetManualHeight(0, nStartY - 1, 0, true);
} for (SCROW nRow = nStartY; nRow <= nEndY; ++nRow)
{ if ( m_pDoc->RowHidden(nRow, nSrcTab) )
rDestDoc.ShowRow( nRow, 0, false ); else
{
rDestDoc.SetRowHeight( nRow, 0, m_pDoc->GetOriginalHeight( nRow, nSrcTab ) );
// if height was set manually, that flag has to be copied, too bool bManual = m_pDoc->IsManualRowHeight(nRow, nSrcTab);
rDestDoc.SetManualHeight(nRow, nRow, 0, bManual);
}
}
// cell range is copied to the original position, but on the first sheet // -> bCutMode must be set // pDoc is always a Clipboard-document
ScGlobal::xDrawClipDocShellRef.clear(); if (bAnyOle)
{
ScGlobal::xDrawClipDocShellRef = new ScDocShell(SfxModelFlags::EMBEDDED_OBJECT | SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS, pDoc); // there must be a ref
ScGlobal::xDrawClipDocShellRef->DoInitNew();
}
return ScGlobal::xDrawClipDocShellRef.get();
}
void ScTransferObj::StripRefs( ScDocument& rDoc,
SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
ScDocument& rDestDoc )
{ // In a clipboard doc the data don't have to be on the first sheet
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.