/* -*- 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 .
*/
// #i111553# provides the name of the VBA constant for this document type (e.g. 'ThisExcelDoc' for Calc)
constexpr OUString SC_UNO_VBAGLOBNAME = u"VBAGlobalConstantName"_ustr;
// load the writer PrinterOptions into the custom tab
m_aUIProperties[nIdx].Name = "OptionsUIFile";
m_aUIProperties[nIdx++].Value <<= u"modules/scalc/ui/printeroptions.ui"_ustr;
// create Section for spreadsheet (results in an extra tab page in dialog)
SvtModuleOptions aOpt;
OUString aAppGroupname( ScResId( SCSTR_PRINTOPT_PRODNAME ) );
aAppGroupname = aAppGroupname.replaceFirst( "%s", aOpt.GetModuleName( SvtModuleOptions::EModule::CALC ) );
m_aUIProperties[nIdx++].Value = setGroupControlOpt(u"tabcontrol-page2"_ustr, aAppGroupname, OUString());
// show subgroup for pages
m_aUIProperties[nIdx++].Value = setSubgroupControlOpt(u"pages"_ustr, ScResId( SCSTR_PRINTOPT_PAGES ), OUString());
// create a bool option for empty pages
m_aUIProperties[nIdx++].Value = setBoolControlOpt(u"suppressemptypages"_ustr, ScResId( SCSTR_PRINTOPT_SUPPRESSEMPTY ),
u".HelpID:vcl:PrintDialog:IsSuppressEmptyPages:CheckBox"_ustr,
u"IsSuppressEmptyPages"_ustr,
bSuppress); // show Subgroup for print content
vcl::PrinterOptionsHelper::UIControlOptions aPrintRangeOpt;
aPrintRangeOpt.maGroupHint = "PrintRange";
m_aUIProperties[nIdx++].Value = setSubgroupControlOpt(u"printrange"_ustr, ScResId( SCSTR_PRINTOPT_PAGES ),
OUString(),
aPrintRangeOpt);
// create a choice for the content to create
uno::Sequence< OUString > aChoices{
ScResId( SCSTR_PRINTOPT_ALLSHEETS ),
ScResId( SCSTR_PRINTOPT_SELECTEDSHEETS ),
ScResId( SCSTR_PRINTOPT_SELECTEDCELLS )};
uno::Sequence< OUString > aHelpIds{
u".HelpID:vcl:PrintDialog:PrintContent:ListBox"_ustr};
m_aUIProperties[nIdx++].Value = setChoiceListControlOpt( u"printextrabox"_ustr, OUString(),
aHelpIds, u"PrintContent"_ustr,
aChoices, nContent );
// show Subgroup for print range
aPrintRangeOpt.mbInternalOnly = true;
m_aUIProperties[nIdx++].Value = setSubgroupControlOpt(u"fromwhich"_ustr, ScResId( SCSTR_PRINTOPT_FROMWHICH ),
OUString(),
aPrintRangeOpt);
// create a choice for the range to print
OUString aPrintRangeName( u"PrintRange"_ustr );
aChoices = { ScResId( SCSTR_PRINTOPT_PRINTALLPAGES ), ScResId( SCSTR_PRINTOPT_PRINTPAGES ) };
aHelpIds = { u".HelpID:vcl:PrintDialog:PrintRange:RadioButton:0"_ustr,
u".HelpID:vcl:PrintDialog:PrintRange:RadioButton:1"_ustr };
uno::Sequence< OUString > aWidgetIds{ u"rbAllPages"_ustr, u"rbRangePages"_ustr };
m_aUIProperties[nIdx++].Value = setChoiceRadiosControlOpt(aWidgetIds, OUString(),
aHelpIds,
aPrintRangeName,
aChoices,
0 );
return *rDoc.GetDrawLayer(); // TTTT should be reference
}
ScModelObj::ScModelObj( ScDocShell* pDocSh ) :
SfxBaseModel( pDocSh ),
aPropSet( lcl_GetDocOptPropertyMap() ),
pDocShell( pDocSh ),
maChangesListeners( m_aMutex )
{ // pDocShell may be NULL if this is the base of a ScDocOptionsObj if ( pDocShell )
{
pDocShell->GetDocument().AddUnoObject(*this); // SfxModel is derived from SfxListener
}
}
ScModelObj::~ScModelObj()
{
SolarMutexGuard g;
if (pDocShell)
pDocShell->GetDocument().RemoveUnoObject(*this);
if (xNumberAgg.is())
xNumberAgg->setDelegator(uno::Reference<uno::XInterface>());
uno::Reference< uno::XAggregation> const & ScModelObj::GetFormatter()
{ // pDocShell may be NULL if this is the base of a ScDocOptionsObj if ( !xNumberAgg.is() && pDocShell )
{ // setDelegator changes RefCount, so we'd better hold the reference ourselves // (directly in m_refCount, so we don't delete ourselves with release())
osl_atomic_increment( &m_refCount ); // we need a reference to SvNumberFormatsSupplierObj during queryInterface, // otherwise it'll be deleted
uno::Reference<util::XNumberFormatsSupplier> xFormatter( new SvNumberFormatsSupplierObj(pDocShell->GetDocument().GetThreadedContext().GetFormatTable() ));
{
xNumberAgg.set(uno::Reference<uno::XAggregation>( xFormatter, uno::UNO_QUERY )); // extra block to force deletion of the temporary before setDelegator
}
// during setDelegator no additional reference should exist
xFormatter = nullptr;
if (xNumberAgg.is())
xNumberAgg->setDelegator( getXWeak() );
osl_atomic_decrement( &m_refCount );
} // if ( !xNumberAgg.is() ) return xNumberAgg;
}
if (rTabViewShell.IsAutoSpell())
aState.append('S'); if (!ThemeColors::UseOnlyWhiteDocBackground())
{ if (rViewRenderingOptions.GetDocColor()
== svtools::ColorConfig::GetDefaultColor(svtools::DOCCOLOR, 1))
aState.append('D');
}
// Try to find a view that matches the tile-zoom requested by iterating over // first few shells. This is to avoid switching of zooms in ScGridWindow::PaintTile // and hence avoid grid-offset recomputation on all shapes which is not cheap.
ScViewData* pViewData = lcl_getViewMatchingDocZoomTab(aFracX, aFracY,
pActiveViewData->GetTabNo(), pViewShell->GetDocId(),
getTabViewRenderState(*pViewShell)); if (!pViewData)
pViewData = pActiveViewData;
// update the size of the area we are painting // FIXME we want to use only the minimal necessary size, like the // following; but for the moment there is too many problems with that and // interaction with editeng used for the cell editing //Size aTileSize(nOutputWidth, nOutputHeight); //if (pGridWindow->GetOutputSizePixel() != aTileSize) // pGridWindow->SetOutputSizePixel(Size(nOutputWidth, nOutputHeight)); // so instead for now, set the viewport size to document size
// Fetch the document size and the tiled rendering area together, // because the tiled rendering area is not cheap to compute, and we want // to pass it down to ScGridWindow::PaintFile to avoid computing twice.
SCCOL nTiledRenderingAreaEndCol = 0;
SCROW nTiledRenderingAreaEndRow = 0;
Size aDocSize = getDocumentSize(nTiledRenderingAreaEndCol, nTiledRenderingAreaEndRow);
if (pInputHandler && pInputHandler->IsInputMode())
{ // forwarding to editeng - we are editing the cell content
EditView* pTableView = pInputHandler->GetTableView();
assert(pTableView);
Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY));
if (pTableView && pTableView->GetOutputArea().Contains(aPoint))
{ switch (nType)
{ case LOK_SETTEXTSELECTION_START:
pTableView->SetCursorLogicPosition(aPoint, /*bPoint=*/false, /*bClearMark=*/false); break; case LOK_SETTEXTSELECTION_END:
pTableView->SetCursorLogicPosition(aPoint, /*bPoint=*/true, /*bClearMark=*/false); break; case LOK_SETTEXTSELECTION_RESET:
pTableView->SetCursorLogicPosition(aPoint, /*bPoint=*/true, /*bClearMark=*/true); break; default:
assert(false); break;
}
bHandled = true;
}
} elseif (pDrawView && pDrawView->IsTextEdit())
{ // forwarding to editeng - we are editing the text in shape
OutlinerView* pOutlinerView = pDrawView->GetTextEditOutlinerView();
EditView& rEditView = pOutlinerView->GetEditView();
Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY)); switch (nType)
{ case LOK_SETTEXTSELECTION_START:
rEditView.SetCursorLogicPosition(aPoint, /*bPoint=*/false, /*bClearMark=*/false); break; case LOK_SETTEXTSELECTION_END:
rEditView.SetCursorLogicPosition(aPoint, /*bPoint=*/true, /*bClearMark=*/false); break; case LOK_SETTEXTSELECTION_RESET:
rEditView.SetCursorLogicPosition(aPoint, /*bPoint=*/true, /*bClearMark=*/true); break; default:
assert(false); break;
}
bHandled = true;
}
if (!bHandled)
{ // just update the cell selection
ScGridWindow* pGridWindow = pViewData->GetActiveWin(); if (!pGridWindow) return;
// move the cell selection handles
pGridWindow->SetCellSelectionPixel(nType, nX * pViewData->GetPPTX(), nY * pViewData->GetPPTY());
}
}
// deselect the shapes & texts
ScDrawView* pDrawView = pViewShell->GetScDrawView(); if (pDrawView)
{
pDrawView->ScEndTextEdit();
pDrawView->UnmarkAll();
} else
pViewShell->Unmark();
// and hide the cell and text selection
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, ""_ostr);
SfxLokHelper::notifyOtherViews(pViewShell, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", ""_ostr);
}
void ScModelObj::setClientZoom(int nTilePixelWidth_, int nTilePixelHeight_, int nTileTwipWidth_, int nTileTwipHeight_)
{
ScViewData* pViewData = ScDocShell::GetViewData(); if (!pViewData) return;
// Currently in LOK clients the doc background cannot be changed, so send this sparingly as possible but for every view. // FIXME: Find a better place to trigger this callback where it would be called just once per view creation. // Doing this in ScTabViewShell init code does not work because callbacks do not work at that point for the first view.
lcl_sendLOKDocumentBackground(pViewData);
pViewData->SetZoom(newZoomX, newZoomY, true); if (ScTabViewShell* pViewShell = pViewData->GetViewShell())
pViewShell->SyncGridWindowMapModeFromDrawMapMode(); // sync zoom to Input Handler like ScTabViewShell::Activate does if (ScInputHandler* pHdl = ScModule::get()->GetInputHdl())
pHdl->SetRefScale(pViewData->GetZoomX(), pViewData->GetZoomY());
// refresh our view's take on other view's cursors & selections
ScGridWindow* pGridWindow = pViewData->GetActiveWin();
pGridWindow->UpdateEditViewPos();
pGridWindow->updateKitOtherCursors();
pGridWindow->updateOtherKitSelections();
pGridWindow->resetCachedViewGridOffsets();
if (ScDrawView* pDrawView = pViewData->GetScDrawView())
pDrawView->resetGridOffsetsForAllSdrPageViews();
}
// show us the text exactly
ScInputOptions aInputOptions(mod->GetInputOptions());
aInputOptions.SetTextWysiwyg(true);
aInputOptions.SetReplaceCellsWarn(false);
mod->SetInputOptions(aInputOptions); if (pDocShell)
pDocShell->CalcOutputFactor();
// when the "This document may contain formatting or content that cannot // be saved..." dialog appears, it is auto-cancelled with tiled rendering, // causing 'Save' being disabled; so let's always save to the original // format auto xChanges = comphelper::ConfigurationChanges::create();
officecfg::Office::Common::Save::Document::WarnAlienFormat::set(false, xChanges);
xChanges->commit();
// if we know what theme the user wants, then we can dispatch that now early if (!sThemeName.isEmpty())
{
css::uno::Sequence<css::beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
{
{ "NewTheme", uno::Any(sThemeName) }
}));
comphelper::dispatchCommand(u".uno:ChangeTheme"_ustr, aPropertyValues);
} if (!sBackgroundThemeName.isEmpty())
{
css::uno::Sequence<css::beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
{
{ "NewTheme", uno::Any(sBackgroundThemeName) }
}));
comphelper::dispatchCommand(".uno:InvertBackground", aPropertyValues);
}
}
void ScModelObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{ // Not interested in reference update hints here
const SfxHintId nId = rHint.GetId(); if ( nId == SfxHintId::Dying )
{
pDocShell = nullptr; // has become invalid if (xNumberAgg.is())
{
SvNumberFormatsSupplierObj* pNumFmt =
comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(
uno::Reference<util::XNumberFormatsSupplier>(xNumberAgg, uno::UNO_QUERY) ); if ( pNumFmt )
pNumFmt->SetNumberFormatter( nullptr );
}
pPrintFuncCache.reset(); // must be deleted because it has a pointer to the DocShell
m_pPrintState.reset();
} elseif ( nId == SfxHintId::DataChanged )
{ // cached data for rendering become invalid when contents change // (if a broadcast is added to SetDrawModified, is has to be tested here, too)
pPrintFuncCache.reset();
m_pPrintState.reset();
// handle "OnCalculate" sheet events (search also for VBA event handlers) if ( pDocShell )
{
ScDocument& rDoc = pDocShell->GetDocument(); if ( rDoc.GetVbaEventProcessor().is() )
{ // If the VBA event processor is set, HasAnyCalcNotification is much faster than HasAnySheetEventScript if ( rDoc.HasAnyCalcNotification() && rDoc.HasAnySheetEventScript( ScSheetEventId::CALCULATE, true ) )
HandleCalculateEvents();
} else
{ if ( rDoc.HasAnySheetEventScript( ScSheetEventId::CALCULATE ) )
HandleCalculateEvents();
}
}
}
// always call parent - SfxBaseModel might need to handle the same hints again
SfxBaseModel::Notify( rBC, rHint ); // SfxBaseModel is derived from SfxListener
}
if (rPropName == SC_UNONAME_RENDERDEV)
{
uno::Reference<awt::XDevice> xRenderDevice(rProp.Value, uno::UNO_QUERY); if ( xRenderDevice.is() )
{
VCLXDevice* pDevice = dynamic_cast<VCLXDevice*>( xRenderDevice.get() ); if ( pDevice )
{
pRet = pDevice->GetOutputDevice().get();
pRet->SetDigitLanguage( ScModule::GetOptDigitLanguage() );
}
}
}
} return pRet;
}
staticbool lcl_ParseTarget( const OUString& rTarget, ScRange& rTargetRange, tools::Rectangle& rTargetRect, bool& rIsSheet, ScDocument& rDoc, SCTAB nSourceTab )
{ // test in same order as in SID_CURRENTCELL execute
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.