xref: /trunk/main/sw/source/core/doc/docchart.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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