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