    /* -*- 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 <editeng/eeitem.hxx>
    #include <editeng/flditem.hxx>
    #include <editeng/CustomPropertyField.hxx>
    #include <o3tl/make_unique.hxx>
    #include <sfx2/printer.hxx>
    #include <sfx2/styfitem.hxx>
    #include <svl/inethist.hxx>
    #include <svl/poolitem.hxx>
    #include <svl/flagitem.hxx>
    #include <unotools/useroptions.hxx>
    #include <sfx2/bindings.hxx>
    #include <sfx2/viewfrm.hxx>
    #include <sfx2/docfile.hxx>
    #include <sfx2/request.hxx>

    #include <editeng/measfld.hxx>
    #include <editeng/editstat.hxx>
    #include <editeng/editeng.hxx>

    #include <svx/dialogs.hrc>
    #include <svx/svdotext.hxx>
    #include <svx/svdpagv.hxx>
    #include <svx/svdopage.hxx>

    #include <sfx2/sfxdlg.hxx>

    #include <svx/sdr/contact/displayinfo.hxx>

    #include <sdmod.hxx>
    #include <app.hrc>
    #include <family.hrc>
    #include <strings.hrc>

    #include <bitmaps.hlst>
    #include <ViewShell.hxx>
    #include <FrameView.hxx>
    #include <sdattr.hxx>
    #include <optsitem.hxx>
    #include <DrawDocShell.hxx>
    #include <drawdoc.hxx>
    #include <Outliner.hxx>
    #include <sdresid.hxx>
    #include <pres.hxx>
    #include <DrawViewShell.hxx>
    #include <OutlineViewShell.hxx>
    #include <OutlineView.hxx>
    #include <ViewShellBase.hxx>
    #include <sdpage.hxx>
    #include <sdxfer.hxx>
    #include <sdabstdlg.hxx>
    #include <svl/intitem.hxx>

    /** retrieves the page that is currently painted. This will only be the master page
        if the current drawn view only shows the master page*/
    static SdPage* GetCurrentPage( sd::ViewShell const * pViewSh, EditFieldInfo const * pInfo, bool& bMasterView )
    {
        if( !pInfo )
            return nullptr;

        bMasterView = false;
        SdPage* pPage = dynamic_cast< SdPage* >( pInfo->GetSdrPage() );
        SdrOutliner* pOutliner = dynamic_cast< SdrOutliner* >( pInfo->GetOutliner() );

        // special case, someone already set the current page on the EditFieldInfo
        // This is used from the svx::UnoGraphicsExporter f.e.
        if( pPage )
        {
            bMasterView = false;
            return pPage;
        }

        // first try to check if we are inside the outline view
        sd::OutlineView* pSdView = nullptr;
        if( auto pOutlineViewShell = dynamic_cast<const sd::OutlineViewShell* >(pViewSh) )
            pSdView = static_cast<sd::OutlineView*>(pOutlineViewShell->GetView());

        if (pSdView != nullptr && (pOutliner ==  &pSdView->GetOutliner()))
        {
            // outline mode
            int nPgNum = 0;
            Outliner& rOutl = pSdView->GetOutliner();
            long nPos = pInfo->GetPara();
            sal_Int32 nParaPos = 0;

            for( Paragraph* pPara = rOutl.GetParagraph( 0 ); pPara && nPos >= 0; pPara = rOutl.GetParagraph( ++nParaPos ), nPos-- )
            {
                if( Outliner::HasParaFlag( pPara, ParaFlag::ISPAGE ) )
                    nPgNum++;
            }

            pPage = pViewSh->GetDoc()->GetSdPage( static_cast<sal_uInt16>(nPgNum), PageKind::Standard );
        }
        else
        {
            // draw mode, slide mode and preview. Get the processed page from the outliner
            if(pOutliner)
            {
                pPage = dynamic_cast< SdPage* >(const_cast< SdrPage* >(pOutliner->getVisualizedPage()));
            }

            // The path using GetPaintingPageView() and GetCurrentPaintingDisplayInfo()
            // is no longer needed. I debugged and checked all usages of PageNumber decompositions
            // which all use the new possibility of setting the visualized page at the SdrOutliner.

            // if all else failed, geht the current page from the object that is
            // currently formatted from the document
            if(!pPage)
            {
                const SdrTextObj* pTextObj = (pViewSh && pViewSh->GetDoc()) ? pViewSh->GetDoc()->GetFormattingTextObj() : nullptr;

                if( pTextObj )
                {
                    pPage = dynamic_cast< SdPage* >( pTextObj->getSdrPageFromSdrObject() );
                }
            }

            if(pPage)
            {
                bMasterView = pPage && pPage->IsMasterPage();
            }
        }

        return pPage;
    }

    /**
     * Link for CalcFieldValue of Outliners
     */
    IMPL_LINK(SdModule, CalcFieldValueHdl, EditFieldInfo*, pInfo, void)
    {
        if (!pInfo)
            return;

        const SvxFieldData* pField = pInfo->GetField().GetField();
        ::sd::DrawDocShell*     pDocShell = nullptr;
        SdDrawDocument* pDoc = nullptr;

        SdrOutliner* pSdrOutliner = dynamic_cast< SdrOutliner* >( pInfo->GetOutliner() );
        if( pSdrOutliner )
        {
            const SdrTextObj* pTextObj = pSdrOutliner->GetTextObj();

            if( pTextObj )
                pDoc = dynamic_cast< SdDrawDocument* >( &pTextObj->getSdrModelFromSdrObject() );

            if( pDoc )
                pDocShell = pDoc->GetDocSh();
        }

        if( !pDocShell )
            pDocShell = dynamic_cast< ::sd::DrawDocShell *>( SfxObjectShell::Current() );

        const SvxDateField* pDateField = nullptr;
        const SvxExtTimeField* pExtTimeField = nullptr;
        const SvxExtFileField* pExtFileField = nullptr;
        const SvxAuthorField* pAuthorField = nullptr;
        const SvxURLField* pURLField = nullptr;

        const editeng::CustomPropertyField* pCustomPropertyField = nullptr;

        if( (pDateField = dynamic_cast< const SvxDateField* >(pField)) != nullptr )
        {
            LanguageType eLang = pInfo->GetOutliner()->GetLanguage( pInfo->GetPara(), pInfo->GetPos() );
            pInfo->SetRepresentation( pDateField->GetFormatted( *GetNumberFormatter(), eLang ) );
        }
        else if( (pExtTimeField = dynamic_cast< const SvxExtTimeField *>(pField)) != nullptr )
        {
            LanguageType eLang = pInfo->GetOutliner()->GetLanguage( pInfo->GetPara(), pInfo->GetPos() );
            pInfo->SetRepresentation( pExtTimeField->GetFormatted( *GetNumberFormatter(), eLang ) );
        }
        else if( (pExtFileField = dynamic_cast< const SvxExtFileField * >(pField)) != nullptr )
        {
            if( pDocShell && (pExtFileField->GetType() != SvxFileType::Fix) )
            {
                OUString aName;
                if( pDocShell->HasName() )
                    aName = pDocShell->GetMedium()->GetName();
                else
                    aName = pDocShell->GetName();

                const_cast< SvxExtFileField* >(pExtFileField)->SetFile( aName );
            }
            pInfo->SetRepresentation( pExtFileField->GetFormatted() );

        }
        else if( (pAuthorField = dynamic_cast< const SvxAuthorField* >( pField )) != nullptr  )
        {
            if( pAuthorField->GetType() != SvxAuthorType::Fix )
            {
                SvtUserOptions aUserOptions;
                SvxAuthorField aAuthorField(
                        aUserOptions.GetFirstName(), aUserOptions.GetLastName(), aUserOptions.GetID(),
                        pAuthorField->GetType(), pAuthorField->GetFormat() );

                *const_cast< SvxAuthorField* >(pAuthorField) = aAuthorField;
            }
            pInfo->SetRepresentation( pAuthorField->GetFormatted() );

        }
        else if( dynamic_cast< const SvxPageField*  >(pField) )
        {
            OUString aRepresentation(" ");

            ::sd::ViewShell* pViewSh = pDocShell ? pDocShell->GetViewShell() : nullptr;
            if(pViewSh == nullptr)
            {
                ::sd::ViewShellBase* pBase = dynamic_cast< ::sd::ViewShellBase *>( SfxViewShell::Current() );
                if(pBase)
                    pViewSh = pBase->GetMainViewShell().get();
            }
            if( !pDoc && pViewSh )
                pDoc = pViewSh->GetDoc();

            bool bMasterView;
            SdPage* pPage = GetCurrentPage( pViewSh, pInfo, bMasterView );

            if( pPage && pDoc && !bMasterView )
            {
                int nPgNum;

                if( (pPage->GetPageKind() == PageKind::Handout) && pViewSh )
                {
                    nPgNum = pViewSh->GetPrintedHandoutPageNum();
                }
                else
                {
                    nPgNum = (pPage->GetPageNum() - 1) / 2 + 1;
                }
                aRepresentation = pDoc->CreatePageNumValue(static_cast<sal_uInt16>(nPgNum));
            }
            else
                aRepresentation = SdResId(STR_FIELD_PLACEHOLDER_NUMBER);

            pInfo->SetRepresentation( aRepresentation );
        }
        else if( dynamic_cast< const SvxPageTitleField*  >(pField) )
        {
            OUString aRepresentation(" ");

            ::sd::ViewShell* pViewSh = pDocShell ? pDocShell->GetViewShell() : nullptr;
            if(pViewSh == nullptr)
            {
                ::sd::ViewShellBase* pBase = dynamic_cast< ::sd::ViewShellBase *>( SfxViewShell::Current() );
                if(pBase)
                    pViewSh = pBase->GetMainViewShell().get();
            }
            if( !pDoc && pViewSh )
                pDoc = pViewSh->GetDoc();

            bool bMasterView;
            SdPage* pPage = GetCurrentPage( pViewSh, pInfo, bMasterView );

            if( pPage && pDoc && !bMasterView )
            {
                aRepresentation = pPage->GetName();
            }
            else
            {
                DocumentType eDocType = pDoc ? pDoc->GetDocumentType() : DocumentType::Impress;
                aRepresentation = ( ( eDocType == DocumentType::Impress )
                                    ? SdResId(STR_FIELD_PLACEHOLDER_SLIDENAME)
                                    : SdResId(STR_FIELD_PLACEHOLDER_PAGENAME) );
            }

            pInfo->SetRepresentation( aRepresentation );
        }
        else if( dynamic_cast< const SvxPagesField*  >(pField) )
        {
            OUString aRepresentation(" ");

            ::sd::ViewShell* pViewSh = pDocShell ? pDocShell->GetViewShell() : nullptr;
            if(pViewSh == nullptr)
            {
                ::sd::ViewShellBase* pBase = dynamic_cast< ::sd::ViewShellBase *>( SfxViewShell::Current() );
                if(pBase)
                    pViewSh = pBase->GetMainViewShell().get();
            }
            if( !pDoc && pViewSh )
                pDoc = pViewSh->GetDoc();

            bool bMasterView;
            SdPage* pPage = GetCurrentPage( pViewSh, pInfo, bMasterView );

            sal_uInt16 nPageCount = 0;

            if( !bMasterView )
            {
                if( pPage && (pPage->GetPageKind() == PageKind::Handout) && pViewSh )
                {
                    nPageCount = pViewSh->GetPrintedHandoutPageCount();
                }
                else if( pDoc )
                {
                    nPageCount = pDoc->GetActiveSdPageCount();
                }
            }

            if( nPageCount > 0 )
                aRepresentation = pDoc->CreatePageNumValue(nPageCount);
            else
                aRepresentation = SdResId(STR_FIELD_PLACEHOLDER_COUNT);

            pInfo->SetRepresentation( aRepresentation );
        }
        else if( (pURLField = dynamic_cast< const SvxURLField* >(pField)) != nullptr )
        {
            switch ( pURLField->GetFormat() )
            {
                case SvxURLFormat::AppDefault: //!!! adjustable at App???
                case SvxURLFormat::Repr:
                    pInfo->SetRepresentation( pURLField->GetRepresentation() );
                    break;

                case SvxURLFormat::Url:
                    pInfo->SetRepresentation( pURLField->GetURL() );
                    break;
            }

            OUString aURL = pURLField->GetURL();

            svtools::ColorConfig aConfig;
            svtools::ColorConfigEntry eEntry =
                INetURLHistory::GetOrCreate()->QueryUrl( aURL ) ? svtools::LINKSVISITED : svtools::LINKS;
            pInfo->SetTextColor( aConfig.GetColorValue(eEntry).nColor );
        }
        else if ( dynamic_cast< const SdrMeasureField* >(pField))
        {
            pInfo->ClearFieldColor();
        }
        else if ((pCustomPropertyField = dynamic_cast<const editeng::CustomPropertyField*>(pField)) != nullptr)
        {
            try
            {
                if (SfxObjectShell::Current() && SfxObjectShell::Current()->IsLoadingFinished())
                {
                    auto pNonConstCustomPropertyField = const_cast<editeng::CustomPropertyField*>(pCustomPropertyField);
                    OUString sCurrent = pNonConstCustomPropertyField->GetFormatted(SfxObjectShell::Current()->getDocProperties());
                    pInfo->SetRepresentation(sCurrent);
                }
                else
                    pInfo->SetRepresentation(pCustomPropertyField->GetCurrentPresentation());
            }
            catch (...)
            {
                pInfo->SetRepresentation(pCustomPropertyField->GetCurrentPresentation());
            }
        }
        else
        {
            OUString aRepresentation;

            bool bHeaderField = dynamic_cast< const SvxHeaderField* >( pField ) != nullptr;
            bool bFooterField = !bHeaderField && (dynamic_cast< const SvxFooterField* >( pField ) != nullptr );
            bool bDateTimeField = !bHeaderField && !bFooterField && (dynamic_cast< const SvxDateTimeField* >( pField ) != nullptr);

            if( bHeaderField || bFooterField || bDateTimeField )
            {
                sd::ViewShell* pViewSh = pDocShell ? pDocShell->GetViewShell() : nullptr;
                bool bMasterView = false;
                SdPage* pPage = GetCurrentPage( pViewSh, pInfo, bMasterView );

                if( (pPage == nullptr) || bMasterView )
                {
                    if( bHeaderField )
                        aRepresentation = SdResId(STR_FIELD_PLACEHOLDER_HEADER);
                    else if (bFooterField )
                        aRepresentation = SdResId(STR_FIELD_PLACEHOLDER_FOOTER);
                    else if (bDateTimeField )
                        aRepresentation = SdResId(STR_FIELD_PLACEHOLDER_DATETIME);
                }
                else
                {
                    const sd::HeaderFooterSettings &rSettings = pPage->getHeaderFooterSettings();

                    if( bHeaderField )
                    {
                        aRepresentation = rSettings.maHeaderText;
                    }
                    else if( bFooterField )
                    {
                        aRepresentation = rSettings.maFooterText;
                    }
                    else if( bDateTimeField )
                    {
                        if( rSettings.mbDateTimeIsFixed )
                        {
                            aRepresentation = rSettings.maDateTimeText;
                        }
                        else
                        {
                            DateTime aDateTime( DateTime::SYSTEM );
                            LanguageType eLang = pInfo->GetOutliner()->GetLanguage( pInfo->GetPara(), pInfo->GetPos() );
                            aRepresentation = SvxDateTimeField::GetFormatted( aDateTime, aDateTime,
                                                  rSettings.meDateFormat, rSettings.meTimeFormat, *GetNumberFormatter(), eLang );
                        }
                    }
                }
            }
            else
            {
                OSL_FAIL("sd::SdModule::CalcFieldValueHdl(), unknown field type!");
            }

            if( aRepresentation.isEmpty() )                // TODO: Edit engine doesn't handle empty fields?
                aRepresentation = " ";
            pInfo->SetRepresentation( aRepresentation );
        }
    }

    /**
     * virtual methods for option dialog
     */
    std::unique_ptr<SfxItemSet> SdModule::CreateItemSet( sal_uInt16 nSlot )
    {
        ::sd::FrameView* pFrameView = nullptr;
        ::sd::DrawDocShell* pDocSh = dynamic_cast< ::sd::DrawDocShell *>( SfxObjectShell::Current() );
        SdDrawDocument* pDoc = nullptr;

        // Here we set the DocType of the option dialog (not document!)
        DocumentType eDocType = DocumentType::Impress;
        if( nSlot == SID_SD_GRAPHIC_OPTIONS )
            eDocType = DocumentType::Draw;

        if (pDocSh)
        {
            pDoc = pDocSh->GetDoc();

            // If the option dialog is identical to the document type,
            // we can pass the FrameView too:
            if( pDoc && eDocType == pDoc->GetDocumentType() )
                pFrameView = pDocSh->GetFrameView();

            ::sd::ViewShell* pViewShell = pDocSh->GetViewShell();
            if (pViewShell != nullptr)
                pViewShell->WriteFrameViewData();
        }

        SdOptions* pOptions = GetSdOptions(eDocType);

        // Pool has by default MapUnit Twips (Awgh!)
        SfxItemPool& rPool = GetPool();
        rPool.SetDefaultMetric( MapUnit::Map100thMM );

        auto pRet = o3tl::make_unique<SfxItemSet>(
            rPool,
            svl::Items<
                SID_ATTR_GRID_OPTIONS, SID_ATTR_GRID_OPTIONS,
                SID_ATTR_METRIC, SID_ATTR_METRIC,
                SID_ATTR_DEFTABSTOP, SID_ATTR_DEFTABSTOP,
                ATTR_OPTIONS_LAYOUT, ATTR_OPTIONS_SCALE_END>{});

        // TP_OPTIONS_LAYOUT:
        pRet->Put( SdOptionsLayoutItem( pOptions, pFrameView ) );

        sal_uInt16 nDefTab = 0;
        if( pFrameView)
            nDefTab = pDoc->GetDefaultTabulator();
        else
            nDefTab = pOptions->GetDefTab();
        pRet->Put( SfxUInt16Item( SID_ATTR_DEFTABSTOP, nDefTab ) );

        FieldUnit nMetric = FieldUnit(0xffff);
        if( pFrameView)
            nMetric = pDoc->GetUIUnit();
        else
            nMetric = static_cast<FieldUnit>(pOptions->GetMetric());

        if( nMetric == FieldUnit(0xffff) )
            nMetric = GetFieldUnit();

        pRet->Put( SfxUInt16Item( SID_ATTR_METRIC, static_cast<sal_uInt16>(nMetric) ) );

        // TP_OPTIONS_MISC:
        SdOptionsMiscItem aSdOptionsMiscItem( pOptions, pFrameView );
        if ( pFrameView )
        {
            aSdOptionsMiscItem.GetOptionsMisc().SetSummationOfParagraphs( pDoc->IsSummationOfParagraphs() );
            aSdOptionsMiscItem.GetOptionsMisc().SetPrinterIndependentLayout (
                static_cast<sal_uInt16>(pDoc->GetPrinterIndependentLayout()));
        }
        pRet->Put( aSdOptionsMiscItem );

        // TP_OPTIONS_SNAP:
        pRet->Put( SdOptionsSnapItem( pOptions, pFrameView ) );

        // TP_SCALE:
        sal_uInt32 nW = 10;
        sal_uInt32 nH = 10;
        sal_Int32  nX;
        sal_Int32  nY;
        if( pDocSh )
        {
            SdrPage* pPage = static_cast<SdrPage*>(pDoc->GetSdPage(0, PageKind::Standard));
            Size aSize(pPage->GetSize());
            nW = aSize.Width();
            nH = aSize.Height();
        }

        if(pFrameView)
        {
            const Fraction& rFraction =  pDoc->GetUIScale();
            nX=rFraction.GetNumerator();
            nY=rFraction.GetDenominator();
        }
        else
        {
            // Get options from configuration file
            pOptions->GetScale( nX, nY );
        }

        pRet->Put( SfxInt32Item( ATTR_OPTIONS_SCALE_X, nX ) );
        pRet->Put( SfxInt32Item( ATTR_OPTIONS_SCALE_Y, nY ) );
        pRet->Put( SfxUInt32Item( ATTR_OPTIONS_SCALE_WIDTH, nW ) );
        pRet->Put( SfxUInt32Item( ATTR_OPTIONS_SCALE_HEIGHT, nH ) );

        // TP_OPTIONS_PRINT:
        pRet->Put( SdOptionsPrintItem( pOptions ) );

        // RID_SVXPAGE_GRID:
        pRet->Put( SdOptionsGridItem( pOptions ) );

        return pRet;
    }
    void SdModule::ApplyItemSet( sal_uInt16 nSlot, const SfxItemSet& rSet )
    {
        const SfxPoolItem*  pItem = nullptr;
        bool bNewDefTab = false;
        bool bNewPrintOptions = false;
        bool bMiscOptions = false;

        ::sd::DrawDocShell* pDocSh = dynamic_cast< ::sd::DrawDocShell *>( SfxObjectShell::Current() );
        SdDrawDocument* pDoc = nullptr;
        // Here we set the DocType of the option dialog (not document!)
        DocumentType eDocType = DocumentType::Impress;
        if( nSlot == SID_SD_GRAPHIC_OPTIONS )
            eDocType = DocumentType::Draw;

        ::sd::ViewShell* pViewShell = nullptr;

        if (pDocSh)
        {
            pDoc = pDocSh->GetDoc();

            pViewShell = pDocSh->GetViewShell();
            if (pViewShell != nullptr)
                pViewShell->WriteFrameViewData();
        }
        SdOptions* pOptions = GetSdOptions(eDocType);
        // Grid
        if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_GRID_OPTIONS ,
                                false, &pItem ))
        {
            const SdOptionsGridItem* pGridItem = static_cast<const SdOptionsGridItem*>(pItem);
            pGridItem->SetOptions( pOptions );
        }

        // Layout
        const SdOptionsLayoutItem* pLayoutItem = nullptr;
        if( SfxItemState::SET == rSet.GetItemState( ATTR_OPTIONS_LAYOUT,
                                false, reinterpret_cast<const SfxPoolItem**>(&pLayoutItem) ))
        {
            pLayoutItem->SetOptions( pOptions );
        }

        // Metric
        if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_METRIC, false, &pItem ) )
        {
            if( pDoc && eDocType == pDoc->GetDocumentType() )
                PutItem( *pItem );
            pOptions->SetMetric( static_cast<const SfxUInt16Item*>( pItem )->GetValue() );
        }
        sal_uInt16 nDefTab = pOptions->GetDefTab();
        // Default-Tabulator
        if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_DEFTABSTOP, false, &pItem ) )
        {
            nDefTab = static_cast<const SfxUInt16Item*>( pItem )->GetValue();
            pOptions->SetDefTab( nDefTab );

            bNewDefTab = true;
        }

        // Scale
        if( SfxItemState::SET == rSet.GetItemState( ATTR_OPTIONS_SCALE_X, false, &pItem ) )
        {
            sal_Int32 nX = static_cast<const SfxInt32Item*>( pItem )->GetValue();
            if( SfxItemState::SET == rSet.GetItemState( ATTR_OPTIONS_SCALE_Y, false, &pItem ) )
            {
                sal_Int32 nY = static_cast<const SfxInt32Item*>( pItem )->GetValue();
                pOptions->SetScale( nX, nY );

                // Apply to document only if doc type match
                if( pDocSh && pDoc && eDocType == pDoc->GetDocumentType() )
                {
                    pDoc->SetUIScale( Fraction( nX, nY ) );
                    if( pViewShell )
                        pViewShell->SetRuler( pViewShell->HasRuler() );
                }
            }
        }

        // Misc
        const SdOptionsMiscItem* pMiscItem = nullptr;
        if( SfxItemState::SET == rSet.GetItemState( ATTR_OPTIONS_MISC,
                                false, reinterpret_cast<const SfxPoolItem**>(&pMiscItem) ))
        {
            pMiscItem->SetOptions( pOptions );
            bMiscOptions = true;
        }

        // Snap
        const SdOptionsSnapItem* pSnapItem = nullptr;
        if( SfxItemState::SET == rSet.GetItemState( ATTR_OPTIONS_SNAP,
                                false, reinterpret_cast<const SfxPoolItem**>(&pSnapItem) ))
        {
            pSnapItem->SetOptions( pOptions );
        }

        SfxItemSet aPrintSet( GetPool(),
                        svl::Items<SID_PRINTER_NOTFOUND_WARN,  SID_PRINTER_NOTFOUND_WARN,
                        SID_PRINTER_CHANGESTODOC,   SID_PRINTER_CHANGESTODOC,
                        ATTR_OPTIONS_PRINT,         ATTR_OPTIONS_PRINT>{} );

        // Print
        const SdOptionsPrintItem* pPrintItem = nullptr;
        if( SfxItemState::SET == rSet.GetItemState( ATTR_OPTIONS_PRINT,
                                false, reinterpret_cast<const SfxPoolItem**>(&pPrintItem) ))
        {
            pPrintItem->SetOptions( pOptions );

            // set PrintOptionsSet
            SdOptionsPrintItem aPrintItem( pOptions );
            SfxFlagItem aFlagItem( SID_PRINTER_CHANGESTODOC );
            SfxPrinterChangeFlags nFlags =
                    (aPrintItem.GetOptionsPrint().IsWarningSize() ? SfxPrinterChangeFlags::CHG_SIZE : SfxPrinterChangeFlags::NONE) |
                    (aPrintItem.GetOptionsPrint().IsWarningOrientation() ? SfxPrinterChangeFlags::CHG_ORIENTATION : SfxPrinterChangeFlags::NONE);
            aFlagItem.SetValue( static_cast<int>(nFlags) );

            aPrintSet.Put( aPrintItem );
            aPrintSet.Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aPrintItem.GetOptionsPrint().IsWarningPrinter() ) );
            aPrintSet.Put( aFlagItem );

            bNewPrintOptions = true;
        }

        // Only if also the document type matches...
        if( pDocSh && pDoc && eDocType == pDoc->GetDocumentType() )
        {
            if( bNewPrintOptions )
            {
                pDocSh->GetPrinter(true)->SetOptions( aPrintSet );
            }

            // set DefTab at Model
            if( bNewDefTab )
            {
                SdDrawDocument* pDocument = pDocSh->GetDoc();
                pDocument->SetDefaultTabulator( nDefTab );

                SdOutliner* pOutl = pDocument->GetOutliner( false );
                if( pOutl )
                    pOutl->SetDefTab( nDefTab );

                SdOutliner* pInternalOutl = pDocument->GetInternalOutliner( false );
                if( pInternalOutl )
                    pInternalOutl->SetDefTab( nDefTab );
            }
            if ( bMiscOptions )
            {
                pDoc->SetSummationOfParagraphs( pMiscItem->GetOptionsMisc().IsSummationOfParagraphs() );
                EEControlBits nSum = pMiscItem->GetOptionsMisc().IsSummationOfParagraphs() ? EEControlBits::ULSPACESUMMATION : EEControlBits::NONE;
                EEControlBits nCntrl;

                SdDrawDocument* pDocument = pDocSh->GetDoc();
                SdrOutliner& rOutl = pDocument->GetDrawOutliner();
                nCntrl = rOutl.GetControlWord() &~ EEControlBits::ULSPACESUMMATION;
                rOutl.SetControlWord( nCntrl | nSum );
                SdOutliner* pOutl = pDocument->GetOutliner( false );
                if( pOutl )
                {
                    nCntrl = pOutl->GetControlWord() &~ EEControlBits::ULSPACESUMMATION;
                    pOutl->SetControlWord( nCntrl | nSum );
                }
                pOutl = pDocument->GetInternalOutliner( false );
                if( pOutl )
                {
                    nCntrl = pOutl->GetControlWord() &~ EEControlBits::ULSPACESUMMATION;
                    pOutl->SetControlWord( nCntrl | nSum );
                }

                // Set printer independent layout mode.
                if( pDoc->GetPrinterIndependentLayout() != pMiscItem->GetOptionsMisc().GetPrinterIndependentLayout() )
                    pDoc->SetPrinterIndependentLayout (pMiscItem->GetOptionsMisc().GetPrinterIndependentLayout());
            }
        }

        pOptions->StoreConfig();

        // Only if also the document type matches...
        if( pDocSh && pDoc && eDocType == pDoc->GetDocumentType() )
        {
            FieldUnit eUIUnit = static_cast<FieldUnit>(pOptions->GetMetric());
            pDoc->SetUIUnit(eUIUnit);

            if (pViewShell)
            {
                // make sure no one is in text edit mode, cause there
                // are some pointers remembered else (!)
                if(pViewShell->GetView())
                    pViewShell->GetView()->SdrEndTextEdit();

                ::sd::FrameView* pFrame = pViewShell->GetFrameView();
                pFrame->Update(pOptions);
                pViewShell->ReadFrameViewData(pFrame);
                pViewShell->SetUIUnit(eUIUnit);
                pViewShell->SetDefTabHRuler( nDefTab );
            }
        }

        if( pViewShell && pViewShell->GetViewFrame() )
            pViewShell->GetViewFrame()->GetBindings().InvalidateAll( true );
    }

    VclPtr<SfxTabPage> SdModule::CreateTabPage( sal_uInt16 nId, TabPageParent pParent, const SfxItemSet& rSet )
    {
        VclPtr<SfxTabPage> pRet;
        SfxAllItemSet aSet(*(rSet.GetPool()));
        SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();

        switch(nId)
        {
            case SID_SD_TP_CONTENTS:
            case SID_SI_TP_CONTENTS:
            {
                ::CreateTabPage fnCreatePage = pFact->GetSdOptionsContentsTabPageCreatorFunc();
                if( fnCreatePage )
                    pRet = (*fnCreatePage)( pParent, &rSet );
            }
            break;
            case SID_SD_TP_SNAP:
            case SID_SI_TP_SNAP:
            {
                ::CreateTabPage fnCreatePage = pFact->GetSdOptionsSnapTabPageCreatorFunc();
                if( fnCreatePage )
                    pRet = (*fnCreatePage)( pParent, &rSet );
            }
            break;
            case SID_SD_TP_PRINT:
            case SID_SI_TP_PRINT:
            {
                ::CreateTabPage fnCreatePage = pFact->GetSdPrintOptionsTabPageCreatorFunc();
                if( fnCreatePage )
                {
                    pRet = (*fnCreatePage)( pParent, &rSet );
                    if(SID_SD_TP_PRINT == nId)
                        aSet.Put (SfxUInt32Item(SID_SDMODE_FLAG,SD_DRAW_MODE));
                    pRet->PageCreated(aSet);
                }
            }
            break;
            case SID_SI_TP_MISC:
            case SID_SD_TP_MISC:
            {
                ::CreateTabPage fnCreatePage = pFact->GetSdOptionsMiscTabPageCreatorFunc();
                if( fnCreatePage )
                {
                    pRet = (*fnCreatePage)( pParent, &rSet );
                    if(SID_SD_TP_MISC == nId)
                        aSet.Put (SfxUInt32Item(SID_SDMODE_FLAG,SD_DRAW_MODE));
                    else
                        aSet.Put (SfxUInt32Item(SID_SDMODE_FLAG,SD_IMPRESS_MODE));
                    pRet->PageCreated(aSet);
                }
            }
            break;
            case RID_SVXPAGE_TEXTANIMATION :
            {
                SfxAbstractDialogFactory* pSfxFact = SfxAbstractDialogFactory::Create();
                ::CreateTabPage fnCreatePage = pSfxFact->GetTabPageCreatorFunc( nId );
                if ( fnCreatePage )
                    pRet = (*fnCreatePage)( pParent, &rSet );
            }
            break;
        }
        DBG_ASSERT( pRet, "SdModule::CreateTabPage(): no valid ID for TabPage!" );

        return pRet;
    }

    std::unique_ptr<SfxStyleFamilies> SdModule::CreateStyleFamilies()
    {
        std::unique_ptr<SfxStyleFamilies> pStyleFamilies(new SfxStyleFamilies);

        pStyleFamilies->emplace_back(SfxStyleFamilyItem(SfxStyleFamily::Para,
                                                        SdResId(STR_GRAPHICS_STYLE_FAMILY),
                                                        Image(BitmapEx(BMP_STYLES_FAMILY_GRAPHICS)),
                                                        RID_GRAPHICSTYLEFAMILY, SD_MOD()->GetResLocale()));

        pStyleFamilies->emplace_back(SfxStyleFamilyItem(SfxStyleFamily::Pseudo,
                                                        SdResId(STR_PRESENTATIONS_STYLE_FAMILY),
                                                        Image(BitmapEx(BMP_STYLES_FAMILY_PRESENTATIONS)),
                                                        RID_PRESENTATIONSTYLEFAMILY, SD_MOD()->GetResLocale()));

        return pStyleFamilies;
    }

    /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

↑ V560 A part of conditional expression is always true: pPage.

↑ V1016 The value '0xffff' is out of range of enum values. This causes unspecified or undefined behavior.

↑ V1016 The value '0xffff' is out of range of enum values. This causes unspecified or undefined behavior.

↑ V547 Expression 'nMetric == FieldUnit(0xffff)' is always false.