Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sc/source/ui/unoobj/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 189 kB image not shown  

Quelle  docuno.cxx   Sprache: C

 
/* -*- 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 <config_feature_opencl.h>

#include <scitems.hxx>

#include <comphelper/dispatchcommand.hxx>
#include <comphelper/propertysequence.hxx>
#include <comphelper/propertyvalue.hxx>
#include <comphelper/sequence.hxx>
#include <editeng/brushitem.hxx>
#include <editeng/editview.hxx>
#include <editeng/memberids.h>
#include <editeng/outliner.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/sizeitem.hxx>
#include <o3tl/any.hxx>
#include <o3tl/safeint.hxx>
#include <svx/fmview.hxx>
#include <svx/svditer.hxx>
#include <svx/svdpage.hxx>
#include <svx/svxids.hrc>

#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <officecfg/Office/Common.hxx>
#include <officecfg/Office/Calc.hxx>
#include <svl/numuno.hxx>
#include <svl/hint.hxx>
#include <unotools/moduleoptions.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include <svx/unopage.hxx>
#include <vcl/pdfextoutdevdata.hxx>
#include <vcl/print.hxx>
#include <vcl/svapp.hxx>
#include <tools/json_writer.hxx>
#include <tools/multisel.hxx>
#include <tools/UnitConversion.hxx>
#include <toolkit/awt/vclxdevice.hxx>

#include <float.h>

#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/util/XTheme.hpp>
#include <com/sun/star/sheet/XNamedRanges.hpp>
#include <com/sun/star/sheet/XLabelRanges.hpp>
#include <com/sun/star/sheet/XSelectedSheetsSupplier.hpp>
#include <com/sun/star/sheet/XUnnamedDatabaseRanges.hpp>
#include <com/sun/star/i18n/XForbiddenCharacters.hpp>
#include <com/sun/star/script/XLibraryContainer.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
#include <com/sun/star/script/XInvocation.hpp>
#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
#include <com/sun/star/beans/XFastPropertySet.hpp>
#include <comphelper/indexedpropertyvalues.hxx>
#include <comphelper/lok.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/profilezone.hxx>
#include <comphelper/servicehelper.hxx>
#include <comphelper/string.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <cppuhelper/supportsservice.hxx>
#if HAVE_FEATURE_OPENCL
#include <opencl/platforminfo.hxx>
#endif
#include <sfx2/lokhelper.hxx>
#include <sfx2/lokcomponenthelpers.hxx>
#include <sfx2/LokControlHandler.hxx>
#include <docmodel/uno/UnoTheme.hxx>
#include <docmodel/theme/Theme.hxx>

#include <cellsuno.hxx>
#include <columnspanset.hxx>
#include <convuno.hxx>
#include <datauno.hxx>
#include <docfunc.hxx>
#include <docoptio.hxx>
#include <docsh.hxx>
#include <docuno.hxx>
#include <drwlayer.hxx>
#include <forbiuno.hxx>
#include <formulagroup.hxx>
#include <gridwin.hxx>
#include <hints.hxx>
#include <inputhdl.hxx>
#include <inputopt.hxx>
#include <interpre.hxx>
#include <linkuno.hxx>
#include <markdata.hxx>
#include <miscuno.hxx>
#include <nameuno.hxx>
#include <notesuno.hxx>
#include <optuno.hxx>
#include <pfuncache.hxx>
#include <postit.hxx>
#include <printfun.hxx>
#include <rangeutl.hxx>
#include <scmod.hxx>
#include <scresid.hxx>
#include <servuno.hxx>
#include <shapeuno.hxx>
#include <sheetevents.hxx>
#include <styleuno.hxx>
#include <tabvwsh.hxx>
#include <targuno.hxx>
#include <unonames.hxx>
#include <ViewSettingsSequenceDefines.hxx>
#include <editsh.hxx>
#include <drawsh.hxx>
#include <drtxtob.hxx>
#include <transobj.hxx>
#include <chgtrack.hxx>
#include <table.hxx>
#include <appoptio.hxx>
#include <formulaopt.hxx>
#include <output.hxx>
#include <stlpool.hxx>

#include <strings.hrc>

using namespace com::sun::star;

// #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;

//  no Which-ID here, map only for PropertySetInfo

//! rename this, those are no longer only options
static std::span<const SfxItemPropertyMapEntry> lcl_GetDocOptPropertyMap()
{
    static const SfxItemPropertyMapEntry aDocOptPropertyMap_Impl[] =
    {
        { SC_UNO_APPLYFMDES,              0, cppu::UnoType<bool>::get(),                                             0, 0},
        { SC_UNO_AREALINKS,               0, cppu::UnoType<sheet::XAreaLinks>::get(),               0, 0},
        { SC_UNO_AUTOCONTFOC,             0, cppu::UnoType<bool>::get(),                                             0, 0},
        { SC_UNO_BASICLIBRARIES,          0, cppu::UnoType<script::XLibraryContainer>::get(),     beans::PropertyAttribute::READONLY, 0},
        { SC_UNO_DIALOGLIBRARIES,         0, cppu::UnoType<script::XLibraryContainer>::get(),     beans::PropertyAttribute::READONLY, 0},
        { SC_UNO_VBAGLOBNAME,             0, cppu::UnoType<OUString>::get(),                  beans::PropertyAttribute::READONLY, 0},
        { SC_UNO_CALCASSHOWN,             PROP_UNO_CALCASSHOWN, cppu::UnoType<bool>::get(),                          0, 0},
        { SC_UNONAME_CLOCAL,              0, cppu::UnoType<lang::Locale>::get(),                                    0, 0},
        { SC_UNO_CJK_CLOCAL,              0, cppu::UnoType<lang::Locale>::get(),                                    0, 0},
        { SC_UNO_CTL_CLOCAL,              0, cppu::UnoType<lang::Locale>::get(),                                    0, 0},
        { SC_UNO_COLLABELRNG,             0, cppu::UnoType<sheet::XLabelRanges>::get(),             0, 0},
        { SC_UNO_DDELINKS,                0, cppu::UnoType<container::XNameAccess>::get(),          0, 0},
        { SC_UNO_DEFTABSTOP,              PROP_UNO_DEFTABSTOP, cppu::UnoType<sal_Int16>::get(),                     0, 0},
        { SC_UNO_EXTERNALDOCLINKS,        0, cppu::UnoType<sheet::XExternalDocLinks>::get(),        0, 0},
        { SC_UNO_FORBIDDEN,               0, cppu::UnoType<i18n::XForbiddenCharacters>::get(),      beans::PropertyAttribute::READONLY, 0},
        { SC_UNO_HASDRAWPAGES,            0, cppu::UnoType<bool>::get(),                                             beans::PropertyAttribute::READONLY, 0},
        { SC_UNO_IGNORECASE,              PROP_UNO_IGNORECASE, cppu::UnoType<bool>::get(),                           0, 0},
        { SC_UNO_ITERENABLED,             PROP_UNO_ITERENABLED, cppu::UnoType<bool>::get(),                          0, 0},
        { SC_UNO_ITERCOUNT,               PROP_UNO_ITERCOUNT, cppu::UnoType<sal_Int32>::get(),                      0, 0},
        { SC_UNO_ITEREPSILON,             PROP_UNO_ITEREPSILON, cppu::UnoType<double>::get(),                       0, 0},
        { SC_UNO_LOOKUPLABELS,            PROP_UNO_LOOKUPLABELS, cppu::UnoType<bool>::get(),                         0, 0},
        { SC_UNO_MATCHWHOLE,              PROP_UNO_MATCHWHOLE, cppu::UnoType<bool>::get(),                           0, 0},
        { SC_UNO_NAMEDRANGES,             0, cppu::UnoType<sheet::XNamedRanges>::get(),             0, 0},
        { SC_UNO_THEME,                   0, cppu::UnoType<util::XTheme>::get(), 0,  0},
        { SC_UNO_DATABASERNG,             0, cppu::UnoType<sheet::XDatabaseRanges>::get(),          0, 0},
        { SC_UNO_NULLDATE,                PROP_UNO_NULLDATE, cppu::UnoType<util::Date>::get(),                      0, 0},
        { SC_UNO_ROWLABELRNG,             0, cppu::UnoType<sheet::XLabelRanges>::get(),             0, 0},
        { SC_UNO_SHEETLINKS,              0, cppu::UnoType<container::XNameAccess>::get(),          0, 0},
        { SC_UNO_SPELLONLINE,             0, cppu::UnoType<bool>::get(),                            0, 0},
        { SC_UNO_STANDARDDEC,             PROP_UNO_STANDARDDEC, cppu::UnoType<sal_Int16>::get(),                    0, 0},
        { SC_UNO_REGEXENABLED,            PROP_UNO_REGEXENABLED, cppu::UnoType<bool>::get(),                         0, 0},
        { SC_UNO_WILDCARDSENABLED,        PROP_UNO_WILDCARDSENABLED, cppu::UnoType<bool>::get(),                         0, 0},
        { SC_UNO_RUNTIMEUID,              0, cppu::UnoType<OUString>::get(),                  beans::PropertyAttribute::READONLY, 0},
        { SC_UNO_HASVALIDSIGNATURES,      0, cppu::UnoType<bool>::get(),                                             beans::PropertyAttribute::READONLY, 0},
        { SC_UNO_ALLOWLINKUPDATE,         0, cppu::UnoType<bool>::get(),                                             beans::PropertyAttribute::READONLY, 0},
        { SC_UNO_ISLOADED,                0, cppu::UnoType<bool>::get(),                                             0, 0},
        { SC_UNO_ISUNDOENABLED,           0, cppu::UnoType<bool>::get(),                                             0, 0},
        { SC_UNO_RECORDCHANGES,           0, cppu::UnoType<bool>::get(),                                             0, 0},
        { SC_UNO_ISRECORDCHANGESPROTECTED,0, cppu::UnoType<bool>::get(),            beans::PropertyAttribute::READONLY, 0},
        { SC_UNO_ISADJUSTHEIGHTENABLED,   0, cppu::UnoType<bool>::get(),                                             0, 0},
        { SC_UNO_ISEXECUTELINKENABLED,    0, cppu::UnoType<bool>::get(),                                             0, 0},
        { SC_UNO_ISCHANGEREADONLYENABLED, 0, cppu::UnoType<bool>::get(),                                             0, 0},
        { SC_UNO_REFERENCEDEVICE,         0, cppu::UnoType<awt::XDevice>::get(),                    beans::PropertyAttribute::READONLY, 0},
        {u"BuildId"_ustr,                      0, ::cppu::UnoType<OUString>::get(),                0, 0},
        { SC_UNO_CODENAME,                0, cppu::UnoType<OUString>::get(),                  0, 0},
        { SC_UNO_INTEROPGRABBAG,          0, cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get(), 0, 0},
    };
    return aDocOptPropertyMap_Impl;
}

//! StandardDecimals as property and from NumberFormatter ????????

static std::span<const SfxItemPropertyMapEntry> lcl_GetColumnsPropertyMap()
{
    static const SfxItemPropertyMapEntry aColumnsPropertyMap_Impl[] =
    {
        { SC_UNONAME_MANPAGE,  0,  cppu::UnoType<bool>::get(),          0, 0 },
        { SC_UNONAME_NEWPAGE,  0,  cppu::UnoType<bool>::get(),          0, 0 },
        { SC_UNONAME_CELLVIS,  0,  cppu::UnoType<bool>::get(),          0, 0 },
        { SC_UNONAME_OWIDTH,   0,  cppu::UnoType<bool>::get(),          0, 0 },
        { SC_UNONAME_CELLWID,  0,  cppu::UnoType<sal_Int32>::get(),    0, 0 },
    };
    return aColumnsPropertyMap_Impl;
}

static std::span<const SfxItemPropertyMapEntry> lcl_GetRowsPropertyMap()
{
    static const SfxItemPropertyMapEntry aRowsPropertyMap_Impl[] =
    {
        { SC_UNONAME_CELLHGT,  0,  cppu::UnoType<sal_Int32>::get(),    0, 0 },
        { SC_UNONAME_CELLFILT, 0,  cppu::UnoType<bool>::get(),          0, 0 },
        { SC_UNONAME_OHEIGHT,  0,  cppu::UnoType<bool>::get(),          0, 0 },
        { SC_UNONAME_MANPAGE,  0,  cppu::UnoType<bool>::get(),          0, 0 },
        { SC_UNONAME_NEWPAGE,  0,  cppu::UnoType<bool>::get(),          0, 0 },
        { SC_UNONAME_CELLVIS,  0,  cppu::UnoType<bool>::get(),          0, 0 },
        { SC_UNONAME_CELLBACK, ATTR_BACKGROUND, ::cppu::UnoType<sal_Int32>::get(), 0, MID_BACK_COLOR },
        { SC_UNONAME_CELLTRAN, ATTR_BACKGROUND, cppu::UnoType<bool>::get(), 0, MID_GRAPHIC_TRANSPARENT },
        // not sorted, not used with SfxItemPropertyMapEntry::GetByName
    };
    return aRowsPropertyMap_Impl;
}

constexpr OUString SCMODELOBJ_SERVICE = u"com.sun.star.sheet.SpreadsheetDocument"_ustr;
constexpr OUString SCDOCSETTINGS_SERVICE = u"com.sun.star.sheet.SpreadsheetDocumentSettings"_ustr;
constexpr OUString SCDOC_SERVICE = u"com.sun.star.document.OfficeDocument"_ustr;

SC_SIMPLE_SERVICE_INFO( ScAnnotationsObj, u"ScAnnotationsObj"_ustr, u"com.sun.star.sheet.CellAnnotations"_ustr )
SC_SIMPLE_SERVICE_INFO( ScDrawPagesObj, u"ScDrawPagesObj"_ustr, u"com.sun.star.drawing.DrawPages"_ustr )
SC_SIMPLE_SERVICE_INFO( ScScenariosObj, u"ScScenariosObj"_ustr, u"com.sun.star.sheet.Scenarios"_ustr )
SC_SIMPLE_SERVICE_INFO( ScSpreadsheetSettingsObj, u"ScSpreadsheetSettingsObj"_ustr, u"com.sun.star.sheet.SpreadsheetDocumentSettings"_ustr )
SC_SIMPLE_SERVICE_INFO( ScTableColumnsObj, u"ScTableColumnsObj"_ustr, u"com.sun.star.table.TableColumns"_ustr )
SC_SIMPLE_SERVICE_INFO( ScTableRowsObj, u"ScTableRowsObj"_ustr, u"com.sun.star.table.TableRows"_ustr )
SC_SIMPLE_SERVICE_INFO( ScTableSheetsObj, u"ScTableSheetsObj"_ustr, u"com.sun.star.sheet.Spreadsheets"_ustr )

class ScPrintUIOptions : public vcl::PrinterOptionsHelper
{
public:
    ScPrintUIOptions();
    void SetDefaults();
};

ScPrintUIOptions::ScPrintUIOptions()
{
    const ScPrintOptions& rPrintOpt = ScModule::get()->GetPrintOptions();
    sal_Int32 nContent = rPrintOpt.GetAllSheets() ? 0 : 1;
    bool bSuppress = rPrintOpt.GetSkipEmpty();

    sal_Int32 nNumProps= 10, nIdx = 0;

    m_aUIProperties.resize(nNumProps);

    // 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 );

    // create an Edit dependent on "Pages" selected
    vcl::PrinterOptionsHelper::UIControlOptions aPageRangeOpt( aPrintRangeName, 1, true );
    m_aUIProperties[nIdx++].Value = setEditControlOpt(u"pagerange"_ustr, OUString(),
                                                      u".HelpID:vcl:PrintDialog:PageRange:Edit"_ustr,
                                                      u"PageRange"_ustr, OUString(), aPageRangeOpt);

    vcl::PrinterOptionsHelper::UIControlOptions aEvenOddOpt(aPrintRangeName, 0, true);
    m_aUIProperties[ nIdx++ ].Value = setChoiceListControlOpt(u"evenoddbox"_ustr,
                                                           OUString(),
                                                           uno::Sequence<OUString>(),
                                                           u"EvenOdd"_ustr,
                                                           uno::Sequence<OUString>(),
                                                           0,
                                                           uno::Sequence< sal_Bool >(),
                                                           aEvenOddOpt);

    assert(nIdx == nNumProps);
}

void ScPrintUIOptions::SetDefaults()
{
    // re-initialize the default values from print options

    const ScPrintOptions& rPrintOpt = ScModule::get()->GetPrintOptions();
    sal_Int32 nContent = rPrintOpt.GetAllSheets() ? 0 : 1;
    bool bSuppress = rPrintOpt.GetSkipEmpty();

    for (beans::PropertyValue & rPropValue : m_aUIProperties)
    {
        uno::Sequence<beans::PropertyValue> aUIProp;
        if ( rPropValue.Value >>= aUIProp )
        {
            for (auto& rProp : asNonConstRange(aUIProp))
            {
                OUString aName = rProp.Name;
                if ( aName == "Property" )
                {
                    beans::PropertyValue aPropertyValue;
                    if ( rProp.Value >>= aPropertyValue )
                    {
                        if ( aPropertyValue.Name == "PrintContent" )
                        {
                            aPropertyValue.Value <<= nContent;
                            rProp.Value <<= aPropertyValue;
                        }
                        else if ( aPropertyValue.Name == "IsSuppressEmptyPages" )
                        {
                            aPropertyValue.Value <<= bSuppress;
                            rProp.Value <<= aPropertyValue;
                        }
                    }
                }
            }
            rPropValue.Value <<= aUIProp;
        }
    }
}

void ScModelObj::CreateAndSet(ScDocShell* pDocSh)
{
    if (pDocSh)
        pDocSh->SetBaseModel( new ScModelObj(pDocSh) );
}

SdrModel& ScModelObj::getSdrModelFromUnoModel() const
{
    ScDocument& rDoc(pDocShell->GetDocument());

    if(!rDoc.GetDrawLayer())
    {
        rDoc.InitDrawLayer();
    }

    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>());

    pPrintFuncCache.reset();
    pPrinterOptions.reset();
}

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;
}

ScDocument* ScModelObj::GetDocument() const
{
    if (pDocShell)
        return &pDocShell->GetDocument();
    return nullptr;
}

SfxObjectShell* ScModelObj::GetEmbeddedObject() const
{
    return pDocShell;
}

void ScModelObj::UpdateAllRowHeights()
{
    if (pDocShell)
        pDocShell->UpdateAllRowHeights();
}

void ScModelObj::BeforeXMLLoading()
{
    if (pDocShell)
        pDocShell->BeforeXMLLoading();
}

void ScModelObj::AfterXMLLoading()
{
    if (pDocShell)
        pDocShell->AfterXMLLoading(true);
}

ScSheetSaveData* ScModelObj::GetSheetSaveData()
{
    if (pDocShell)
        return pDocShell->GetSheetSaveData();
    return nullptr;
}

ScFormatSaveData* ScModelObj::GetFormatSaveData()
{
    if (pDocShell)
        return pDocShell->GetFormatSaveData();
    return nullptr;
}

void ScModelObj::RepaintRange( const ScRange& rRange )
{
    if (pDocShell)
        pDocShell->PostPaint( rRange, PaintPartFlags::Grid );
}

void ScModelObj::RepaintRange( const ScRangeList& rRange )
{
    if (pDocShell)
        pDocShell->PostPaint(rRange, PaintPartFlags::Grid, SC_PF_TESTMERGE);
}

static OString getTabViewRenderState(const ScTabViewShell& rTabViewShell)
{
    OStringBuffer aState;
    const ScViewRenderingOptions& rViewRenderingOptions = rTabViewShell.GetViewRenderingData();

    if (rTabViewShell.IsAutoSpell())
        aState.append('S');
    if (!ThemeColors::UseOnlyWhiteDocBackground())
    {
        if (rViewRenderingOptions.GetDocColor()
            == svtools::ColorConfig::GetDefaultColor(svtools::DOCCOLOR, 1))
            aState.append('D');
    }

    aState.append(';');

    OString aThemeName = OUStringToOString(rViewRenderingOptions.GetColorSchemeName(), RTL_TEXTENCODING_UTF8);
    aState.append(aThemeName);

    return aState.makeStringAndClear();
}

static ScViewData* lcl_getViewMatchingDocZoomTab(const Fraction& rZoomX,
                                              const Fraction& rZoomY,
                                              const SCTAB nTab,
                                              const ViewShellDocId& rDocId,
                                              std::string_view rViewRenderState)
{
    constexpr size_t nMaxIter = 5;
    size_t nIter = 0;
    for (SfxViewShell* pViewShell = SfxViewShell::GetFirst();
            pViewShell && nIter < nMaxIter;
            (pViewShell = SfxViewShell::GetNext(*pViewShell)), ++nIter)
    {
        if (pViewShell->GetDocId() != rDocId)
            continue;

        ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
        if (!pTabViewShell)
            continue;

        ScViewData& rData = pTabViewShell->GetViewData();
        if (rData.GetTabNo() == nTab && rData.GetZoomX() == rZoomX && rData.GetZoomY() == rZoomY &&
            getTabViewRenderState(*pTabViewShell) == rViewRenderState)
        {
            return &rData;
        }
    }

    return nullptr;
}

void ScModelObj::paintTile( VirtualDevice& rDevice,
                            int nOutputWidth, int nOutputHeight,
                            int nTilePosX, int nTilePosY,
                            tools::Long nTileWidth, tools::Long nTileHeight )
{
    ScTabViewShell* pViewShell = pDocShell->GetBestViewShell(false);

    // FIXME: Can this happen? What should we do?
    if (!pViewShell)
        return;

    ScViewData* pActiveViewData = &pViewShell->GetViewData();
    Fraction aFracX(o3tl::toTwips(nOutputWidth, o3tl::Length::px), nTileWidth);
    Fraction aFracY(o3tl::toTwips(nOutputHeight, o3tl::Length::px), nTileHeight);

    // 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;

    ScGridWindow* pGridWindow = pViewData->GetActiveWin();

    // 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);

    pGridWindow->SetOutputSizePixel(Size(aDocSize.Width() * pViewData->GetPPTX(), aDocSize.Height() * pViewData->GetPPTY()));

    pGridWindow->PaintTile( rDevice, nOutputWidth, nOutputHeight,
                            nTilePosX, nTilePosY, nTileWidth, nTileHeight,
                            nTiledRenderingAreaEndCol, nTiledRenderingAreaEndRow );

    // Draw Form controls
    ScDrawLayer* pDrawLayer = pDocShell->GetDocument().GetDrawLayer();
    SdrPage* pPage = pDrawLayer->GetPage(sal_uInt16(pViewData->GetTabNo()));
    SdrView* pDrawView = pViewData->GetViewShell()->GetScDrawView();
    tools::Rectangle aTileRect(Point(nTilePosX, nTilePosY), Size(nTileWidth, nTileHeight));
    Size aOutputSize(nOutputWidth, nOutputHeight);
    LokControlHandler::paintControlTile(pPage, pDrawView, *pGridWindow, rDevice, aOutputSize, aTileRect);
}

void ScModelObj::setPart( int nPart, bool /*bAllowChangeFocus*/ )
{
    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return;

    ScTabView* pTabView = pViewData->GetView();
    if (!pTabView)
        return;

    if (SdrView* pDrawView = pViewData->GetViewShell()->GetScDrawView())
        pDrawView->SetNegativeX(comphelper::LibreOfficeKit::isActive() &&
            pViewData->GetDocument().IsLayoutRTL(nPart));

    pTabView->SelectTabPage(nPart + 1);
}

