diff options
Diffstat (limited to 'sc/source/filter/rtf/eeimpars.cxx')
-rw-r--r-- | sc/source/filter/rtf/eeimpars.cxx | 657 |
1 files changed, 657 insertions, 0 deletions
diff --git a/sc/source/filter/rtf/eeimpars.cxx b/sc/source/filter/rtf/eeimpars.cxx new file mode 100644 index 000000000..8d768efa5 --- /dev/null +++ b/sc/source/filter/rtf/eeimpars.cxx @@ -0,0 +1,657 @@ +/* -*- 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 . + */ + +#include <scitems.hxx> +#include <editeng/eeitem.hxx> + +#include <editeng/adjustitem.hxx> +#include <editeng/editobj.hxx> +#include <editeng/escapementitem.hxx> +#include <editeng/langitem.hxx> +#include <o3tl/unit_conversion.hxx> +#include <svx/svdograf.hxx> +#include <svx/svdpage.hxx> +#include <sfx2/sfxhtml.hxx> +#include <svl/numformat.hxx> +#include <svl/zforlist.hxx> +#include <vcl/virdev.hxx> +#include <vcl/svapp.hxx> +#include <unotools/charclass.hxx> +#include <unotools/configmgr.hxx> +#include <comphelper/string.hxx> +#include <osl/diagnose.h> +#include <officecfg/Office/Common.hxx> + +#include <eeimport.hxx> +#include <global.hxx> +#include <document.hxx> +#include <editutil.hxx> +#include <docpool.hxx> +#include <attrib.hxx> +#include <patattr.hxx> +#include <eeparser.hxx> +#include <drwlayer.hxx> +#include <rangenam.hxx> +#include <progress.hxx> +#include <stringutil.hxx> +#include <rowheightcontext.hxx> +#include <fuinsert.hxx> + +#include <globstr.hrc> +#include <scresid.hxx> + +#include <memory> + +ScEEImport::ScEEImport( ScDocument* pDocP, const ScRange& rRange ) : + maRange( rRange ), + mpDoc( pDocP ) +{ + const ScPatternAttr* pPattern = mpDoc->GetPattern( + maRange.aStart.Col(), maRange.aStart.Row(), maRange.aStart.Tab() ); + mpEngine.reset( new ScTabEditEngine(*pPattern, mpDoc->GetEditPool(), mpDoc, mpDoc->GetEditPool()) ); + mpEngine->SetUpdateLayout( false ); + mpEngine->EnableUndo( false ); +} + +ScEEImport::~ScEEImport() +{ + // Sequence important, or else we crash in some dtor! + // Is guaranteed as ScEEImport is base class +} + +ErrCode ScEEImport::Read( SvStream& rStream, const OUString& rBaseURL ) +{ + ErrCode nErr = mpParser->Read( rStream, rBaseURL ); + + SCCOL nEndCol; + SCROW nEndRow; + mpParser->GetDimensions( nEndCol, nEndRow ); + if ( nEndCol != 0 ) + { + nEndCol += maRange.aStart.Col() - 1; + if ( nEndCol > mpDoc->MaxCol() ) + nEndCol = mpDoc->MaxCol(); + } + else + nEndCol = maRange.aStart.Col(); + if ( nEndRow != 0 ) + { + nEndRow += maRange.aStart.Row() - 1; + if ( nEndRow > mpDoc->MaxRow() ) + nEndRow = mpDoc->MaxRow(); + } + else + nEndRow = maRange.aStart.Row(); + maRange.aEnd.Set( nEndCol, nEndRow, maRange.aStart.Tab() ); + + return nErr; +} + +namespace +{ + bool IsValidSel(const ScTabEditEngine& rEngine, const ESelection& rSel) + { + const auto nParaCount = rEngine.GetParagraphCount(); + return rSel.nStartPara < nParaCount && rSel.nEndPara < nParaCount; + } +} + +void ScEEImport::WriteToDocument( bool bSizeColsRows, double nOutputFactor, SvNumberFormatter* pFormatter, bool bConvertDate ) +{ + std::unique_ptr<ScProgress> pProgress( new ScProgress( mpDoc->GetDocumentShell(), + ScResId( STR_LOAD_DOC ), mpParser->ListSize(), true ) ); + sal_uLong nProgress = 0; + + SCCOL nStartCol, nEndCol; + SCROW nStartRow, nEndRow; + SCTAB nTab; + SCROW nOverlapRowMax, nLastMergedRow; + SCCOL nMergeColAdd; + nStartCol = maRange.aStart.Col(); + nStartRow = maRange.aStart.Row(); + nTab = maRange.aStart.Tab(); + nEndCol = maRange.aEnd.Col(); + nEndRow = maRange.aEnd.Row(); + nOverlapRowMax = 0; + nMergeColAdd = 0; + nLastMergedRow = SCROW_MAX; + bool bHasGraphics = false; + ScEEParseEntry* pE; + if (!pFormatter) + pFormatter = mpDoc->GetFormatTable(); + bool bNumbersEnglishUS = false; + if (pFormatter->GetLanguage() == LANGUAGE_SYSTEM && !utl::ConfigManager::IsFuzzing()) + { + // Automatic language option selected. Check for the global 'use US English' option. + bNumbersEnglishUS = officecfg::Office::Common::Filter::HTML::Import::NumbersEnglishUS::get(); + } + ScDocumentPool* pDocPool = mpDoc->GetPool(); + ScRangeName* pRangeNames = mpDoc->GetRangeName(); + for ( size_t i = 0, n = mpParser->ListSize(); i < n; ++i ) + { + pE = mpParser->ListEntry( i ); + SCROW nRow = nStartRow + pE->nRow; + if ( nRow != nLastMergedRow ) + nMergeColAdd = 0; + SCCOL nCol = nStartCol + pE->nCol + nMergeColAdd; + // Determine RowMerge + // Pure ColMerge and ColMerge of the first MergeRow already done during parsing + if (nRow <= nOverlapRowMax && mpDoc->ValidCol(nCol)) + { + while ( nCol <= mpDoc->MaxCol() && mpDoc->HasAttrib( nCol, nRow, nTab, + nCol, nRow, nTab, HasAttrFlags::Overlapped ) ) + { + nCol++; + nMergeColAdd++; + } + nLastMergedRow = nRow; + } + // Add for second run + pE->nCol = nCol; + pE->nRow = nRow; + if ( mpDoc->ValidCol(nCol) && mpDoc->ValidRow(nRow) ) + { + SfxItemSet aSet = mpEngine->GetAttribs( pE->aSel ); + // Remove default: we set left/right ourselves depending on Text or + // Number + // EditView.GetAttribs always returns complete Set filled with + // defaults + const SfxPoolItem& rItem = aSet.Get( EE_PARA_JUST ); + if ( static_cast<const SvxAdjustItem&>(rItem).GetAdjust() == SvxAdjust::Left ) + aSet.ClearItem( EE_PARA_JUST ); + + // Test whether simple String without mixed attributes + bool bSimple = ( pE->aSel.nStartPara == pE->aSel.nEndPara ); + for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END && bSimple; nId++) + { + const SfxPoolItem* pItem = nullptr; + SfxItemState eState = aSet.GetItemState( nId, true, &pItem ); + if (eState == SfxItemState::DONTCARE) + bSimple = false; + else if (eState == SfxItemState::SET) + { + if ( nId == EE_CHAR_ESCAPEMENT ) // Super-/Subscript always via EE + { + if ( static_cast<SvxEscapement>(static_cast<const SvxEscapementItem*>(pItem)->GetEnumValue()) + != SvxEscapement::Off ) + bSimple = false; + } + } + } + if ( bSimple ) + { // Contains field commands? + SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, false ); + if ( eFieldState == SfxItemState::DONTCARE || eFieldState == SfxItemState::SET ) + bSimple = false; + } + + // HTML + OUString aValStr, aNumStr; + double fVal = 0.0; + sal_uInt32 nNumForm = 0; + LanguageType eNumLang = LANGUAGE_NONE; + if ( pE->pNumStr ) + { // SDNUM needs to be if SDVAL + aNumStr = *pE->pNumStr; + if ( pE->pValStr ) + aValStr = *pE->pValStr; + fVal = SfxHTMLParser::GetTableDataOptionsValNum( + nNumForm, eNumLang, aValStr, aNumStr, *pFormatter ); + } + + // Set attributes + auto pAttr = std::make_unique<ScPatternAttr>( pDocPool ); + pAttr->GetFromEditItemSet( &aSet ); + SfxItemSet* pAttrItemSet = &pAttr->GetItemSet(); + if (!aNumStr.isEmpty()) + { + pAttrItemSet->Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumForm ) ); + pAttrItemSet->Put( SvxLanguageItem( eNumLang, ATTR_LANGUAGE_FORMAT ) ); + } + const SfxItemSet& rESet = pE->aItemSet; + if ( rESet.Count() ) + { + const SfxPoolItem* pItem; + if ( rESet.GetItemState( ATTR_BACKGROUND, false, &pItem) == SfxItemState::SET ) + pAttrItemSet->Put( *pItem ); + if ( rESet.GetItemState( ATTR_BORDER, false, &pItem) == SfxItemState::SET ) + pAttrItemSet->Put( *pItem ); + if ( rESet.GetItemState( ATTR_SHADOW, false, &pItem) == SfxItemState::SET ) + pAttrItemSet->Put( *pItem ); + // HTML + if ( rESet.GetItemState( ATTR_HOR_JUSTIFY, false, &pItem) == SfxItemState::SET ) + pAttrItemSet->Put( *pItem ); + if ( rESet.GetItemState( ATTR_VER_JUSTIFY, false, &pItem) == SfxItemState::SET ) + pAttrItemSet->Put( *pItem ); + if ( rESet.GetItemState( ATTR_LINEBREAK, false, &pItem) == SfxItemState::SET ) + pAttrItemSet->Put( *pItem ); + if ( rESet.GetItemState( ATTR_FONT_COLOR, false, &pItem) == SfxItemState::SET ) + pAttrItemSet->Put( *pItem ); + if ( rESet.GetItemState( ATTR_FONT_UNDERLINE, false, &pItem) == SfxItemState::SET ) + pAttrItemSet->Put( *pItem ); + // HTML LATIN/CJK/CTL script type dependent + const SfxPoolItem* pFont; + if ( rESet.GetItemState( ATTR_FONT, false, &pFont) != SfxItemState::SET ) + pFont = nullptr; + const SfxPoolItem* pHeight; + if ( rESet.GetItemState( ATTR_FONT_HEIGHT, false, &pHeight) != SfxItemState::SET ) + pHeight = nullptr; + const SfxPoolItem* pWeight; + if ( rESet.GetItemState( ATTR_FONT_WEIGHT, false, &pWeight) != SfxItemState::SET ) + pWeight = nullptr; + const SfxPoolItem* pPosture; + if ( rESet.GetItemState( ATTR_FONT_POSTURE, false, &pPosture) != SfxItemState::SET ) + pPosture = nullptr; + // Number format + const SfxPoolItem* pNumFmt = nullptr; + if ( rESet.GetItemState(ATTR_VALUE_FORMAT, false, &pNumFmt) == SfxItemState::SET ) + pAttrItemSet->Put(*pNumFmt); + if ( pFont || pHeight || pWeight || pPosture ) + { + OUString aStr( mpEngine->GetText( pE->aSel ) ); + SvtScriptType nScriptType = mpDoc->GetStringScriptType( aStr ); + const SvtScriptType nScripts[3] = { SvtScriptType::LATIN, + SvtScriptType::ASIAN, SvtScriptType::COMPLEX }; + for (SvtScriptType nScript : nScripts) + { + if ( nScriptType & nScript ) + { + if ( pFont ) + { + pAttrItemSet->Put( pFont->CloneSetWhich( + ScGlobal::GetScriptedWhichID(nScript, ATTR_FONT )) ); + } + if ( pHeight ) + { + pAttrItemSet->Put( pHeight->CloneSetWhich( + ScGlobal::GetScriptedWhichID(nScript, ATTR_FONT_HEIGHT )) ); + } + if ( pWeight ) + { + pAttrItemSet->Put( pWeight->CloneSetWhich( + ScGlobal::GetScriptedWhichID(nScript, ATTR_FONT_WEIGHT )) ); + } + if ( pPosture ) + { + pAttrItemSet->Put( pPosture->CloneSetWhich( + ScGlobal::GetScriptedWhichID(nScript, ATTR_FONT_POSTURE )) ); + } + } + } + } + } + if ( pE->nColOverlap > 1 || pE->nRowOverlap > 1 ) + { // Merged cells, with SfxItemSet.Put() is faster than + // with ScDocument.DoMerge() afterwards + ScMergeAttr aMerge( pE->nColOverlap, pE->nRowOverlap ); + pAttrItemSet->Put( aMerge ); + SCROW nRO = 0; + if ( pE->nColOverlap > 1 ) + mpDoc->ApplyFlagsTab( nCol+1, nRow, + nCol + pE->nColOverlap - 1, nRow, nTab, + ScMF::Hor ); + if ( pE->nRowOverlap > 1 ) + { + nRO = nRow + pE->nRowOverlap - 1; + mpDoc->ApplyFlagsTab( nCol, nRow+1, + nCol, nRO , nTab, + ScMF::Ver ); + if ( nRO > nOverlapRowMax ) + nOverlapRowMax = nRO; + } + if ( pE->nColOverlap > 1 && pE->nRowOverlap > 1 ) + mpDoc->ApplyFlagsTab( nCol+1, nRow+1, + nCol + pE->nColOverlap - 1, nRO, nTab, + ScMF::Hor | ScMF::Ver ); + } + const ScStyleSheet* pStyleSheet = + mpDoc->GetPattern( nCol, nRow, nTab )->GetStyleSheet(); + pAttr->SetStyleSheet( const_cast<ScStyleSheet*>(pStyleSheet) ); + auto rAttrItemSet2 = mpDoc->SetPattern( nCol, nRow, nTab, std::move(pAttr) )->GetItemSet(); + + // Add data + if (bSimple) + { + ScSetStringParam aParam; + aParam.mpNumFormatter = pFormatter; + aParam.mbDetectNumberFormat = true; + aParam.meSetTextNumFormat = ScSetStringParam::SpecialNumberOnly; + aParam.mbHandleApostrophe = false; + aParam.mbCheckLinkFormula = true; + + if (!aValStr.isEmpty()) + mpDoc->SetValue( nCol, nRow, nTab, fVal ); + else if ( !pE->aSel.HasRange() ) + { + // maybe ALT text of IMG or similar + mpDoc->SetString( nCol, nRow, nTab, pE->aAltText, &aParam ); + // If SelRange is completely empty, the succeeding text can be in the same paragraph! + } + else + { + OUString aStr; + if( pE->bEntirePara ) + { + aStr = mpEngine->GetText( pE->aSel.nStartPara ); + } + else + { + aStr = comphelper::string::strip(mpEngine->GetText(pE->aSel), ' '); + } + + bool bTextFormat = false; + + if (const SfxUInt32Item* pNumFmt = rAttrItemSet2.GetItemIfSet(ATTR_VALUE_FORMAT, false)) + { + sal_uInt32 nNumFmt = pNumFmt->GetValue(); + SvNumFormatType nType = pFormatter->GetType(nNumFmt); + if (nType == SvNumFormatType::TEXT) + // Format is set to Text. + bTextFormat = true; + } + + // TODO: RTF import should follow the language tag, + // currently this follows the HTML options for both, HTML + // and RTF. + if (bNumbersEnglishUS) + { + pFormatter->ChangeIntl( LANGUAGE_ENGLISH_US); + sal_uInt32 nIndex = pFormatter->GetStandardIndex( LANGUAGE_ENGLISH_US); + double fEnVal = 0.0; + if (pFormatter->IsNumberFormat( aStr, nIndex, fEnVal)) + { + sal_uInt32 nNewIndex = + pFormatter->GetFormatForLanguageIfBuiltIn( + nIndex, LANGUAGE_SYSTEM); + OSL_ENSURE( nNewIndex != nIndex, "ScEEImport::WriteToDocument: NumbersEnglishUS not a built-in format?"); + pFormatter->GetInputLineString( fEnVal, nNewIndex, aStr); + } + else + bTextFormat = true; + pFormatter->ChangeIntl( LANGUAGE_SYSTEM); + } + + // #105460#, #i4180# String cells can't contain tabs or linebreaks + // -> replace with spaces + aStr = aStr.replaceAll( "\t", " " ); + aStr = aStr.replaceAll( "\n", " " ); + + if (bTextFormat) + { + aParam.mbDetectNumberFormat = false; + aParam.meSetTextNumFormat = ScSetStringParam::Always; + } + else + aParam.mbDetectNumberFormat = bConvertDate; + + mpDoc->SetString(nCol, nRow, nTab, aStr, &aParam); + } + } + else if (std::unique_ptr<EditTextObject> pTextObject = IsValidSel(*mpEngine, pE->aSel) ? mpEngine->CreateTextObject(pE->aSel) : nullptr) + { + // The cell will own the text object instance. + mpDoc->SetEditText(ScAddress(nCol,nRow,nTab), std::move(pTextObject)); + } + if ( !pE->maImageList.empty() ) + bHasGraphics |= GraphicSize( nCol, nRow, pE ); + if ( pE->pName ) + { // Anchor Name => RangeName + if (!pRangeNames->findByUpperName(ScGlobal::getCharClass().uppercase(*pE->pName))) + { + ScRangeData* pData = new ScRangeData( *mpDoc, *pE->pName, + ScAddress( nCol, nRow, nTab ) ); + pRangeNames->insert( pData ); + } + } + } + pProgress->SetStateOnPercent( ++nProgress ); + } + if ( bSizeColsRows ) + { + // Column widths + ColWidthsMap& rColWidths = mpParser->GetColWidths(); + if ( !rColWidths.empty() ) + { + nProgress = 0; + pProgress->SetState( nProgress, nEndCol - nStartCol + 1 ); + for ( SCCOL nCol = nStartCol; nCol <= nEndCol; nCol++ ) + { + sal_uInt16 nWidth = 0; + ColWidthsMap::const_iterator it = rColWidths.find( nCol ); + if ( it != rColWidths.end() ) + nWidth = it->second; + if ( nWidth ) + mpDoc->SetColWidth( nCol, nTab, nWidth ); + pProgress->SetState( ++nProgress ); + } + } + pProgress.reset(); // SetOptimalHeight has its own ProgressBar + // Adjust line height, base is 100% zoom + Fraction aZoom( 1, 1 ); + // Factor is printer to display ratio + double nPPTX = ScGlobal::nScreenPPTX * static_cast<double>(aZoom) / nOutputFactor; + double nPPTY = ScGlobal::nScreenPPTY * static_cast<double>(aZoom); + ScopedVclPtrInstance< VirtualDevice > pVirtDev; + sc::RowHeightContext aCxt(mpDoc->MaxRow(), nPPTX, nPPTY, aZoom, aZoom, pVirtDev); + aCxt.setExtraHeight(ScGlobal::nLastRowHeightExtra); + mpDoc->SetOptimalHeight(aCxt, 0, nEndRow, 0, true); + + if ( !maRowHeights.empty() ) + { + for ( SCROW nRow = nStartRow; nRow <= nEndRow; nRow++ ) + { + RowHeightMap::const_iterator it = maRowHeights.find( nRow ); + sal_uInt16 nHeight = it == maRowHeights.end() ? 0 : it->second; + if ( nHeight > mpDoc->GetRowHeight( nRow, nTab ) ) + mpDoc->SetRowHeight( nRow, nTab, nHeight ); + } + } + } + if ( !bHasGraphics ) + return; + + // Insert graphics + for ( size_t i = 0, nListSize = mpParser->ListSize(); i < nListSize; ++i ) + { + pE = mpParser->ListEntry( i ); + if ( !pE->maImageList.empty() ) + { + SCCOL nCol = pE->nCol; + SCROW nRow = pE->nRow; + if ( mpDoc->ValidCol(nCol) && mpDoc->ValidRow(nRow) ) + InsertGraphic( nCol, nRow, nTab, pE ); + } + } +} + +bool ScEEImport::GraphicSize( SCCOL nCol, SCROW nRow, ScEEParseEntry* pE ) +{ + if ( pE->maImageList.empty() ) + return false; + bool bHasGraphics = false; + OutputDevice* pDefaultDev = Application::GetDefaultDevice(); + tools::Long nWidth, nHeight; + nWidth = nHeight = 0; + char nDir = nHorizontal; + for (const std::unique_ptr<ScHTMLImage> & pImage : pE->maImageList) + { + ScHTMLImage* pI = pImage.get(); + if ( pI->pGraphic ) + bHasGraphics = true; + Size aSizePix = pI->aSize; + aSizePix.AdjustWidth(2 * pI->aSpace.X() ); + aSizePix.AdjustHeight(2 * pI->aSpace.Y() ); + Size aLogicSize = pDefaultDev->PixelToLogic( aSizePix, MapMode( MapUnit::MapTwip ) ); + if ( nDir & nHorizontal ) + nWidth += aLogicSize.Width(); + else if ( nWidth < aLogicSize.Width() ) + nWidth = aLogicSize.Width(); + if ( nDir & nVertical ) + nHeight += aLogicSize.Height(); + else if ( nHeight < aLogicSize.Height() ) + nHeight = aLogicSize.Height(); + nDir = pI->nDir; + } + // Column widths + ColWidthsMap& rColWidths = mpParser->GetColWidths(); + tools::Long nThisWidth = 0; + ColWidthsMap::const_iterator it = rColWidths.find( nCol ); + if ( it != rColWidths.end() ) + nThisWidth = it->second; + tools::Long nColWidths = nThisWidth; + SCCOL nColSpanCol = nCol + pE->nColOverlap; + for ( SCCOL nC = nCol + 1; nC < nColSpanCol; nC++ ) + { + ColWidthsMap::const_iterator it2 = rColWidths.find( nC ); + if ( it2 != rColWidths.end() ) + nColWidths += it2->second; + } + if ( nWidth > nColWidths ) + { // Only insert difference in first column + rColWidths[ nCol ] = nWidth - nColWidths + nThisWidth; + } + // Distribute line height difference between all affected lines + SCROW nRowSpan = pE->nRowOverlap; + + assert(nRowSpan != 0); + if ( nRowSpan == 0 ) + return bHasGraphics; + + nHeight /= nRowSpan; + + if ( nHeight == 0 ) + nHeight = 1; // For definite comparison + for ( SCROW nR = nRow; nR < nRow + nRowSpan; nR++ ) + { + RowHeightMap::const_iterator it2 = maRowHeights.find( nR ); + tools::Long nRowHeight = it2 == maRowHeights.end() ? 0 : it2->second; + if ( nHeight > nRowHeight ) + { + maRowHeights[ nR ] = nHeight; + } + } + return bHasGraphics; +} + +void ScEEImport::InsertGraphic( SCCOL nCol, SCROW nRow, SCTAB nTab, + ScEEParseEntry* pE ) +{ + if ( pE->maImageList.empty() ) + return ; + ScDrawLayer* pModel = mpDoc->GetDrawLayer(); + if (!pModel) + { + mpDoc->InitDrawLayer(); + pModel = mpDoc->GetDrawLayer(); + } + SdrPage* pPage = pModel->GetPage( static_cast<sal_uInt16>(nTab) ); + OutputDevice* pDefaultDev = Application::GetDefaultDevice(); + + Point aCellInsertPos( + o3tl::convert(mpDoc->GetColOffset(nCol, nTab), o3tl::Length::twip, o3tl::Length::mm100), + o3tl::convert(mpDoc->GetRowOffset(nRow, nTab), o3tl::Length::twip, o3tl::Length::mm100)); + + Point aInsertPos( aCellInsertPos ); + Point aSpace; + Size aLogicSize; + char nDir = nHorizontal; + for (const std::unique_ptr<ScHTMLImage> & pImage : pE->maImageList) + { + ScHTMLImage* pI = pImage.get(); + if ( nDir & nHorizontal ) + { // Horizontal + aInsertPos.AdjustX(aLogicSize.Width() ); + aInsertPos.AdjustX(aSpace.X() ); + aInsertPos.setY( aCellInsertPos.Y() ); + } + else + { // Vertical + aInsertPos.setX( aCellInsertPos.X() ); + aInsertPos.AdjustY(aLogicSize.Height() ); + aInsertPos.AdjustY(aSpace.Y() ); + } + // Add offset of Spacing + aSpace = pDefaultDev->PixelToLogic( pI->aSpace, MapMode( MapUnit::Map100thMM ) ); + aInsertPos += aSpace; + + Size aSizePix = pI->aSize; + aLogicSize = pDefaultDev->PixelToLogic( aSizePix, MapMode( MapUnit::Map100thMM ) ); + + // Limit size + ::ScLimitSizeOnDrawPage( aLogicSize, aInsertPos, pPage->GetSize() ); + + if ( pI->pGraphic ) + { + tools::Rectangle aRect ( aInsertPos, aLogicSize ); + SdrGrafObj* pObj = new SdrGrafObj( + *pModel, + *pI->pGraphic, + aRect); + + // calling SetGraphicLink here doesn't work + pObj->SetName( pI->aURL ); + + pPage->InsertObject( pObj ); + + // SetGraphicLink has to be used after inserting the object, + // otherwise an empty graphic is swapped in and the contact stuff crashes. + // See #i37444#. + pObj->SetGraphicLink( pI->aURL ); + + pObj->SetLogicRect( aRect ); // Only after InsertObject! + } + nDir = pI->nDir; + } +} + +ScEEParser::ScEEParser( EditEngine* pEditP ) : + pEdit( pEditP ), + pPool( EditEngine::CreatePool() ), + pDocPool( new ScDocumentPool ), + nRtfLastToken(0), + nColCnt(0), + nRowCnt(0), + nColMax(0), + nRowMax(0) +{ + // pPool is foisted on SvxRTFParser at RtfImportState::Start later on + pPool->SetSecondaryPool( pDocPool.get() ); + pPool->FreezeIdRanges(); + NewActEntry( nullptr ); +} + +ScEEParser::~ScEEParser() +{ + mxActEntry.reset(); + maList.clear(); + + // Don't delete Pool until the lists have been deleted + pPool->SetSecondaryPool( nullptr ); + pDocPool.clear(); + pPool.clear(); +} + +void ScEEParser::NewActEntry( const ScEEParseEntry* pE ) +{ // New free-flying mxActEntry + mxActEntry = std::make_shared<ScEEParseEntry>(pPool.get()); + mxActEntry->aSel.nStartPara = (pE ? pE->aSel.nEndPara + 1 : 0); + mxActEntry->aSel.nStartPos = 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |