xref: /aoo41x/main/sw/source/core/doc/docchart.cxx (revision efeef26f)
1*efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*efeef26fSAndrew Rist  * distributed with this work for additional information
6*efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9*efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*efeef26fSAndrew Rist  *
11*efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*efeef26fSAndrew Rist  *
13*efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15*efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17*efeef26fSAndrew Rist  * specific language governing permissions and limitations
18*efeef26fSAndrew Rist  * under the License.
19*efeef26fSAndrew Rist  *
20*efeef26fSAndrew Rist  *************************************************************/
21*efeef26fSAndrew Rist 
22*efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <com/sun/star/frame/XModel.hpp>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <com/sun/star/chart2/XChartDocument.hpp>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <float.h>
33cdf0e10cSrcweir #include <hintids.hxx>
34cdf0e10cSrcweir #include <vcl/window.hxx>
35cdf0e10cSrcweir #include <doc.hxx>
36cdf0e10cSrcweir #include <docary.hxx>
37cdf0e10cSrcweir #include <ndindex.hxx>
38cdf0e10cSrcweir #include <swtable.hxx>
39cdf0e10cSrcweir #include <ndtxt.hxx>
40cdf0e10cSrcweir #include <ndole.hxx>
41cdf0e10cSrcweir #include <calc.hxx>
42cdf0e10cSrcweir #include <frmfmt.hxx>
43cdf0e10cSrcweir #include <cellfml.hxx>
44cdf0e10cSrcweir #include <viewsh.hxx>
45cdf0e10cSrcweir #include <ndole.hxx>
46cdf0e10cSrcweir #include <calbck.hxx>
47cdf0e10cSrcweir #include <cntfrm.hxx>
48cdf0e10cSrcweir #include <swtblfmt.hxx>
49cdf0e10cSrcweir #include <tblsel.hxx>
50cdf0e10cSrcweir #include <cellatr.hxx>
51cdf0e10cSrcweir #include <vos/mutex.hxx>
52cdf0e10cSrcweir #include <vcl/svapp.hxx>
53cdf0e10cSrcweir 
54cdf0e10cSrcweir #include <unochart.hxx>
55cdf0e10cSrcweir 
56cdf0e10cSrcweir using namespace com::sun::star;
57cdf0e10cSrcweir using namespace com::sun::star::uno;
58cdf0e10cSrcweir 
59cdf0e10cSrcweir 
UpdateCharts() const60cdf0e10cSrcweir void SwTable::UpdateCharts() const
61cdf0e10cSrcweir {
62cdf0e10cSrcweir     GetFrmFmt()->GetDoc()->UpdateCharts( GetFrmFmt()->GetName() );
63cdf0e10cSrcweir }
64cdf0e10cSrcweir 
IsTblComplexForChart(const String & rSelection,SwChartLines * pGetCLines) const65cdf0e10cSrcweir sal_Bool SwTable::IsTblComplexForChart( const String& rSelection,
66cdf0e10cSrcweir 									SwChartLines* pGetCLines ) const
67cdf0e10cSrcweir {
68cdf0e10cSrcweir 	const SwTableBox* pSttBox, *pEndBox;
69cdf0e10cSrcweir 	if( 2 < rSelection.Len() )
70cdf0e10cSrcweir 	{
71cdf0e10cSrcweir 		// spitze Klammern am Anfang & Ende enfernen
72cdf0e10cSrcweir 		String sBox( rSelection );
73cdf0e10cSrcweir 		if( '<' == sBox.GetChar( 0  ) ) sBox.Erase( 0, 1 );
74cdf0e10cSrcweir 		if( '>' == sBox.GetChar( sBox.Len()-1  ) ) sBox.Erase( sBox.Len()-1 );
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 		xub_StrLen nTrenner = sBox.Search( ':' );
77cdf0e10cSrcweir 		ASSERT( STRING_NOTFOUND != nTrenner, "keine gueltige Selektion" );
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 		pSttBox = GetTblBox( sBox.Copy( 0, nTrenner ));
80cdf0e10cSrcweir 		pEndBox = GetTblBox( sBox.Copy( nTrenner+1 ));
81cdf0e10cSrcweir 	}
82cdf0e10cSrcweir 	else
83cdf0e10cSrcweir 	{
84cdf0e10cSrcweir 		const SwTableLines* pLns = &GetTabLines();
85cdf0e10cSrcweir 		pSttBox = (*pLns)[ 0 ]->GetTabBoxes()[ 0 ];
86cdf0e10cSrcweir 		while( !pSttBox->GetSttNd() )
87cdf0e10cSrcweir 			// bis zur Content Box!
88cdf0e10cSrcweir 			pSttBox = pSttBox->GetTabLines()[ 0 ]->GetTabBoxes()[ 0 ];
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 		const SwTableBoxes* pBoxes = &(*pLns)[ pLns->Count()-1 ]->GetTabBoxes();
91cdf0e10cSrcweir 		pEndBox = (*pBoxes)[ pBoxes->Count()-1 ];
92cdf0e10cSrcweir 		while( !pEndBox->GetSttNd() )
93cdf0e10cSrcweir 		{
94cdf0e10cSrcweir 			// bis zur Content Box!
95cdf0e10cSrcweir 			pLns = &pEndBox->GetTabLines();
96cdf0e10cSrcweir 			pBoxes = &(*pLns)[ pLns->Count()-1 ]->GetTabBoxes();
97cdf0e10cSrcweir 			pEndBox = (*pBoxes)[ pBoxes->Count()-1 ];
98cdf0e10cSrcweir 		}
99cdf0e10cSrcweir 	}
100cdf0e10cSrcweir 
101cdf0e10cSrcweir 	return !pSttBox || !pEndBox || !::ChkChartSel( *pSttBox->GetSttNd(),
102cdf0e10cSrcweir 										*pEndBox->GetSttNd(), pGetCLines );
103cdf0e10cSrcweir }
104cdf0e10cSrcweir 
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 
IMPL_LINK(SwDoc,DoUpdateAllCharts,Timer *,EMPTYARG)107cdf0e10cSrcweir IMPL_LINK( SwDoc, DoUpdateAllCharts, Timer *, EMPTYARG )
108cdf0e10cSrcweir {
109cdf0e10cSrcweir 	ViewShell* pVSh;
110cdf0e10cSrcweir 	GetEditShell( &pVSh );
111cdf0e10cSrcweir 	if( pVSh )
112cdf0e10cSrcweir 	{
113cdf0e10cSrcweir 		const SwFrmFmts& rTblFmts = *GetTblFrmFmts();
114cdf0e10cSrcweir 		for( sal_uInt16 n = 0; n < rTblFmts.Count(); ++n )
115cdf0e10cSrcweir 		{
116cdf0e10cSrcweir 			SwTable* pTmpTbl;
117cdf0e10cSrcweir 			const SwTableNode* pTblNd;
118cdf0e10cSrcweir 			SwFrmFmt* pFmt = rTblFmts[ n ];
119cdf0e10cSrcweir 
120cdf0e10cSrcweir 			if( 0 != ( pTmpTbl = SwTable::FindTable( pFmt ) ) &&
121cdf0e10cSrcweir 				0 != ( pTblNd = pTmpTbl->GetTableNode() ) &&
122cdf0e10cSrcweir 				pTblNd->GetNodes().IsDocNodes() )
123cdf0e10cSrcweir 			{
124cdf0e10cSrcweir 				_UpdateCharts( *pTmpTbl, *pVSh );
125cdf0e10cSrcweir 			}
126cdf0e10cSrcweir 		}
127cdf0e10cSrcweir 	}
128cdf0e10cSrcweir 	return 0;
129cdf0e10cSrcweir }
130cdf0e10cSrcweir 
_UpdateCharts(const SwTable & rTbl,ViewShell & rVSh) const131cdf0e10cSrcweir void SwDoc::_UpdateCharts( const SwTable& rTbl, ViewShell& rVSh ) const
132cdf0e10cSrcweir {
133cdf0e10cSrcweir 	String aName( rTbl.GetFrmFmt()->GetName() );
134cdf0e10cSrcweir 	SwOLENode *pONd;
135cdf0e10cSrcweir 	SwStartNode *pStNd;
136cdf0e10cSrcweir 	SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
137cdf0e10cSrcweir 	while( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
138cdf0e10cSrcweir 	{
139cdf0e10cSrcweir 		aIdx++;
140cdf0e10cSrcweir 		SwFrm* pFrm;
141cdf0e10cSrcweir 		if( 0 != ( pONd = aIdx.GetNode().GetOLENode() ) &&
142cdf0e10cSrcweir 			aName.Equals( pONd->GetChartTblName() ) &&
143cdf0e10cSrcweir 			0 != ( pFrm = pONd->getLayoutFrm( rVSh.GetLayout() ) ) )
144cdf0e10cSrcweir 		{
145cdf0e10cSrcweir             SwChartDataProvider *pPCD = GetChartDataProvider();
146cdf0e10cSrcweir             if (pPCD)
147cdf0e10cSrcweir                 pPCD->InvalidateTable( &rTbl );
148cdf0e10cSrcweir 			// following this the framework will now take care of repainting
149cdf0e10cSrcweir 			// the chart or it's replacement image...
150cdf0e10cSrcweir 		}
151cdf0e10cSrcweir 		aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
152cdf0e10cSrcweir 	}
153cdf0e10cSrcweir }
154cdf0e10cSrcweir 
UpdateCharts(const String & rName) const155cdf0e10cSrcweir void SwDoc::UpdateCharts( const String &rName ) const
156cdf0e10cSrcweir {
157cdf0e10cSrcweir 	SwTable* pTmpTbl = SwTable::FindTable( FindTblFmtByName( rName ) );
158cdf0e10cSrcweir 	if( pTmpTbl )
159cdf0e10cSrcweir 	{
160cdf0e10cSrcweir 		ViewShell* pVSh;
161cdf0e10cSrcweir 		GetEditShell( &pVSh );
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 		if( pVSh )
164cdf0e10cSrcweir 			_UpdateCharts( *pTmpTbl, *pVSh );
165cdf0e10cSrcweir 	}
166cdf0e10cSrcweir }
167cdf0e10cSrcweir 
SetTableName(SwFrmFmt & rTblFmt,const String & rNewName)168cdf0e10cSrcweir void SwDoc::SetTableName( SwFrmFmt& rTblFmt, const String &rNewName )
169cdf0e10cSrcweir {
170cdf0e10cSrcweir // 	sal_Bool bStop = 1;
171cdf0e10cSrcweir 
172cdf0e10cSrcweir 	const String aOldName( rTblFmt.GetName() );
173cdf0e10cSrcweir 
174cdf0e10cSrcweir 	sal_Bool bNameFound = 0 == rNewName.Len();
175cdf0e10cSrcweir 	if( !bNameFound )
176cdf0e10cSrcweir 	{
177cdf0e10cSrcweir 		SwFrmFmt* pFmt;
178cdf0e10cSrcweir 		const SwFrmFmts& rTbl = *GetTblFrmFmts();
179cdf0e10cSrcweir 		for( sal_uInt16 i = rTbl.Count(); i; )
180cdf0e10cSrcweir 			if( !( pFmt = rTbl[ --i ] )->IsDefault() &&
181cdf0e10cSrcweir 				pFmt->GetName() == rNewName && IsUsed( *pFmt ) )
182cdf0e10cSrcweir 			{
183cdf0e10cSrcweir 				bNameFound = sal_True;
184cdf0e10cSrcweir 				break;
185cdf0e10cSrcweir 			}
186cdf0e10cSrcweir 	}
187cdf0e10cSrcweir 
188cdf0e10cSrcweir 	if( !bNameFound )
189cdf0e10cSrcweir 		rTblFmt.SetName( rNewName, sal_True );
190cdf0e10cSrcweir 	else
191cdf0e10cSrcweir 		rTblFmt.SetName( GetUniqueTblName(), sal_True );
192cdf0e10cSrcweir 
193cdf0e10cSrcweir 	SwStartNode *pStNd;
194cdf0e10cSrcweir 	SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
195cdf0e10cSrcweir 	while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
196cdf0e10cSrcweir 	{
197cdf0e10cSrcweir 		aIdx++;
198cdf0e10cSrcweir 		SwOLENode *pNd = aIdx.GetNode().GetOLENode();
199cdf0e10cSrcweir 		if( pNd && aOldName == pNd->GetChartTblName() )
200cdf0e10cSrcweir 		{
201cdf0e10cSrcweir 			pNd->SetChartTblName( rNewName );
202cdf0e10cSrcweir 
203cdf0e10cSrcweir             ViewShell* pVSh;
204cdf0e10cSrcweir             GetEditShell( &pVSh );
205cdf0e10cSrcweir 
206cdf0e10cSrcweir             SwTable* pTable = SwTable::FindTable( &rTblFmt );
207cdf0e10cSrcweir             SwChartDataProvider *pPCD = GetChartDataProvider();
208cdf0e10cSrcweir             if (pPCD)
209cdf0e10cSrcweir                 pPCD->InvalidateTable( pTable );
210cdf0e10cSrcweir 			// following this the framework will now take care of repainting
211cdf0e10cSrcweir 			// the chart or it's replacement image...
212cdf0e10cSrcweir 		}
213cdf0e10cSrcweir 		aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
214cdf0e10cSrcweir 	}
215cdf0e10cSrcweir 	SetModified();
216cdf0e10cSrcweir }
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 
GetChartDataProvider(bool bCreate) const219cdf0e10cSrcweir SwChartDataProvider * SwDoc::GetChartDataProvider( bool bCreate ) const
220cdf0e10cSrcweir {
221cdf0e10cSrcweir     // since there must be only one instance of this object per document
222cdf0e10cSrcweir     // we need a mutex here
223cdf0e10cSrcweir     vos::OGuard aGuard( Application::GetSolarMutex() );
224cdf0e10cSrcweir 
225cdf0e10cSrcweir     if (bCreate && !aChartDataProviderImplRef.get())
226cdf0e10cSrcweir     {
227cdf0e10cSrcweir         aChartDataProviderImplRef = comphelper::ImplementationReference< SwChartDataProvider
228cdf0e10cSrcweir             , chart2::data::XDataProvider >( new SwChartDataProvider( this ) );
229cdf0e10cSrcweir     }
230cdf0e10cSrcweir     return aChartDataProviderImplRef.get();
231cdf0e10cSrcweir }
232cdf0e10cSrcweir 
233cdf0e10cSrcweir 
CreateChartInternalDataProviders(const SwTable * pTable)234cdf0e10cSrcweir void SwDoc::CreateChartInternalDataProviders( const SwTable *pTable )
235cdf0e10cSrcweir {
236cdf0e10cSrcweir     if (pTable)
237cdf0e10cSrcweir     {
238cdf0e10cSrcweir         String aName( pTable->GetFrmFmt()->GetName() );
239cdf0e10cSrcweir         SwOLENode *pONd;
240cdf0e10cSrcweir         SwStartNode *pStNd;
241cdf0e10cSrcweir         SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
242cdf0e10cSrcweir         while (0 != (pStNd = aIdx.GetNode().GetStartNode()))
243cdf0e10cSrcweir         {
244cdf0e10cSrcweir             aIdx++;
245cdf0e10cSrcweir             if( 0 != ( pONd = aIdx.GetNode().GetOLENode() ) &&
246cdf0e10cSrcweir                 aName.Equals( pONd->GetChartTblName() ) /* OLE node is chart? */ &&
247cdf0e10cSrcweir                 0 != (pONd->getLayoutFrm( GetCurrentLayout() )) /* chart frame is not hidden */ )
248cdf0e10cSrcweir             {
249cdf0e10cSrcweir                 uno::Reference < embed::XEmbeddedObject > xIP = pONd->GetOLEObj().GetOleRef();
250cdf0e10cSrcweir                 if ( svt::EmbeddedObjectRef::TryRunningState( xIP ) )
251cdf0e10cSrcweir                 {
252cdf0e10cSrcweir                     uno::Reference< chart2::XChartDocument > xChart( xIP->getComponent(), UNO_QUERY );
253cdf0e10cSrcweir                     if (xChart.is())
254cdf0e10cSrcweir                         xChart->createInternalDataProvider( sal_True );
255cdf0e10cSrcweir 
256cdf0e10cSrcweir                     // there may be more than one chart for each table thus we need to continue the loop...
257cdf0e10cSrcweir                 }
258cdf0e10cSrcweir             }
259cdf0e10cSrcweir             aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
260cdf0e10cSrcweir         }
261cdf0e10cSrcweir     }
262cdf0e10cSrcweir }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir 
GetChartControllerHelper()265cdf0e10cSrcweir SwChartLockController_Helper & SwDoc::GetChartControllerHelper()
266cdf0e10cSrcweir {
267cdf0e10cSrcweir     if (!pChartControllerHelper)
268cdf0e10cSrcweir     {
269cdf0e10cSrcweir         pChartControllerHelper = new SwChartLockController_Helper( this );
270cdf0e10cSrcweir     }
271cdf0e10cSrcweir     return *pChartControllerHelper;
272cdf0e10cSrcweir }
273cdf0e10cSrcweir 
274