int ScModelObj::getParts()
{
    ScDocument& rDoc = pDocShell->GetDocument();
    return rDoc.GetTableCount();
}

int ScModelObj::getPart()
{
    ScViewData* pViewData = ScDocShell::GetViewData();
    return pViewData ? pViewData->GetViewShell()->getPart() : 0;
}

OUString ScModelObj::getPartInfo( int nPart )
{
    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return OUString();

    const bool bIsVisible = pViewData->GetDocument().IsVisible(nPart);
    const bool bIsProtected = pViewData->GetDocument().IsTabProtected(nPart);
    //FIXME: Implement IsSelected().
    const bool bIsSelected = false//pViewData->GetDocument()->IsSelected(nPart);
    const bool bIsRTLLayout = pViewData->GetDocument().IsLayoutRTL(nPart);

    ::tools::JsonWriter jsonWriter;
    jsonWriter.put("visible"static_cast<unsigned int>(bIsVisible));
    jsonWriter.put("rtllayout"static_cast<unsigned int>(bIsRTLLayout));
    jsonWriter.put("protected"static_cast<unsigned int>(bIsProtected));
    jsonWriter.put("selected"static_cast<unsigned int>(bIsSelected));

    OUString tabName;
    pViewData->GetDocument().GetName(nPart, tabName);
    jsonWriter.put("name", tabName);

    sal_Int64 hashCode;
    pViewData->GetDocument().GetHashCode(nPart, hashCode);
    jsonWriter.put("hash", hashCode);

    Size lastColRow = getDataArea(nPart);
    jsonWriter.put("lastcolumn", lastColRow.getWidth());
    jsonWriter.put("lastrow", lastColRow.getHeight());

    return OStringToOUString(jsonWriter.finishAndGetAsOString(), RTL_TEXTENCODING_UTF8);
}

