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