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