OUString ScModelObj::getPartName( int nPart )
{
    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return OUString();

    OUString sTabName;
    pViewData->GetDocument().GetName(nPart, sTabName);
    return sTabName;
}

OUString ScModelObj::getPartHash( int nPart )
{
    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return OUString();

    sal_Int64 nHashCode;
    return (pViewData->GetDocument().GetHashCode(nPart, nHashCode) ? OUString::number(nHashCode) : OUString());
}

VclPtr<vcl::Window> ScModelObj::getDocWindow()
{
    SolarMutexGuard aGuard;

    ScTabViewShell* pViewShell = pDocShell->GetBestViewShell(false);

    // FIXME: Can this happen? What should we do?
    if (!pViewShell)
        return VclPtr<vcl::Window>();

    if (VclPtr<vcl::Window> pWindow = SfxLokHelper::getInPlaceDocWindow(pViewShell))
        return pWindow;

    return pViewShell->GetViewData().GetActiveWin();
}

Size ScModelObj::getDocumentSize()
{
    SCCOL nTiledRenderingAreaEndCol = 0;
    SCROW nTiledRenderingAreaEndRow = 0;
    return getDocumentSize(nTiledRenderingAreaEndCol, nTiledRenderingAreaEndRow);
}

Size ScModelObj::getDocumentSize(SCCOL& rnTiledRenderingAreaEndCol, SCROW& rnTiledRenderingAreaEndRow)
{
    Size aSize(10, 10); // minimum size

    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return aSize;

    SCTAB nTab = pViewData->GetTabNo();
    rnTiledRenderingAreaEndCol = 0;
    rnTiledRenderingAreaEndRow = 0;
    const ScDocument& rDoc = pDocShell->GetDocument();

    rDoc.GetTiledRenderingArea(nTab, rnTiledRenderingAreaEndCol, rnTiledRenderingAreaEndRow);

    const ScDocument* pThisDoc = &rDoc;
    const double fPPTX = pViewData->GetPPTX();
    const double fPPTY = pViewData->GetPPTY();

    auto GetColWidthPx = [pThisDoc, fPPTX, nTab](SCCOL nCol) {
        const sal_uInt16 nSize = pThisDoc->GetColWidth(nCol, nTab);
        return ScViewData::ToPixel(nSize, fPPTX);
    };

    tools::Long nDocWidthPixel = pViewData->GetLOKWidthHelper().computePosition(rnTiledRenderingAreaEndCol, GetColWidthPx);
    tools::Long nDocHeightPixel = pThisDoc->GetScaledRowHeight(0, rnTiledRenderingAreaEndRow, nTab, fPPTY);

    if (nDocWidthPixel > 0 && nDocHeightPixel > 0)
    {
        // convert to twips
        aSize.setWidth(nDocWidthPixel / fPPTX);
        aSize.setHeight(nDocHeightPixel / fPPTY);
    }
    else
    {
        // convert to twips
        aSize.setWidth(rDoc.GetColWidth(0, rnTiledRenderingAreaEndCol, nTab));
        aSize.setHeight(rDoc.GetRowHeight(0, rnTiledRenderingAreaEndRow, nTab));
    }

    return aSize;
}

