/* -*- 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 .
*/
void ScDocument::SetPrinter( VclPtr<SfxPrinter> const & pNewPrinter )
{ if ( pNewPrinter == mpPrinter.get() )
{ // #i6706# SetPrinter is called with the same printer again if // the JobSetup has changed. In that case just call UpdateDrawPrinter // (SetRefDevice for drawing layer) because of changed text sizes.
UpdateDrawPrinter();
} else
{
ScopedVclPtr<SfxPrinter> xKeepAlive( mpPrinter );
mpPrinter = pNewPrinter;
UpdateDrawPrinter();
mpPrinter->SetDigitLanguage( ScModule::GetOptDigitLanguage() );
}
InvalidateTextWidth(nullptr, nullptr, false); // in both cases
}
void ScDocument::SetPrintOptions()
{ if ( !mpPrinter ) GetPrinter(); // this sets mpPrinter
OSL_ENSURE( mpPrinter, "Error in printer creation :-/" );
void ScDocument::CopyStdStylesFrom( const ScDocument& rSrcDoc )
{ // number format exchange list has to be handled here, too
NumFmtMergeHandler aNumFmtMergeHdl(*this, rSrcDoc);
mxPoolHelper->GetStylePool()->CopyStdStylesFrom( rSrcDoc.mxPoolHelper->GetStylePool() );
}
void ScDocument::InvalidateTextWidth( std::u16string_view rStyleName )
{ const SCTAB nCount = GetTableCount(); for ( SCTAB i=0; i<nCount && maTabs[i]; i++ ) if ( maTabs[i]->GetPageStyle() == rStyleName )
InvalidateTextWidth( i );
}
assert(IsThreadedGroupCalcInProgress());
maThreadSpecific.pContext = nullptr; // If any of the thread_local data would cause problems if they stay around for too long // (and e.g. outlive the ScDocument), clean them up here, they cannot be cleaned up // later from the main thread. if(maThreadSpecific.xRecursionHelper)
maThreadSpecific.xRecursionHelper->Clear();
}
bool ScDocument::IdleCalcTextWidth() // true = try next again
{ // #i75610# if a printer hasn't been set or created yet, don't create one for this if (!mbIdleEnabled || IsInLinkUpdate() || GetPrinter(false) == nullptr) returnfalse;
if (!pStyle || getScaleValue(*pStyle, ATTR_PAGE_SCALETOPAGES) == 0)
{ // Move to the next sheet as the current one has scale-to-pages set, // and bail out.
aScope.incTab(); returnfalse;
}
aScope.setCol(pTab->ClampToAllocatedColumns(aScope.Col())); // Start at specified cell position (nCol, nRow, nTab).
ScColumn* pCol = &pTab->aCol[aScope.Col()];
std::optional<ScColumnTextWidthIterator> pColIter(std::in_place, *this, *pCol, aScope.Row(), MaxRow());
OutputDevice* pDev = nullptr;
sal_uInt16 nRestart = 0;
sal_uInt16 nCount = 0; while ( (nZoom > 0) && (nCount < CALCMAX) && (nRestart < 2) )
{ if (pColIter->hasCell())
{ // More cell in this column.
SCROW nRow = pColIter->getPos();
aScope.setRow(nRow);
if (pColIter->getValue() == TEXTWIDTH_DIRTY)
{ // Calculate text width for this cell. double nPPTX = 0.0; double nPPTY = 0.0; if (!pDev)
{
pDev = GetPrinter();
assert(pDev);
aScope.setOldMapMode(pDev->GetMapMode());
pDev->SetMapMode(MapMode(MapUnit::MapPixel)); // Important for GetNeededSize
pColIter->setValue(nNewWidth);
aScope.setNeedMore(true);
}
pColIter->next();
} else
{ // No more cell in this column. Move to the left column and start at row 0.
bool bNewTab = false;
aScope.setRow(0);
aScope.incCol(-1);
if (aScope.Col() < 0)
{ // No more column to the left. Move to the right-most column of the next sheet.
aScope.setCol(MaxCol());
aScope.incTab();
bNewTab = true;
}
if (!HasTable(aScope.Tab()))
{ // Sheet doesn't exist at specified sheet position. Restart at sheet 0.
aScope.setTab(0);
nRestart++;
bNewTab = true;
}
if ( pStyle )
{ // Check if the scale-to-pages setting is set. If // set, we exit the loop. If not, get the page // scale factor of the new sheet. if (getScaleValue(*pStyle, ATTR_PAGE_SCALETOPAGES) == 0)
{
nZoom = getScaleValue(*pStyle, ATTR_PAGE_SCALE);
aZoomFract = Fraction(nZoom, 100);
} else
nZoom = 0;
} else
{
OSL_FAIL( "Missing StyleSheet :-/" );
}
}
if ( nZoom > 0 )
{
pCol = &pTab->aCol[aScope.Col()];
pColIter.emplace(*this, *pCol, aScope.Row(), MaxRow());
} else
{
aScope.incTab(); // Move to the next sheet as the current one has scale-to-pages set. returnfalse;
}
}
}
++nCount;
if (!aScope.continueIter()) break;
}
return aScope.getNeedMore();
}
void ScDocument::RepaintRange( const ScRange& rRange )
{ if ( bIsVisible && mpShell )
{
ScModelObj* pModel = mpShell->GetModel(); if ( pModel )
pModel->RepaintRange( rRange ); // locked repaints are checked there
}
}
void ScDocument::RepaintRange( const ScRangeList& rRange )
{ if ( bIsVisible && mpShell )
{
ScModelObj* pModel = mpShell->GetModel(); if ( pModel )
pModel->RepaintRange( rRange ); // locked repaints are checked there
}
}
void ScDocument::SaveDdeLinks(SvStream& rStream) const
{ // when 4.0-Export, remove all with mode != DEFAULT bool bExport40 = ( rStream.GetVersion() <= SOFFICE_FILEFORMAT_40 );
// Collect all the external ref links first.
std::vector<ScExternalRefLink*> aRefLinks; for (sal_uInt16 i = 0; i < nCount; ++i)
{
::sfx2::SvBaseLink* pBase = rLinks[i].get();
ScExternalRefLink* pRefLink = dynamic_cast<ScExternalRefLink*>(pBase); if (pRefLink)
aRefLinks.push_back(pRefLink);
}
weld::WaitObject aWaitSwitch(pWin);
pExternalRefMgr->enableDocTimer(false);
ScProgress aProgress(GetDocumentShell(), ScResId(SCSTR_UPDATE_EXTDOCS), aRefLinks.size(), true); for (size_t i = 0, n = aRefLinks.size(); i < n; ++i)
{
aProgress.SetState(i+1);
bool ScDocument::CreateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem, sal_uInt8 nMode, const ScMatrixRef& pResults )
{ /* Create a DDE link without updating it (i.e. for Excel import), to prevent unwanted connections. First try to find existing link. Set result array
on existing and new links. */ //TODO: store DDE links additionally at document (for efficiency)?
OSL_ENSURE( nMode != SC_DDE_IGNOREMODE, "ScDocument::CreateDdeLink - SC_DDE_IGNOREMODE not allowed here" );
sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc); if (!pMgr) returnfalse;
if (nMode != SC_DDE_IGNOREMODE)
{
ScDdeLink* pDdeLink = lclGetDdeLink(pMgr, rAppl, rTopic, rItem, nMode); if( !pDdeLink )
{ // create a new DDE link, but without TryUpdate
pDdeLink = new ScDdeLink( *this, rAppl, rTopic, rItem, nMode );
pMgr->InsertDDELink(pDdeLink, rAppl, rTopic, rItem);
}
// insert link results if( pResults )
pDdeLink->SetResult( pResults );
void ScDocument::UpdateAreaLinks()
{
sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(false); if (!pMgr) return;
const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks(); // Note: SvBaseLink::Update can remove entries after the current one for (size_t i = 0; i < rLinks.size(); ++i)
{
::sfx2::SvBaseLink* pBase = rLinks[i].get(); if (dynamic_cast<const ScAreaLink*>( pBase) != nullptr)
pBase->Update();
}
}
// #i52120# Look for duplicates (after updating all positions). // If several links start at the same cell, the one with the lower index is removed // (file format specifies only one link definition for a cell).
void ScDocument::CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode )
{ if (HasLinkFormulaNeedingCheck()) return;
// Prefer RPN over tokenized formula if available. if (rCode.GetCodeLen())
{ if (rCode.HasOpCodeRPN(ocDde) || rCode.HasOpCodeRPN(ocWebservice))
SetLinkFormulaNeedingCheck(true);
} elseif (rCode.GetLen())
{ if (rCode.HasOpCode(ocDde) || rCode.HasOpCode(ocWebservice))
SetLinkFormulaNeedingCheck(true);
} else
{ // Possible with named expression without expression like Excel // internal print ranges, obscure user define names, ... formula error // cells without formula ...
SAL_WARN("sc.core","ScDocument::CheckLinkFormulaNeedingCheck - called with empty ScTokenArray");
}
}
// TimerDelays etc. void ScDocument::KeyInput()
{ if ( pChartListenerCollection->hasListeners() )
pChartListenerCollection->StartTimer(); if (apTemporaryChartLock)
apTemporaryChartLock->StartOrContinueLocking();
}
SfxBindings* ScDocument::GetViewBindings()
{ // used to invalidate slots after changes to this document
if ( !mpShell ) return nullptr; // no ObjShell -> no view
// first check current view
SfxViewFrame* pViewFrame = SfxViewFrame::Current(); if ( pViewFrame && pViewFrame->GetObjectShell() != mpShell ) // wrong document?
pViewFrame = nullptr;
// otherwise use first view for this doc if ( !pViewFrame )
pViewFrame = SfxViewFrame::GetFirst( mpShell );
if (pViewFrame) return &pViewFrame->GetBindings(); else return nullptr;
}
while (bFound)
{
ScRefCellValue aCell(*this, ScAddress(nCol, nRow, nTab));
// fdo#32786 TITLE_CASE/SENTENCE_CASE need the extra handling in EditEngine (loop over words/sentences). // Still use TransliterationWrapper directly for text cells with other transliteration types, // for performance reasons. if (aCell.getType() == CELLTYPE_EDIT ||
(aCell.getType() == CELLTYPE_STRING &&
( nType == TransliterationFlags::SENTENCE_CASE || nType == TransliterationFlags::TITLE_CASE)))
{ if (!pEngine)
pEngine.reset(new ScFieldEditEngine(this, GetEnginePool(), GetEditPool()));
// defaults from cell attributes must be set so right language is used const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab );
SfxItemSet aDefaults( pEngine->GetEmptyItemSet() ); if ( ScStyleSheet* pPreviewStyle = GetPreviewCellStyle( nCol, nRow, nTab ) )
{
ScPatternAttr aPreviewPattern( *pPattern );
aPreviewPattern.SetStyleSheet(pPreviewStyle);
aPreviewPattern.FillEditItemSet(&aDefaults);
} else
{
SfxItemSet* pFontSet = GetPreviewFont( nCol, nRow, nTab );
pPattern->FillEditItemSet(&aDefaults, pFontSet);
}
pEngine->SetDefaults(std::move(aDefaults)); if (aCell.getType() == CELLTYPE_STRING)
pEngine->SetTextCurrentDefaults(aCell.getSharedString()->getString()); elseif (aCell.getEditText())
pEngine->SetTextCurrentDefaults(*aCell.getEditText());
if ( pEngine->IsModified() )
{
ScEditAttrTester aTester( pEngine.get() ); if ( aTester.NeedsObject() )
{ // remove defaults (paragraph attributes) before creating text object
pEngine->SetDefaults(pEngine->GetEmptyItemSet());
// The cell will take ownership of the text object instance.
SetEditText(ScAddress(nCol,nRow,nTab), pEngine->CreateTextObject());
} else
{
ScSetStringParam aParam;
aParam.setTextInput();
SetString(ScAddress(nCol,nRow,nTab), pEngine->GetText(), &aParam);
}
}
}
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.