Files
libreoffice/sw/source/core/doc/docchart.cxx

499 lines
16 KiB
C++
Raw Normal View History

2000-09-18 23:08:29 +00:00
/*************************************************************************
*
* $RCSfile: docchart.cxx,v $
*
2001-07-05 09:34:53 +00:00
* $Revision: 1.5 $
2000-09-18 23:08:29 +00:00
*
2001-07-05 09:34:53 +00:00
* last change: $Author: ama $ $Date: 2001-07-05 10:11:52 $
2000-09-18 23:08:29 +00:00
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library 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 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (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.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#ifdef PRECOMPILED
#include "core_pch.hxx"
#endif
#pragma hdrstop
#include <float.h>
#ifndef _HINTIDS_HXX
#include <hintids.hxx>
#endif
2001-05-15 06:50:55 +00:00
#ifndef _IPOBJ_HXX
2000-09-18 23:08:29 +00:00
#include <so3/ipobj.hxx>
#endif
#ifndef _SCH_DLL_HXX
#include <sch/schdll.hxx>
#endif
#ifndef _SCH_MEMCHRT_HXX
#include <sch/memchrt.hxx>
#endif
2001-07-05 09:34:53 +00:00
#ifndef _WINDOW_HXX //autogen
#include <vcl/window.hxx>
#endif
2000-09-18 23:08:29 +00:00
#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _DOCARY_HXX
#include <docary.hxx>
#endif
2001-05-15 06:50:55 +00:00
#ifndef _NDINDEX_HXX
2000-09-18 23:08:29 +00:00
#include <ndindex.hxx>
#endif
#ifndef _SWTABLE_HXX
#include <swtable.hxx>
#endif
2001-05-15 06:50:55 +00:00
#ifndef _NDTXT_HXX
2000-09-18 23:08:29 +00:00
#include <ndtxt.hxx>
#endif
#ifndef _CALC_HXX
#include <calc.hxx>
#endif
2001-05-15 06:50:55 +00:00
#ifndef _FRMFMT_HXX
2000-09-18 23:08:29 +00:00
#include <frmfmt.hxx>
#endif
2001-05-15 06:50:55 +00:00
#ifndef _CELLFML_HXX
2000-09-18 23:08:29 +00:00
#include <cellfml.hxx>
#endif
#ifndef _VIEWSH_HXX
#include <viewsh.hxx>
#endif
2001-05-15 06:50:55 +00:00
#ifndef _NDOLE_HXX
2000-09-18 23:08:29 +00:00
#include <ndole.hxx>
#endif
2001-05-15 06:50:55 +00:00
#ifndef _CALBCK_HXX
2000-09-18 23:08:29 +00:00
#include <calbck.hxx>
#endif
2001-05-15 06:50:55 +00:00
#ifndef _CNTFRM_HXX
2000-09-18 23:08:29 +00:00
#include <cntfrm.hxx>
#endif
2001-05-15 06:50:55 +00:00
#ifndef _SWTBLFMT_HXX
2000-09-18 23:08:29 +00:00
#include <swtblfmt.hxx>
#endif
#ifndef _TBLSEL_HXX
#include <tblsel.hxx>
#endif
2001-05-15 06:50:55 +00:00
#ifndef _CELLATR_HXX
2000-09-18 23:08:29 +00:00
#include <cellatr.hxx>
#endif
SchMemChart *SwTable::UpdateData( SchMemChart* pData,
const String* pSelection ) const
{
SwCalc aCalc( *GetFrmFmt()->GetDoc() );
SwTblCalcPara aCalcPara( aCalc, *this );
2001-05-15 06:50:55 +00:00
String sSelection, sRowColInfo;
BOOL bSetChartRange = TRUE;
2000-09-18 23:08:29 +00:00
// worauf bezieht sich das Chart?
if( pData && pData->SomeData1().Len() )
2001-05-15 06:50:55 +00:00
{
sSelection = pData->SomeData1();
sRowColInfo = pData->SomeData2();
}
else if( pData && pData->GetChartRange().maRanges.size() )
{
SchDLL::ConvertChartRangeForWriter( *pData, FALSE );
sSelection = pData->SomeData1();
sRowColInfo = pData->SomeData2();
bSetChartRange = FALSE;
}
2000-09-18 23:08:29 +00:00
else if( pSelection )
2001-05-15 06:50:55 +00:00
{
sSelection = *pSelection;
sRowColInfo.AssignAscii( RTL_CONSTASCII_STRINGPARAM("11") );
}
2000-09-18 23:08:29 +00:00
SwChartLines aLines;
2001-05-15 06:50:55 +00:00
if( !IsTblComplexForChart( sSelection, &aLines ))
2000-09-18 23:08:29 +00:00
{
USHORT nLines = aLines.Count(), nBoxes = aLines[0]->Count();
if( !pData )
{
//JP 08.02.99: als default wird mit Spalten/Zeilenueberschrift
// eingefuegt, deshalb das -1
pData = SchDLL::NewMemChart( nBoxes-1, nLines-1 );
pData->SetSubTitle( aEmptyStr );
pData->SetXAxisTitle( aEmptyStr );
pData->SetYAxisTitle( aEmptyStr );
pData->SetZAxisTitle( aEmptyStr );
}
USHORT nRowStt = 0, nColStt = 0;
2001-05-15 06:50:55 +00:00
if( sRowColInfo.Len() )
2000-09-18 23:08:29 +00:00
{
2001-05-15 06:50:55 +00:00
if( '1' == sRowColInfo.GetChar( 0 ))
2000-09-18 23:08:29 +00:00
++nRowStt;
2001-05-15 06:50:55 +00:00
if( '1' == sRowColInfo.GetChar( 1 ))
2000-09-18 23:08:29 +00:00
++nColStt;
}
if( (nBoxes - nColStt) > pData->GetColCount() )
2001-05-15 06:50:55 +00:00
SchDLL::MemChartInsertCols( *pData, 0, (nBoxes - nColStt) - pData->GetColCount() );
2000-09-18 23:08:29 +00:00
else if( (nBoxes - nColStt) < pData->GetColCount() )
2001-05-15 06:50:55 +00:00
SchDLL::MemChartRemoveCols( *pData, 0, pData->GetColCount() - (nBoxes - nColStt) );
2000-09-18 23:08:29 +00:00
if( (nLines - nRowStt) > pData->GetRowCount() )
2001-05-15 06:50:55 +00:00
SchDLL::MemChartInsertRows( *pData, 0, (nLines - nRowStt) - pData->GetRowCount() );
2000-09-18 23:08:29 +00:00
else if( (nLines - nRowStt) < pData->GetRowCount() )
2001-05-15 06:50:55 +00:00
SchDLL::MemChartRemoveRows( *pData, 0, pData->GetRowCount() - (nLines - nRowStt) );
2000-09-18 23:08:29 +00:00
ASSERT( pData->GetRowCount() >= (nLines - nRowStt ) &&
pData->GetColCount() >= (nBoxes - nColStt ),
"Die Struktur fuers Chart ist zu klein,\n"
"es wird irgendwo in den Speicher geschrieben!" );
// Row-Texte setzen
USHORT n;
if( nRowStt )
for( n = nColStt; n < nBoxes; ++n )
{
const SwTableBox *pBox = (*aLines[ 0 ])[ n ];
ASSERT( pBox->GetSttNd(), "Box without SttIdx" );
SwNodeIndex aIdx( *pBox->GetSttNd(), 1 );
const SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode();
if( !pTNd )
pTNd = aIdx.GetNodes().GoNextSection( &aIdx, TRUE, FALSE )
->GetTxtNode();
pData->SetColText( n - nColStt, pTNd->GetExpandTxt() );
}
else
{
String aText;
for( n = nColStt; n < nBoxes; ++n )
{
SchDLL::GetDefaultForColumnText( *pData, n - nColStt, aText );
pData->SetColText( n - nColStt, aText );
}
}
// Col-Texte setzen
if( nColStt )
for( n = nRowStt; n < nLines; ++n )
{
const SwTableBox *pBox = (*aLines[ n ])[ 0 ];
ASSERT( pBox->GetSttNd(), "Box without SttIdx" );
SwNodeIndex aIdx( *pBox->GetSttNd(), 1 );
const SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode();
if( !pTNd )
pTNd = aIdx.GetNodes().GoNextSection( &aIdx, TRUE, FALSE )
->GetTxtNode();
pData->SetRowText( n - nRowStt, pTNd->GetExpandTxt() );
}
else
{
String aText;
for( n = nRowStt; n < nLines; ++n )
{
SchDLL::GetDefaultForRowText( *pData, n - nRowStt, aText );
pData->SetRowText( n - nRowStt, aText );
}
}
// und dann fehlen nur noch die Daten
const SwTblBoxNumFormat& rDfltNumFmt = *(SwTblBoxNumFormat*)
GetDfltAttr( RES_BOXATR_FORMAT );
pData->SetNumberFormatter( GetFrmFmt()->GetDoc()->GetNumberFormatter());
2000-11-07 09:05:20 +00:00
2000-09-18 23:08:29 +00:00
int bFirstRow = TRUE;
for( n = nRowStt; n < nLines; ++n )
{
for( USHORT i = nColStt; i < nBoxes; ++i )
{
const SwTableBox* pBox = (*aLines[ n ])[ i ];
ASSERT( pBox->GetSttNd(), "Box without SttIdx" );
SwNodeIndex aIdx( *pBox->GetSttNd(), 1 );
const SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode();
if( !pTNd )
pTNd = aIdx.GetNodes().GoNextSection( &aIdx, TRUE, FALSE )
->GetTxtNode();
pData->SetData( short( i - nColStt ),
short( n - nRowStt ),
pTNd->GetTxt().Len()
? pBox->GetValue( aCalcPara )
: DBL_MIN );
if( i == nColStt || bFirstRow )
{
// first box of row set the numberformat
const SwTblBoxNumFormat& rNumFmt = pBox->GetFrmFmt()->
GetTblBoxNumFmt();
if( rNumFmt != rDfltNumFmt )
{
pData->SetNumFormatIdCol( i, rNumFmt.GetValue() );
if( bFirstRow )
pData->SetNumFormatIdRow( n, rNumFmt.GetValue() );
}
}
}
bFirstRow = FALSE;
2000-11-07 09:05:20 +00:00
}
2000-09-18 23:08:29 +00:00
}
else if( pData )
{
if( pData->GetColCount() )
2001-05-15 06:50:55 +00:00
SchDLL::MemChartRemoveCols( *pData, 0, pData->GetColCount() );
2000-09-18 23:08:29 +00:00
if( pData->GetRowCount() )
2001-05-15 06:50:55 +00:00
SchDLL::MemChartRemoveRows( *pData, 0, pData->GetRowCount() );
}
2001-05-15 06:56:28 +00:00
else
bSetChartRange = FALSE;
2001-05-15 06:50:55 +00:00
if( bSetChartRange )
{
// convert the selection string to the SchartRanges
pData->SomeData1() = sSelection;
pData->SomeData2() = sRowColInfo;
SchDLL::ConvertChartRangeForWriter( *pData, TRUE );
2000-09-18 23:08:29 +00:00
}
return pData;
}
BOOL SwTable::IsTblComplexForChart( const String& rSelection,
SwChartLines* pGetCLines ) const
{
const SwTableBox* pSttBox, *pEndBox;
if( 2 < rSelection.Len() )
{
// spitze Klammern am Anfang & Ende enfernen
String sBox( rSelection );
if( '<' == sBox.GetChar( 0 ) ) sBox.Erase( 0, 1 );
if( '>' == sBox.GetChar( sBox.Len()-1 ) ) sBox.Erase( sBox.Len()-1 );
xub_StrLen nTrenner = sBox.Search( ':' );
ASSERT( STRING_NOTFOUND != nTrenner, "keine gueltige Selektion" );
pSttBox = GetTblBox( sBox.Copy( 0, nTrenner ));
pEndBox = GetTblBox( sBox.Copy( nTrenner+1 ));
}
else
{
const SwTableLines* pLns = &GetTabLines();
pSttBox = (*pLns)[ 0 ]->GetTabBoxes()[ 0 ];
while( !pSttBox->GetSttNd() )
// bis zur Content Box!
pSttBox = pSttBox->GetTabLines()[ 0 ]->GetTabBoxes()[ 0 ];
const SwTableBoxes* pBoxes = &(*pLns)[ pLns->Count()-1 ]->GetTabBoxes();
pEndBox = (*pBoxes)[ pBoxes->Count()-1 ];
while( !pEndBox->GetSttNd() )
{
// bis zur Content Box!
pLns = &pEndBox->GetTabLines();
pBoxes = &(*pLns)[ pLns->Count()-1 ]->GetTabBoxes();
pEndBox = (*pBoxes)[ pBoxes->Count()-1 ];
}
}
return !pSttBox || !pEndBox || !::ChkChartSel( *pSttBox->GetSttNd(),
*pEndBox->GetSttNd(), pGetCLines );
}
IMPL_LINK( SwDoc, DoUpdateAllCharts, Timer *, pTimer )
{
ViewShell* pVSh;
GetEditShell( &pVSh );
if( pVSh )
{
const SwFrmFmts& rTblFmts = *GetTblFrmFmts();
for( USHORT n = 0; n < rTblFmts.Count(); ++n )
{
SwTable* pTmpTbl;
const SwTableNode* pTblNd;
SwFrmFmt* pFmt = rTblFmts[ n ];
if( 0 != ( pTmpTbl = SwTable::FindTable( pFmt ) ) &&
0 != ( pTblNd = pTmpTbl->GetTableNode() ) &&
pTblNd->GetNodes().IsDocNodes() )
{
_UpdateCharts( *pTmpTbl, *pVSh );
}
}
}
return 0;
}
void SwDoc::_UpdateCharts( const SwTable& rTbl, ViewShell& rVSh ) const
{
String aName( rTbl.GetFrmFmt()->GetName() );
SwOLENode *pONd;
SwStartNode *pStNd;
SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
while( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
{
aIdx++;
SwFrm* pFrm;
if( 0 != ( pONd = aIdx.GetNode().GetOLENode() ) &&
aName.Equals( pONd->GetChartTblName() ) &&
0 != ( pFrm = pONd->GetFrm() ) )
{
SwOLEObj& rOObj = pONd->GetOLEObj();
SchMemChart *pData = SchDLL::GetChartData( rOObj.GetOleRef() );
FASTBOOL bDelData = 0 == pData;
ASSERT( pData, "UpdateChart ohne irgendwelche Daten?" );
pData = rTbl.UpdateData( pData );
2001-05-15 06:50:55 +00:00
if( pData->GetColCount() && pData->GetRowCount() )
2000-09-18 23:08:29 +00:00
{
SchDLL::Update( rOObj.GetOleRef(), pData, rVSh.GetWin() );
SwClientIter aIter( *pONd );
for( pFrm = (SwFrm*)aIter.First( TYPE(SwFrm) ); pFrm;
pFrm = (SwFrm*)aIter.Next() )
{
if( pFrm->Frm().HasArea() )
rVSh.InvalidateWindows( pFrm->Frm() );
}
}
if ( bDelData )
delete pData;
}
aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
}
}
void SwDoc::UpdateCharts( const String &rName ) const
{
SwTable* pTmpTbl = SwTable::FindTable( FindTblFmtByName( rName ) );
if( pTmpTbl )
{
ViewShell* pVSh;
GetEditShell( &pVSh );
if( pVSh )
_UpdateCharts( *pTmpTbl, *pVSh );
}
}
void SwDoc::SetTableName( SwFrmFmt& rTblFmt, const String &rNewName )
{
const String aOldName( rTblFmt.GetName() );
BOOL bNameFound = 0 == rNewName.Len();
if( !bNameFound )
{
SwFrmFmt* pFmt;
const SwFrmFmts& rTbl = *GetTblFrmFmts();
for( USHORT i = rTbl.Count(); i; )
if( !( pFmt = rTbl[ --i ] )->IsDefault() &&
pFmt->GetName() == rNewName && IsUsed( *pFmt ) )
{
bNameFound = TRUE;
break;
}
}
if( !bNameFound )
rTblFmt.SetName( rNewName );
else
rTblFmt.SetName( GetUniqueTblName() );
SwStartNode *pStNd;
SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
{
aIdx++;
SwOLENode *pNd = aIdx.GetNode().GetOLENode();
if( pNd && aOldName == pNd->GetChartTblName() )
{
pNd->SetChartTblName( rNewName );
SwOLEObj& rOObj = pNd->GetOLEObj();
SchMemChart *pData = SchDLL::GetChartData( rOObj.GetOleRef() );
if( pData )
{
ViewShell* pVSh;
GetEditShell( &pVSh );
if( aOldName == pData->GetMainTitle() )
{
pData->SetMainTitle( rNewName );
if( pVSh )
SchDLL::Update( rOObj.GetOleRef(), pData, pVSh->GetWin() );
}
if( pVSh )
{
SwFrm *pFrm;
SwClientIter aIter( *pNd );
for( pFrm = (SwFrm*)aIter.First( TYPE(SwFrm) ); pFrm;
pFrm = (SwFrm*)aIter.Next() )
{
if( pFrm->Frm().HasArea() )
pVSh->InvalidateWindows( pFrm->Frm() );
}
}
}
}
aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
}
SetModified();
}