Size ScModelObj::getDataArea(long nPart)
{
    Size aSize(1, 1);

    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData || !pDocShell)
        return aSize;

    SCTAB nTab = nPart;
    SCCOL nEndCol = 0;
    SCROW nEndRow = 0;
    ScDocument& rDoc = pDocShell->GetDocument();

    ScTable* pTab = rDoc.FetchTable(nTab);
    if (!pTab)
        return aSize;

    pTab->GetCellArea(nEndCol, nEndRow);
    aSize = Size(nEndCol, nEndRow);

    return aSize;
}

void ScModelObj::postKeyEvent(int nType, int nCharCode, int nKeyCode)
{
    SolarMutexGuard aGuard;
    SfxLokHelper::postKeyEventAsync(getDocWindow(), nType, nCharCode, nKeyCode);
}

void ScModelObj::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
{
    SolarMutexGuard aGuard;

    ScTabViewShell* pViewShell = pDocShell->GetBestViewShell(false);

    // FIXME: Can this happen? What should we do?
    if (!pViewShell)
        return;

    ScViewData* pViewData = &pViewShell->GetViewData();

    ScGridWindow* pGridWindow = pViewData->GetActiveWin();

    if (!pGridWindow)
        return;

    SCTAB nTab = pViewData->GetTabNo();
    const ScDocument& rDoc = pDocShell->GetDocument();
    bool bDrawNegativeX = rDoc.IsNegativePage(nTab);
    if (SfxLokHelper::testInPlaceComponentMouseEventHit(pViewShell, nType, nX, nY, nCount,
                                                        nButtons, nModifier, pViewData->GetPPTX(),
                                                        pViewData->GetPPTY(), bDrawNegativeX))
        return;

    Point aPointTwip(nX, nY);

    // Check if a control is hit
    Point aPointHMM = o3tl::convert(aPointTwip, o3tl::Length::twip, o3tl::Length::mm100);
    Point aPointHMMDraw(bDrawNegativeX ? -aPointHMM.X() : aPointHMM.X(), aPointHMM.Y());
    ScDrawLayer* pDrawLayer = pDocShell->GetDocument().GetDrawLayer();
    SdrPage* pPage = pDrawLayer->GetPage(sal_uInt16(nTab));
    SdrView* pDrawView = pViewData->GetViewShell()->GetScDrawView();
    if (LokControlHandler::postMouseEvent(pPage, pDrawView, *pGridWindow, nType, aPointHMMDraw, nCount, nButtons, nModifier))
        return;

    if (!pGridWindow->HasChildPathFocus(true))
        pGridWindow->GrabFocus();

    // Calc operates in pixels...
    const Point aPosition(nX * pViewData->GetPPTX() + pGridWindow->GetOutOffXPixel(),
                          nY * pViewData->GetPPTY() + pGridWindow->GetOutOffYPixel());

    VclEventId aEvent = VclEventId::NONE;
    MouseEvent aData(aPosition, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
    aData.setLogicPosition(aPointHMM);
    switch (nType)
    {
        case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
            aEvent = VclEventId::WindowMouseButtonDown;
            break;
        case LOK_MOUSEEVENT_MOUSEBUTTONUP:
            aEvent = VclEventId::WindowMouseButtonUp;
            break;
        case LOK_MOUSEEVENT_MOUSEMOVE:
            aEvent = VclEventId::WindowMouseMove;
            break;
        default:
            break;
    }

    Application::LOKHandleMouseEvent(aEvent, pGridWindow, &aData);
}

void ScModelObj::setTextSelection(int nType, int nX, int nY)
{
    SolarMutexGuard aGuard;

    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return;

    ScTabViewShell* pViewShell = pViewData->GetViewShell();

    LokChartHelper aChartHelper(pViewShell);
    if (aChartHelper.setTextSelection(nType, nX, nY))
        return;

    ScInputHandler* pInputHandler = ScModule::get()->GetInputHdl(pViewShell);
    ScDrawView* pDrawView = pViewData->GetScDrawView();

    bool bHandled = false;

    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;
        }
    }
    else if (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());
    }
}

