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 #include <com/sun/star/chart/ChartDataRowSource.hpp> 32 #include <com/sun/star/chart2/data/XDataProvider.hpp> 33 #include <com/sun/star/chart2/data/XDataReceiver.hpp> 34 #include <com/sun/star/beans/PropertyState.hpp> 35 36 #include <sot/storage.hxx> 37 #include <sot/clsids.hxx> 38 39 #include "edtwin.hxx" 40 #include "errhdl.hxx" 41 #include "wrtsh.hxx" 42 #include "cmdid.h" 43 #include "frmatr.hxx" 44 #include "view.hxx" 45 #include "basesh.hxx" 46 #include "swundo.hxx" 47 #include "tablemgr.hxx" 48 #include "frmfmt.hxx" 49 #include "instable.hxx" 50 #include "swerror.h" 51 #include "table.hrc" 52 #include "swabstdlg.hxx" 53 #include "swcli.hxx" 54 #include "docsh.hxx" 55 #include "unotbl.hxx" 56 #include "unochart.hxx" 57 58 using namespace ::com::sun::star; 59 60 /*------------------------------------------------------------------------ 61 Beschreibung: Zeilenhoehe einstellen (Dialog) 62 ------------------------------------------------------------------------*/ 63 64 65 void SwTableFUNC::ColWidthDlg( Window *pParent ) 66 { 67 InitTabCols(); 68 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); 69 DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!"); 70 71 VclAbstractDialog* pDlg = pFact->CreateSwTableWidthDlg( pParent, *this ,DLG_COL_WIDTH ); 72 DBG_ASSERT(pDlg, "Dialogdiet fail!"); 73 pDlg->Execute(); 74 delete pDlg; 75 } 76 77 /*-------------------------------------------------------------------- 78 Beschreibung: Breite ermitteln 79 --------------------------------------------------------------------*/ 80 81 82 SwTwips SwTableFUNC::GetColWidth(sal_uInt16 nNum) const 83 { 84 SwTwips nWidth = 0; 85 86 if( aCols.Count() > 0 ) 87 { 88 if(aCols.Count() == GetColCount()) 89 { 90 nWidth = (SwTwips)((nNum == aCols.Count()) ? 91 aCols.GetRight() - aCols[nNum-1] : 92 nNum == 0 ? aCols[nNum] - aCols.GetLeft() : 93 aCols[nNum] - aCols[nNum-1]); 94 } 95 else 96 { 97 SwTwips nRValid = nNum < GetColCount() ? 98 aCols[(sal_uInt16)GetRightSeparator((int)nNum)]: 99 aCols.GetRight(); 100 SwTwips nLValid = nNum ? 101 aCols[(sal_uInt16)GetRightSeparator((int)nNum - 1)]: 102 aCols.GetLeft(); 103 nWidth = nRValid - nLValid; 104 } 105 } 106 else 107 nWidth = aCols.GetRight(); 108 109 return nWidth; 110 } 111 112 113 114 SwTwips SwTableFUNC::GetMaxColWidth( sal_uInt16 nNum ) const 115 { 116 ASSERT(nNum <= aCols.Count(), "Index out of Area"); 117 118 if ( GetColCount() > 0 ) 119 { 120 // Die max. Breite ergibt sich aus der eigenen Breite und 121 // der Breite der Nachbarzellen um je MINLAY verringert 122 SwTwips nMax = nNum == 0 ? 123 GetColWidth(1) - MINLAY : 124 nNum == GetColCount() ? 125 GetColWidth( nNum-1 ) - MINLAY : 126 GetColWidth(nNum - 1) + GetColWidth( nNum + 1 ) - 2 * MINLAY; 127 128 return nMax + GetColWidth(nNum) ; 129 } 130 else 131 return GetColWidth(nNum); 132 } 133 134 135 136 void SwTableFUNC::SetColWidth(sal_uInt16 nNum, SwTwips nNewWidth ) 137 { 138 // aktuelle Breite setzen 139 // alle folgenden Verschieben 140 sal_Bool bCurrentOnly = sal_False; 141 SwTwips nWidth = 0; 142 143 if ( aCols.Count() > 0 ) 144 { 145 if(aCols.Count() != GetColCount()) 146 bCurrentOnly = sal_True; 147 nWidth = GetColWidth(nNum); 148 149 int nDiff = (int)(nNewWidth - nWidth); 150 if( !nNum ) 151 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(0)) ] += nDiff; 152 else if( nNum < GetColCount() ) 153 { 154 if(nDiff < GetColWidth(nNum + 1) - MINLAY) 155 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(nNum)) ] += nDiff; 156 else 157 { 158 int nDiffLeft = nDiff - (int)GetColWidth(nNum + 1) + (int)MINLAY; 159 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(nNum)) ] += (nDiff - nDiffLeft); 160 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(nNum - 1)) ] -= nDiffLeft; 161 } 162 } 163 else 164 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(nNum-1)) ] -= nDiff; 165 } 166 else 167 aCols.SetRight( Min( nNewWidth, aCols.GetRightMax()) ); 168 169 pSh->StartAllAction(); 170 pSh->SetTabCols( aCols, bCurrentOnly ); 171 pSh->EndAllAction(); 172 } 173 174 175 176 void SwTableFUNC::InitTabCols() 177 { 178 ASSERT(pSh, keine Shell); 179 180 if( pFmt && pSh) 181 pSh->GetTabCols( aCols ); 182 } 183 184 185 186 SwTableFUNC::SwTableFUNC(SwWrtShell *pShell, sal_Bool bCopyFmt) 187 : pFmt(pShell->GetTableFmt()), 188 pSh(pShell), 189 bCopy(bCopyFmt) 190 { 191 // gfs. das Format fuer die Bearbeitung kopieren 192 if( pFmt && bCopy ) 193 pFmt = new SwFrmFmt( *pFmt ); 194 } 195 196 197 198 SwTableFUNC::~SwTableFUNC() 199 { 200 if(bCopy) 201 delete pFmt; 202 } 203 204 void SwTableFUNC::UpdateChart() 205 { 206 //Update der Felder in der Tabelle vom User ausgeloesst, alle 207 //Charts zu der Tabelle werden auf den neuesten Stand gebracht. 208 SwFrmFmt *pFmt2 = pSh->GetTableFmt(); 209 if ( pFmt2 && pSh->HasOLEObj( pFmt2->GetName() ) ) 210 { 211 pSh->StartAllAction(); 212 pSh->UpdateCharts( pFmt2->GetName() ); 213 pSh->EndAllAction(); 214 } 215 } 216 217 uno::Reference< frame::XModel > SwTableFUNC::InsertChart( 218 uno::Reference< chart2::data::XDataProvider > &rxDataProvider, 219 sal_Bool bFillWithData, 220 const rtl::OUString &rCellRange, 221 SwFlyFrmFmt** ppFlyFrmFmt ) 222 { 223 uno::Reference< frame::XModel > xChartModel; 224 pSh->StartUndo( UNDO_UI_INSERT_CHART ); 225 pSh->StartAllAction(); 226 227 String aName; 228 if (pSh->IsCrsrInTbl()) 229 { 230 aName = pSh->GetTableFmt()->GetName(); 231 // insert node before table 232 pSh->MoveTable( fnTableCurr, fnTableStart ); 233 pSh->Up( sal_False, 1, sal_False ); 234 if ( pSh->IsCrsrInTbl() ) 235 { 236 if ( aName != pSh->GetTableFmt()->GetName() ) 237 pSh->Down( sal_False, 1, sal_False ); // two adjacent tables 238 } 239 pSh->SplitNode(); 240 } 241 242 // insert chart 243 ::rtl::OUString aObjName; 244 comphelper::EmbeddedObjectContainer aCnt; 245 uno::Reference < embed::XEmbeddedObject > xObj = 246 aCnt.CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aObjName ); 247 248 ::svt::EmbeddedObjectRef aEmbObjRef( xObj, ::com::sun::star::embed::Aspects::MSOLE_CONTENT ); 249 if ( xObj.is() ) 250 { 251 252 SwFlyFrmFmt* pTmp = 0; 253 pSh->InsertOleObject( aEmbObjRef, &pTmp ); 254 if (ppFlyFrmFmt) 255 *ppFlyFrmFmt = pTmp; 256 257 uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY ); 258 if( xCompSupp.is()) 259 { 260 xChartModel.set( xCompSupp->getComponent(), uno::UNO_QUERY ); 261 if( xChartModel.is() ) 262 xChartModel->lockControllers(); //#i79578# don't request a new replacement image for charts to often - block change notifications 263 } 264 265 // set the table name at the OLE-node 266 if (aName.Len()) 267 pSh->SetChartName( aName ); 268 } 269 pSh->EndAllAction(); 270 271 if ( xObj.is() ) 272 { 273 // Let the chart be activated after the inserting 274 SfxInPlaceClient* pClient = pSh->GetView().FindIPClient( xObj, &pSh->GetView().GetEditWin() ); 275 if ( !pClient ) 276 { 277 pClient = new SwOleClient( &pSh->GetView(), &pSh->GetView().GetEditWin(), aEmbObjRef ); 278 pSh->SetCheckForOLEInCaption( sal_True ); 279 } 280 pSh->CalcAndSetScale( aEmbObjRef ); 281 //#50270# Error brauchen wir nicht handeln, das erledigt das 282 //DoVerb in der SfxViewShell 283 ErrCode nErr = pClient->DoVerb( SVVERB_SHOW ); 284 (void) nErr; 285 } 286 287 uno::Reference< chart2::data::XDataReceiver > xDataReceiver( xChartModel, uno::UNO_QUERY ); 288 if (bFillWithData && xDataReceiver.is() && rxDataProvider.is()) 289 { 290 xDataReceiver->attachDataProvider( rxDataProvider ); 291 292 uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pSh->GetView().GetDocShell()->GetModel(), uno::UNO_QUERY ); 293 xDataReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier ); 294 295 // default values for ranges that do not consist of a single row or column 296 bool bHasCategories = true; 297 bool bFirstCellAsLabel = true; 298 chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; 299 300 SwRangeDescriptor aDesc; 301 FillRangeDescriptor( aDesc, rCellRange ); 302 bool bSingleRowCol = aDesc.nTop == aDesc.nBottom || aDesc.nLeft == aDesc.nRight; 303 if (bSingleRowCol) 304 { 305 aDesc.Normalize(); 306 sal_Int32 nRowLen = aDesc.nRight - aDesc.nLeft + 1; 307 sal_Int32 nColLen = aDesc.nBottom - aDesc.nTop + 1; 308 309 bHasCategories = false; 310 if (nRowLen == 1 && nColLen == 1) 311 bFirstCellAsLabel = false; 312 else if (nRowLen > 1) 313 eDataRowSource = chart::ChartDataRowSource_ROWS; 314 else if (nColLen > 1) 315 eDataRowSource = chart::ChartDataRowSource_COLUMNS; 316 else { 317 DBG_ERROR( "unexpected state" ); 318 } 319 } 320 321 uno::Sequence< beans::PropertyValue > aArgs( 4 ); 322 aArgs[0] = beans::PropertyValue( 323 ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1, 324 uno::makeAny( rCellRange ), beans::PropertyState_DIRECT_VALUE ); 325 aArgs[1] = beans::PropertyValue( 326 ::rtl::OUString::createFromAscii("HasCategories"), -1, 327 uno::makeAny( bHasCategories ), beans::PropertyState_DIRECT_VALUE ); 328 aArgs[2] = beans::PropertyValue( 329 ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1, 330 uno::makeAny( bFirstCellAsLabel ), beans::PropertyState_DIRECT_VALUE ); 331 aArgs[3] = beans::PropertyValue( 332 ::rtl::OUString::createFromAscii("DataRowSource"), -1, 333 uno::makeAny( eDataRowSource ), beans::PropertyState_DIRECT_VALUE ); 334 xDataReceiver->setArguments( aArgs ); 335 } 336 337 pSh->EndUndo( UNDO_UI_INSERT_CHART ); 338 339 if( xChartModel.is() ) 340 xChartModel->unlockControllers(); //#i79578# don't request a new replacement image for charts to often 341 return xChartModel; 342 } 343 344 sal_uInt16 SwTableFUNC::GetCurColNum() const 345 { 346 sal_uInt16 nPos = pSh->GetCurTabColNum(); 347 sal_uInt16 nCount = 0; 348 for(sal_uInt16 i = 0; i < nPos; i++ ) 349 if(aCols.IsHidden(i)) 350 nCount ++; 351 return nPos - nCount; 352 } 353 354 355 356 357 sal_uInt16 SwTableFUNC::GetColCount() const 358 { 359 sal_uInt16 nCount = 0; 360 for(sal_uInt16 i = 0; i < aCols.Count(); i++ ) 361 if(aCols.IsHidden(i)) 362 nCount ++; 363 return aCols.Count() - nCount; 364 } 365 366 367 368 int SwTableFUNC::GetRightSeparator(int nNum) const 369 { 370 DBG_ASSERT( nNum < (int)GetColCount() ,"Index out of range"); 371 int i = 0; 372 while( nNum >= 0 ) 373 { 374 if( !aCols.IsHidden( static_cast< sal_uInt16 >(i)) ) 375 nNum--; 376 i++; 377 } 378 return i - 1; 379 } 380 381 382 383