/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "pairs.hxx"

#include <bf_svx/eeitem.hxx>
#include <bf_sfx2/sfxsids.hrc>
#ifdef _MSC_VER
#pragma hdrstop
#endif
#include <bf_svx/svdopath.hxx>
#include <vcl/msgbox.hxx>
#include <bf_svtools/itempool.hxx>
#include <bf_svx/svdorect.hxx>
#include <bf_sfx2/printer.hxx>

#include <bf_svx/editdata.hxx>
#include "schattr.hxx"

#ifndef _SVX_CHRTITEM_HXX //autogen
#define ITEMID_DOUBLE           0
#define ITEMID_CHARTDATADESCR   SCHATTR_DATADESCR_DESCR
#define ITEMID_CHARTSTYLE       CHATTR_DIAGRAM_STYLE
#define ITEMID_CHARTLEGENDPOS   SCHATTR_LEGEND_POS

#include <bf_svtools/eitem.hxx>

#include <bf_svx/chrtitem.hxx>
#endif

#define ITEMID_FONTHEIGHT  EE_CHAR_FONTHEIGHT
#define ITEMID_FONTWIDTH   EE_CHAR_FONTWIDTH
#include <bf_svx/fhgtitem.hxx>
#include <bf_svx/fwdtitem.hxx>
#ifndef _CHTMODEL_HXX
#include <globfunc.hxx>
#include <chtmodel.hxx>
#endif
#include <bf_svx/svdoutl.hxx>   // wg. SdrOutliner
#include <bf_svx/svdpage.hxx>
#include  "objadj.hxx"
#include "schresid.hxx"
#include "objid.hxx"
#include "datarow.hxx"
#include  <bf_svx/dlgutil.hxx>

#include "chtscene.hxx"
#include "glob.hrc"
#include <math.h>
#include <float.h>

#include "chmod3d.hxx"
#include "docshell.hxx"

#include <bf_sfx2/app.hxx>
#include <vcl/virdev.hxx>

#include <rtl/logfile.hxx>

#include "chaxis.hxx"
#include "ChXChartDocument.hxx"

#include "ReBuildHint.hxx"
namespace binfilter {

/*************************************************************************
|*
|* Datenbeschriftung aendern;
|* FG: 24.4.97 nRow ist ein Parameter der ermoeglicht die Datenbeschriftung
|*     einer einzigen Reihe zu aendern, falls er -1 ist werden alle
|*     Datenreihen mit dem uebergebenen Attributen belegt. (default ist alle)
|*
\************************************************************************/

/*N*/ void ChartModel::ChangeDataDescr(SvxChartDataDescr eDescr, BOOL bSym,
/*N*/                                long nRowToChange, BOOL bBuildChart)
/*N*/ {
/*N*/     if( nRowToChange == -1 ||
/*N*/         IsPieChart())
/*N*/     {
/*N*/         // change setting globally
/*N*/         eDataDescr = eDescr;
/*N*/         bShowSym = bSym;
/*N*/
/*N*/         // clear individual settings
/*N*/         long nEndRow = GetRowCount();
/*N*/         for( long nRow = 0; nRow < nEndRow; nRow++ )
/*N*/         {
/*N*/             SfxItemSet &rAttr = (const_cast< SfxItemSet& >( GetDataRowAttr( (short)nRow )));
/*N*/
/*N*/             rAttr.Put( SvxChartDataDescrItem( eDescr ));
/*N*/             rAttr.Put( SfxBoolItem( SCHATTR_DATADESCR_SHOW_SYM, bSym ));
/*N*/         }
/*N*/     }
/*N*/     else
/*N*/     {
/*N*/         SfxItemSet &rAttr = (const_cast< SfxItemSet& >( GetDataRowAttr( (short)nRowToChange )));
/*N*/
/*N*/       rAttr.Put( SvxChartDataDescrItem( eDescr ));
/*N*/       rAttr.Put( SfxBoolItem( SCHATTR_DATADESCR_SHOW_SYM, bSym ));
/*N*/     }
/*N*/
/*N*/   if( bBuildChart )
/*?*/       BuildChart( FALSE );
/*N*/ }

/*************************************************************************
|*
|* Seitengroesse aendern;
|* Liefert bei Aenderung TRUE.
|*
\************************************************************************/

/*N*/ BOOL ChartModel::ResizePage(const Size& rNewSize)
/*N*/ {
/*N*/   SdrPage* pPage = GetPage(0);
/*N*/
/*N*/   if (!pPage || pPage->GetSize() == rNewSize) return FALSE;
/*N*/   else
/*N*/   {
/*N*/       BOOL bWasChanged = IsChanged();
/*N*/
/*N*/       pPage->SetSize(rNewSize);
/*N*/       eOldChartStyle = eChartStyle;
/*N*/       if (rNewSize.Width () != 0 && rNewSize.Height () != 0) BuildChart(FALSE);
/*N*/
/*N*/       if (!bWasChanged) SetChanged(FALSE);
/*N*/
/*N*/       return TRUE;
/*N*/   }
/*N*/ }


/************************************************************************
|*
|* skaliere Texte neu um
|*
\************************************************************************/

/*N*/ void ChartModel::ResizeText (SfxItemSet *pTextAttr, Size aPageSize, BOOL bResizePage )
/*N*/ {
/*N*/ 	double fRatio = 1.0;
/*N*/   if( bResizePage )
        {
            double fDenominator = aInitialSize.Height();
            if( fDenominator != 0 )
/*N*/           fRatio = (double)aPageSize.Height() / fDenominator;
        }
/*N*/   else
        {
            double fDenominator = aLastDiagramRectangle.GetHeight();
            if( fDenominator != 0 )
/*?*/           fRatio = (double)aDiagramRectangle.GetHeight() / fDenominator;
        }
/*N*/
/*N*/   // resize all three fonts
/*N*/   static const USHORT nWhichIds[ 3 ] = {
/*N*/       EE_CHAR_FONTHEIGHT,
/*N*/       EE_CHAR_FONTHEIGHT_CJK,
/*N*/       EE_CHAR_FONTHEIGHT_CTL
/*N*/   };
/*N*/
/*N*/   for( int i=0; i < 3; i++ )
/*N*/   {
/*N*/       long nHeight = ((SvxFontHeightItem &)pTextAttr->Get( nWhichIds[ i ] )).GetHeight();
/*N*/
/*N*/         //    Scale and round height.
/*N*/       nHeight = (long)( fRatio * (double)nHeight + 0.5 );
/*N*/
/*N*/       float fPoints = (float)CalcToPoint( nHeight, SFX_MAPUNIT_100TH_MM, 10 );
/*N*/       if( fPoints < 2.0 ) fPoints = 2.0;
/*N*/
/*N*/       pTextAttr->Put( SvxFontHeightItem( CalcToUnit( fPoints / (float)10.0, SFX_MAPUNIT_100TH_MM ),
/*N*/                                          100, nWhichIds[ i ] ));
/*N*/   }
/*N*/ }

/*************************************************************************
|*
|* Attribute lesen
|*
\************************************************************************/

//SfxItemSet ChartModel::GetAttr() const
/*N*/ void ChartModel::GetAttr(SfxItemSet& rAttr)
/*N*/ {
/*N*/   CHART_TRACE( "ChartModel::GetAttr(SfxItemSet& rAttr)" );
/*N*/
/*N*/   rAttr.Put(SvxChartStyleItem(ChartStyle()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_TITLE_SHOW_MAIN, ShowMainTitle()));
/*N*/   rAttr.Put(SfxStringItem(CHATTR_TITLE_MAIN, MainTitle()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_TITLE_SHOW_SUB, ShowSubTitle()));
/*N*/   rAttr.Put(SfxStringItem(CHATTR_TITLE_SUB, SubTitle()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_TITLE_SHOW_X_AXIS, ShowXAxisTitle()));
/*N*/   rAttr.Put(SfxStringItem(CHATTR_TITLE_X_AXIS, XAxisTitle()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_TITLE_SHOW_Y_AXIS, ShowYAxisTitle()));
/*N*/   rAttr.Put(SfxStringItem(CHATTR_TITLE_Y_AXIS, YAxisTitle()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_TITLE_SHOW_Z_AXIS, ShowZAxisTitle()));
/*N*/   rAttr.Put(SfxStringItem(CHATTR_TITLE_Z_AXIS, ZAxisTitle()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_X_AXIS, ShowXAxis()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_X_MAIN, ShowXGridMain()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_X_HELP, ShowXGridHelp()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_X_DESCR, ShowXDescr()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_Y_AXIS, ShowYAxis()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_Y_MAIN, ShowYGridMain()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_Y_HELP, ShowYGridHelp()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_Y_DESCR, ShowYDescr()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_Z_AXIS, ShowZAxis()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_Z_MAIN, ShowZGridMain()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_Z_HELP, ShowZGridHelp()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_Z_DESCR, ShowZDescr()));
/*N*/
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_2Y_AXIS, GetAxisByUID(CHART_AXIS_SECONDARY_Y)->IsVisible()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_2Y_DESCR, GetAxisByUID(CHART_AXIS_SECONDARY_Y)->HasDescription()));
/*N*/
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_2X_AXIS, GetAxisByUID(CHART_AXIS_SECONDARY_X)->IsVisible()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_AXISGRID_SHOW_2X_DESCR, GetAxisByUID(CHART_AXIS_SECONDARY_X)->HasDescription()));
/*N*/
/*N*/   const SfxPoolItem *pPoolItem = NULL;
/*N*/   if (pLegendAttr->GetItemState(SCHATTR_LEGEND_POS, TRUE, &pPoolItem)
/*N*/                           == SFX_ITEM_SET)
/*N*/       rAttr.Put(SvxChartLegendPosItem
/*N*/                   (((const SvxChartLegendPosItem*)pPoolItem)->GetValue(),
/*N*/                   pItemPool->GetSlotId(SCHATTR_LEGEND_POS)));
/*N*/
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_DATA_SWITCH, IsSwitchData()));
/*N*/
/*N*/
/*N*/   rAttr.Put (SfxBoolItem (SCHATTR_STAT_AVERAGE,bShowAverage));
/*N*/   rAttr.Put (SfxInt32Item (SCHATTR_STAT_KIND_ERROR, (INT32) eErrorKind));
/*N*/   rAttr.Put (SfxInt32Item (SCHATTR_STAT_INDICATE, (INT32) eIndicate));
/*N*/   rAttr.Put (SvxDoubleItem (fIndicatePercent, SCHATTR_STAT_PERCENT));
/*N*/   rAttr.Put (SvxDoubleItem (fIndicateBigError, SCHATTR_STAT_BIGERROR));
/*N*/   rAttr.Put (SvxDoubleItem (fIndicatePlus, SCHATTR_STAT_CONSTPLUS));
/*N*/   rAttr.Put (SvxDoubleItem (fIndicateMinus, SCHATTR_STAT_CONSTMINUS));
/*N*/   rAttr.Put (SfxInt32Item (SCHATTR_STAT_REGRESSTYPE, (INT32) eRegression));
/*N*/
/*N*/   //Datenbeschriftung
/*N*/   rAttr.Put(SfxBoolItem(SCHATTR_DATADESCR_SHOW_SYM,bShowSym));
/*N*/   rAttr.Put(SvxChartDataDescrItem(eDataDescr));
/*N*/
/*N*/   rAttr.Put(SfxInt32Item(CHATTR_BARWIDTH,GetBarPercentWidth()));
/*N*/   rAttr.Put(SfxBoolItem(CHATTR_BARCONNECT, (BOOL)(m_nDefaultColorSet&CHSPECIAL_TRACELINES)));
/*N*/
/*N*/   if (pChartAttr->GetItemState(SCHATTR_STYLE_SHAPE, TRUE, &pPoolItem)== SFX_ITEM_SET)
/*N*/   {
/*?*/       long nTmp= (long)((const SfxInt32Item*)pPoolItem)->GetValue();
/*?*/       rAttr.Put(SfxInt32Item(SCHATTR_STYLE_SHAPE,nTmp));
/*N*/   }
/*N*/
/*N*/   ChartScene *pLclScene=GetScene();
/*N*/   if(pLclScene)
/*N*/       rAttr.Put(pLclScene->GetItemSet());
/*N*/
/*N*/     if( pChartAttr->GetItemState( SCHATTR_USER_DEFINED_ATTR, TRUE, &pPoolItem ) == SFX_ITEM_SET )
/*N*/     {
/*?*/         rAttr.Put( *pPoolItem );
/*N*/     }
/*N*/ }

