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 60 void SwTable::UpdateCharts() const 61 { 62 GetFrmFmt()->GetDoc()->UpdateCharts( GetFrmFmt()->GetName() ); 63 } 64 65 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 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 131 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 155 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 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 219 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 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 265 SwChartLockController_Helper & SwDoc::GetChartControllerHelper() 266 { 267 if (!pChartControllerHelper) 268 { 269 pChartControllerHelper = new SwChartLockController_Helper( this ); 270 } 271 return *pChartControllerHelper; 272 } 273 274