<commit_before>/* -*- 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 <unotools/pathoptions.hxx>
#include <vcl/builder.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/settings.hxx>
#include <tools/urlobj.hxx>
#include <sfx2/dialoghelper.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/docfile.hxx>
#include <svl/cntwall.hxx>
#include <sfx2/cntids.hrc>
#include <svx/dialogs.hrc>

#include <cuires.hrc>
#include <svx/dialmgr.hxx>
#include <editeng/memberids.hrc>
#include <editeng/editrids.hrc>
#include <editeng/eerdll.hxx>

// table background
#define TBL_DEST_CELL   0
#define TBL_DEST_ROW    1
#define TBL_DEST_TBL    2

#include <editeng/brushitem.hxx>
#include "backgrnd.hxx"

#include <svx/xtable.hxx>
#include <sfx2/opengrf.hxx>
#include <svx/svxerr.hxx>
#include <svx/drawitem.hxx>
#include <dialmgr.hxx>
#include <sfx2/htmlmode.hxx>
#include <svtools/controldims.hrc>
#include <svx/flagsdef.hxx>
#include <svx/xfillit0.hxx>
#include <svx/xflgrit.hxx>
#include <svl/intitem.hxx>
#include <sfx2/request.hxx>
#include <svtools/grfmgr.hxx>

using namespace ::com::sun::star;
// static ----------------------------------------------------------------

static sal_uInt16 pRanges[] =
{
    SID_VIEW_FLD_PIC, SID_VIEW_FLD_PIC,
    SID_ATTR_BRUSH, SID_ATTR_BRUSH,
    SID_ATTR_BRUSH_CHAR, SID_ATTR_BRUSH_CHAR,
    0
};

struct SvxBackgroundTable_Impl
{
    SvxBrushItem*   pCellBrush;
    SvxBrushItem*   pRowBrush;
    SvxBrushItem*   pTableBrush;
    sal_uInt16      nCellWhich;
    sal_uInt16      nRowWhich;
    sal_uInt16      nTableWhich;
    sal_Int32       nActPos;

    SvxBackgroundTable_Impl()
        : pCellBrush(NULL)
        , pRowBrush(NULL)
        , pTableBrush(NULL)
        , nCellWhich(0)
        , nRowWhich(0)
        , nTableWhich(0)
        , nActPos(0)
    {}
};

struct SvxBackgroundPara_Impl
{
    SvxBrushItem*   pParaBrush;
    SvxBrushItem*   pCharBrush;

    sal_Int32           nActPos;

    SvxBackgroundPara_Impl()
        : pParaBrush(NULL)
        , pCharBrush(NULL)
        , nActPos(LISTBOX_ENTRY_NOTFOUND)
    {}

};

struct SvxBackgroundPage_Impl
{
    Timer*          pLoadTimer;
    sal_Bool        bIsImportDlgInExecute;

    SvxBackgroundPage_Impl()
        : pLoadTimer(NULL)
        , bIsImportDlgInExecute(sal_False)
    {}
};

static inline sal_uInt8 lcl_PercentToTransparency(long nPercent)
{
    //0xff must not be returned!
    return sal_uInt8(nPercent ? (50 + 0xfe * nPercent) / 100 : 0);
}
static inline sal_uInt8 lcl_TransparencyToPercent(sal_uInt8 nTrans)
{
    return (nTrans * 100 + 127) / 254;
}
static void lcl_SetTransparency(SvxBrushItem& rBrush, long nTransparency)
{
    uno::Any aTransparency;
    aTransparency <<= (sal_Int8)nTransparency;
    rBrush.PutValue(aTransparency, MID_GRAPHIC_TRANSPARENCY);
}

/// Returns the fill style of the currently selected entry.
static XFillStyle lcl_getFillStyle(ListBox* pLbSelect)
{
    return (XFillStyle)(sal_uLong)pLbSelect->GetEntryData(pLbSelect->GetSelectEntryPos());
}

// Selects the entry matching the specified fill style.
static void lcl_setFillStyle(ListBox* pLbSelect, XFillStyle eStyle)
{
    for (int i = 0; i < pLbSelect->GetEntryCount(); ++i)
        if ((XFillStyle)(sal_uLong)pLbSelect->GetEntryData(i) == eStyle)
        {
            pLbSelect->SelectEntryPos(i);
            return;
        }
}


sal_uInt16 GetItemId_Impl( ValueSet& rValueSet, const Color& rCol )
{
    sal_Bool    bFound = sal_False;
    sal_uInt16  nCount = rValueSet.GetItemCount();
    sal_uInt16  n      = 1;

    while ( !bFound && n <= nCount )
    {
        Color aValCol = rValueSet.GetItemColor(n);

        bFound = (   aValCol.GetRed()   == rCol.GetRed()
                  && aValCol.GetGreen() == rCol.GetGreen()
                  && aValCol.GetBlue()  == rCol.GetBlue() );

        if ( !bFound )
            n++;
    }
    return bFound ? n : 0;
}

// class BackgroundPreview -----------------------------------------------

/*  [Description]

    preview window for brush or bitmap
*/

class BackgroundPreviewImpl : public Window
{
public:
    BackgroundPreviewImpl(Window* pParent);
    void setBmp(bool bBmp);
    ~BackgroundPreviewImpl();

    void            NotifyChange( const Color&  rColor );
    void            NotifyChange( const Bitmap* pBitmap );

protected:
    virtual void    Paint( const Rectangle& rRect );
    virtual void    DataChanged( const DataChangedEvent& rDCEvt );
    virtual void    Resize();

private:

    void recalcDrawPos();

    bool            bIsBmp;
    Bitmap*         pBitmap;
    Point           aDrawPos;
    Size            aDrawSize;
    Rectangle       aDrawRect;
    sal_uInt8            nTransparency;
};

BackgroundPreviewImpl::BackgroundPreviewImpl(Window* pParent)
    : Window(pParent, WB_BORDER)
    , bIsBmp(false)
    , pBitmap(NULL)
    , aDrawRect(Point(0,0), GetOutputSizePixel())
    , nTransparency(0)
{
    SetBorderStyle(WINDOW_BORDER_MONO);
    Paint(aDrawRect);
}

extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeBackgroundPreview(Window *pParent, VclBuilder::stringmap &)
{
    return new BackgroundPreviewImpl(pParent);
}

void BackgroundPreviewImpl::setBmp(bool bBmp)
{
    bIsBmp = bBmp;
    Invalidate();
}



BackgroundPreviewImpl::~BackgroundPreviewImpl()
{
    delete pBitmap;
}


void BackgroundPreviewImpl::NotifyChange( const Color& rColor )
{
    if ( !bIsBmp )
    {
        const static Color aTranspCol( COL_TRANSPARENT );

        nTransparency = lcl_TransparencyToPercent( rColor.GetTransparency() );

        SetFillColor( rColor == aTranspCol ? GetSettings().GetStyleSettings().GetFieldColor() : (Color) rColor.GetRGBColor() );
        Paint( aDrawRect );
    }
}



void BackgroundPreviewImpl::NotifyChange( const Bitmap* pNewBitmap )
{
    if ( bIsBmp && (pNewBitmap || pBitmap) )
    {
        if ( pNewBitmap && pBitmap )
            *pBitmap = *pNewBitmap;
        else if ( pNewBitmap && !pBitmap )
            pBitmap = new Bitmap( *pNewBitmap );
        else if ( !pNewBitmap )
            DELETEZ( pBitmap );

        recalcDrawPos();

        Invalidate( aDrawRect );
        Update();
    }
}

void BackgroundPreviewImpl::recalcDrawPos()
{
    if ( pBitmap )
    {
        Size aSize = GetOutputSizePixel();
        // InnerSize == Size without one pixel border
        Size aInnerSize = aSize;
        aInnerSize.Width() -= 2;
        aInnerSize.Height() -= 2;
        aDrawSize = pBitmap->GetSizePixel();

        // bitmap bigger than preview window?
        if ( aDrawSize.Width() > aInnerSize.Width() )
        {
            aDrawSize.Height() = aDrawSize.Height() * aInnerSize.Width() / aDrawSize.Width();
            if ( aDrawSize.Height() > aInnerSize.Height() )
            {
                aDrawSize.Width() = aDrawSize.Height();
                aDrawSize.Height() = aInnerSize.Height();
            }
            else
                aDrawSize.Width() = aInnerSize.Width();
        }
        else if ( aDrawSize.Height() > aInnerSize.Height() )
        {
            aDrawSize.Width() = aDrawSize.Width() * aInnerSize.Height() / aDrawSize.Height();
            if ( aDrawSize.Width() > aInnerSize.Width() )
            {
                aDrawSize.Height() = aDrawSize.Width();
                aDrawSize.Width() = aInnerSize.Width();
            }
            else
                aDrawSize.Height() = aInnerSize.Height();
        }

        aDrawPos.X() = (aSize.Width()  - aDrawSize.Width())  / 2;
        aDrawPos.Y() = (aSize.Height() - aDrawSize.Height()) / 2;
    }
}

void BackgroundPreviewImpl::Resize()
{
    Window::Resize();
    aDrawRect = Rectangle(Point(0,0), GetOutputSizePixel());
    recalcDrawPos();
}



