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