uno::Reference<datatransfer::XTransferable> ScModelObj::getSelection()
{
    SolarMutexGuard aGuard;

    TransferableDataHelper aDataHelper;
    uno::Reference<datatransfer::XTransferable> xTransferable;

    if (ScViewData* pViewData = ScDocShell::GetViewData())
    {
        if ( ScEditShell * pShell = dynamic_cast<ScEditShell*>( pViewData->GetViewShell()->GetViewFrame().GetDispatcher()->GetShell(0) ) )
            xTransferable = pShell->GetEditView()->GetTransferable();
        else if ( nullptr != dynamic_cast<ScDrawTextObjectBar*>( pViewData->GetViewShell()->GetViewFrame().GetDispatcher()->GetShell(0) ))
        {
            ScDrawView* pView = pViewData->GetScDrawView();
            OutlinerView* pOutView = pView->GetTextEditOutlinerView();
            if (pOutView)
                xTransferable = pOutView->GetEditView().GetTransferable();
        }
        else if ( ScDrawShell * pDrawShell = dynamic_cast<ScDrawShell*>( pViewData->GetViewShell()->GetViewFrame().GetDispatcher()->GetShell(0) ) )
            xTransferable = pDrawShell->GetDrawView()->CopyToTransferable();
        else
            xTransferable = pViewData->GetViewShell()->CopyToTransferable();
    }

    if (!xTransferable.is())
        xTransferable.set( aDataHelper.GetTransferable() );

    return xTransferable;
}