/*************************************************************************
|*
|* Attribute setzen
|*
\************************************************************************/

/*N*/ void ChartModel::PutAttr(const SfxItemSet& rAttr)
/*N*/ {
/*N*/   const SfxPoolItem *pPoolItem = NULL;
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_TITLE_SHOW_MAIN, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       ShowMainTitle () = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_TITLE_MAIN, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*?*/       MainTitle () = ((const SfxStringItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_TITLE_SHOW_SUB, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       ShowSubTitle () = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_TITLE_SUB, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*?*/       SubTitle () = ((const SfxStringItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_TITLE_SHOW_X_AXIS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       ShowXAxisTitle () = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_TITLE_X_AXIS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*?*/       XAxisTitle () = ((const SfxStringItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_TITLE_SHOW_Y_AXIS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       ShowYAxisTitle () = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_TITLE_Y_AXIS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*?*/       YAxisTitle () = ((const SfxStringItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_TITLE_SHOW_Z_AXIS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       ShowZAxisTitle () = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_TITLE_Z_AXIS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*?*/       ZAxisTitle () = ((const SfxStringItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_X_AXIS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       ShowXAxis (((const SfxBoolItem*)pPoolItem)->GetValue());
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_X_MAIN, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       ShowXGridMain () = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_X_HELP, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*?*/       ShowXGridHelp () = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_X_DESCR, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       ShowXDescr (((const SfxBoolItem*)pPoolItem)->GetValue());
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_Y_AXIS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       ShowYAxis (((const SfxBoolItem*)pPoolItem)->GetValue());
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_Y_MAIN, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       ShowYGridMain () = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_Y_HELP, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*?*/       ShowYGridHelp () = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_Y_DESCR, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       ShowYDescr (((const SfxBoolItem*)pPoolItem)->GetValue());
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_Z_AXIS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       ShowZAxis (((const SfxBoolItem*)pPoolItem)->GetValue());
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_Z_MAIN, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*?*/       ShowZGridMain () = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_Z_HELP, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*?*/       ShowZGridHelp () = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_Z_DESCR, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       ShowZDescr (((const SfxBoolItem*)pPoolItem)->GetValue());
/*N*/
/*N*/
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_2Y_AXIS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/   {
/*N*/       BOOL b = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/       pChartBAxis->GetItemSet()->Put(SfxBoolItem(SCHATTR_AXIS_SHOWAXIS,b));
/*N*/   }
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_2Y_DESCR, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/   {
/*N*/       BOOL b = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/       pChartBAxis->GetItemSet()->Put(SfxBoolItem(SCHATTR_AXIS_SHOWDESCR,b));
/*N*/   }
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_2X_AXIS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/   {
/*N*/       BOOL b = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/       pChartAAxis->GetItemSet()->Put(SfxBoolItem(SCHATTR_AXIS_SHOWAXIS,b));
/*N*/   }
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_AXISGRID_SHOW_2X_DESCR, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/   {
/*N*/       BOOL b = ((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/       pChartAAxis->GetItemSet()->Put(SfxBoolItem(SCHATTR_AXIS_SHOWDESCR,b));
/*N*/   }
/*N*/
/*N*/
/*N*/
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_LEGEND_POS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       pLegendAttr->Put(SvxChartLegendPosItem
/*N*/           (((const SvxChartLegendPosItem*)pPoolItem)->GetValue(),
/*?*/            pItemPool->GetWhich(CHATTR_LEGEND_POS)));
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_DATA_SWITCH, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*?*/       ChangeSwitchData(((const SfxBoolItem*)pPoolItem)->GetValue());
/*N*/
/*N*/
/*N*/
/*N*/ //Statistik
/*N*/    if (rAttr.GetItemState(SCHATTR_STAT_CONSTPLUS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       fIndicatePlus=((const SvxDoubleItem*)pPoolItem)->GetValue();
/*N*/
/*N*/    if (rAttr.GetItemState(SCHATTR_STAT_BIGERROR, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       fIndicateBigError=((const SvxDoubleItem*)pPoolItem)->GetValue();
/*N*/
/*N*/    if (rAttr.GetItemState(SCHATTR_STAT_PERCENT, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       fIndicatePercent=((const SvxDoubleItem*)pPoolItem)->GetValue();
/*N*/
/*N*/    if (rAttr.GetItemState(SCHATTR_STAT_INDICATE, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*?*/       eIndicate=(SvxChartIndicate)((const SfxInt32Item*)pPoolItem)->GetValue();
/*N*/
/*N*/    if (rAttr.GetItemState(SCHATTR_STAT_KIND_ERROR, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       eErrorKind=(SvxChartKindError)((const SfxInt32Item*)pPoolItem)->GetValue();
/*N*/
/*N*/    if (rAttr.GetItemState(SCHATTR_STAT_AVERAGE, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       bShowAverage=((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/
/*N*/    if (rAttr.GetItemState(SCHATTR_STAT_CONSTMINUS, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       fIndicateMinus=((const SvxDoubleItem*)pPoolItem)->GetValue();
/*N*/    if (rAttr.GetItemState(SCHATTR_STAT_REGRESSTYPE, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       eRegression=(SvxChartRegress)((const SfxInt32Item*)pPoolItem)->GetValue();
/*N*/
/*N*/
/*N*/      //Datenbeschriftung
/*N*/      SvxChartDataDescr eNewDataDescr,eOldDataDescr;
/*N*/      BOOL bNewShowSym, bOldShowSym;
/*N*/
/*N*/      eNewDataDescr = eOldDataDescr = eDataDescr;
/*N*/      bNewShowSym = bOldShowSym = bShowSym;
/*N*/
/*N*/     if (rAttr.GetItemState(SCHATTR_DATADESCR_DESCR, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       eNewDataDescr=(SvxChartDataDescr)((const SvxChartDataDescrItem*)pPoolItem)->GetValue();
/*N*/
/*N*/     if (rAttr.GetItemState(SCHATTR_DATADESCR_SHOW_SYM, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/       bNewShowSym=((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/
/*N*/     if( bOldShowSym != bNewShowSym || eOldDataDescr != eNewDataDescr )
/*N*/     {
/*?*/         ChangeDataDescr(eNewDataDescr,bNewShowSym);
/*N*/     }
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_BARWIDTH, TRUE, &pPoolItem)
/*N*/               == SFX_ITEM_SET)
/*?*/       SetBarPercentWidth((long)((const SfxInt32Item*)pPoolItem)->GetValue());
/*N*/
/*N*/
/*N*/    if (rAttr.GetItemState(CHATTR_BARCONNECT, TRUE, &pPoolItem)
/*N*/                   == SFX_ITEM_SET)
/*N*/    {
/*N*/      BOOL bTmp=((const SfxBoolItem*)pPoolItem)->GetValue();
/*N*/      m_nDefaultColorSet=(bTmp)
/*N*/          ?(m_nDefaultColorSet|CHSPECIAL_TRACELINES)
/*N*/          :(m_nDefaultColorSet|CHSPECIAL_TRACELINES)-CHSPECIAL_TRACELINES;
/*N*/    }
/*N*/
/*N*/   if (rAttr.GetItemState(SCHATTR_STYLE_SHAPE, TRUE, &pPoolItem)== SFX_ITEM_SET)
/*N*/   {
/*N*/       long nTmp= (long)((const SfxInt32Item*)pPoolItem)->GetValue();
/*N*/       SfxItemSet aS(*pItemPool,SCHATTR_STYLE_SHAPE,SCHATTR_STYLE_SHAPE,0);
/*N*/       aS.Put(SfxInt32Item(SCHATTR_STYLE_SHAPE,nTmp));
/*N*/       PutDataRowAttrAll(aS);
/*N*/   }
/*N*/
/*N*/   // Autopilot mit CHATTR_
/*N*/   if (rAttr.GetItemState(CHATTR_STYLE_SHAPE, TRUE, &pPoolItem)== SFX_ITEM_SET)
/*N*/   {
/*?*/       long nTmp= (long)((const SfxInt32Item*)pPoolItem)->GetValue();
/*?*/       SfxItemSet aS(*pItemPool,SCHATTR_STYLE_SHAPE,SCHATTR_STYLE_SHAPE,0);
/*?*/       aS.Put(SfxInt32Item(SCHATTR_STYLE_SHAPE,nTmp));
/*?*/       PutDataRowAttrAll(aS);
/*N*/   }
/*N*/   if( rAttr.GetItemState(CHATTR_AXIS_AUTO_ORIGIN, TRUE, &pPoolItem) == SFX_ITEM_SET)
/*N*/   {
/*?*/       BOOL bTmp= (BOOL)((const SfxBoolItem*)pPoolItem)->GetValue();
/*?*/       SfxItemSet aS( *pItemPool, SCHATTR_AXIS_AUTO_ORIGIN, SCHATTR_AXIS_AUTO_ORIGIN);
/*?*/       aS.Put( SfxBoolItem( SCHATTR_AXIS_AUTO_ORIGIN, bTmp ));
/*?*/       if( pChartYAxis )
/*?*/       {
/*?*/           pChartYAxis->SetAttributes( aS );
/*?*/       }
/*?*/       if( pChartBAxis )
/*?*/       {
/*?*/           pChartBAxis->SetAttributes( aS );
/*?*/       }
/*N*/   }
/*N*/
/*N*/   ChartScene *pLclScene=GetScene();
/*N*/   if(pLclScene) //ToDo: Ist das hier nötig??? warum nicht direkt rAttr? #63904#
/*N*/   {
/*N*/       SfxItemSet aSceneSet(*pItemPool,nRowWhichPairs);
/*N*/       aSceneSet.Put(rAttr);
/*N*/
/*N*/       pLclScene->SetItemSet(aSceneSet);
/*N*/
/*N*/   }
/*N*/
/*N*/     if( rAttr.GetItemState( SCHATTR_USER_DEFINED_ATTR, TRUE, &pPoolItem ) == SFX_ITEM_SET )
/*N*/     {
/*?*/         pChartAttr->Put( *pPoolItem );
/*N*/     }
/*N*/
/*N*/
/*N*/   if (rAttr.GetItemState(CHATTR_DIAGRAM_STYLE, TRUE, &pPoolItem)
/*N*/               == SFX_ITEM_SET)
/*?*/       ChangeChart( ((const SvxChartStyleItem*)pPoolItem)->GetValue());
/*N*/ }

/*N*/ long ChartModel::GetAxisUID(long nRow)
/*N*/ {
/*N*/   return ((const SfxInt32Item &)GetDataRowAttr(nRow).Get(SCHATTR_AXIS)).GetValue();
/*N*/ };


/*************************************************************************
|*
|* gesamte Grafik initialisieren
|*
\************************************************************************/

/*N*/ void ChartModel::Initialize()
/*N*/ {
/*N*/   mbIsInitialized = TRUE;
/*N*/
/*N*/   if (!(aInitialSize.Height () && aInitialSize.Width ()))
/*N*/   {
/*?*/       SdrPage* pPage = GetPage(0);
/*?*/       if (pPage) aInitialSize = pPage->GetSize();
/*?*/
/*?*/       if (!(aInitialSize.Height () && aInitialSize.Width ())) aInitialSize = Size (7000, 8000);
/*?*/ //        13000, 8666
/*N*/   }
/*N*/
/*N*/   ScaleText( 0, aInitialSize );
/*N*/
/*N*/   if( bShouldBuildChart )
/*N*/   {
/*N*/       //  Force build chart.  If it has been loaded from an XML file, than that is
/*N*/       //  done by unlocking it.
/*N*/       bNoBuildChart = FALSE;
/*N*/
/*N*/       if( pDocShell &&
/*N*/           pDocShell->IsEnableSetModified())
/*N*/       {
/*?*/           pDocShell->EnableSetModified( FALSE );
/*?*/           if (IsLockedBuild())
/*?*/               UnlockBuild();
/*?*/           else
/*?*/               BuildChart( FALSE );
/*?*/           pDocShell->EnableSetModified( TRUE );
/*N*/       }
/*N*/       else
/*N*/           if (IsLockedBuild())
/*?*/               UnlockBuild();
/*N*/           else
/*N*/               BuildChart( FALSE );
/*N*/   }
/*N*/
/*N*/   SetDiagramRectangle( GetChartRect() );
/*N*/ }


/*************************************************************************
|*
|* Sub-Methode von BuildChart()
|*
\************************************************************************/
/*N*/ void ChartModel::ScaleText( long nTitle, const Size& rPageSize )
/*N*/ {
/*N*/   // #67459#
/*N*/   // if the page size is unchanged ...
/*N*/   if( aInitialSize == rPageSize )
/*N*/   {
/*N*/       // ... and the diagram (possibly) has been resized
/*N*/       if( GetDiagramHasBeenMovedOrResized() && (aLastDiagramRectangle != aDiagramRectangle) )
/*N*/       {
/*?*/           if( nTitle != CHOBJID_DIAGRAM_X_AXIS )
/*?*/               ResizeText( &GetAttr(CHOBJID_DIAGRAM_X_AXIS), rPageSize, FALSE );
/*?*/           if( nTitle != CHOBJID_DIAGRAM_Y_AXIS )
/*?*/               ResizeText( &GetAttr(CHOBJID_DIAGRAM_Y_AXIS), rPageSize, FALSE );
/*?*/           if( nTitle != CHOBJID_DIAGRAM_A_AXIS )
/*?*/               ResizeText( &GetAttr(CHOBJID_DIAGRAM_A_AXIS), rPageSize, FALSE );
/*?*/           if( nTitle != CHOBJID_DIAGRAM_B_AXIS )
/*?*/               ResizeText( &GetAttr(CHOBJID_DIAGRAM_B_AXIS), rPageSize, FALSE );
/*?*/           if( nTitle != CHOBJID_DIAGRAM_Z_AXIS )
/*?*/               ResizeText( &GetAttr(CHOBJID_DIAGRAM_Z_AXIS), rPageSize, FALSE );
/*?*/
/*?*/           for( size_t i = 0; i < aDataRowAttrList.size(); i++ )
/*?*/               ResizeText( aDataRowAttrList[ i ], rPageSize, FALSE );
/*?*/           ResizeText(pDummyAttr,rPageSize);   // also resize crash test dummy to normal for next test ?
/*N*/       }
/*N*/   }
/*N*/   else    // page size has changed
/*N*/   {
/*N*/       if(nTitle != CHOBJID_TITLE_MAIN)
/*N*/           ResizeText (pMainTitleAttr ,rPageSize);
/*N*/       if(nTitle != CHOBJID_TITLE_SUB)
/*N*/           ResizeText (pSubTitleAttr  ,rPageSize);
/*N*/       if(nTitle != CHOBJID_DIAGRAM_TITLE_X_AXIS)
/*N*/           ResizeText (pXAxisTitleAttr,rPageSize);
/*N*/       if(nTitle != CHOBJID_DIAGRAM_TITLE_Y_AXIS)
/*N*/           ResizeText (pYAxisTitleAttr,rPageSize);
/*N*/       if(nTitle != CHOBJID_DIAGRAM_TITLE_Z_AXIS)
/*N*/           ResizeText (pZAxisTitleAttr,rPageSize);
/*N*/
/*N*/       if(nTitle != CHOBJID_DIAGRAM_X_AXIS)
/*N*/           ResizeText(&GetAttr(CHOBJID_DIAGRAM_X_AXIS),rPageSize);
/*N*/       if(nTitle != CHOBJID_DIAGRAM_Y_AXIS)
/*N*/           ResizeText(&GetAttr(CHOBJID_DIAGRAM_Y_AXIS),rPageSize);
/*N*/       if(nTitle != CHOBJID_DIAGRAM_A_AXIS)
/*N*/           ResizeText(&GetAttr(CHOBJID_DIAGRAM_A_AXIS),rPageSize);
/*N*/       if(nTitle != CHOBJID_DIAGRAM_B_AXIS)
/*N*/           ResizeText(&GetAttr(CHOBJID_DIAGRAM_B_AXIS),rPageSize);
/*N*/       if(nTitle != CHOBJID_DIAGRAM_Z_AXIS)
/*N*/           ResizeText(&GetAttr(CHOBJID_DIAGRAM_Z_AXIS),rPageSize);
/*N*/       if(nTitle != CHOBJID_LEGEND)
/*N*/           ResizeText(pLegendAttr, rPageSize);
/*N*/       for( size_t i = 0; i < aDataRowAttrList.size(); i++ )
/*N*/           ResizeText( aDataRowAttrList[ i ], rPageSize );
/*N*/       ResizeText(pDummyAttr,rPageSize);   // also resize crash test dummy to normal for next test ?
/*N*/   }
/*N*/ }

Point ChartModel::calcRelativePosition( const Point& rStartPoint, const Size& rInitialSize, const Size& rNewSize )
{
    Point aRet( rStartPoint );
    double fX_Denominator = rInitialSize.Width();
    double fY_Denominator = rInitialSize.Height();
    if( fX_Denominator != 0.0 && fY_Denominator != 0.0 )
    {
        double fRelativXPosition = rStartPoint.X() / fX_Denominator;
        double fRelativYPosition = rStartPoint.Y() / fY_Denominator;
        aRet.X() = static_cast<long>( rNewSize.Width()  * fRelativXPosition );
        aRet.Y() = static_cast<long>( rNewSize.Height() * fRelativYPosition );
    }
    return aRet;
}

/*************************************************************************
|*
|* Sub-Methode von BuildChart(), Anzeige des Haupttitels
|*
\************************************************************************/
/*N*/ void ChartModel::DoShowMainTitle(USHORT& rIndex,const long nYOfs)
/*N*/ {
/*N*/   SdrPage* pPage=GetPage(0);
/*N*/   const Size& rPageSize=pPage->GetSize();
/*N*/
/*N*/   Point aTitlePosition;
/*N*/   if (bUseRelativePositionsForChartGroups && (aTitleTopCenter.X() >= 0) &&
/*N*/      (aTitleTopCenter.Y() >= 0) && GetMainTitleHasBeenMoved())
/*N*/   {
/*N*/ 	    aTitlePosition = calcRelativePosition( aTitleTopCenter, aInitialSize, rPageSize );
/*N*/   }
/*N*/   else
/*N*/   {
/*N*/       aTitlePosition.X() = aChartRect.Left() + aChartRect.GetWidth() / 2;
/*N*/       aTitlePosition.Y() = aChartRect.Top();
/*N*/   }
/*N*/
/*N*/   SdrTextObj *pObj = CreateTextObj(CHOBJID_TITLE_MAIN, aTitlePosition,
/*N*/                                    aMainTitle,
/*N*/                                    *pMainTitleAttr, TRUE, CHADJUST_TOP_CENTER);
/*N*/
/*N*/   aChartRect.Top() += GetOutputSize(*pObj).Height() + nYOfs;
/*N*/   pObj->SetResizeProtect(TRUE);
/*N*/   pPage->NbcInsertObject(pObj, rIndex++);
/*N*/ }
/*************************************************************************
|*
|* Sub-Methode von BuildChart(), man koennte vermutlich DoShowMainTitle und
|* DoShowSubTitle zu DoShowTitle zusammenfassen
|*
\************************************************************************/
/*N*/ void ChartModel::DoShowSubTitle(USHORT& rIndex,const long nYOfs)
/*N*/ {
/*N*/   SdrPage* pPage=GetPage(0);
/*N*/   const Size& rPageSize=pPage->GetSize();
/*N*/
/*N*/   Point aSubTitlePosition;
/*N*/   if (bUseRelativePositionsForChartGroups && (aSubTitleTopCenter.X() >= 0) &&
/*N*/     (aSubTitleTopCenter.Y() >= 0) && GetSubTitleHasBeenMoved())
/*N*/   {
/*N*/ 	    aSubTitlePosition = calcRelativePosition( aSubTitleTopCenter, aInitialSize, rPageSize );
/*N*/   }
/*N*/   else
/*N*/   {
/*N*/      aSubTitlePosition.X() = aChartRect.Left() + aChartRect.GetWidth() / 2;
/*N*/      aSubTitlePosition.Y() = aChartRect.Top();
/*N*/   }
/*N*/   SdrTextObj *pObj = CreateTextObj(CHOBJID_TITLE_SUB, aSubTitlePosition,
/*N*/                                   aSubTitle,
/*N*/                                   *pSubTitleAttr, TRUE, CHADJUST_TOP_CENTER);
/*N*/
/*N*/   aChartRect.Top() += GetOutputSize(*pObj).Height() + nYOfs;
/*N*/   pObj->SetResizeProtect(TRUE);
/*N*/   pPage->NbcInsertObject(pObj, rIndex++);
/*N*/ }

/*************************************************************************
|*
|* Sub-Methode von BuildChart(), Anzeige der Legende
|*
\************************************************************************/
/*N*/ void ChartModel::DoShowLegend(const Rectangle& rWholeRect,
/*N*/                             const long nXOfs,const long nYOfs,USHORT& rIndex)
/*N*/ {
/*N*/   SdrPage* pPage=GetPage(0);
/*N*/   const Size& rPageSize=pPage->GetSize();
/*N*/
/*N*/   SvxChartLegendPos eLegendPos = ((const SvxChartLegendPosItem&) pLegendAttr->Get(SCHATTR_LEGEND_POS)).
/*N*/                              GetValue();
/*N*/
/*N*/   if (eLegendPos != CHLEGEND_NONE)
/*N*/   {
/*N*/       SdrObject   *pObj = CreateLegend(rWholeRect);
/*N*/
/*N*/       if (pObj)
/*N*/       {
/*N*/           Rectangle   aRect = pObj->GetLogicRect();
/*N*/           ChartAdjust eAdjust(CHADJUST_TOP_LEFT);
/*N*/
/*N*/           Point aLegendPosition;
/*N*/           if (bUseRelativePositionsForChartGroups && (aLegendTopLeft.X() >= 0) &&
/*N*/              (aLegendTopLeft.Y() >= 0) && GetLegendHasBeenMoved())
/*N*/           {
/*N*/ 				aLegendPosition = calcRelativePosition( aLegendTopLeft, aInitialSize, rPageSize );
/*N*/
/*N*/               if( bAdjustMarginsForLegend )
/*N*/               {
/*N*/                   switch (eLegendPos)
/*N*/                   {
/*N*/                       case CHLEGEND_LEFT:
/*?*/                           eAdjust = CHADJUST_TOP_LEFT;
/*?*/                           aChartRect.Left() += aRect.GetWidth() + nXOfs;
/*?*/                           break;
/*?*/
/*?*/                       case CHLEGEND_TOP:
/*?*/                           eAdjust = CHADJUST_TOP_LEFT;
/*?*/                           aChartRect.Top() += aRect.GetHeight() + nYOfs;
/*?*/                           break;
/*N*/
/*N*/                       case CHLEGEND_RIGHT:
/*N*/                           eAdjust = CHADJUST_TOP_LEFT;
/*N*/                           aChartRect.Right() -= aRect.GetWidth() + nXOfs;
/*N*/                           break;
/*N*/
/*?*/                       case CHLEGEND_BOTTOM:
/*?*/                           eAdjust = CHADJUST_TOP_LEFT;
/*?*/                           aChartRect.Bottom() -= aRect.GetHeight() + nYOfs;
/*?*/                           break;
/*?*/                       default:
/*?*/                           break;
/*N*/                   }
/*N*/               }
/*N*/                 // #96418# why shifting the legend nXOfs/nYOfs away from the
/*N*/                 // edge, if it moved manually; it may well reach the edge in
/*N*/                 // that case.  So just check if it laps out of the edge.  Apart
/*N*/                 // from that the default position did not satisfy this condition
/*N*/                 // and was therefore always shifted inside
/*N*/               if (aLegendPosition.X() + aRect.GetWidth() > rPageSize.Width())
/*N*/               {
/*?*/                   aLegendPosition.X() =  rPageSize.Width() - aRect.GetWidth();
/*N*/               }
/*N*/               if (aLegendPosition.Y() + aRect.GetHeight() > rPageSize.Height())
/*N*/               {
/*?*/                   aLegendPosition.Y() =  rPageSize.Height() - aRect.GetHeight();
/*N*/               }
/*N*/             }
/*N*/           else
/*N*/           {
/*N*/               switch (eLegendPos)
/*N*/               {
/*N*/                   case CHLEGEND_LEFT:
/*?*/                       aLegendPosition.X() = rWholeRect.Left();
/*?*/                       aLegendPosition.Y() = rWholeRect.Top() + rWholeRect.GetHeight() / 2;
/*?*/                       eAdjust = CHADJUST_CENTER_LEFT;
/*?*/                       aChartRect.Left() += aRect.GetWidth() + nXOfs;
/*?*/                       break;
/*?*/
/*?*/                   case CHLEGEND_TOP:
/*?*/                       aLegendPosition.X() = rWholeRect.Left() + rWholeRect.GetWidth() / 2;
/*?*/                       aLegendPosition.Y() = aChartRect.Top();
/*?*/                       eAdjust = CHADJUST_TOP_CENTER;
/*?*/                       aChartRect.Top() += aRect.GetHeight() + nYOfs;
/*?*/                       break;
/*N*/
/*N*/                   case CHLEGEND_RIGHT:
/*N*/                       aLegendPosition.X() = rWholeRect.Right();
/*N*/                       aLegendPosition.Y() = rWholeRect.Top() + rWholeRect.GetHeight() / 2;
/*N*/                       eAdjust = CHADJUST_CENTER_RIGHT;
/*N*/                       aChartRect.Right() -= aRect.GetWidth() + nXOfs;
/*N*/                       break;
/*N*/
/*N*/                   case CHLEGEND_BOTTOM:
/*?*/                       aLegendPosition.X() = rWholeRect.Left() + rWholeRect.GetWidth() / 2;
/*?*/                       aLegendPosition.Y() = rWholeRect.Bottom();
/*?*/                       eAdjust = CHADJUST_BOTTOM_CENTER;
/*?*/                       aChartRect.Bottom() -= aRect.GetHeight() + nYOfs;
/*?*/                       break;
/*N*/                   default:
/*?*/                       break;
/*N*/               }
/*N*/           }
/*N*/
/*N*/           //  For 3D pie charts that whose position and size have not been altered
/*N*/           //  manually, the calculated size in aChartRect is
/*N*/           //  set to aDiagramRectangle after a possible adaption to half
/*N*/           //  it's height.  This adaption mimics the behaviour from BuildChart
/*N*/           //  and takes place only if the diagram is not more than twice as wide
/*N*/           //  as it is high.
/*N*/           if (IsPieChart() && IsReal3D() && ! GetDiagramHasBeenMovedOrResized())
/*N*/           {
/*N*/               long nWidth=aChartRect.GetWidth();
/*N*/               long nHeight=aChartRect.GetHeight();
/*N*/               if( ((double)nHeight/(double)nWidth) > 0.5 )
/*N*/               {
/*N*/                   aChartRect.Top()+=nHeight/4;
/*N*/                   aChartRect.Bottom()-=nHeight/4;
/*N*/               }
/*N*/               SetDiagramRectangle (aChartRect);
/*N*/           }
/*N*/
/*N*/           aRect.SetPos(aLegendPosition);
/*N*/           AdjustRect(aRect, eAdjust);
/*N*/           pObj->NbcSetLogicRect(aRect);
/*N*/           pObj->SetResizeProtect(TRUE);
/*N*/           if (pObj->ISA(SchObjGroup))
/*N*/           {
/*N*/               ((SchObjGroup *)pObj)->SetGroupType(SchObjGroup::LEGEND);
/*N*/               ((SchObjGroup *)pObj)->SetModel(this);
/*N*/           }
/*N*/           pPage->InsertObject(pObj, rIndex);
/*N*/       }
/*N*/   }
/*N*/ }

//Übertragung der Page-Objekt-Attribute in die Modeleigenen AttrSets
/*N*/ void ChartModel::Rescue3DObjAttr(SdrObjList* pList)//#52277#
/*N*/ {
/*N*/   CHART_TRACE( "ChartModel::Rescue3DObjAttr" );
/*N*/   if(pList)
/*N*/   {
/*N*/       SdrObject* pObj;
/*N*/       long nRow, nCol;
/*N*/       SfxItemSet aSet( *pItemPool, SDRATTR_3D_FIRST, SDRATTR_3D_LAST);
/*N*/       aSet.ClearItem();
/*N*/
/*N*/       SdrObjListIter aIterator( *pList, IM_DEEPWITHGROUPS );
/*N*/
/*N*/       while( aIterator.IsMore() )
/*N*/       {
/*N*/           pObj = aIterator.Next();
/*N*/           SchDataRow*     pDataRow   = GetDataRow( *pObj );
/*N*/           SchDataPoint*   pDataPoint = GetDataPoint( *pObj );
/*N*/           if( pDataRow )
/*N*/           {
/*N*/               nRow = pDataRow->GetRow();
/*N*/               aSet.Put(pObj->GetItemSet());
/*N*/
/*N*/               aSet.ClearInvalidItems();
                    SfxItemSet* pItemSet = aDataRowAttrList[ nRow ];
                    if(pItemSet)
/*N*/ 				    pItemSet->Put( aSet );
/*N*/               aSet.ClearItem();
/*N*/           }
/*N*/           else if( pDataPoint )
/*N*/           {
/*N*/               nCol = pDataPoint->GetCol();
/*N*/               nRow = pDataPoint->GetRow();
/*N*/               aSet.Put(pObj->GetItemSet());
/*N*/
/*N*/               aSet.ClearInvalidItems();
/*N*/               PutDataPointAttr( nCol, nRow, aSet );
/*N*/               aSet.ClearItem();
/*N*/           }
/*N*/           else
/*N*/           {
/*N*/               SchObjectId *pId = GetObjectId( *pObj );
/*N*/               if( pId )
/*N*/               {
/*N*/                   long nId = pId->GetObjId();
/*N*/                   aSet.Put(pObj->GetItemSet());
/*N*/                   if( aSet.Count() )
/*N*/                   {
/*N*/                       aSet.ClearInvalidItems();
/*N*/                       GetAttr( nId ).Put( aSet, TRUE );
/*N*/                       aSet.ClearItem();
/*N*/                   }
/*N*/               }
/*N*/           }
/*N*/       }
/*N*/   }
/*N*/ }

/*************************************************************************
|*
|* Sub-Methode von BuildChart(), Loeschen aller Chartobjecte
|*
\************************************************************************/
/*N*/ void ChartModel::DeleteChartObjects()
/*N*/ {
/*N*/   SdrPage* pPage=GetPage(0);
/*N*/   /*BOOL bResize = (aInitialSize != */pPage->GetSize()/*)*/;
/*N*/
/*N*/   // FG: Bevor die Objekte geloescht und neu aufgebaut werden, merkt man sich deren
/*N*/   //     Position. Da in InitalSize die urspruengliche Seitengroesse steht, kann
/*N*/   //     man nun die relative Position auf der Seite bestimmen.
/*N*/   //     Diese relative Position bleibt bei einem Resize erhalten,
/*N*/   //     falls der  Schalter "bUseRelativePositionsForChartGroups" auf TRUE steht.
/*N*/
/*N*/   SdrObject* pGroupObject = GetObjWithId( CHOBJID_DIAGRAM_AREA, *pPage );
/*N*/   if( pGroupObject != NULL )
/*N*/       DeleteObject( pGroupObject );
/*N*/
/*N*/   pGroupObject = GetObjWithId( CHOBJID_TITLE_MAIN, *pPage );
/*N*/   if (pGroupObject != NULL)
/*N*/   {
/*N*/       aTitleTopCenter = pGroupObject->GetBoundRect().TopCenter();
/*N*/       DeleteObject(pGroupObject);
/*N*/   }
/*N*/
/*N*/   pGroupObject = GetObjWithId(CHOBJID_TITLE_SUB, *pPage);
/*N*/   if (pGroupObject != NULL)
/*N*/   {
/*N*/       aSubTitleTopCenter = pGroupObject->GetBoundRect().TopCenter();
/*N*/       DeleteObject(pGroupObject);
/*N*/   }
/*N*/
/*N*/   pGroupObject = GetObjWithId(CHOBJID_DIAGRAM, *pPage);
/*N*/   if (pGroupObject != NULL)
/*N*/   {
/*N*/       // FG: 11.3.97 Wenn die Grenzen des Objekts woanders gesetzt worden sind, duerfen sie hier
/*N*/       //             nicht mehr gesetzt werden.
/*N*/       if (pGroupObject->ISA(SchObjGroup))
/*N*/       {
/*N*/           if (GetDiagramHasBeenMovedOrResized() &&
/*N*/              ((SchObjGroup *) pGroupObject)->GetAskForLogicRect())
/*N*/           {
/*N*/               // FG: So leider nicht das Chart-Rect ist fehlerhafterweise nicht das Bounding-Rectangle
/*N*/               // aDiagramRectangle = pGroupObject->GetLogicRect();
/*N*/               SetDiagramRectangle( GetChartRect() );
/*N*/           }
/*N*/       }
/*N*/       else if (pGroupObject->ISA(ChartScene))
/*N*/       {
/*N*/           if (GetDiagramHasBeenMovedOrResized() &&
/*N*/              ((ChartScene *) pGroupObject)->GetAskForLogicRect())
/*N*/           {
/*N*/               // FG: So leider nicht das Chart-Rect ist fehlerhafterweise nicht das Bounding-Rectangle
/*N*/               // aDiagramRectangle = pGroupObject->GetLogicRect();
/*N*/               SetDiagramRectangle( GetChartRect() );
/*N*/           }
/*N*/
/*N*/
/*N*/           if( pGroupObject == pScene )
/*N*/               pScene = NULL;
/*N*/       }
/*N*/       DeleteObject(pGroupObject);
/*N*/   }
/*N*/
/*N*/   pGroupObject = GetObjWithId(CHOBJID_LEGEND, *pPage);
/*N*/   if (pGroupObject != NULL)
/*N*/   {
/*N*/       // FG: 11.3.97 Wenn die Grenzen des Objekts woanders gesetzt worden sind, duerfen sie hier
/*N*/       //             nicht mehr gesetzt werden.
/*N*/       if (GetLegendHasBeenMoved()&&
/*N*/             ((SchObjGroup *) pGroupObject)->GetAskForLogicRect() )
/*N*/             // #107305# I don't see where aLegendTopLeft should have changed at
/*N*/             // another place, if not via resizing.  Besides, why should it for
/*N*/             // the legend and not the titles?
/*N*/ //             && ! bResize )
/*N*/       {
/*N*/               aLegendTopLeft = pGroupObject->GetLogicRect().TopLeft();
/*N*/       }
/*N*/       DeleteObject(pGroupObject);
/*N*/   }
/*N*/
/*N*/
/*N*/
/*N*/   pGroupObject = GetObjWithId(CHOBJID_DIAGRAM_TITLE_X_AXIS, *pPage);
/*N*/   if (pGroupObject != NULL)
/*N*/   {
/*N*/       aTitleXAxisPosition = SetPointOfRectangle(pGroupObject->GetBoundRect(), eAdjustXAxesTitle);
/*N*/       DeleteObject(pGroupObject);
/*N*/   }
/*N*/
/*N*/   pGroupObject = GetObjWithId(CHOBJID_DIAGRAM_TITLE_Y_AXIS, *pPage);
/*N*/   if (pGroupObject != NULL)
/*N*/   {
/*N*/       pGroupObject->GetBoundRect();
/*N*/       pGroupObject->GetSnapRect();
/*N*/       aTitleYAxisPosition = SetPointOfRectangle(pGroupObject->GetBoundRect(), eAdjustYAxesTitle);
/*N*/       DeleteObject(pGroupObject);
/*N*/   }
/*N*/
/*N*/   pGroupObject = GetObjWithId(CHOBJID_DIAGRAM_TITLE_Z_AXIS, *pPage);
/*N*/   if (pGroupObject != NULL)
/*N*/   {
/*N*/       aTitleZAxisPosition = SetPointOfRectangle(pGroupObject->GetBoundRect(), eAdjustXAxesTitle);
/*N*/       DeleteObject(pGroupObject);
/*N*/   }
/*N*/ }
/*************************************************************************
|*
|* Sub-Methode von BuildChart(), Wertebereichueberpruefung mit MsgBox
|*
\************************************************************************/
/*N*/ BOOL ChartModel::CheckRanges(BOOL bCheckAlways)
/*N*/ {
/*N*/   //ToDo:CHOBJID_DIAGRAM_B_AXIS
/*N*/   BOOL bOK=TRUE;
/*N*/   if ((eChartStyle != eOldChartStyle) || (bCheckAlways))
/*N*/   {
/*N*/       if ((pChartYAxis->GetMin() < 0.0) && (pChartYAxis->GetMax() > 0.0) && (!IsSignedChart()))
/*N*/       {
/*?*/           // FG: Falls ein Pointer auf ein Fenster uebergeben wird ist die Dialogbox nicht-modal
/*?*/           //     Nutzt man dies fuer Veraenderungen am Chart aus, stuertzt das Programm ab.
/*?*/           // InfoBox aInfoBox(SFX_APP()->GetAppWindow(), String(SchResId(STR_ONLY_ABS_VALUES)));
/*?*/           InfoBox aInfoBox(NULL, SchResId(STR_ONLY_ABS_VALUES).toString());
/*?*/           aInfoBox.Execute();
/*?*/           eOldChartStyle = eChartStyle;
/*?*/           bOK=FALSE;
/*N*/       }
/*N*/       else if ((pChartYAxis->GetMin() < 0.0) && (!IsNegativeChart ()))
/*N*/           {
/*N*/               // FG: Falls ein Pointer auf ein Fenster uebergeben wird ist die Dialogbox nicht-modal
/*N*/               //     Nutzt man dies fuer Veraenderungen am Chart aus, stuertzt das Programm ab.
/*N*/               // InfoBox aInfoBox(SFX_APP()->GetAppWindow(), String(SchResId(STR_NO_MIN_VALUES)));
/*?*/               InfoBox aInfoBox(NULL, SchResId(STR_NO_MIN_VALUES).toString());
/*?*/               aInfoBox.Execute();
/*?*/               eOldChartStyle = eChartStyle;
/*?*/               bOK=FALSE;
/*N*/           }
/*N*/   }
/*N*/   return bOK;
/*N*/ }
/*************************************************************************
|*
|* Sub-Methode von BuildChart(), Chart-ReSizing
|*
\************************************************************************/
/*N*/ void ChartModel::ResizeChart(const Size& rPageSize)
/*N*/ {
/*N*/   if (GetUseRelativePositions() && GetDiagramHasBeenMovedOrResized())
/*N*/   {
/*N*/       if ((rPageSize.Width() == aInitialSize.Width()) && (rPageSize.Height() == aInitialSize.Height()))
/*N*/       {  // Es war also ein Resize nur des Diagramms (also nur der Grafik und nicht der Seite)
/*N*/           aChartRect= aDiagramRectangle;
/*N*/       }
/*N*/       else  // Dann war es ein Resize des gesamten Charts
/*N*/       {
            //  The whole chart has been resized.
            //  The old size aDiagramRectangle of the diagram has to fullfill the constraint
            //  the it has to have a positive extent both in the horizontal and the vertical
            //  direction.
            //
            //  Previously the constraints to fullfill have been tighter:
            //  All four border lines had to lie inside the chart rectangle.
                double fFactorX = 1.0;
                double fFactorY = 1.0;
                double fX_Denominator = aInitialSize.Width();
                double fY_Denominator = aInitialSize.Height();
                if( fX_Denominator != 0.0 && fY_Denominator != 0.0 )
                {
                    fFactorX = rPageSize.Width() / fX_Denominator;
                    fFactorY = rPageSize.Height() / fY_Denominator;
                }

/*N*/           if (    (aDiagramRectangle.nLeft < aDiagramRectangle.nRight)
/*N*/               &&  (aDiagramRectangle.nTop < aDiagramRectangle.nBottom) )
/*N*/           {
/*?*/ 					aChartRect.nLeft = static_cast<long>( aDiagramRectangle.Left() * fFactorX );
/*?*/ 					aChartRect.nTop =  static_cast<long>( aDiagramRectangle.Top()  * fFactorY );
/*?*/ 					aChartRect.nRight = static_cast<long>( aDiagramRectangle.Right() *  fFactorX );
/*?*/ 					aChartRect.nBottom = static_cast<long>( aDiagramRectangle.Bottom() * fFactorY );
/*?*/           }
/*N*/       }
/*N*/   }
/*N*/
/*N*/ }
/*************************************************************************
|*
|* Sub-Methode von BuildChart(),
|*
|* FG: Hier wird der Platz berechnet, den man als oberen Rand freilassen
|*     soll,falls keine Titel dargestellt werden.
|*
\************************************************************************/
/*N*/ void ChartModel::CalculateUpperBorder()
/*N*/ {
/*N*/   if ((!bShowMainTitle && !bShowSubTitle))
/*N*/   {
/*N*/       BOOL bSwitchColRow = eChartStyle == CHSTYLE_2D_BAR ||
/*N*/                            eChartStyle == CHSTYLE_2D_STACKEDBAR ||
/*N*/                            eChartStyle == CHSTYLE_2D_PERCENTBAR ||
/*N*/                            eChartStyle == CHSTYLE_3D_BAR ||
/*N*/                            eChartStyle == CHSTYLE_3D_FLATBAR ||
/*N*/                            eChartStyle == CHSTYLE_3D_STACKEDFLATBAR ||
/*N*/                            eChartStyle == CHSTYLE_3D_PERCENTFLATBAR;
/*N*/
/*N*/       SfxItemSet aTextAttr((const SfxItemSet &)GetAttr(
/*N*/                   bSwitchColRow ?
/*N*/                       CHOBJID_DIAGRAM_X_AXIS
/*N*/                     : CHOBJID_DIAGRAM_Y_AXIS));
/*N*/
/*N*/       Size aTextSize (((SvxFontWidthItem &) aTextAttr.Get (EE_CHAR_FONTWIDTH)).GetWidth (),
/*N*/                       ((SvxFontHeightItem &) aTextAttr.Get (EE_CHAR_FONTHEIGHT)).GetHeight ());
/*N*/
/*N*/       aChartRect.Top () += aTextSize.Height () / 2;
/*N*/   }
/*N*/ }
/*************************************************************************
|*
|* Sub-Methode von BuildChart(), Chart-ReSizing
|*
\************************************************************************/
/*N*/ void ChartModel::CreateRectsAndTitles(long whatTitle)
/*N*/ {
/*N*/       // FG: Abhaengig von der Groesse der Page, also der Ausgabe
/*N*/       // werden die Raender erst mal auf 2% der jeweiligen Richtungsausdehnung gesetzt
/*N*/       // abgespeichert wird das im ChartModel. Sollte ein Text uber den  den linken
/*N*/       // Rand zu weit hinausragen, also linker Rand OuterRect(SdrTextObj) < 0,
/*N*/       // So wird entweder der Offset neu berechnet oder der Text veraendert.
/*N*/       // Im Moment ist es nur moeglich den linken Rand nachzuregeln.
/*N*/       SdrPage* pPage=GetPage(0);
/*N*/       const Size& rPageSize=pPage->GetSize();
/*N*/
/*N*/       long nYOfs = (rPageSize.Height() / 100) * 2;
/*N*/       long nXOfs = (rPageSize.Width() /100) * 2;
/*N*/       USHORT nIndex = 0;
/*N*/
/*N*/         // #97159# the chart rect was set one unit too large in either direction
/*N*/         aChartRect.SetPos( Point( 0, 0 ) );
/*N*/         aChartRect.SetSize( rPageSize );
/*N*/
/*N*/       SchRectObj* pRect = new SchRectObj(aChartRect);
/*N*/       pRect->SetModel( this );
/*N*/       pPage->InsertObject(SetObjectAttr( pRect, CHOBJID_DIAGRAM_AREA,
/*N*/                                             FALSE, TRUE, pDiagramAreaAttr), nIndex++);
/*N*/
/*N*/       aChartRect.Left()   += nXOfs;  // FG: Dies ist das Rechteck in das das Chart (also die Balken ...)
/*N*/       aChartRect.Top()    += nYOfs;  //     rein muss. Erst ist es maximal gross und dann wird immer
/*N*/       aChartRect.Right()  -= nXOfs;  //     mehr abgezwackt.
/*N*/       aChartRect.Bottom() -= nYOfs;
/*N*/
/*N*/       Rectangle aWholeRect (aChartRect);
/*N*/
/*N*/           // Falls aInitialSize Null ist dann wird es auf die Seitengroesse gesetzt
/*N*/       if( !aInitialSize.Width ()) aInitialSize.Width () = rPageSize.Width ();
/*N*/       if( !aInitialSize.Height ()) aInitialSize.Height () = rPageSize.Height ();
/*N*/
/*N*/           // FG: Dieser Offset wird bei der Legende und den Diagrammtiteln gebraucht.
/*N*/           // Er wird aus aesthetischen Gruenden verdoppelt.
/*N*/           // Also ab jetzt oberer Rand nYOfs + Titel + 2*nYOfs + Unteritel + 2*nYOfs + Diagramm
/*N*/           // Fuer die Legende gilt das fuer den X-Abstand.
/*N*/       nXOfs *= 2; nYOfs *=2;
/*N*/
/*N*/      if (bTextScalable)
/*N*/         ScaleText(whatTitle,rPageSize);
/*N*/
/*N*/      if (bShowMainTitle)
/*N*/          DoShowMainTitle(nIndex,nYOfs);
/*N*/
/*N*/      if (bShowSubTitle)
/*N*/          DoShowSubTitle(nIndex,nYOfs);
/*N*/
/*N*/       CalculateUpperBorder();
/*N*/       DoShowLegend(aWholeRect,nXOfs,nYOfs,nIndex);
/*N*/       ResizeChart(rPageSize);
/*N*/ }
/*************************************************************************
|*
|* gesamte Grafik erzeugen
|*
\************************************************************************/

namespace
{
class lcl_MapModeResetGuard
{
public:
    lcl_MapModeResetGuard( OutputDevice * pOutDev ) :
            m_pOutDev( pOutDev ),
            m_aMapMode( pOutDev ? pOutDev->GetMapMode() : MapMode() )
    {}

    ~lcl_MapModeResetGuard()
    {
        if( m_pOutDev )
            m_pOutDev->SetMapMode( m_aMapMode );
    }

private:
    OutputDevice *   m_pOutDev;
    MapMode          m_aMapMode;
};

}

/*N*/ void ChartModel::BuildChart(BOOL bCheckRanges,long whatTitle)
/*N*/ {
/*N*/   RTL_LOGFILE_CONTEXT_AUTHOR (context, "sch", "af119097", "::ChartModel::BuildChart");
/*N*/
/*N*/ #ifdef DBG_UTIL
/*N*/   rtl::OString aBStr(rtl::OUStringToOString(aMainTitle, RTL_TEXTENCODING_ASCII_US));
/*N*/   CHART_TRACE1( "ChartModel::BuildChart (%s)", aBStr.getStr());
/*N*/ #endif
/*N*/
/*N*/   //kein setzen der p*Attr durch die Objekte
/*N*/   SetAttrAutoStorage(FALSE);
/*N*/
/*N*/   if (bNoBuildChart)
/*N*/   {
/*N*/       bShouldBuildChart = TRUE;
/*N*/   }
/*N*/   else
/*N*/   {
/*N*/       RTL_LOGFILE_CONTEXT_AUTHOR (context2,
/*N*/           "sch", "af119097", "::ChartModel::BuildChart not locked");
/*N*/       //nicht ganz so schön, aber vorteilhaft. Hiermit wird ein Itemset mit
/*N*/       //Attributen gefüllt, die beim Einfügen etc. als default benutzt werden
/*N*/       //(SetDefAttrRow). Da an dieser Stelle ein Defaultset erstellt wird, sind
/*N*/       //auch Chart-globale Items gleich gesetzt (Shape3D, Fehlerbalken,Datenbeschriftung)
/*N*/       //lediglich die Linien oder Flächenfarbe muss generiert werden!
/*N*/       //Alternative: nur in ChangeChart defaults erstellen
/*N*/       if( pChartData )
/*N*/       {
/*N*/           // in scatter charts the first series is for x values
/*N*/           // so use first 'y-series' to copy attributes to new series
/*N*/           if( IsXYChart())
/*N*/           {
/*N*/               if( GetRowCount() > 1 )
/*N*/                   pDummyAttr->Put( GetDataRowAttr( 1 ));
/*N*/           }
/*N*/           else
/*N*/               if( GetRowCount() > 0 )
/*N*/                   pDummyAttr->Put( GetDataRowAttr( 0 ));
/*N*/       }
/*N*/
/*N*/       //Hotfix für OLE-Charts #54884# Die Wurzel des Übels liegt möglicherweise irgendwo anders!
/*N*/       if(!pRefOutDev)
/*N*/       {
/*?*/           if(pChartRefOutDev)
/*?*/           {
/*?*/               OSL_FAIL("ChartModel::BuildChart: restoring lost pRefOutDev... something strange happend!");
/*?*/               SetRefDevice(pChartRefOutDev);
/*?*/           }
/*?*/           else
/*?*/           {
/*?*/               CHART_TRACE( "ChartModel::BuildChart no pRefOutDev!" );
/*?*/               if( pDocShell )
/*?*/               {
/*?*/                     // this is a valid upcast, because we 'know' that the
/*?*/                     // pDocShell member is always a SchChartDocShell
/*?*/                     OutputDevice * pOutDev = static_cast< SchChartDocShell * >( pDocShell )->GetRefDevice();
/*?*/                     SetRefDevice( pOutDev );
/*?*/                     GetOutliner()->SetRefDevice( pOutDev );
/*?*/               }
/*?*/               else
/*?*/               {
/*?*/                   OutputDevice* pOut = Application::GetDefaultDevice();
/*?*/                   // this is no error: if a ChartModel is copied via clipboard there is no docshell
/*?*/                   // OSL_FAIL("ChartModel::BuildChart : no Docshell! (OutputDevice)");
/*?*/                   pChartRefOutDev = new VirtualDevice( *pOut );
/*?*/                   MapMode aMapMode = pChartRefOutDev->GetMapMode();
/*?*/                   aMapMode.SetMapUnit(MAP_100TH_MM);
/*?*/                   pChartRefOutDev->SetMapMode(aMapMode);
/*?*/                   SetRefDevice(pChartRefOutDev);
/*?*/                   GetOutliner()->SetRefDevice(pChartRefOutDev);
/*?*/               }
/*N*/           }
/*N*/       }
/*N*/
/*N*/       CheckRanges(bCheckRanges);
/*N*/
/*N*/       if( !pChartData )       // create default chart if no chart exists so far
/*N*/           InitChartData();
/*N*/
/*N*/       if (GetColCount() && GetRowCount())
/*N*/       {
/*N*/           SdrPage* pPage = GetPage(0);
/*N*/           if (pPage)
/*N*/           {
/*N*/                 //#61431# MapMode speichern, am Ende BuildCharts restaurieren
/*N*/
/*N*/                 // remember the MapMode of the Printer and restore it at the end
/*N*/                 // of the current block, because it may be changed later in this
/*N*/                 // method (AdjustPrinter)
/*N*/                 lcl_MapModeResetGuard aPrinterMapModeGuard(
/*N*/                     static_cast< SchChartDocShell * >( GetObjectShell() )->GetPrinter() );
/*N*/
/*N*/                 AdjustPrinter();
/*N*/
/*N*/               // FG : DAs hier braucht es weil bei 3D-Charts der Bildchsimraufbau von der ChartScene
/*N*/               //      erst beim ersten Paint initiiert wird. Erst dann werden die Achsentitel ausgegeben
/*N*/               //      da ist aber BuildChart, aInitialSize=aPageSize setzt schon gelaufen. Deshalb diese
/*N*/               //      "Chart-Globale" Variable;
/*N*/               aInitialSizefor3d = aInitialSize;
/*N*/
/*N*/               // ItemSet mit entspr. Bereich anlegen
/*N*/               SfxItemSet aSet( GetItemPool(),
/*N*/                   SDRATTR_3DSCENE_FIRST, SDRATTR_3DSCENE_LAST);
/*N*/               BOOL bItemSetUsed = FALSE;
/*N*/
/*N*/               if( pScene )
/*N*/               {
/*N*/                   aSet.Put(pScene->GetItemSet());
/*N*/                   bItemSetUsed = TRUE;
/*N*/                   aSceneMatrix = pScene->GetTransform();
/*N*/               }
/*N*/               else
/*N*/               {
/*N*/                   SdrObject* pLoadedScene = GetObjWithId(CHOBJID_DIAGRAM, *pPage);
/*N*/                   if (pLoadedScene && pLoadedScene->ISA(E3dPolyScene))
/*N*/                   {
/*N*/                       aSet.Put(pLoadedScene->GetItemSet());
/*N*/                       bItemSetUsed = TRUE;
/*N*/                       aSceneMatrix = ((E3dPolyScene*) pLoadedScene)->GetTransform();
/*N*/                       Rescue3DObjAttr(pLoadedScene->GetSubList()); //#52277#
/*N*/                   }
/*N*/               }
/*N*/
/*N*/               DeleteChartObjects();
/*N*/               Size aPageSize = pPage->GetSize();
/*N*/
/*N*/               SdrObjGroup *pObj = NULL;
/*N*/               BOOL bNeedSetDiagram=FALSE;
/*N*/
/*N*/               // if type addin is set the core CreateChart shoudln't be called
/*N*/               // if an addin is used together with a base diagram type the base
/*N*/               // type should be set as chart type here (!= CHSTYLE_ADDIN)
/*N*/               if( eChartStyle != CHSTYLE_ADDIN )
/*N*/               {
/*N*/                   // core CreateChart
/*N*/                   CreateRectsAndTitles(whatTitle);
/*N*/
/*N*/                   if(bResizePie && IsPieChart() && IsReal3D())
/*N*/                   {
/*N*/                       long nWidth=aChartRect.GetWidth();
/*N*/                       long nHeight=aChartRect.GetHeight();
/*N*/                       if( ((double)nHeight/(double)nWidth) > 0.5 )
/*N*/                       {
/*?*/                           bNeedSetDiagram=TRUE;
/*?*/                           aChartRect.Top()+=nHeight/4;
/*?*/                           aChartRect.Bottom()-=nHeight/4;
/*?*/                               SetDiagramHasBeenMovedOrResized(TRUE);
/*?*/                           SetUseRelativePositions(TRUE);
/*?*/                           bResizePie=FALSE;
/*N*/                       }
/*N*/                   }
/*N*/
/*N*/                   pObj = CreateChart(aChartRect);
/*N*/
/*N*/                   if (pObj->ISA(SchObjGroup))
/*N*/                   {
/*N*/                       ((SchObjGroup *)pObj)->SetModel(this);
/*N*/                       ((SchObjGroup *)pObj)->SetGroupIsChart();
/*N*/                   }
/*N*/
/*N*/                   pPage->NbcInsertObject(pObj, 1);
/*N*/
/*N*/               }
/*N*/
/*N*/               // ====================
/*N*/               // call AddIn if required
/*N*/               // ====================
/*N*/               if( mbIsInitialized &&
/*N*/                     mxChartAddIn.is())
/*N*/               {
/*?*/                   // avoid recursion
/*?*/                   if( ! GetChartStatusFlag( CHS_NO_ADDIN_REFRESH ))
/*?*/                   {
/*?*/                       SetChartStatusFlag( CHS_NO_ADDIN_REFRESH );
/*?*/                       try
/*?*/                       {
/*?*/                           mxChartAddIn->refresh();
/*?*/                       }
/*?*/                       catch( ::com::sun::star::uno::Exception aEx )
/*?*/                       {
/*?*/ #ifdef DBG_UTIL
/*?*/                           rtl::OString aTmpBStr(rtl::OUStringToOString(aEx.Message, RTL_TEXTENCODING_ASCII_US));
/*?*/                           OSL_TRACE( "AddIn threw exception during refresh(): %s", aTmpBStr.getStr());
/*?*/ #else
/*?*/                           (void)aEx;
/*?*/ #endif
/*?*/                       }
/*?*/                       ResetChartStatusFlag( CHS_NO_ADDIN_REFRESH );
/*N*/                   }
/*N*/               }
/*N*/
/*N*/               aInitialSize = aPageSize;
/*N*/
/*N*/               if(pScene && IsReal3D() )
/*N*/               {
/*N*/
/*N*/ #ifndef NO_56798_FIX //#56798# QuickFix 5.0-Final
/*N*/
/*N*/                   if(bClearDepth)
/*N*/                   {
/*N*/                       aSet.ClearItem(SDRATTR_3DOBJ_DEPTH);
/*N*/                       bClearDepth=FALSE;
/*N*/                   }
/*N*/ #endif
/*N*/
/*?*/                   aSet.ClearItem(SDRATTR_3DOBJ_DOUBLE_SIDED); //#56941#
/*?*/                   aSet.ClearItem(SDRATTR_3DOBJ_HORZ_SEGS);
/*N*/
/*N*/                   if(bItemSetUsed)
/*N*/                   {
/*N*/                       //funktioniert nur, wenn nicht durch vorherigen Aufruf (CheckRanges) eine MsgBox entstand
/*N*/                       if(eChartStyle != eOldChartStyle)
/*N*/                       {
/*N*/                           // Falls sich der ChartStyle aendert, die Extrude-Tiefe
/*N*/                           // auf unfueltig setzen
/*N*/                           const SfxPoolItem* pPoolItem = NULL;
/*N*/                           SfxItemState eState = aSet.GetItemState(SDRATTR_3DOBJ_DEPTH, FALSE, &pPoolItem);
/*N*/                           if(eState == SFX_ITEM_SET)
/*N*/                           {
/*N*/                               // Ist gesetzt, invalidiere
/*N*/                               aSet.InvalidateItem(SDRATTR_3DOBJ_DEPTH);
/*N*/                               CHART_TRACE( "Chart: Invalidating saveable item ..." );
/*N*/                           }
/*N*/                       }
/*N*/
/*N*/                       // Attribute an neuer Szene setzen
/*N*/                       pScene->SetItemSet(aSet);
/*N*/
/*N*/                   }
/*N*/
/*N*/                   pScene->NbcSetTransform(aSceneMatrix);
/*N*/
/*N*/                   const SfxPoolItem *pPoolItem = NULL;
/*N*/                   if(!IsPieChart())
/*N*/                   {
/*N*/                       if(pChartXAxis->HasDescription())
/*N*/                       {
/*N*/                           if(GetAttr(CHOBJID_DIAGRAM_X_AXIS).GetItemState( SCHATTR_TEXT_OVERLAP, FALSE, &pPoolItem ) >= SFX_ITEM_AVAILABLE )
/*N*/                           {
/*N*/                               if(!( (const SfxBoolItem*) pPoolItem)->GetValue())
/*N*/                                   pScene->ReduceDescrList(aXDescrList);
/*N*/                           }
/*N*/                       }
/*N*/
/*N*/                       if(pChartYAxis->HasDescription())
/*N*/                       {
/*N*/                           if(GetAttr(CHOBJID_DIAGRAM_Y_AXIS).GetItemState( SCHATTR_TEXT_OVERLAP, FALSE, &pPoolItem ) >= SFX_ITEM_AVAILABLE )
/*N*/                           {
/*N*/                               if(!( (const SfxBoolItem*) pPoolItem)->GetValue())
/*N*/                                   pScene->ReduceDescrList(aYDescrList);
/*N*/                           }
/*N*/                       }
/*N*/
/*N*/                       if(pChartZAxis->HasDescription())
/*N*/                       {
/*N*/                           if(GetAttr(CHOBJID_DIAGRAM_Z_AXIS).GetItemState( SCHATTR_TEXT_OVERLAP, FALSE, &pPoolItem ) >= SFX_ITEM_AVAILABLE )
/*N*/                           {
/*N*/                               if(!( (const SfxBoolItem*) pPoolItem)->GetValue())
/*N*/                                   pScene->ReduceDescrList(aZDescrList);
/*N*/                           }
/*N*/                       }
/*N*/                   }
/*N*/               }
/*N*/
/*N*/
/*N*/               if(bNeedSetDiagram && pScene)
/*N*/               {
/*?*/                   Rectangle aRectangle;
/*?*/                   aRectangle = pScene->GetSnapRect();
/*?*/                   ((ChartScene *)pObj)->SetAskForLogicRect(FALSE);
/*?*/                   SetDiagramRectangle(aRectangle);
/*?*/                   SetDiagramHasBeenMovedOrResized(TRUE);
/*N*/               }
/*N*/
/*N*/               //#61431# MapMode speichern, am Ende BuildCharts restaurieren
/*N*/
/*N*/                 // the MapMode of the RefDevice is restored by the
/*N*/                 // lcl_MapModeResetGuard
/*N*/             }
/*N*/       }
/*N*/   }
/*N*/   //Jetzt sollen sich die Objekte wieder drum kümmern, da?das Model die Attribute erhält
/*N*/   SetAttrAutoStorage(TRUE);
/*N*/   SetDiagramRectangle( aChartRect );
/*N*/   eOldChartStyle = eChartStyle;
/*N*/
/*N*/     // notify build to listeners
/*N*/     Broadcast( SchReBuildHint());
/*N*/ }



/*N*/ void ChartModel::SetUseRelativePositions (BOOL value)
/*N*/ {
/*N*/   if (value == FALSE)
/*N*/   {
/*N*/       SetDiagramHasBeenMovedOrResized(FALSE);
/*N*/       SetMainTitleHasBeenMoved(FALSE);
/*N*/       SetSubTitleHasBeenMoved(FALSE);
/*N*/       SetLegendHasBeenMoved(FALSE);
/*N*/       SetXAxisTitleHasBeenMoved(FALSE);
/*N*/       SetYAxisTitleHasBeenMoved(FALSE);
/*N*/       SetZAxisTitleHasBeenMoved(FALSE);
/*N*/       if((IsReal3D() && IsPieChart()))
/*N*/       {
/*?*/           Matrix4D aMatrix; //Reset der Matrix.... könnte man auch grundsätzlich machen?
/*?*/           aMatrix.RotateX(-F_PI/3);
/*?*/           aSceneMatrix=aMatrix;
/*?*/           if(pScene)
/*?*/               pScene->NbcSetTransform(aSceneMatrix);
/*?*/           bResizePie=TRUE;
/*N*/       }
/*N*/   }
/*N*/   bUseRelativePositionsForChartGroups = value;
/*N*/ }

/*************************************************************************
|*
|* bestimme Varianz
|*
\************************************************************************/


/*N*/ double ChartModel::GetVariantY (long nRow)
/*N*/ {
/*N*/   long nColCnt = GetColCount();
/*N*/
/*N*/   if (nColCnt)
/*N*/   {
/*N*/       double fSum     = 0.0;
/*N*/       double fQuadSum = 0.0;
/*N*/       long nValidCols = nColCnt;
/*N*/
/*N*/       for (long nCol = 0;
/*N*/                 nCol < nColCnt;
/*N*/                 nCol ++)
/*N*/       {
/*N*/           double fData = GetData ((short) nCol, (short) nRow, FALSE);
/*N*/
/*N*/           if( fData == DBL_MIN )
/*N*/           {
/*N*/               nValidCols--;
/*N*/           }
/*N*/           else
/*N*/           {
/*N*/               fSum     += fData;
/*N*/               fQuadSum += fData * fData;
/*N*/           }
/*N*/       }
/*N*/
/*N*/       return nValidCols? (fQuadSum - fSum*fSum / (double)nValidCols) / (double)nValidCols: DBL_MIN;
/*N*/   }
/*N*/   else return 0;
/*N*/ }

/*************************************************************************
|*
|* bestimme Varianz
|*
\************************************************************************/


/*N*/ double ChartModel::GetSigmaY (long nRow)
/*N*/ {
/*N*/   return sqrt (GetVariantY (nRow));
/*N*/ }

/*************************************************************************
|*
|* bestimme Fehler des groessten Wertes
|*
\************************************************************************/


/*N*/ double ChartModel::GetBigErrorY (long   nRow,
/*N*/                                double fError)
/*N*/ {
/*N*/   double     fMax    = 0.0;
/*N*/   long       nColCnt = GetColCount();
/*N*/
/*N*/   for (long nCol = 0;
/*N*/             nCol < nColCnt;
/*N*/             nCol ++)
/*N*/   {
/*N*/       double fData = GetData ((short) nCol, (short) nRow, FALSE);
/*N*/
/*N*/       if (fData != DBL_MIN)
/*N*/           if (fData > fMax) fMax = fData;
/*N*/   }
/*N*/
/*N*/   return fMax * fError / 100.0;
/*N*/ }

}

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