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 #include <com/sun/star/chart/ChartDataRowSource.hpp> 28 #include <com/sun/star/chart2/data/XDataProvider.hpp> 29 #include <com/sun/star/chart2/data/XDataReceiver.hpp> 30 #include <com/sun/star/beans/PropertyState.hpp> 31 32 #include <sot/storage.hxx> 33 #include <sot/clsids.hxx> 34 #include <svx/charthelper.hxx> 35 36 #include "edtwin.hxx" 37 #include "errhdl.hxx" 38 #include "wrtsh.hxx" 39 #include "cmdid.h" 40 #include "frmatr.hxx" 41 #include "view.hxx" 42 #include "basesh.hxx" 43 #include "swundo.hxx" 44 #include "tablemgr.hxx" 45 #include "frmfmt.hxx" 46 #include "instable.hxx" 47 #include "swerror.h" 48 #include "table.hrc" 49 #include "swabstdlg.hxx" 50 #include "swcli.hxx" 51 #include "docsh.hxx" 52 #include "unotbl.hxx" 53 #include "unochart.hxx" 54 55 using namespace ::com::sun::star; 56 57 /*------------------------------------------------------------------------ 58 Beschreibung: Zeilenhoehe einstellen (Dialog) 59 ------------------------------------------------------------------------*/ 60 61 62 void SwTableFUNC::ColWidthDlg( Window *pParent ) 63 { 64 InitTabCols(); 65 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); 66 DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!"); 67 68 VclAbstractDialog* pDlg = pFact->CreateSwTableWidthDlg( pParent, *this ,DLG_COL_WIDTH ); 69 DBG_ASSERT(pDlg, "Dialogdiet fail!"); 70 pDlg->Execute(); 71 delete pDlg; 72 } 73 74 /*-------------------------------------------------------------------- 75 Beschreibung: Breite ermitteln 76 --------------------------------------------------------------------*/ 77 78 79 SwTwips SwTableFUNC::GetColWidth(sal_uInt16 nNum) const 80 { 81 SwTwips nWidth = 0; 82 83 if( aCols.Count() > 0 ) 84 { 85 if(aCols.Count() == GetColCount()) 86 { 87 nWidth = (SwTwips)((nNum == aCols.Count()) ? 88 aCols.GetRight() - aCols[nNum-1] : 89 nNum == 0 ? aCols[nNum] - aCols.GetLeft() : 90 aCols[nNum] - aCols[nNum-1]); 91 } 92 else 93 { 94 SwTwips nRValid = nNum < GetColCount() ? 95 aCols[(sal_uInt16)GetRightSeparator((int)nNum)]: 96 aCols.GetRight(); 97 SwTwips nLValid = nNum ? 98 aCols[(sal_uInt16)GetRightSeparator((int)nNum - 1)]: 99 aCols.GetLeft(); 100 nWidth = nRValid - nLValid; 101 } 102 } 103 else 104 nWidth = aCols.GetRight(); 105 106 return nWidth; 107 } 108 109 110 111 SwTwips SwTableFUNC::GetMaxColWidth( sal_uInt16 nNum ) const 112 { 113 ASSERT(nNum <= aCols.Count(), "Index out of Area"); 114 115 if ( GetColCount() > 0 ) 116 { 117 // Die max. Breite ergibt sich aus der eigenen Breite und 118 // der Breite der Nachbarzellen um je MINLAY verringert 119 SwTwips nMax = nNum == 0 ? 120 GetColWidth(1) - MINLAY : 121 nNum == GetColCount() ? 122 GetColWidth( nNum-1 ) - MINLAY : 123 GetColWidth(nNum - 1) + GetColWidth( nNum + 1 ) - 2 * MINLAY; 124 125 return nMax + GetColWidth(nNum) ; 126 } 127 else 128 return GetColWidth(nNum); 129 } 130 131 132 133 void SwTableFUNC::SetColWidth(sal_uInt16 nNum, SwTwips nNewWidth ) 134 { 135 // aktuelle Breite setzen 136 // alle folgenden Verschieben 137 sal_Bool bCurrentOnly = sal_False; 138 SwTwips nWidth = 0; 139 140 if ( aCols.Count() > 0 ) 141 { 142 if(aCols.Count() != GetColCount()) 143 bCurrentOnly = sal_True; 144 nWidth = GetColWidth(nNum); 145 146 int nDiff = (int)(nNewWidth - nWidth); 147 if( !nNum ) 148 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(0)) ] += nDiff; 149 else if( nNum < GetColCount() ) 150 { 151 if(nDiff < GetColWidth(nNum + 1) - MINLAY) 152 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(nNum)) ] += nDiff; 153 else 154 { 155 int nDiffLeft = nDiff - (int)GetColWidth(nNum + 1) + (int)MINLAY; 156 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(nNum)) ] += (nDiff - nDiffLeft); 157 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(nNum - 1)) ] -= nDiffLeft; 158 } 159 } 160 else 161 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(nNum-1)) ] -= nDiff; 162 } 163 else 164 aCols.SetRight( Min( nNewWidth, aCols.GetRightMax()) ); 165 166 pSh->StartAllAction(); 167 pSh->SetTabCols( aCols, bCurrentOnly ); 168 pSh->EndAllAction(); 169 } 170 171 172 173 void SwTableFUNC::InitTabCols() 174 { 175 ASSERT(pSh, keine Shell); 176 177 if( pFmt && pSh) 178 pSh->GetTabCols( aCols ); 179 } 180 181 182 183 SwTableFUNC::SwTableFUNC(SwWrtShell *pShell, sal_Bool bCopyFmt) 184 : pFmt(pShell->GetTableFmt()), 185 pSh(pShell), 186 bCopy(bCopyFmt) 187 { 188 // gfs. das Format fuer die Bearbeitung kopieren 189 if( pFmt && bCopy ) 190 pFmt = new SwFrmFmt( *pFmt ); 191 } 192 193 194 195 SwTableFUNC::~SwTableFUNC() 196 { 197 if(bCopy) 198 delete pFmt; 199 } 200 201 void SwTableFUNC::UpdateChart() 202 { 203 //Update der Felder in der Tabelle vom User ausgeloesst, alle 204 //Charts zu der Tabelle werden auf den neuesten Stand gebracht. 205 SwFrmFmt *pFmt2 = pSh->GetTableFmt(); 206 if ( pFmt2 && pSh->HasOLEObj( pFmt2->GetName() ) ) 207 { 208 pSh->StartAllAction(); 209 pSh->UpdateCharts( pFmt2->GetName() ); 210 pSh->EndAllAction(); 211 } 212 } 213 214 uno::Reference< frame::XModel > SwTableFUNC::InsertChart( 215 uno::Reference< chart2::data::XDataProvider > &rxDataProvider, 216 sal_Bool bFillWithData, 217 const rtl::OUString &rCellRange, 218 SwFlyFrmFmt** ppFlyFrmFmt ) 219 { 220 uno::Reference< frame::XModel > xChartModel; 221 pSh->StartUndo( UNDO_UI_INSERT_CHART ); 222 pSh->StartAllAction(); 223 224 String aName; 225 if (pSh->IsCrsrInTbl()) 226 { 227 aName = pSh->GetTableFmt()->GetName(); 228 // insert node before table 229 pSh->MoveTable( fnTableCurr, fnTableStart ); 230 pSh->Up( sal_False, 1, sal_False ); 231 if ( pSh->IsCrsrInTbl() ) 232 { 233 if ( aName != pSh->GetTableFmt()->GetName() ) 234 pSh->Down( sal_False, 1, sal_False ); // two adjacent tables 235 } 236 pSh->SplitNode(); 237 } 238 239 // insert chart 240 ::rtl::OUString aObjName; 241 comphelper::EmbeddedObjectContainer aCnt; 242 uno::Reference < embed::XEmbeddedObject > xObj = 243 aCnt.CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aObjName ); 244 245 ::svt::EmbeddedObjectRef aEmbObjRef( xObj, ::com::sun::star::embed::Aspects::MSOLE_CONTENT ); 246 if ( xObj.is() ) 247 { 248 249 SwFlyFrmFmt* pTmp = 0; 250 pSh->InsertOleObject( aEmbObjRef, &pTmp ); 251 if (ppFlyFrmFmt) 252 *ppFlyFrmFmt = pTmp; 253 254 uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY ); 255 if( xCompSupp.is()) 256 { 257 xChartModel.set( xCompSupp->getComponent(), uno::UNO_QUERY ); 258 if( xChartModel.is() ) 259 xChartModel->lockControllers(); //#i79578# don't request a new replacement image for charts to often - block change notifications 260 } 261 262 // set the table name at the OLE-node 263 if (aName.Len()) 264 pSh->SetChartName( aName ); 265 } 266 pSh->EndAllAction(); 267 268 if ( xObj.is() ) 269 { 270 // Let the chart be activated after the inserting 271 SfxInPlaceClient* pClient = pSh->GetView().FindIPClient( xObj, &pSh->GetView().GetEditWin() ); 272 if ( !pClient ) 273 { 274 pClient = new SwOleClient( &pSh->GetView(), &pSh->GetView().GetEditWin(), aEmbObjRef ); 275 pSh->SetCheckForOLEInCaption( sal_True ); 276 } 277 pSh->CalcAndSetScale( aEmbObjRef ); 278 //#50270# Error brauchen wir nicht handeln, das erledigt das 279 //DoVerb in der SfxViewShell 280 ErrCode nErr = pClient->DoVerb( SVVERB_SHOW ); 281 (void) nErr; 282 283 // #121334# 284 ChartHelper::AdaptDefaultsForChart( xObj ); 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