void ScModelObj::setGraphicSelection(int nType, int nX, int nY)
{
    SolarMutexGuard aGuard;

    ScTabViewShell* pViewShell = pDocShell->GetBestViewShell(false);

    // FIXME: Can this happen? What should we do?
    if (!pViewShell)
        return;

    ScViewData* pViewData = &pViewShell->GetViewData();

    ScGridWindow* pGridWindow = pViewData->GetActiveWin();

    double fPPTX = pViewData->GetPPTX();
    double fPPTY = pViewData->GetPPTY();

    pViewShell = pViewData->GetViewShell();
    LokChartHelper aChartHelper(pViewShell);
    if (aChartHelper.setGraphicSelection(nType, nX, nY, fPPTX, fPPTY))
        return;

    int nPixelX = nX * fPPTX;
    int nPixelY = nY * fPPTY;

    switch (nType)
    {
    case LOK_SETGRAPHICSELECTION_START:
        {
            MouseEvent aClickEvent(Point(nPixelX, nPixelY), 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT);
            pGridWindow->MouseButtonDown(aClickEvent);
            MouseEvent aMoveEvent(Point(nPixelX, nPixelY), 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT);
            pGridWindow->MouseMove(aMoveEvent);
        }
        break;
    case LOK_SETGRAPHICSELECTION_END:
        {
            MouseEvent aMoveEvent(Point(nPixelX, nPixelY), 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT);
            pGridWindow->MouseMove(aMoveEvent);
            MouseEvent aClickEvent(Point(nPixelX, nPixelY), 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT);
            pGridWindow->MouseButtonUp(aClickEvent);
        }
        break;
    default:
        assert(false);
        break;
    }
}

void ScModelObj::resetSelection()
{
    SolarMutexGuard aGuard;

    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return;

    ScTabViewShell* pViewShell = pViewData->GetViewShell();

    // 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::setClipboard(const uno::Reference<datatransfer::clipboard::XClipboard>& xClipboard)
{
    SolarMutexGuard aGuard;

    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return;

    pViewData->GetActiveWin()->SetClipboard(xClipboard);
}

bool ScModelObj::isMimeTypeSupported()
{
    SolarMutexGuard aGuard;

    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return false;


    TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(pViewData->GetActiveWin()));
    return EditEngine::HasValidData(aDataHelper.GetTransferable());
}

static void lcl_sendLOKDocumentBackground(const ScViewData* pViewData)
{
    ScDocShell& rDocSh = pViewData->GetDocShell();
    ScDocument& rDoc = rDocSh.GetDocument();
    const SfxPoolItem& rItem(rDoc.getCellAttributeHelper().getDefaultCellAttribute().GetItem(ATTR_BACKGROUND));
    const SvxBrushItem& rBackground = static_cast<const SvxBrushItem&>(rItem);
    const Color& rColor = rBackground.GetColor();

    ScTabViewShell* pViewShell = pViewData->GetViewShell();
    pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_DOCUMENT_BACKGROUND_COLOR, rColor.AsRGBHexString().toUtf8());
}

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);

    const Fraction newZoomX(o3tl::toTwips(nTilePixelWidth_, o3tl::Length::px), nTileTwipWidth_);
    const Fraction newZoomY(o3tl::toTwips(nTilePixelHeight_, o3tl::Length::px), nTileTwipHeight_);

    double fDeltaPPTX = std::abs(ScGlobal::nScreenPPTX * static_cast<double>(newZoomX) - pViewData->GetPPTX());
    double fDeltaPPTY = std::abs(ScGlobal::nScreenPPTY * static_cast<double>(newZoomY) - pViewData->GetPPTY());
    constexpr double fEps = 1E-08;

    if (pViewData->GetZoomX() == newZoomX && pViewData->GetZoomY() == newZoomY && fDeltaPPTX < fEps && fDeltaPPTY < fEps)
        return;

    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();
}

void ScModelObj::getRowColumnHeaders(const tools::Rectangle& rRectangle, tools::JsonWriter& rJsonWriter)
{
    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return;

    ScTabView* pTabView = pViewData->GetView();
    if (!pTabView)
        return;

    pTabView->getRowColumnHeaders(rRectangle, rJsonWriter);
}

OString ScModelObj::getSheetGeometryData(bool bColumns, bool bRows, bool bSizes, bool bHidden,
                                         bool bFiltered, bool bGroups)
{
    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return ""_ostr;

    ScTabView* pTabView = pViewData->GetView();
    if (!pTabView)
        return ""_ostr;

    return pTabView->getSheetGeometryData(bColumns, bRows, bSizes, bHidden, bFiltered, bGroups);
}

void ScModelObj::getCellCursor(tools::JsonWriter& rJsonWriter)
{
    SolarMutexGuard aGuard;

    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return;

    ScGridWindow* pGridWindow = pViewData->GetActiveWin();
    if (!pGridWindow)
        return;

    rJsonWriter.put("commandName"".uno:CellCursor");
    rJsonWriter.put("commandValues", pGridWindow->getCellCursor());
}

PointerStyle ScModelObj::getPointer()
{
    SolarMutexGuard aGuard;

    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return PointerStyle::Arrow;

    ScGridWindow* pGridWindow = pViewData->GetActiveWin();
    if (!pGridWindow)
        return PointerStyle::Arrow;

    return pGridWindow->GetPointer();
}

void ScModelObj::getTrackedChanges(tools::JsonWriter& rJson)
{
    if (pDocShell)
    {
        if (ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack())
            pChangeTrack->GetChangeTrackInfo(rJson);
    }
}

void ScModelObj::setClientVisibleArea(const tools::Rectangle& rRectangle)
{
    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return;

    // set the PgUp/PgDown offset
    pViewData->ForcePageUpDownOffset(rRectangle.GetHeight());

    // Store the visible area so that we can use at places like shape insertion
    pViewData->setLOKVisibleArea(rRectangle);

    if (comphelper::LibreOfficeKit::isCompatFlagSet(
            comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs))
    {
        ScTabView* pTabView = pViewData->GetView();
        if (pTabView)
            pTabView->extendTiledAreaIfNeeded();
    }
}

void ScModelObj::setOutlineState(bool bColumn, int nLevel, int nIndex, bool bHidden)
{
    ScViewData* pViewData = ScDocShell::GetViewData();
    if (!pViewData)
        return;

    ScDBFunc* pFunc = pViewData->GetView();

    if (pFunc)
        pFunc->SetOutlineState(bColumn, nLevel, nIndex, bHidden);
}

void ScModelObj::getPostIts(tools::JsonWriter& rJsonWriter)
{
    if (!pDocShell)
        return;

    ScDocument& rDoc = pDocShell->GetDocument();
    std::vector<sc::NoteEntry> aNotes;
    rDoc.GetAllNoteEntries(aNotes);

    auto commentsNode = rJsonWriter.startArray("comments");
    for (const sc::NoteEntry& aNote : aNotes)
    {
        auto commentNode = rJsonWriter.startStruct();

        rJsonWriter.put("id", aNote.mpNote->GetId());
        rJsonWriter.put("tab", aNote.maPos.Tab());
        rJsonWriter.put("author", aNote.mpNote->GetAuthor());
        rJsonWriter.put("dateTime", aNote.mpNote->GetDate());
        rJsonWriter.put("text", aNote.mpNote->GetText());

        // Calculating the cell cursor position
        if (ScViewData* pViewData = ScDocShell::GetViewData())
        {
            ScGridWindow* pGridWindow = pViewData->GetActiveWin();
            if (pGridWindow)
            {
                rJsonWriter.put("cellRange", ScPostIt::NoteRangeToJsonString(rDoc, aNote.maPos));
            }
        }
    }
}

