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