void BackgroundPreviewImpl::Paint( const Rectangle& )
{
    const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
    SetBackground(Wallpaper(rStyleSettings.GetWindowColor()));
    SetLineColor();
    if(bIsBmp)
        SetFillColor( Color(COL_TRANSPARENT) );
    DrawRect( aDrawRect );
    if ( bIsBmp )
    {
        if ( pBitmap )
            DrawBitmap( aDrawPos, aDrawSize, *pBitmap );
        else
        {
            Size aSize = GetOutputSizePixel();
            DrawLine( Point(0,0),               Point(aSize.Width(),aSize.Height()) );
            DrawLine( Point(0,aSize.Height()),  Point(aSize.Width(),0) );
        }
    }
}

void BackgroundPreviewImpl::DataChanged( const DataChangedEvent& rDCEvt )
{
    if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
         (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    {
        Invalidate();
    }
    Window::DataChanged( rDCEvt );
}

// class SvxBackgroundTabPage --------------------------------------------

#define HDL(hdl) LINK(this,SvxBackgroundTabPage,hdl)

SvxBackgroundTabPage::SvxBackgroundTabPage(Window* pParent, const SfxItemSet& rCoreSet)
    : SvxTabPage(pParent, "BackgroundPage", "cui/ui/backgroundpage.ui", rCoreSet)
    , m_pXPool(rCoreSet.GetPool())
    , m_aXFillAttr(m_pXPool)
    , m_rXFillSet(m_aXFillAttr.GetItemSet())
    , nHtmlMode(0)
    , bAllowShowSelector(true)
    , bIsGraphicValid(false)
    , bLinkOnly(false)
    , bColTransparency(false)
    , bGraphTransparency(false)
    , pPageImpl(new SvxBackgroundPage_Impl)
    , pImportDlg(NULL)
    , pTableBck_Impl(NULL)
    , pParaBck_Impl(NULL)
{
    get(m_pAsGrid, "asgrid");
    get(m_pSelectTxt, "asft");
    get(m_pLbSelect, "selectlb");
    get(m_pTblDesc, "forft");
    get(m_pTblLBox, "tablelb");
    get(m_pParaLBox, "paralb");

    get(m_pBackGroundColorFrame, "backgroundcolorframe");
    get(m_pBackgroundColorSet, "backgroundcolorset");
    get(m_pPreviewWin1, "preview1");

    get(m_pColTransFT, "transparencyft");
    get(m_pColTransMF, "transparencymf");
    get(m_pBtnPreview, "showpreview");

    // Initialize gradient controls
    get(m_pBackGroundGradientFrame, "backgroundgradientframe");
    get(m_pLbGradients, "gradientslb");
    Size aSize = getDrawListBoxOptimalSize(this);
    m_pLbGradients->set_width_request(aSize.Width());
    m_pLbGradients->set_height_request(aSize.Height());
    get(m_pCtlPreview, "previewctl");
    aSize = getDrawPreviewOptimalSize(this);
    m_pCtlPreview->set_width_request(aSize.Width());
    m_pCtlPreview->set_height_request(aSize.Height());

    get(m_pBitmapContainer, "graphicgrid");
    get(m_pFileFrame, "fileframe");
    get(m_pBtnBrowse, "browse");
    get(m_pBtnLink, "link");
    get(m_pFtUnlinked, "unlinkedft");
    get(m_pFtFile, "fileft");

    get(m_pTypeFrame, "typeframe");
    get(m_pBtnPosition, "positionrb");
    get(m_pBtnArea, "arearb");
    get(m_pBtnTile, "tilerb");
    get(m_pWndPosition, "windowpos");

    get(m_pGraphTransFrame, "graphtransframe");
    get(m_pGraphTransMF, "graphtransmf");

    get(m_pPreviewWin2, "preview2");
    m_pPreviewWin2->setBmp(true);

    // this page needs ExchangeSupport
    SetExchangeSupport();

    const SfxPoolItem* pItem;
    SfxObjectShell* pShell;

    if ( SFX_ITEM_SET == rCoreSet.GetItemState( SID_HTML_MODE, false, &pItem )
         || ( 0 != ( pShell = SfxObjectShell::Current()) &&
              0 != ( pItem = pShell->GetItem( SID_HTML_MODE ) ) ) )
    {
        nHtmlMode = ((SfxUInt16Item*)pItem)->GetValue();
    }

    FillColorValueSets_Impl();

    m_pBackgroundColorSet->SetSelectHdl( HDL(BackgroundColorHdl_Impl) );
    m_pBackgroundColorSet->SetStyle(m_pBackgroundColorSet->GetStyle() | WB_ITEMBORDER | WB_NAMEFIELD | WB_NONEFIELD);
    m_pBackgroundColorSet->SetText(SVX_RESSTR(RID_SVXSTR_TRANSPARENT));
}



SvxBackgroundTabPage::~SvxBackgroundTabPage()
{
    delete pPageImpl->pLoadTimer;
    delete pPageImpl;
    delete pImportDlg;

    if( pTableBck_Impl)
    {
        delete pTableBck_Impl->pCellBrush;
        delete pTableBck_Impl->pRowBrush;
        delete pTableBck_Impl->pTableBrush;
        delete pTableBck_Impl;
    }

    if(pParaBck_Impl)
    {
        delete pParaBck_Impl->pParaBrush;
        delete pParaBck_Impl->pCharBrush;
        delete pParaBck_Impl;
    }
}



sal_uInt16* SvxBackgroundTabPage::GetRanges()

/*  [Description]

    returns the area of the which-values
*/

{
    return pRanges;
}



SfxTabPage* SvxBackgroundTabPage::Create( Window* pParent,
                                          const SfxItemSet& rAttrSet )

/*  [Description]

    create method for the TabDialog
*/

{
    return ( new SvxBackgroundTabPage( pParent, rAttrSet ) );
}



void SvxBackgroundTabPage::Reset( const SfxItemSet& rSet )
{
// os: Such a nonsense! One will always find such an item somewhere,
//     but it must be existing in the rSet!
//  const SfxPoolItem* pX = GetOldItem( rSet, SID_VIEW_FLD_PIC );
//  if( pX && pX->ISA(SfxWallpaperItem))
    if(SFX_ITEM_AVAILABLE <= rSet.GetItemState(GetWhich(SID_VIEW_FLD_PIC), false))
    {
        ResetFromWallpaperItem( rSet );
        return;
    }

    // condition of the preview button is persistent due to UserData
    OUString aUserData = GetUserData();
    m_pBtnPreview->Check( !aUserData.isEmpty() && '1' == aUserData[0] );

    // don't be allowed to call ShowSelector() after reset anymore
    bAllowShowSelector = sal_False;


    // get and evaluate Input-BrushItem
    const SvxBrushItem* pBgdAttr = NULL;
    sal_uInt16 nSlot = SID_ATTR_BRUSH;
    const SfxPoolItem* pItem;
    sal_uInt16 nDestValue = USHRT_MAX;

    if ( SFX_ITEM_SET == rSet.GetItemState( SID_BACKGRND_DESTINATION,
                                            false, &pItem ) )
    {
        nDestValue = ((const SfxUInt16Item*)pItem)->GetValue();
        m_pTblLBox->SelectEntryPos(nDestValue);

        switch ( nDestValue )
        {
            case TBL_DEST_CELL:
                nSlot = SID_ATTR_BRUSH;
            break;
            case TBL_DEST_ROW:
                nSlot = SID_ATTR_BRUSH_ROW;
            break;
            case TBL_DEST_TBL:
                nSlot = SID_ATTR_BRUSH_TABLE;
            break;
        }
    }
    else if( SFX_ITEM_SET == rSet.GetItemState(
                SID_PARA_BACKGRND_DESTINATION, false, &pItem ) )
    {
        nDestValue = ((const SfxUInt16Item*)pItem)->GetValue();
        // character activated?
        sal_Int32 nParaSel  = m_pParaLBox->GetSelectEntryPos();
        if(1 == nParaSel)
        {
            // then it was a "standard"-call
            nDestValue = nParaSel;
        }
        m_pParaLBox->SelectEntryPos(nDestValue);

        switch ( nDestValue )
        {
            case PARA_DEST_PARA:
                nSlot = SID_ATTR_BRUSH;
            break;
            case PARA_DEST_CHAR:
                nSlot = SID_ATTR_BRUSH_CHAR;
            break;
        }
    }
    //#111173# the destination item is missing when the parent style has been changed
    if(USHRT_MAX == nDestValue && (m_pParaLBox->IsVisible()||m_pTblLBox->IsVisible()))
        nDestValue = 0;
    sal_uInt16 nWhich = GetWhich( nSlot );

    if ( rSet.GetItemState( nWhich, false ) >= SFX_ITEM_AVAILABLE )
        pBgdAttr = (const SvxBrushItem*)&( rSet.Get( nWhich ) );

    m_pBtnTile->Check();

    if ( pBgdAttr )
    {
        FillControls_Impl(*pBgdAttr, aUserData);
        aBgdColor = ( (SvxBrushItem*)pBgdAttr )->GetColor();
    }
    else
    {
        m_pSelectTxt->Hide();
        m_pLbSelect->Hide();
        lcl_setFillStyle(m_pLbSelect, XFILL_SOLID);
        ShowColorUI_Impl();

        const SfxPoolItem* pOld = GetOldItem( rSet, SID_ATTR_BRUSH );

        if ( pOld )
            aBgdColor = ( (SvxBrushItem*)pOld )->GetColor();
    }

    if ( nDestValue != USHRT_MAX )
    {
        if(m_pTblLBox->IsVisible())
        {
            sal_Int32 nValue = m_pTblLBox->GetSelectEntryPos();

            if ( pTableBck_Impl )
            {
                DELETEZ( pTableBck_Impl->pCellBrush);
                DELETEZ( pTableBck_Impl->pRowBrush);
                DELETEZ( pTableBck_Impl->pTableBrush);
            }
            else
                pTableBck_Impl = new SvxBackgroundTable_Impl();

            pTableBck_Impl->nActPos = nValue;

            nWhich = GetWhich( SID_ATTR_BRUSH );
            if ( rSet.GetItemState( nWhich, false ) >= SFX_ITEM_AVAILABLE )
            {
                pBgdAttr = (const SvxBrushItem*)&( rSet.Get( nWhich ) );
                pTableBck_Impl->pCellBrush = new SvxBrushItem(*pBgdAttr);
            }
            pTableBck_Impl->nCellWhich = nWhich;

            if ( rSet.GetItemState( SID_ATTR_BRUSH_ROW, false ) >= SFX_ITEM_AVAILABLE )
            {
                pBgdAttr = (const SvxBrushItem*)&( rSet.Get( SID_ATTR_BRUSH_ROW ) );
                pTableBck_Impl->pRowBrush = new SvxBrushItem(*pBgdAttr);
            }
            pTableBck_Impl->nRowWhich = SID_ATTR_BRUSH_ROW;

            if ( rSet.GetItemState( SID_ATTR_BRUSH_TABLE, false ) >= SFX_ITEM_AVAILABLE )
            {
                pBgdAttr = (const SvxBrushItem*)&( rSet.Get( SID_ATTR_BRUSH_TABLE ) );
                pTableBck_Impl->pTableBrush = new SvxBrushItem(*pBgdAttr);
            }
            pTableBck_Impl->nTableWhich = SID_ATTR_BRUSH_TABLE;

            TblDestinationHdl_Impl(m_pTblLBox);
            m_pTblLBox->SaveValue();
        }
        else
        {
            sal_Int32 nValue = m_pParaLBox->GetSelectEntryPos();

            if ( pParaBck_Impl )
            {
                delete pParaBck_Impl->pParaBrush;
                delete pParaBck_Impl->pCharBrush;
            }
            else
                pParaBck_Impl = new SvxBackgroundPara_Impl();

            pParaBck_Impl->nActPos = nValue;

            nWhich = GetWhich( SID_ATTR_BRUSH );
            if ( rSet.GetItemState( nWhich, false ) >= SFX_ITEM_AVAILABLE )
            {
                pBgdAttr = (const SvxBrushItem*)&( rSet.Get( nWhich ) );
                pParaBck_Impl->pParaBrush = new SvxBrushItem(*pBgdAttr);
            }

            nWhich = GetWhich( SID_ATTR_BRUSH_CHAR );
            rSet.GetItemState( nWhich, true );
            rSet.GetItemState( nWhich, false );
            if ( rSet.GetItemState( nWhich, true ) > SFX_ITEM_AVAILABLE )
            {
                pBgdAttr = (const SvxBrushItem*)&( rSet.Get( nWhich ) );
                pParaBck_Impl->pCharBrush = new SvxBrushItem(*pBgdAttr);
            }
            else
                pParaBck_Impl->pCharBrush = new SvxBrushItem(SID_ATTR_BRUSH_CHAR);

            ParaDestinationHdl_Impl(m_pParaLBox);
            m_pParaLBox->SaveValue();
        }
    }
}

void SvxBackgroundTabPage::ResetFromWallpaperItem( const SfxItemSet& rSet )
{
    ShowSelector();

    // condition of the preview button is persistent due to UserData
    OUString aUserData = GetUserData();
    m_pBtnPreview->Check( !aUserData.isEmpty() && '1' == aUserData[0] );

    // get and evaluate Input-BrushItem
    const SvxBrushItem* pBgdAttr = NULL;
    sal_uInt16 nSlot = SID_VIEW_FLD_PIC;
    sal_uInt16 nWhich = GetWhich( nSlot );
    SvxBrushItem* pTemp = 0;

    if ( rSet.GetItemState( nWhich, false ) >= SFX_ITEM_AVAILABLE )
    {
        const CntWallpaperItem* pItem = (const CntWallpaperItem*)&rSet.Get( nWhich );
        pTemp = new SvxBrushItem( *pItem, nWhich );
        pBgdAttr = pTemp;
    }

    m_pBtnTile->Check();

    if ( pBgdAttr )
    {
        FillControls_Impl(*pBgdAttr, aUserData);
        // brush shall be kept when showing the graphic, too
        if( aBgdColor != pBgdAttr->GetColor() )
        {
            aBgdColor = pBgdAttr->GetColor();
            sal_uInt16 nCol = GetItemId_Impl(*m_pBackgroundColorSet, aBgdColor);
            m_pBackgroundColorSet->SelectItem( nCol );
            m_pPreviewWin1->NotifyChange( aBgdColor );
        }
    }
    else
    {
        lcl_setFillStyle(m_pLbSelect, XFILL_SOLID);
        ShowColorUI_Impl();

        const SfxPoolItem* pOld = GetOldItem( rSet, SID_VIEW_FLD_PIC );
        if ( pOld )
            aBgdColor = Color( ((CntWallpaperItem*)pOld)->GetColor() );
    }

    // We now have always a link to the background
    bLinkOnly = sal_True;
    m_pBtnLink->Check( true );
    m_pBtnLink->Show( false );

    delete pTemp;
}





void SvxBackgroundTabPage::FillUserData()

/*  [Description]

    When destroying a SfxTabPage this virtual method is called,
    so that the TabPage can save internal information.

    In this case the condition of the preview button is saved.
*/

{
    SetUserData( m_pBtnPreview->IsChecked() ? OUString('1') : OUString('0') );
}



sal_Bool SvxBackgroundTabPage::FillItemSet( SfxItemSet& rCoreSet )
{
    if ( pPageImpl->pLoadTimer && pPageImpl->pLoadTimer->IsActive() )
    {
        pPageImpl->pLoadTimer->Stop();
        LoadTimerHdl_Impl( pPageImpl->pLoadTimer );
    }
// os: Such a nonsense! One will always find such an item somewhere,
//     but it must be existing in the rSet!

//  const SfxPoolItem* pX = GetOldItem( rCoreSet, SID_VIEW_FLD_PIC );
//  if( pX && pX->ISA(SfxWallpaperItem))
    if(SFX_ITEM_AVAILABLE <= rCoreSet.GetItemState(GetWhich(SID_VIEW_FLD_PIC), false))
        return FillItemSetWithWallpaperItem( rCoreSet, SID_VIEW_FLD_PIC );

    sal_Bool bModified = sal_False;
    sal_uInt16 nSlot = SID_ATTR_BRUSH;

    if ( m_pTblLBox->IsVisible() )
    {
        switch( m_pTblLBox->GetSelectEntryPos() )
        {
            case TBL_DEST_CELL:
                nSlot = SID_ATTR_BRUSH;
            break;
            case TBL_DEST_ROW:
                nSlot = SID_ATTR_BRUSH_ROW;
            break;
            case TBL_DEST_TBL:
                nSlot = SID_ATTR_BRUSH_TABLE;
            break;
        }
    }
    else if (m_pParaLBox->GetData() == m_pParaLBox)
    {
        switch(m_pParaLBox->GetSelectEntryPos())
        {
            case PARA_DEST_PARA:
                nSlot = SID_ATTR_BRUSH;
            break;
            case PARA_DEST_CHAR:
                nSlot = SID_ATTR_BRUSH_CHAR;
            break;
        }
    }
    sal_uInt16 nWhich = GetWhich( nSlot );

    const SfxPoolItem* pOld = GetOldItem( rCoreSet, nSlot );
    SfxItemState eOldItemState = rCoreSet.GetItemState(nSlot, false);
    const SfxItemSet& rOldSet = GetItemSet();

    sal_Bool bGraphTransparencyChanged = bGraphTransparency && (m_pGraphTransMF->GetText() != m_pGraphTransMF->GetSavedValue());
    if ( pOld )
    {
        const SvxBrushItem& rOldItem    = (const SvxBrushItem&)*pOld;
        SvxGraphicPosition  eOldPos     = rOldItem.GetGraphicPos();
        const sal_Bool          bIsBrush    = ( XFILL_SOLID == lcl_getFillStyle(m_pLbSelect) );
        const bool bIsGradient = ( XFILL_GRADIENT == lcl_getFillStyle(m_pLbSelect) );

        // transparency has to be set if enabled, the color not already set to "No fill" and
        if( bColTransparency &&
            aBgdColor.GetTransparency() < 0xff)
        {
            aBgdColor.SetTransparency(lcl_PercentToTransparency(static_cast<long>(m_pColTransMF->GetValue())));
        }
        if (   ( (GPOS_NONE == eOldPos) && (bIsBrush || bIsGradient)  )
            || ( (GPOS_NONE != eOldPos) && !(bIsBrush || bIsGradient) ) ) // Brush <-> Bitmap changed?
        {
            // background art hasn't been changed:

            if ( (GPOS_NONE == eOldPos) || !m_pLbSelect->IsVisible() )
            {
                if (bIsBrush)
                {
                    // Brush-treatment:
                    if ( rOldItem.GetColor() != aBgdColor ||
                            (SFX_ITEM_AVAILABLE >= eOldItemState && !m_pBackgroundColorSet->IsNoSelection()))
                    {
                        bModified = sal_True;
                        rCoreSet.Put( SvxBrushItem( aBgdColor, nWhich ) );
                    }
                    else if ( SFX_ITEM_DEFAULT == rOldSet.GetItemState( nWhich, false ) )
                        rCoreSet.ClearItem( nWhich );
                    // Handle XFILL_GRADIENT -> XFILL_SOLID
                    XFillStyleItem aFillStyleItem(XFILL_SOLID, GetWhich(SID_SW_ATTR_FILL_STYLE));
                    rCoreSet.Put(aFillStyleItem);
                }
                else
                {
                    XFillStyleItem aFillStyleItem(((const XFillStyleItem&)m_rXFillSet.Get(XATTR_FILLSTYLE)).GetValue(), GetWhich(SID_SW_ATTR_FILL_STYLE));
                    rCoreSet.Put(aFillStyleItem);

                    const XFillGradientItem& rFillGradientItem = (const XFillGradientItem&)m_rXFillSet.Get(XATTR_FILLGRADIENT);
                    XFillGradientItem aFillGradientItem(rFillGradientItem.GetName(), rFillGradientItem.GetGradientValue(), GetWhich(SID_SW_ATTR_FILL_GRADIENT));
                    rCoreSet.Put(aFillGradientItem);
                }
            }
            else
            {
                // Bitmap-treatment:

                SvxGraphicPosition  eNewPos  = GetGraphicPosition_Impl();
                const sal_Bool          bIsLink  = m_pBtnLink->IsChecked();
                const sal_Bool          bWasLink = (NULL != rOldItem.GetGraphicLink() );


                if ( !bIsLink && !bIsGraphicValid )
                    bIsGraphicValid = LoadLinkedGraphic_Impl();

                if (   bGraphTransparencyChanged ||
                       eNewPos != eOldPos
                    || bIsLink != bWasLink
                    || ( bWasLink  && rOldItem.GetGraphicLink()
                                       != aBgdGraphicPath )
                    || ( !bWasLink && rOldItem.GetGraphic()->GetBitmap()
                                       != aBgdGraphic.GetBitmap() )
                   )
                {
                    bModified = sal_True;

                    SvxBrushItem aTmpBrush(nWhich);
                    if ( bIsLink )
                    {
                        aTmpBrush = SvxBrushItem( aBgdGraphicPath,
                                                aBgdGraphicFilter,
                                                eNewPos,
                                                nWhich );
                    }
                    else
                        aTmpBrush = SvxBrushItem( aBgdGraphic,
                                        eNewPos,
                                        nWhich );
                    lcl_SetTransparency(aTmpBrush, static_cast<long>(m_pGraphTransMF->GetValue()));

                    rCoreSet.Put(aTmpBrush);
                }
                else if ( SFX_ITEM_DEFAULT == rOldSet.GetItemState( nWhich, false ) )
                    rCoreSet.ClearItem( nWhich );
            }
        }
        else // Brush <-> Bitmap changed!
        {
            if (bIsBrush || bIsGradient)
            {
                rCoreSet.Put( SvxBrushItem( aBgdColor, nWhich ) );
                if (bIsGradient)
                {
                    // Handle XFILL_BITMAP -> XFILL_GRADIENT
                    XFillStyleItem aFillStyleItem(((const XFillStyleItem&)m_rXFillSet.Get(XATTR_FILLSTYLE)).GetValue(), GetWhich(SID_SW_ATTR_FILL_STYLE));
                    rCoreSet.Put(aFillStyleItem);

                    const XFillGradientItem& rFillGradientItem = (const XFillGradientItem&)m_rXFillSet.Get(XATTR_FILLGRADIENT);
                    XFillGradientItem aFillGradientItem(rFillGradientItem.GetName(), rFillGradientItem.GetGradientValue(), GetWhich(SID_SW_ATTR_FILL_GRADIENT));
                    rCoreSet.Put(aFillGradientItem);
                }
            }
            else
            {
                SvxBrushItem* pTmpBrush = 0;
                if ( m_pBtnLink->IsChecked() )
                {
                    pTmpBrush = new SvxBrushItem( aBgdGraphicPath,
                                                aBgdGraphicFilter,
                                                GetGraphicPosition_Impl(),
                                                nWhich );
                }
                else
                {
                    if ( !bIsGraphicValid )
                        bIsGraphicValid = LoadLinkedGraphic_Impl();

                    if ( bIsGraphicValid )
                        pTmpBrush = new SvxBrushItem( aBgdGraphic,
                                                    GetGraphicPosition_Impl(),
                                                    nWhich );
                }
                if(pTmpBrush)
                {
                    lcl_SetTransparency(*pTmpBrush, static_cast<long>(m_pGraphTransMF->GetValue()));
                    rCoreSet.Put(*pTmpBrush);
                    delete pTmpBrush;
                }
            }
            bModified = ( bIsBrush || bIsGradient || m_pBtnLink->IsChecked() || bIsGraphicValid );
        }
    }
    else if ( SID_ATTR_BRUSH_CHAR == nSlot && aBgdColor != Color( COL_WHITE ) )
    {
        rCoreSet.Put( SvxBrushItem( aBgdColor, nWhich ) );
        bModified = sal_True;
    }

    if( m_pTblLBox->IsVisible() )
    {
        // the current condition has already been put
        if( nSlot != SID_ATTR_BRUSH && pTableBck_Impl->pCellBrush)
        {
            const SfxPoolItem* pOldCell =
                GetOldItem( rCoreSet, SID_ATTR_BRUSH );

            if ( *pTableBck_Impl->pCellBrush != *pOldCell )
            {
                rCoreSet.Put( *pTableBck_Impl->pCellBrush );
                bModified |= sal_True;
            }
        }

        if( nSlot != SID_ATTR_BRUSH_ROW && pTableBck_Impl->pRowBrush)
        {
            const SfxPoolItem* pOldRow =
                GetOldItem( rCoreSet, SID_ATTR_BRUSH_ROW );

            if ( *pTableBck_Impl->pRowBrush != *pOldRow )
            {
                rCoreSet.Put( *pTableBck_Impl->pRowBrush );
                bModified |= sal_True;
            }
        }

        if( nSlot != SID_ATTR_BRUSH_TABLE && pTableBck_Impl->pTableBrush)
        {
            const SfxPoolItem* pOldTable =
                GetOldItem( rCoreSet, SID_ATTR_BRUSH_TABLE );

            if ( *pTableBck_Impl->pTableBrush != *pOldTable )
            {
                rCoreSet.Put( *pTableBck_Impl->pTableBrush );
                bModified |= sal_True;
            }
        }

        if( m_pTblLBox->GetSavedValue() != m_pTblLBox->GetSelectEntryPos() )
        {
            rCoreSet.Put( SfxUInt16Item( SID_BACKGRND_DESTINATION,
                                         m_pTblLBox->GetSelectEntryPos() ) );
            bModified |= sal_True;
        }
    }
    else if (m_pParaLBox->GetData() == m_pParaLBox)
    {
        // the current condition has already been put
        if( nSlot != SID_ATTR_BRUSH && m_pParaLBox->IsVisible()) // not in search format dialog
        {
            const SfxPoolItem* pOldPara =
                GetOldItem( rCoreSet, SID_ATTR_BRUSH );

            if ( *pParaBck_Impl->pParaBrush != *pOldPara )
            {
                rCoreSet.Put( *pParaBck_Impl->pParaBrush );
                bModified |= sal_True;
            }
        }

        if( nSlot != SID_ATTR_BRUSH_CHAR )
        {
            const SfxPoolItem* pOldChar =
                GetOldItem( rCoreSet, SID_ATTR_BRUSH_CHAR );
            DBG_ASSERT(pParaBck_Impl, "pParaBck_Impl == NULL ?");
            if ( pOldChar &&
                    //#111173#  crash report shows that pParaBck_Impl can be NULL, the cause is unknown
                    pParaBck_Impl &&
                        (*pParaBck_Impl->pCharBrush != *pOldChar ||
                *pParaBck_Impl->pCharBrush != SvxBrushItem(SID_ATTR_BRUSH_CHAR)))
            {
                rCoreSet.Put( *pParaBck_Impl->pCharBrush );
                bModified |= sal_True;
            }
        }

        if( m_pParaLBox->GetSavedValue() != m_pParaLBox->GetSelectEntryPos() )
        {
            rCoreSet.Put( SfxUInt16Item( SID_BACKGRND_DESTINATION,
                                         m_pParaLBox->GetSelectEntryPos() ) );
            bModified |= sal_True;
        }
    }
    return bModified;
}

sal_Bool SvxBackgroundTabPage::FillItemSetWithWallpaperItem( SfxItemSet& rCoreSet, sal_uInt16 nSlot)
{
    sal_uInt16 nWhich = GetWhich( nSlot );
    const SfxPoolItem* pOld = GetOldItem( rCoreSet, nSlot );
    const SfxItemSet& rOldSet = GetItemSet();
    DBG_ASSERT(pOld,"FillItemSetWithWallpaperItem: Item not found");

    SvxBrushItem        rOldItem( (const CntWallpaperItem&)*pOld, nWhich );<commit_msg>coverity#705461 Dereference null return value<commit_after>/* -*- 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 <unotools/pathoptions.hxx>
#include <vcl/builder.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/settings.hxx>
#include <tools/urlobj.hxx>
#include <sfx2/dialoghelper.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/docfile.hxx>
#include <svl/cntwall.hxx>
#include <sfx2/cntids.hrc>
#include <svx/dialogs.hrc>

#include <cuires.hrc>
#include <svx/dialmgr.hxx>
#include <editeng/memberids.hrc>
#include <editeng/editrids.hrc>
#include <editeng/eerdll.hxx>

// table background
#define TBL_DEST_CELL   0
#define TBL_DEST_ROW    1
#define TBL_DEST_TBL    2

#include <editeng/brushitem.hxx>
#include "backgrnd.hxx"

#include <svx/xtable.hxx>
#include <sfx2/opengrf.hxx>
#include <svx/svxerr.hxx>
#include <svx/drawitem.hxx>
#include <dialmgr.hxx>
#include <sfx2/htmlmode.hxx>
#include <svtools/controldims.hrc>
#include <svx/flagsdef.hxx>
#include <svx/xfillit0.hxx>
#include <svx/xflgrit.hxx>
#include <svl/intitem.hxx>
#include <sfx2/request.hxx>
#include <svtools/grfmgr.hxx>

using namespace ::com::sun::star;
// static ----------------------------------------------------------------

static sal_uInt16 pRanges[] =
{
    SID_VIEW_FLD_PIC, SID_VIEW_FLD_PIC,
    SID_ATTR_BRUSH, SID_ATTR_BRUSH,
    SID_ATTR_BRUSH_CHAR, SID_ATTR_BRUSH_CHAR,
    0
};

struct SvxBackgroundTable_Impl
{
    SvxBrushItem*   pCellBrush;
    SvxBrushItem*   pRowBrush;
    SvxBrushItem*   pTableBrush;
    sal_uInt16      nCellWhich;
    sal_uInt16      nRowWhich;
    sal_uInt16      nTableWhich;
    sal_Int32       nActPos;

    SvxBackgroundTable_Impl()
        : pCellBrush(NULL)
        , pRowBrush(NULL)
        , pTableBrush(NULL)
        , nCellWhich(0)
        , nRowWhich(0)
        , nTableWhich(0)
        , nActPos(0)
    {}
};

struct SvxBackgroundPara_Impl
{
    SvxBrushItem*   pParaBrush;
    SvxBrushItem*   pCharBrush;

    sal_Int32           nActPos;

    SvxBackgroundPara_Impl()
        : pParaBrush(NULL)
        , pCharBrush(NULL)
        , nActPos(LISTBOX_ENTRY_NOTFOUND)
    {}

};

struct SvxBackgroundPage_Impl
{
    Timer*          pLoadTimer;
    sal_Bool        bIsImportDlgInExecute;

    SvxBackgroundPage_Impl()
        : pLoadTimer(NULL)
        , bIsImportDlgInExecute(sal_False)
    {}
};

static inline sal_uInt8 lcl_PercentToTransparency(long nPercent)
{
    //0xff must not be returned!
    return sal_uInt8(nPercent ? (50 + 0xfe * nPercent) / 100 : 0);
}
static inline sal_uInt8 lcl_TransparencyToPercent(sal_uInt8 nTrans)
{
    return (nTrans * 100 + 127) / 254;
}
static void lcl_SetTransparency(SvxBrushItem& rBrush, long nTransparency)
{
    uno::Any aTransparency;
    aTransparency <<= (sal_Int8)nTransparency;
    rBrush.PutValue(aTransparency, MID_GRAPHIC_TRANSPARENCY);
}

/// Returns the fill style of the currently selected entry.
static XFillStyle lcl_getFillStyle(ListBox* pLbSelect)
{
    return (XFillStyle)(sal_uLong)pLbSelect->GetEntryData(pLbSelect->GetSelectEntryPos());
}

// Selects the entry matching the specified fill style.
static void lcl_setFillStyle(ListBox* pLbSelect, XFillStyle eStyle)
{
    for (int i = 0; i < pLbSelect->GetEntryCount(); ++i)
        if ((XFillStyle)(sal_uLong)pLbSelect->GetEntryData(i) == eStyle)
        {
            pLbSelect->SelectEntryPos(i);
            return;
        }
}


sal_uInt16 GetItemId_Impl( ValueSet& rValueSet, const Color& rCol )
{
    sal_Bool    bFound = sal_False;
    sal_uInt16  nCount = rValueSet.GetItemCount();
    sal_uInt16  n      = 1;

    while ( !bFound && n <= nCount )
    {
        Color aValCol = rValueSet.GetItemColor(n);

        bFound = (   aValCol.GetRed()   == rCol.GetRed()
                  && aValCol.GetGreen() == rCol.GetGreen()
                  && aValCol.GetBlue()  == rCol.GetBlue() );

        if ( !bFound )
            n++;
    }
    return bFound ? n : 0;
}

// class BackgroundPreview -----------------------------------------------

/*  [Description]

    preview window for brush or bitmap
*/

class BackgroundPreviewImpl : public Window
{
public:
    BackgroundPreviewImpl(Window* pParent);
    void setBmp(bool bBmp);
    ~BackgroundPreviewImpl();

    void            NotifyChange( const Color&  rColor );
    void            NotifyChange( const Bitmap* pBitmap );

protected:
    virtual void    Paint( const Rectangle& rRect );
    virtual void    DataChanged( const DataChangedEvent& rDCEvt );
    virtual void    Resize();

private:

    void recalcDrawPos();

    bool            bIsBmp;
    Bitmap*         pBitmap;
    Point           aDrawPos;
    Size            aDrawSize;
    Rectangle       aDrawRect;
    sal_uInt8            nTransparency;
};

BackgroundPreviewImpl::BackgroundPreviewImpl(Window* pParent)
    : Window(pParent, WB_BORDER)
    , bIsBmp(false)
    , pBitmap(NULL)
    , aDrawRect(Point(0,0), GetOutputSizePixel())
    , nTransparency(0)
{
    SetBorderStyle(WINDOW_BORDER_MONO);
    Paint(aDrawRect);
}

extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeBackgroundPreview(Window *pParent, VclBuilder::stringmap &)
{
    return new BackgroundPreviewImpl(pParent);
}

void BackgroundPreviewImpl::setBmp(bool bBmp)
{
    bIsBmp = bBmp;
    Invalidate();
}



BackgroundPreviewImpl::~BackgroundPreviewImpl()
{
    delete pBitmap;
}


void BackgroundPreviewImpl::NotifyChange( const Color& rColor )
{
    if ( !bIsBmp )
    {
        const static Color aTranspCol( COL_TRANSPARENT );

        nTransparency = lcl_TransparencyToPercent( rColor.GetTransparency() );

        SetFillColor( rColor == aTranspCol ? GetSettings().GetStyleSettings().GetFieldColor() : (Color) rColor.GetRGBColor() );
        Paint( aDrawRect );
    }
}



void BackgroundPreviewImpl::NotifyChange( const Bitmap* pNewBitmap )
{
    if ( bIsBmp && (pNewBitmap || pBitmap) )
    {
        if ( pNewBitmap && pBitmap )
            *pBitmap = *pNewBitmap;
        else if ( pNewBitmap && !pBitmap )
            pBitmap = new Bitmap( *pNewBitmap );
        else if ( !pNewBitmap )
            DELETEZ( pBitmap );

        recalcDrawPos();

        Invalidate( aDrawRect );
        Update();
    }
}

void BackgroundPreviewImpl::recalcDrawPos()
{
    if ( pBitmap )
    {
        Size aSize = GetOutputSizePixel();
        // InnerSize == Size without one pixel border
        Size aInnerSize = aSize;
        aInnerSize.Width() -= 2;
        aInnerSize.Height() -= 2;
        aDrawSize = pBitmap->GetSizePixel();

        // bitmap bigger than preview window?
        if ( aDrawSize.Width() > aInnerSize.Width() )
        {
            aDrawSize.Height() = aDrawSize.Height() * aInnerSize.Width() / aDrawSize.Width();
            if ( aDrawSize.Height() > aInnerSize.Height() )
            {
                aDrawSize.Width() = aDrawSize.Height();
                aDrawSize.Height() = aInnerSize.Height();
            }
            else
                aDrawSize.Width() = aInnerSize.Width();
        }
        else if ( aDrawSize.Height() > aInnerSize.Height() )
        {
            aDrawSize.Width() = aDrawSize.Width() * aInnerSize.Height() / aDrawSize.Height();
            if ( aDrawSize.Width() > aInnerSize.Width() )
            {
                aDrawSize.Height() = aDrawSize.Width();
                aDrawSize.Width() = aInnerSize.Width();
            }
            else
                aDrawSize.Height() = aInnerSize.Height();
        }

        aDrawPos.X() = (aSize.Width()  - aDrawSize.Width())  / 2;
        aDrawPos.Y() = (aSize.Height() - aDrawSize.Height()) / 2;
    }
}

void BackgroundPreviewImpl::Resize()
{
    Window::Resize();
    aDrawRect = Rectangle(Point(0,0), GetOutputSizePixel());
    recalcDrawPos();
}



void BackgroundPreviewImpl::Paint( const Rectangle& )
{
    const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
    SetBackground(Wallpaper(rStyleSettings.GetWindowColor()));
    SetLineColor();
    if(bIsBmp)
        SetFillColor( Color(COL_TRANSPARENT) );
    DrawRect( aDrawRect );
    if ( bIsBmp )
    {
        if ( pBitmap )
            DrawBitmap( aDrawPos, aDrawSize, *pBitmap );
        else
        {
            Size aSize = GetOutputSizePixel();
            DrawLine( Point(0,0),               Point(aSize.Width(),aSize.Height()) );
            DrawLine( Point(0,aSize.Height()),  Point(aSize.Width(),0) );
        }
    }
}

void BackgroundPreviewImpl::DataChanged( const DataChangedEvent& rDCEvt )
{
    if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
         (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    {
        Invalidate();
    }
    Window::DataChanged( rDCEvt );
}

// class SvxBackgroundTabPage --------------------------------------------

#define HDL(hdl) LINK(this,SvxBackgroundTabPage,hdl)

SvxBackgroundTabPage::SvxBackgroundTabPage(Window* pParent, const SfxItemSet& rCoreSet)
    : SvxTabPage(pParent, "BackgroundPage", "cui/ui/backgroundpage.ui", rCoreSet)
    , m_pXPool(rCoreSet.GetPool())
    , m_aXFillAttr(m_pXPool)
    , m_rXFillSet(m_aXFillAttr.GetItemSet())
    , nHtmlMode(0)
    , bAllowShowSelector(true)
    , bIsGraphicValid(false)
    , bLinkOnly(false)
    , bColTransparency(false)
    , bGraphTransparency(false)
    , pPageImpl(new SvxBackgroundPage_Impl)
    , pImportDlg(NULL)
    , pTableBck_Impl(NULL)
    , pParaBck_Impl(NULL)
{
    get(m_pAsGrid, "asgrid");
    get(m_pSelectTxt, "asft");
    get(m_pLbSelect, "selectlb");
    get(m_pTblDesc, "forft");
    get(m_pTblLBox, "tablelb");
    get(m_pParaLBox, "paralb");

    get(m_pBackGroundColorFrame, "backgroundcolorframe");
    get(m_pBackgroundColorSet, "backgroundcolorset");
    get(m_pPreviewWin1, "preview1");

    get(m_pColTransFT, "transparencyft");
    get(m_pColTransMF, "transparencymf");
    get(m_pBtnPreview, "showpreview");

    // Initialize gradient controls
    get(m_pBackGroundGradientFrame, "backgroundgradientframe");
    get(m_pLbGradients, "gradientslb");
    Size aSize = getDrawListBoxOptimalSize(this);
    m_pLbGradients->set_width_request(aSize.Width());
    m_pLbGradients->set_height_request(aSize.Height());
    get(m_pCtlPreview, "previewctl");
    aSize = getDrawPreviewOptimalSize(this);
    m_pCtlPreview->set_width_request(aSize.Width());
    m_pCtlPreview->set_height_request(aSize.Height());

    get(m_pBitmapContainer, "graphicgrid");
    get(m_pFileFrame, "fileframe");
    get(m_pBtnBrowse, "browse");
    get(m_pBtnLink, "link");
    get(m_pFtUnlinked, "unlinkedft");
    get(m_pFtFile, "fileft");

    get(m_pTypeFrame, "typeframe");
    get(m_pBtnPosition, "positionrb");
    get(m_pBtnArea, "arearb");
    get(m_pBtnTile, "tilerb");
    get(m_pWndPosition, "windowpos");

    get(m_pGraphTransFrame, "graphtransframe");
    get(m_pGraphTransMF, "graphtransmf");

    get(m_pPreviewWin2, "preview2");
    m_pPreviewWin2->setBmp(true);

    // this page needs ExchangeSupport
    SetExchangeSupport();

    const SfxPoolItem* pItem;
    SfxObjectShell* pShell;

    if ( SFX_ITEM_SET == rCoreSet.GetItemState( SID_HTML_MODE, false, &pItem )
         || ( 0 != ( pShell = SfxObjectShell::Current()) &&
              0 != ( pItem = pShell->GetItem( SID_HTML_MODE ) ) ) )
    {
        nHtmlMode = ((SfxUInt16Item*)pItem)->GetValue();
    }

    FillColorValueSets_Impl();

    m_pBackgroundColorSet->SetSelectHdl( HDL(BackgroundColorHdl_Impl) );
    m_pBackgroundColorSet->SetStyle(m_pBackgroundColorSet->GetStyle() | WB_ITEMBORDER | WB_NAMEFIELD | WB_NONEFIELD);
    m_pBackgroundColorSet->SetText(SVX_RESSTR(RID_SVXSTR_TRANSPARENT));
}



SvxBackgroundTabPage::~SvxBackgroundTabPage()
{
    delete pPageImpl->pLoadTimer;
    delete pPageImpl;
    delete pImportDlg;

    if( pTableBck_Impl)
    {
        delete pTableBck_Impl->pCellBrush;
        delete pTableBck_Impl->pRowBrush;
        delete pTableBck_Impl->pTableBrush;
        delete pTableBck_Impl;
    }

    if(pParaBck_Impl)
    {
        delete pParaBck_Impl->pParaBrush;
        delete pParaBck_Impl->pCharBrush;
        delete pParaBck_Impl;
    }
}



sal_uInt16* SvxBackgroundTabPage::GetRanges()

/*  [Description]

    returns the area of the which-values
*/

{
    return pRanges;
}



SfxTabPage* SvxBackgroundTabPage::Create( Window* pParent,
                                          const SfxItemSet& rAttrSet )

/*  [Description]

    create method for the TabDialog
*/

{
    return ( new SvxBackgroundTabPage( pParent, rAttrSet ) );
}



void SvxBackgroundTabPage::Reset( const SfxItemSet& rSet )
{
// os: Such a nonsense! One will always find such an item somewhere,
//     but it must be existing in the rSet!
//  const SfxPoolItem* pX = GetOldItem( rSet, SID_VIEW_FLD_PIC );
//  if( pX && pX->ISA(SfxWallpaperItem))
    if(SFX_ITEM_AVAILABLE <= rSet.GetItemState(GetWhich(SID_VIEW_FLD_PIC), false))
    {
        ResetFromWallpaperItem( rSet );
        return;
    }

    // condition of the preview button is persistent due to UserData
    OUString aUserData = GetUserData();
    m_pBtnPreview->Check( !aUserData.isEmpty() && '1' == aUserData[0] );

    // don't be allowed to call ShowSelector() after reset anymore
    bAllowShowSelector = sal_False;


    // get and evaluate Input-BrushItem
    const SvxBrushItem* pBgdAttr = NULL;
    sal_uInt16 nSlot = SID_ATTR_BRUSH;
    const SfxPoolItem* pItem;
    sal_uInt16 nDestValue = USHRT_MAX;

    if ( SFX_ITEM_SET == rSet.GetItemState( SID_BACKGRND_DESTINATION,
                                            false, &pItem ) )
    {
        nDestValue = ((const SfxUInt16Item*)pItem)->GetValue();
        m_pTblLBox->SelectEntryPos(nDestValue);

        switch ( nDestValue )
        {
            case TBL_DEST_CELL:
                nSlot = SID_ATTR_BRUSH;
            break;
            case TBL_DEST_ROW:
                nSlot = SID_ATTR_BRUSH_ROW;
            break;
            case TBL_DEST_TBL:
                nSlot = SID_ATTR_BRUSH_TABLE;
            break;
        }
    }
    else if( SFX_ITEM_SET == rSet.GetItemState(
                SID_PARA_BACKGRND_DESTINATION, false, &pItem ) )
    {
        nDestValue = ((const SfxUInt16Item*)pItem)->GetValue();
        // character activated?
        sal_Int32 nParaSel  = m_pParaLBox->GetSelectEntryPos();
        if(1 == nParaSel)
        {
            // then it was a "standard"-call
            nDestValue = nParaSel;
        }
        m_pParaLBox->SelectEntryPos(nDestValue);

        switch ( nDestValue )
        {
            case PARA_DEST_PARA:
                nSlot = SID_ATTR_BRUSH;
            break;
            case PARA_DEST_CHAR:
                nSlot = SID_ATTR_BRUSH_CHAR;
            break;
        }
    }
    //#111173# the destination item is missing when the parent style has been changed
    if(USHRT_MAX == nDestValue && (m_pParaLBox->IsVisible()||m_pTblLBox->IsVisible()))
        nDestValue = 0;
    sal_uInt16 nWhich = GetWhich( nSlot );

    if ( rSet.GetItemState( nWhich, false ) >= SFX_ITEM_AVAILABLE )
        pBgdAttr = (const SvxBrushItem*)&( rSet.Get( nWhich ) );

    m_pBtnTile->Check();

    if ( pBgdAttr )
    {
        FillControls_Impl(*pBgdAttr, aUserData);
        aBgdColor = ( (SvxBrushItem*)pBgdAttr )->GetColor();
    }
    else
    {
        m_pSelectTxt->Hide();
        m_pLbSelect->Hide();
        lcl_setFillStyle(m_pLbSelect, XFILL_SOLID);
        ShowColorUI_Impl();

        const SfxPoolItem* pOld = GetOldItem( rSet, SID_ATTR_BRUSH );

        if ( pOld )
            aBgdColor = ( (SvxBrushItem*)pOld )->GetColor();
    }

    if ( nDestValue != USHRT_MAX )
    {
        if(m_pTblLBox->IsVisible())
        {
            sal_Int32 nValue = m_pTblLBox->GetSelectEntryPos();

            if ( pTableBck_Impl )
            {
                DELETEZ( pTableBck_Impl->pCellBrush);
                DELETEZ( pTableBck_Impl->pRowBrush);
                DELETEZ( pTableBck_Impl->pTableBrush);
            }
            else
                pTableBck_Impl = new SvxBackgroundTable_Impl();

            pTableBck_Impl->nActPos = nValue;

            nWhich = GetWhich( SID_ATTR_BRUSH );
            if ( rSet.GetItemState( nWhich, false ) >= SFX_ITEM_AVAILABLE )
            {
                pBgdAttr = (const SvxBrushItem*)&( rSet.Get( nWhich ) );
                pTableBck_Impl->pCellBrush = new SvxBrushItem(*pBgdAttr);
            }
            pTableBck_Impl->nCellWhich = nWhich;

            if ( rSet.GetItemState( SID_ATTR_BRUSH_ROW, false ) >= SFX_ITEM_AVAILABLE )
            {
                pBgdAttr = (const SvxBrushItem*)&( rSet.Get( SID_ATTR_BRUSH_ROW ) );
                pTableBck_Impl->pRowBrush = new SvxBrushItem(*pBgdAttr);
            }
            pTableBck_Impl->nRowWhich = SID_ATTR_BRUSH_ROW;

            if ( rSet.GetItemState( SID_ATTR_BRUSH_TABLE, false ) >= SFX_ITEM_AVAILABLE )
            {
                pBgdAttr = (const SvxBrushItem*)&( rSet.Get( SID_ATTR_BRUSH_TABLE ) );
                pTableBck_Impl->pTableBrush = new SvxBrushItem(*pBgdAttr);
            }
            pTableBck_Impl->nTableWhich = SID_ATTR_BRUSH_TABLE;

            TblDestinationHdl_Impl(m_pTblLBox);
            m_pTblLBox->SaveValue();
        }
        else
        {
            sal_Int32 nValue = m_pParaLBox->GetSelectEntryPos();

            if ( pParaBck_Impl )
            {
                delete pParaBck_Impl->pParaBrush;
                delete pParaBck_Impl->pCharBrush;
            }
            else
                pParaBck_Impl = new SvxBackgroundPara_Impl();

            pParaBck_Impl->nActPos = nValue;

            nWhich = GetWhich( SID_ATTR_BRUSH );
            if ( rSet.GetItemState( nWhich, false ) >= SFX_ITEM_AVAILABLE )
            {
                pBgdAttr = (const SvxBrushItem*)&( rSet.Get( nWhich ) );
                pParaBck_Impl->pParaBrush = new SvxBrushItem(*pBgdAttr);
            }

            nWhich = GetWhich( SID_ATTR_BRUSH_CHAR );
            rSet.GetItemState( nWhich, true );
            rSet.GetItemState( nWhich, false );
            if ( rSet.GetItemState( nWhich, true ) > SFX_ITEM_AVAILABLE )
            {
                pBgdAttr = (const SvxBrushItem*)&( rSet.Get( nWhich ) );
                pParaBck_Impl->pCharBrush = new SvxBrushItem(*pBgdAttr);
            }
            else
                pParaBck_Impl->pCharBrush = new SvxBrushItem(SID_ATTR_BRUSH_CHAR);

            ParaDestinationHdl_Impl(m_pParaLBox);
            m_pParaLBox->SaveValue();
        }
    }
}

void SvxBackgroundTabPage::ResetFromWallpaperItem( const SfxItemSet& rSet )
{
    ShowSelector();

    // condition of the preview button is persistent due to UserData
    OUString aUserData = GetUserData();
    m_pBtnPreview->Check( !aUserData.isEmpty() && '1' == aUserData[0] );

    // get and evaluate Input-BrushItem
    const SvxBrushItem* pBgdAttr = NULL;
    sal_uInt16 nSlot = SID_VIEW_FLD_PIC;
    sal_uInt16 nWhich = GetWhich( nSlot );
    SvxBrushItem* pTemp = 0;

    if ( rSet.GetItemState( nWhich, false ) >= SFX_ITEM_AVAILABLE )
    {
        const CntWallpaperItem* pItem = (const CntWallpaperItem*)&rSet.Get( nWhich );
        pTemp = new SvxBrushItem( *pItem, nWhich );
        pBgdAttr = pTemp;
    }

    m_pBtnTile->Check();

    if ( pBgdAttr )
    {
        FillControls_Impl(*pBgdAttr, aUserData);
        // brush shall be kept when showing the graphic, too
        if( aBgdColor != pBgdAttr->GetColor() )
        {
            aBgdColor = pBgdAttr->GetColor();
            sal_uInt16 nCol = GetItemId_Impl(*m_pBackgroundColorSet, aBgdColor);
            m_pBackgroundColorSet->SelectItem( nCol );
            m_pPreviewWin1->NotifyChange( aBgdColor );
        }
    }
    else
    {
        lcl_setFillStyle(m_pLbSelect, XFILL_SOLID);
        ShowColorUI_Impl();

        const SfxPoolItem* pOld = GetOldItem( rSet, SID_VIEW_FLD_PIC );
        if ( pOld )
            aBgdColor = Color( ((CntWallpaperItem*)pOld)->GetColor() );
    }

    // We now have always a link to the background
    bLinkOnly = sal_True;
    m_pBtnLink->Check( true );
    m_pBtnLink->Show( false );

    delete pTemp;
}





void SvxBackgroundTabPage::FillUserData()

/*  [Description]

    When destroying a SfxTabPage this virtual method is called,
    so that the TabPage can save internal information.

    In this case the condition of the preview button is saved.
*/

{
    SetUserData( m_pBtnPreview->IsChecked() ? OUString('1') : OUString('0') );
}



sal_Bool SvxBackgroundTabPage::FillItemSet( SfxItemSet& rCoreSet )
{
    if ( pPageImpl->pLoadTimer && pPageImpl->pLoadTimer->IsActive() )
    {
        pPageImpl->pLoadTimer->Stop();
        LoadTimerHdl_Impl( pPageImpl->pLoadTimer );
    }
// os: Such a nonsense! One will always find such an item somewhere,
//     but it must be existing in the rSet!

//  const SfxPoolItem* pX = GetOldItem( rCoreSet, SID_VIEW_FLD_PIC );
//  if( pX && pX->ISA(SfxWallpaperItem))
    if(SFX_ITEM_AVAILABLE <= rCoreSet.GetItemState(GetWhich(SID_VIEW_FLD_PIC), false))
        return FillItemSetWithWallpaperItem( rCoreSet, SID_VIEW_FLD_PIC );

    sal_Bool bModified = sal_False;
    sal_uInt16 nSlot = SID_ATTR_BRUSH;

    if ( m_pTblLBox->IsVisible() )
    {
        switch( m_pTblLBox->GetSelectEntryPos() )
        {
            case TBL_DEST_CELL:
                nSlot = SID_ATTR_BRUSH;
            break;
            case TBL_DEST_ROW:
                nSlot = SID_ATTR_BRUSH_ROW;
            break;
            case TBL_DEST_TBL:
                nSlot = SID_ATTR_BRUSH_TABLE;
            break;
        }
    }
    else if (m_pParaLBox->GetData() == m_pParaLBox)
    {
        switch(m_pParaLBox->GetSelectEntryPos())
        {
            case PARA_DEST_PARA:
                nSlot = SID_ATTR_BRUSH;
            break;
            case PARA_DEST_CHAR:
                nSlot = SID_ATTR_BRUSH_CHAR;
            break;
        }
    }
    sal_uInt16 nWhich = GetWhich( nSlot );

    const SfxPoolItem* pOld = GetOldItem( rCoreSet, nSlot );
    SfxItemState eOldItemState = rCoreSet.GetItemState(nSlot, false);
    const SfxItemSet& rOldSet = GetItemSet();

    sal_Bool bGraphTransparencyChanged = bGraphTransparency && (m_pGraphTransMF->GetText() != m_pGraphTransMF->GetSavedValue());
    if ( pOld )
    {
        const SvxBrushItem& rOldItem    = (const SvxBrushItem&)*pOld;
        SvxGraphicPosition  eOldPos     = rOldItem.GetGraphicPos();
        const sal_Bool          bIsBrush    = ( XFILL_SOLID == lcl_getFillStyle(m_pLbSelect) );
        const bool bIsGradient = ( XFILL_GRADIENT == lcl_getFillStyle(m_pLbSelect) );

        // transparency has to be set if enabled, the color not already set to "No fill" and
        if( bColTransparency &&
            aBgdColor.GetTransparency() < 0xff)
        {
            aBgdColor.SetTransparency(lcl_PercentToTransparency(static_cast<long>(m_pColTransMF->GetValue())));
        }
        if (   ( (GPOS_NONE == eOldPos) && (bIsBrush || bIsGradient)  )
            || ( (GPOS_NONE != eOldPos) && !(bIsBrush || bIsGradient) ) ) // Brush <-> Bitmap changed?
        {
            // background art hasn't been changed:

            if ( (GPOS_NONE == eOldPos) || !m_pLbSelect->IsVisible() )
            {
                if (bIsBrush)
                {
                    // Brush-treatment:
                    if ( rOldItem.GetColor() != aBgdColor ||
                            (SFX_ITEM_AVAILABLE >= eOldItemState && !m_pBackgroundColorSet->IsNoSelection()))
                    {
                        bModified = sal_True;
                        rCoreSet.Put( SvxBrushItem( aBgdColor, nWhich ) );
                    }
                    else if ( SFX_ITEM_DEFAULT == rOldSet.GetItemState( nWhich, false ) )
                        rCoreSet.ClearItem( nWhich );
                    // Handle XFILL_GRADIENT -> XFILL_SOLID
                    XFillStyleItem aFillStyleItem(XFILL_SOLID, GetWhich(SID_SW_ATTR_FILL_STYLE));
                    rCoreSet.Put(aFillStyleItem);
                }
                else
                {
                    XFillStyleItem aFillStyleItem(((const XFillStyleItem&)m_rXFillSet.Get(XATTR_FILLSTYLE)).GetValue(), GetWhich(SID_SW_ATTR_FILL_STYLE));
                    rCoreSet.Put(aFillStyleItem);

                    const XFillGradientItem& rFillGradientItem = (const XFillGradientItem&)m_rXFillSet.Get(XATTR_FILLGRADIENT);
                    XFillGradientItem aFillGradientItem(rFillGradientItem.GetName(), rFillGradientItem.GetGradientValue(), GetWhich(SID_SW_ATTR_FILL_GRADIENT));
                    rCoreSet.Put(aFillGradientItem);
                }
            }
            else
            {
                // Bitmap-treatment:

                SvxGraphicPosition  eNewPos  = GetGraphicPosition_Impl();
                const sal_Bool          bIsLink  = m_pBtnLink->IsChecked();
                const sal_Bool          bWasLink = (NULL != rOldItem.GetGraphicLink() );


                if ( !bIsLink && !bIsGraphicValid )
                    bIsGraphicValid = LoadLinkedGraphic_Impl();

                if (   bGraphTransparencyChanged ||
                       eNewPos != eOldPos
                    || bIsLink != bWasLink
                    || ( bWasLink  && rOldItem.GetGraphicLink()
                                       != aBgdGraphicPath )
                    || ( !bWasLink && rOldItem.GetGraphic()->GetBitmap()
                                       != aBgdGraphic.GetBitmap() )
                   )
                {
                    bModified = sal_True;

                    SvxBrushItem aTmpBrush(nWhich);
                    if ( bIsLink )
                    {
                        aTmpBrush = SvxBrushItem( aBgdGraphicPath,
                                                aBgdGraphicFilter,
                                                eNewPos,
                                                nWhich );
                    }
                    else
                        aTmpBrush = SvxBrushItem( aBgdGraphic,
                                        eNewPos,
                                        nWhich );
                    lcl_SetTransparency(aTmpBrush, static_cast<long>(m_pGraphTransMF->GetValue()));

                    rCoreSet.Put(aTmpBrush);
                }
                else if ( SFX_ITEM_DEFAULT == rOldSet.GetItemState( nWhich, false ) )
                    rCoreSet.ClearItem( nWhich );
            }
        }
        else // Brush <-> Bitmap changed!
        {
            if (bIsBrush || bIsGradient)
            {
                rCoreSet.Put( SvxBrushItem( aBgdColor, nWhich ) );
                if (bIsGradient)
                {
                    // Handle XFILL_BITMAP -> XFILL_GRADIENT
                    XFillStyleItem aFillStyleItem(((const XFillStyleItem&)m_rXFillSet.Get(XATTR_FILLSTYLE)).GetValue(), GetWhich(SID_SW_ATTR_FILL_STYLE));
                    rCoreSet.Put(aFillStyleItem);

                    const XFillGradientItem& rFillGradientItem = (const XFillGradientItem&)m_rXFillSet.Get(XATTR_FILLGRADIENT);
                    XFillGradientItem aFillGradientItem(rFillGradientItem.GetName(), rFillGradientItem.GetGradientValue(), GetWhich(SID_SW_ATTR_FILL_GRADIENT));
                    rCoreSet.Put(aFillGradientItem);
                }
            }
            else
            {
                SvxBrushItem* pTmpBrush = 0;
                if ( m_pBtnLink->IsChecked() )
                {
                    pTmpBrush = new SvxBrushItem( aBgdGraphicPath,
                                                aBgdGraphicFilter,
                                                GetGraphicPosition_Impl(),
                                                nWhich );
                }
                else
                {
                    if ( !bIsGraphicValid )
                        bIsGraphicValid = LoadLinkedGraphic_Impl();

                    if ( bIsGraphicValid )
                        pTmpBrush = new SvxBrushItem( aBgdGraphic,
                                                    GetGraphicPosition_Impl(),
                                                    nWhich );
                }
                if(pTmpBrush)
                {
                    lcl_SetTransparency(*pTmpBrush, static_cast<long>(m_pGraphTransMF->GetValue()));
                    rCoreSet.Put(*pTmpBrush);
                    delete pTmpBrush;
                }
            }
            bModified = ( bIsBrush || bIsGradient || m_pBtnLink->IsChecked() || bIsGraphicValid );
        }
    }
    else if ( SID_ATTR_BRUSH_CHAR == nSlot && aBgdColor != Color( COL_WHITE ) )
    {
        rCoreSet.Put( SvxBrushItem( aBgdColor, nWhich ) );
        bModified = sal_True;
    }

    if( m_pTblLBox->IsVisible() )
    {
        // the current condition has already been put
        if( nSlot != SID_ATTR_BRUSH && pTableBck_Impl->pCellBrush)
        {
            const SfxPoolItem* pOldCell =
                GetOldItem( rCoreSet, SID_ATTR_BRUSH );

            if ( *pTableBck_Impl->pCellBrush != *pOldCell )
            {
                rCoreSet.Put( *pTableBck_Impl->pCellBrush );
                bModified |= sal_True;
            }
        }

        if( nSlot != SID_ATTR_BRUSH_ROW && pTableBck_Impl->pRowBrush)
        {
            const SfxPoolItem* pOldRow =
                GetOldItem( rCoreSet, SID_ATTR_BRUSH_ROW );

            if ( *pTableBck_Impl->pRowBrush != *pOldRow )
            {
                rCoreSet.Put( *pTableBck_Impl->pRowBrush );
                bModified |= sal_True;
            }
        }

        if( nSlot != SID_ATTR_BRUSH_TABLE && pTableBck_Impl->pTableBrush)
        {
            const SfxPoolItem* pOldTable =
                GetOldItem( rCoreSet, SID_ATTR_BRUSH_TABLE );

            if ( *pTableBck_Impl->pTableBrush != *pOldTable )
            {
                rCoreSet.Put( *pTableBck_Impl->pTableBrush );
                bModified |= sal_True;
            }
        }

        if( m_pTblLBox->GetSavedValue() != m_pTblLBox->GetSelectEntryPos() )
        {
            rCoreSet.Put( SfxUInt16Item( SID_BACKGRND_DESTINATION,
                                         m_pTblLBox->GetSelectEntryPos() ) );
            bModified |= sal_True;
        }
    }
    else if (m_pParaLBox->GetData() == m_pParaLBox)
    {
        // the current condition has already been put
        if( nSlot != SID_ATTR_BRUSH && m_pParaLBox->IsVisible()) // not in search format dialog
        {
            const SfxPoolItem* pOldPara =
                GetOldItem( rCoreSet, SID_ATTR_BRUSH );

            if ( *pParaBck_Impl->pParaBrush != *pOldPara )
            {
                rCoreSet.Put( *pParaBck_Impl->pParaBrush );
                bModified |= sal_True;
            }
        }

        if( nSlot != SID_ATTR_BRUSH_CHAR )
        {
            const SfxPoolItem* pOldChar =
                GetOldItem( rCoreSet, SID_ATTR_BRUSH_CHAR );
            DBG_ASSERT(pParaBck_Impl, "pParaBck_Impl == NULL ?");
            if ( pOldChar &&
                    //#111173#  crash report shows that pParaBck_Impl can be NULL, the cause is unknown
                    pParaBck_Impl &&
                        (*pParaBck_Impl->pCharBrush != *pOldChar ||
                *pParaBck_Impl->pCharBrush != SvxBrushItem(SID_ATTR_BRUSH_CHAR)))
            {
                rCoreSet.Put( *pParaBck_Impl->pCharBrush );
                bModified |= sal_True;
            }
        }

        if( m_pParaLBox->GetSavedValue() != m_pParaLBox->GetSelectEntryPos() )
        {
            rCoreSet.Put( SfxUInt16Item( SID_BACKGRND_DESTINATION,
                                         m_pParaLBox->GetSelectEntryPos() ) );
            bModified |= sal_True;
        }
    }
    return bModified;
}

sal_Bool SvxBackgroundTabPage::FillItemSetWithWallpaperItem( SfxItemSet& rCoreSet, sal_uInt16 nSlot)
{
    sal_uInt16 nWhich = GetWhich( nSlot );
    const SfxPoolItem* pOld = GetOldItem( rCoreSet, nSlot );
    DBG_ASSERT(pOld,"FillItemSetWithWallpaperItem: Item not found");
    if (!pOld)
        return sal_False;
    const SfxItemSet& rOldSet = GetItemSet();

    SvxBrushItem        rOldItem( (const CntWallpaperItem&)*pOld, nWhich );
{'fraction_non_alphanumeric': 0.10641539328752724, 'fraction_numerical': 0.004753271682993342, 'mean_word_length': 2.070015434264066, 'pattern_counts': {'":': 0, '<': 87, '<?xml version=': 0, '>': 327, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 60, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1985570', 'n_tokens_mistral': 22125, 'n_tokens_neox': 20963, 'n_words': 3718}