OString ScPostIt::NoteRangeToJsonString(const ScDocument& rDoc, const ScAddress&&nbsp;rPos)
{
    SCCOL nX(rPos.Col());
    SCROW nY(rPos.Row());
    OString aStartCellAddress(OString::number(nX) + " " + OString::number(nY));
    const ScPatternAttr* pMarkPattern = rDoc.GetPattern(nX, nY, rPos.Tab());
    const ScMergeAttr* pMergeItem = nullptr;
    if (pMarkPattern && pMarkPattern->GetItemSet().GetItemState(ATTR_MERGE, false, &pMergeItem) == SfxItemState::SET)
    {
        SCCOL nCol = pMergeItem->GetColMerge();
        if (nCol > 1)
            nX += nCol - 1;
        SCROW nRow = pMergeItem->GetRowMerge();
        if (nRow > 1)
            nY += nRow - 1;
    }
    OString aEndCellAddress(OString::number(nX) + " " + OString::number(nY));
    return aStartCellAddress + " " + aEndCellAddress;
}

void ScModelObj::getPostItsPos(tools::JsonWriter& rJsonWriter)
{
    if (!pDocShell)
        return;

    ScDocument& rDoc = pDocShell->GetDocument();
    std::vector<sc::NoteEntry> aNotes;
    rDoc.GetAllNoteEntries(aNotes);

    auto commentsNode = rJsonWriter.startArray("commentsPos");
    for (const sc::NoteEntry& aNote : aNotes)
    {
        auto commentNode = rJsonWriter.startStruct();

        rJsonWriter.put("id", aNote.mpNote->GetId());
        rJsonWriter.put("tab", aNote.maPos.Tab());

        // Calculating the cell cursor position
        if (ScViewData* pViewData = ScDocShell::GetViewData())
        {
            ScGridWindow* pGridWindow = pViewData->GetActiveWin();
            if (pGridWindow)
            {
                rJsonWriter.put("cellRange", ScPostIt::NoteRangeToJsonString(rDoc, aNote.maPos));
            }
        }
    }
}

void ScModelObj::completeFunction(const OUString& rFunctionName)
{
    if (ScInputHandler* pHdl = ScModule::get()->GetInputHdl())
    {
        assert(!rFunctionName.isEmpty());
        pHdl->LOKPasteFunctionData(rFunctionName);
    }
}

OString ScModelObj::getViewRenderState(SfxViewShell* pViewShell)
{
    ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
    if (!pTabViewShell)
    {
        ScViewData* pViewData = ScDocShell::GetViewData();
        pTabViewShell = pViewData ? pViewData->GetViewShell() : nullptr;
    }

    if (pTabViewShell)
        return getTabViewRenderState(*pTabViewShell);

    return OString();
}

void ScModelObj::initializeForTiledRendering(const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
{
    SolarMutexGuard aGuard;

    ScModule* mod = ScModule::get();
    // enable word autocompletion
    ScAppOptions aAppOptions(mod->GetAppOptions());
    aAppOptions.SetAutoComplete(true);
    mod->SetAppOptions(aAppOptions);

    OUString sThemeName;
    OUString sBackgroundThemeName;

    for (const beans::PropertyValue& rValue : rArguments)
    {
        if (rValue.Name == ".uno:SpellOnline" && rValue.Value.has<bool>())
        {
            ScViewData* pViewData = ScDocShell::GetViewData();
            if (ScTabViewShell* pTabViewShell = pViewData ? pViewData->GetViewShell() : nullptr)
                pTabViewShell->EnableAutoSpell(rValue.Value.get<bool>());
        }
        else if (rValue.Name == ".uno:ChangeTheme" && rValue.Value.has<OUString>())
            sThemeName = rValue.Value.get<OUString>();
        else if (rValue.Name == ".uno:InvertBackground" && rValue.Value.has<OUString>())
            sBackgroundThemeName = rValue.Value.get<OUString>();
    }

    // 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);
    }
}

uno::Any SAL_CALL ScModelObj::queryInterface( const uno::Type& rType )
{
    uno::Any aReturn = ::cppu::queryInterface(rType,
                static_cast< sheet::XSpreadsheetDocument *>(this),
                static_cast< document::XActionLockable *>(this),
                static_cast< sheet::XCalculatable *>(this),
                static_cast< util::XProtectable *>(this),
                static_cast< drawing::XDrawPagesSupplier *>(this),
                static_cast< sheet::XGoalSeek *>(this),
                static_cast< sheet::XConsolidatable *>(this),
                static_cast< sheet::XDocumentAuditing *>(this),
                static_cast< style::XStyleFamiliesSupplier *>(this),
                static_cast< view::XRenderable *>(this),
                static_cast< document::XLinkTargetSupplier *>(this),
                static_cast< beans::XPropertySet *>(this),
                static_cast< lang::XMultiServiceFactory *>(this),
                static_cast< lang::XServiceInfo *>(this),
                static_cast< util::XChangesNotifier *>(this),
                static_cast< sheet::opencl::XOpenCLSelection *>(this),
                static_cast< chart2::XDataProviderAccess *>(this));
    if ( aReturn.hasValue() )
        return aReturn;

    uno::Any aRet(SfxBaseModel::queryInterface( rType ));
    if ( !aRet.hasValue()
        && rType != cppu::UnoType<css::document::XDocumentEventBroadcaster>::get()
        && rType != cppu::UnoType<css::frame::XController>::get()
        && rType != cppu::UnoType<css::frame::XFrame>::get()
        && rType != cppu::UnoType<css::script::XInvocation>::get()
        && rType != cppu::UnoType<css::beans::XFastPropertySet>::get()
        && rType != cppu::UnoType<css::awt::XWindow>::get())
    {
        GetFormatter();
        if ( xNumberAgg.is() )
            aRet = xNumberAgg->queryAggregation( rType );
    }

    return aRet;
}

void SAL_CALL ScModelObj::acquire() noexcept
{
    SfxBaseModel::acquire();
}

void SAL_CALL ScModelObj::release() noexcept
{
    SfxBaseModel::release();
}

uno::Sequence<uno::Type> SAL_CALL ScModelObj::getTypes()
{
    static const uno::Sequence<uno::Type> aTypes = [&]()
    {
        uno::Sequence<uno::Type> aAggTypes;
        if ( GetFormatter().is() )
        {
            const uno::Type& rProvType = cppu::UnoType<lang::XTypeProvider>::get();
            uno::Any aNumProv(xNumberAgg->queryAggregation(rProvType));
            if(auto xNumProv
               = o3tl::tryAccess<uno::Reference<lang::XTypeProvider>>(aNumProv))
            {
                aAggTypes = (*xNumProv)->getTypes();
            }
        }
        return comphelper::concatSequences(
            SfxBaseModel::getTypes(),
            aAggTypes,
            uno::Sequence<uno::Type>
            {
                cppu::UnoType<sheet::XSpreadsheetDocument>::get(),
                cppu::UnoType<document::XActionLockable>::get(),
                cppu::UnoType<sheet::XCalculatable>::get(),
                cppu::UnoType<util::XProtectable>::get(),
                cppu::UnoType<drawing::XDrawPagesSupplier>::get(),
                cppu::UnoType<sheet::XGoalSeek>::get(),
                cppu::UnoType<sheet::XConsolidatable>::get(),
                cppu::UnoType<sheet::XDocumentAuditing>::get(),
                cppu::UnoType<style::XStyleFamiliesSupplier>::get(),
                cppu::UnoType<view::XRenderable>::get(),
                cppu::UnoType<document::XLinkTargetSupplier>::get(),
                cppu::UnoType<beans::XPropertySet>::get(),
                cppu::UnoType<lang::XMultiServiceFactory>::get(),
                cppu::UnoType<lang::XServiceInfo>::get(),
                cppu::UnoType<util::XChangesNotifier>::get(),
                cppu::UnoType<sheet::opencl::XOpenCLSelection>::get(),
            } );
    }();
    return aTypes;
}

uno::Sequence<sal_Int8> SAL_CALL ScModelObj::getImplementationId()
{
    return css::uno::Sequence<sal_Int8>();
}

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();
    }
    else if ( 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
}

// XSpreadsheetDocument

uno::Reference<sheet::XSpreadsheets> SAL_CALL ScModelObj::getSheets()
{
    return getScSheets();
}

rtl::Reference<ScTableSheetsObj> ScModelObj::getScSheets()
{
    SolarMutexGuard aGuard;
    if (pDocShell)
        return new ScTableSheetsObj(pDocShell);
    return nullptr;
}

css::uno::Reference< ::css::chart2::data::XDataProvider > SAL_CALL ScModelObj::createDataProvider()
{
    if (pDocShell)
    {
        return css::uno::Reference< ::css::chart2::data::XDataProvider > (
            ScServiceProvider::MakeInstance(ScServiceProvider::Type::CHDATAPROV, pDocShell), uno::UNO_QUERY);
    }
    return nullptr;
}

// XStyleFamiliesSupplier

uno::Reference<container::XNameAccess> SAL_CALL ScModelObj::getStyleFamilies()
{
    SolarMutexGuard aGuard;
    if (pDocShell)
        return new ScStyleFamiliesObj(pDocShell);
    return nullptr;
}

// XRenderable

static OutputDevice* lcl_GetRenderDevice( const uno::Sequence<beans::PropertyValue>&&nbsp;rOptions )
{
    OutputDevice* pRet = nullptr;
    for (const beans::PropertyValue& rProp : rOptions)
    {
        const OUString & rPropName = rProp.Name;

        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;
}

static bool 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

    ScAddress aAddress;
    SCTAB nNameTab;
    sal_Int32 nNumeric = 0;

    bool bRangeValid = false;
    bool bRectValid = false;

    if ( rTargetRange.Parse( rTarget, rDoc ) & ScRefFlags::VALID )
    {
        bRangeValid = true;             // range reference
    }
    else if ( aAddress.Parse( rTarget, rDoc ) & ScRefFlags::VALID )
    {
        rTargetRange = aAddress;
        bRangeValid = true;             // cell reference
    }
    else if ( ScRangeUtil::MakeRangeFromName( rTarget, rDoc, nSourceTab, rTargetRange ) ||
              ScRangeUtil::MakeRangeFromName( rTarget, rDoc, nSourceTab, rTargetRange, RUTL_DBASE ) )
    {
        bRangeValid = true;             // named range or database range
    }
    else if ( comphelper::string::isdigitAsciiString(rTarget) &&
              ( nNumeric = rTarget.toInt32() ) > 0 && nNumeric <= rDoc.MaxRow()+1 )
    {
        // row number is always mapped to cell A(row) on the same sheet
        rTargetRange = ScAddress( 0, static_cast<SCROW>(nNumeric-1), nSourceTab );     // target row number is 1-based
        bRangeValid = true;             // row number
    }
    else if ( rDoc.GetTable( rTarget, nNameTab ) )
    {
        rTargetRange = ScAddress(0,0,nNameTab);
        bRangeValid = true;             // sheet name
        rIsSheet = true;                // needs special handling (first page of the sheet)
    }
    else
    {
        // look for named drawing object

        ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
        if ( pDrawLayer )
        {
            SCTAB nTabCount = rDoc.GetTableCount();
            for (SCTAB i=0; i<nTabCount && !bRangeValid; i++)
            {
                SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(i));
                OSL_ENSURE(pPage,"Page ?");
                if (pPage)
                {
                    SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );
                    SdrObject* pObject = aIter.Next();
                    while (pObject && !bRangeValid)
                    {
                        if ( ScDrawLayer::GetVisibleName( pObject ) == rTarget )
                        {
                            rTargetRect = pObject->GetLogicRect();              // 1/100th mm
                            rTargetRange = rDoc.GetRange( i, rTargetRect );    // underlying cells
                            bRangeValid = bRectValid = true;                    // rectangle is valid
                        }
                        pObject = aIter.Next();
                    }
                }
            }
        }
    }
    if ( bRangeValid && !bRectValid )
    {
        //  get rectangle for cell range
        rTargetRect = rDoc.GetMMRect( rTargetRange.aStart.Col(), rTargetRange.aStart.Row(),
                                      rTargetRange.aEnd.Col(),   rTargetRange.aEnd.Row(),
                                      rTargetRange.aStart.Tab() );
    }

    return bRangeValid;
}

static Printer* lcl_GetPrinter(const uno::Sequence<beans::PropertyValue>& rOptions)
{
    Printer* pPrinter = nullptr;
    OutputDevice* pDev = lcl_GetRenderDevice(rOptions);
    if (pDev && pDev->GetOutDevType() == OUTDEV_PRINTER)
        pPrinter = dynamic_cast<Printer*>(pDev);
    return pPrinter;
}

static Size lcl_GetPrintPageSize(Size aSize)
{
    aSize.setWidth(o3tl::convert(aSize.Width(), o3tl::Length::mm100, o3tl::Length::twip));
    aSize.setHeight(o3tl::convert(aSize.Height(), o3tl::Length::mm100, o3tl::Length::twip));
    return aSize;
}

bool ScModelObj::FillRenderMarkData( const uno::Any& aSelection,
                                     const uno::Sequence< beans::PropertyValue >& rOptions,
                                     ScMarkData& rMark,
                                     ScPrintSelectionStatus& rStatus, OUString& rPagesStr,
                                     bool& rbRenderToGraphic ) const
{
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=93 H=96 G=94

¤ Dauer der Verarbeitung: 0.29 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.