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_svx.hxx" 26 27 #include <svx/sdr/table/tablecontroller.hxx> 28 #include <tablemodel.hxx> 29 30 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> 31 #include <com/sun/star/container/XIndexAccess.hpp> 32 33 #include <com/sun/star/beans/XPropertySet.hpp> 34 #include <com/sun/star/table/XMergeableCellRange.hpp> 35 #include <com/sun/star/table/XMergeableCell.hpp> 36 37 #include <sal/config.h> 38 39 #include <vcl/svapp.hxx> 40 #include <svl/whiter.hxx> 41 42 #include <sfx2/request.hxx> 43 44 #include <editeng/scripttypeitem.hxx> 45 #include <svx/svdotable.hxx> 46 #include <svx/sdr/overlay/overlayobjectcell.hxx> 47 #include <svx/sdr/overlay/overlaymanager.hxx> 48 #include <svx/svxids.hrc> 49 #include <editeng/outlobj.hxx> 50 #include <svx/svdoutl.hxx> 51 #include <svx/svdpagv.hxx> 52 #include <svx/svdetc.hxx> 53 #include <editeng/editobj.hxx> 54 #include "editeng/editstat.hxx" 55 #include "editeng/unolingu.hxx" 56 #include "svx/sdrpagewindow.hxx" 57 #include <svx/selectioncontroller.hxx> 58 #include <svx/svdmodel.hxx> 59 #include "svx/sdrpaintwindow.hxx" 60 #include <svx/svxdlg.hxx> 61 #include <editeng/boxitem.hxx> 62 #include "cell.hxx" 63 #include <editeng/borderline.hxx> 64 #include <editeng/colritem.hxx> 65 #include "editeng/bolnitem.hxx" 66 #include "svx/svdstr.hrc" 67 #include "svx/svdglob.hxx" 68 #include "svx/svdpage.hxx" 69 #include "tableundo.hxx" 70 #include "tablelayouter.hxx" 71 72 using ::rtl::OUString; 73 using namespace ::sdr::table; 74 using namespace ::com::sun::star; 75 using namespace ::com::sun::star::uno; 76 using namespace ::com::sun::star::table; 77 using namespace ::com::sun::star::beans; 78 using namespace ::com::sun::star::container; 79 using namespace ::com::sun::star::text; 80 using namespace ::com::sun::star::style; 81 82 namespace sdr { namespace table { 83 84 // -------------------------------------------------------------------- 85 // class SvxTableControllerModifyListener 86 // -------------------------------------------------------------------- 87 88 class SvxTableControllerModifyListener : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XModifyListener > 89 { 90 public: 91 SvxTableControllerModifyListener( SvxTableController* pController ) 92 : mpController( pController ) {} 93 94 // XModifyListener 95 virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException); 96 97 // XEventListener 98 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); 99 100 SvxTableController* mpController; 101 }; 102 103 // -------------------------------------------------------------------- 104 // XModifyListener 105 // -------------------------------------------------------------------- 106 107 void SAL_CALL SvxTableControllerModifyListener::modified( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException) 108 { 109 if( mpController ) 110 mpController->onTableModified(); 111 } 112 113 // -------------------------------------------------------------------- 114 // XEventListener 115 // -------------------------------------------------------------------- 116 117 void SAL_CALL SvxTableControllerModifyListener::disposing( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException) 118 { 119 mpController = 0; 120 } 121 122 // -------------------------------------------------------------------- 123 // class SvxTableController 124 // -------------------------------------------------------------------- 125 126 rtl::Reference< sdr::SelectionController > CreateTableController( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController ) 127 { 128 return SvxTableController::create( pView, pObj, xRefController ); 129 } 130 131 // -------------------------------------------------------------------- 132 133 rtl::Reference< sdr::SelectionController > SvxTableController::create( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController ) 134 { 135 if( xRefController.is() ) 136 { 137 SvxTableController* pController = dynamic_cast< SvxTableController* >( xRefController.get() ); 138 if( pController && (pController->mxTableObj.get() == pObj) && (pController->mpView == pView) ) 139 return xRefController; 140 } 141 return new SvxTableController( pView, pObj ); 142 } 143 144 // -------------------------------------------------------------------- 145 146 SvxTableController::SvxTableController( SdrObjEditView* pView, const SdrObject* pObj ) 147 : mbCellSelectionMode(false) 148 , mbLeftButtonDown(false) 149 , mpSelectionOverlay(0) 150 , mpView( dynamic_cast< SdrView* >( pView ) ) 151 , mxTableObj( dynamic_cast< SdrTableObj* >( const_cast< SdrObject* >( pObj ) ) ) 152 , mpModel( 0 ) 153 , mnUpdateEvent( 0 ) 154 { 155 if( pObj ) 156 mpModel = pObj->GetModel(); 157 158 if( mxTableObj.is() ) 159 { 160 static_cast< const SdrTableObj* >( pObj )->getActiveCellPos( maCursorFirstPos ); 161 maCursorLastPos = maCursorFirstPos; 162 163 Reference< XTable > xTable( static_cast< const SdrTableObj* >( pObj )->getTable() ); 164 if( xTable.is() ) 165 { 166 mxModifyListener = new SvxTableControllerModifyListener( this ); 167 xTable->addModifyListener( mxModifyListener ); 168 169 mxTable.set( dynamic_cast< TableModel* >( xTable.get() ) ); 170 } 171 } 172 } 173 174 // -------------------------------------------------------------------- 175 176 SvxTableController::~SvxTableController() 177 { 178 if( mnUpdateEvent ) 179 { 180 Application::RemoveUserEvent( mnUpdateEvent ); 181 } 182 183 if( mxModifyListener.is() && mxTableObj.get() ) 184 { 185 Reference< XTable > xTable( static_cast< SdrTableObj* >( mxTableObj.get() )->getTable() ); 186 if( xTable.is() ) 187 { 188 xTable->removeModifyListener( mxModifyListener ); 189 mxModifyListener.clear(); 190 } 191 } 192 } 193 194 // -------------------------------------------------------------------- 195 196 const sal_uInt16 ACTION_NONE = 0; 197 const sal_uInt16 ACTION_GOTO_FIRST_CELL = 1; 198 const sal_uInt16 ACTION_GOTO_FIRST_COLUMN = 2; 199 const sal_uInt16 ACTION_GOTO_FIRST_ROW = 3; 200 const sal_uInt16 ACTION_GOTO_LEFT_CELL = 4; 201 const sal_uInt16 ACTION_GOTO_UP_CELL = 5; 202 const sal_uInt16 ACTION_GOTO_RIGHT_CELL = 6; 203 const sal_uInt16 ACTION_GOTO_DOWN_CELL = 7; 204 const sal_uInt16 ACTION_GOTO_LAST_CELL = 8; 205 const sal_uInt16 ACTION_GOTO_LAST_COLUMN = 9; 206 const sal_uInt16 ACTION_GOTO_LAST_ROW = 10; 207 const sal_uInt16 ACTION_EDIT_CELL = 11; 208 const sal_uInt16 ACTION_STOP_TEXT_EDIT = 12; 209 const sal_uInt16 ACTION_REMOVE_SELECTION = 13; 210 const sal_uInt16 ACTION_START_SELECTION = 14; 211 const sal_uInt16 ACTION_HANDLED_BY_VIEW = 15; 212 const sal_uInt16 ACTION_TAB = 18; 213 214 bool SvxTableController::onKeyInput(const KeyEvent& rKEvt, Window* pWindow ) 215 { 216 if( !checkTableObject() ) 217 return false; 218 219 // check if we are read only 220 if( mpModel && mpModel->IsReadOnly()) 221 { 222 switch( rKEvt.GetKeyCode().GetCode() ) 223 { 224 case awt::Key::DOWN: 225 case awt::Key::UP: 226 case awt::Key::LEFT: 227 case awt::Key::RIGHT: 228 case awt::Key::TAB: 229 case awt::Key::HOME: 230 case awt::Key::END: 231 case awt::Key::NUM2: 232 case awt::Key::NUM4: 233 case awt::Key::NUM6: 234 case awt::Key::NUM8: 235 case awt::Key::ESCAPE: 236 case awt::Key::F2: 237 break; 238 default: 239 // tell the view we eat the event, no further processing needed 240 return true; 241 } 242 } 243 244 sal_uInt16 nAction = getKeyboardAction( rKEvt, pWindow ); 245 246 return executeAction( nAction, ( rKEvt.GetKeyCode().IsShift() ) ? sal_True : sal_False, pWindow ); 247 } 248 249 // -------------------------------------------------------------------- 250 // ::com::sun::star::awt::XMouseClickHandler: 251 // -------------------------------------------------------------------- 252 253 bool SvxTableController::onMouseButtonDown(const MouseEvent& rMEvt, Window* pWindow ) 254 { 255 if( !pWindow || !checkTableObject() ) 256 return false; 257 258 SdrViewEvent aVEvt; 259 if( !rMEvt.IsRight() && mpView->PickAnything(rMEvt,SDRMOUSEBUTTONDOWN, aVEvt) == SDRHIT_HANDLE ) 260 return false; 261 262 TableHitKind eHit = static_cast< SdrTableObj* >(mxTableObj.get())->CheckTableHit( pWindow->PixelToLogic(rMEvt.GetPosPixel()), maMouseDownPos.mnCol, maMouseDownPos.mnRow, 0 ); 263 264 mbLeftButtonDown = (rMEvt.GetClicks() == 1) && rMEvt.IsLeft(); 265 266 if( eHit == SDRTABLEHIT_CELL ) 267 { 268 StartSelection( maMouseDownPos ); 269 return true; 270 } 271 272 if( rMEvt.IsRight() && eHit != SDRTABLEHIT_NONE ) 273 return true; // right click will become context menu 274 275 // for cell selektion with the mouse remember our first hit 276 if( mbLeftButtonDown ) 277 { 278 RemoveSelection(); 279 280 Point aPnt(rMEvt.GetPosPixel()); 281 if (pWindow!=NULL) 282 aPnt=pWindow->PixelToLogic(aPnt); 283 284 SdrHdl* pHdl = mpView->PickHandle(aPnt); 285 286 if( pHdl ) 287 { 288 mbLeftButtonDown = false; 289 } 290 else 291 { 292 ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() ); 293 294 if( !pWindow || !pTableObj || eHit == SDRTABLEHIT_NONE) 295 { 296 mbLeftButtonDown = false; 297 } 298 } 299 } 300 301 return false; 302 } 303 304 // -------------------------------------------------------------------- 305 306 bool SvxTableController::onMouseButtonUp(const MouseEvent& rMEvt, Window* /*pWin*/) 307 { 308 if( !checkTableObject() ) 309 return false; 310 311 mbLeftButtonDown = false; 312 313 if( rMEvt.GetClicks() == 2 ) 314 return true; 315 316 return false; 317 } 318 319 // -------------------------------------------------------------------- 320 321 bool SvxTableController::onMouseMove(const MouseEvent& rMEvt, Window* pWindow ) 322 { 323 if( !checkTableObject() ) 324 return false; 325 326 if( rMEvt.IsLeft() ) 327 { 328 int i = 0; 329 i++; 330 } 331 332 SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() ); 333 CellPos aPos; 334 if( mbLeftButtonDown && pTableObj && pTableObj->CheckTableHit( pWindow->PixelToLogic(rMEvt.GetPosPixel()), aPos.mnCol, aPos.mnRow, 0 ) != SDRTABLEHIT_NONE ) 335 { 336 if(aPos != maMouseDownPos) 337 { 338 if( mbCellSelectionMode ) 339 { 340 setSelectedCells( maMouseDownPos, aPos ); 341 return true; 342 } 343 else 344 { 345 StartSelection( maMouseDownPos ); 346 } 347 } 348 else if( mbCellSelectionMode ) 349 { 350 UpdateSelection( aPos ); 351 return true; 352 } 353 } 354 return false; 355 } 356 357 // -------------------------------------------------------------------- 358 359 void SvxTableController::onSelectionHasChanged() 360 { 361 bool bSelected = false; 362 363 SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() ); 364 if( pTableObj && pTableObj->IsTextEditActive() ) 365 { 366 pTableObj->getActiveCellPos( maCursorFirstPos ); 367 maCursorLastPos = maCursorFirstPos; 368 mbCellSelectionMode = false; 369 } 370 else 371 { 372 const SdrMarkList& rMarkList= mpView->GetMarkedObjectList(); 373 if( rMarkList.GetMarkCount() == 1 ) 374 bSelected = mxTableObj.get() == rMarkList.GetMark(0)->GetMarkedSdrObj(); 375 } 376 377 if( bSelected ) 378 { 379 updateSelectionOverlay(); 380 } 381 else 382 { 383 destroySelectionOverlay(); 384 } 385 } 386 387 // -------------------------------------------------------------------- 388 389 void SvxTableController::GetState( SfxItemSet& rSet ) 390 { 391 if( !mxTable.is() || !mxTableObj.is() || !mxTableObj->GetModel() ) 392 return; 393 394 SfxItemSet* pSet = 0; 395 396 bool bVertDone = false; 397 398 // Iterate over all requested items in the set. 399 SfxWhichIter aIter( rSet ); 400 sal_uInt16 nWhich = aIter.FirstWhich(); 401 while (nWhich) 402 { 403 switch (nWhich) 404 { 405 case SID_TABLE_VERT_BOTTOM: 406 case SID_TABLE_VERT_CENTER: 407 case SID_TABLE_VERT_NONE: 408 { 409 if( !mxTable.is() || !mxTableObj->GetModel() ) 410 { 411 rSet.DisableItem(nWhich); 412 } 413 else if(!bVertDone) 414 { 415 if( !pSet ) 416 { 417 pSet = new SfxItemSet( mxTableObj->GetModel()->GetItemPool() ); 418 MergeAttrFromSelectedCells(*pSet, sal_False); 419 } 420 421 SdrTextVertAdjust eAdj = SDRTEXTVERTADJUST_BLOCK; 422 423 if( pSet->GetItemState( SDRATTR_TEXT_VERTADJUST ) != SFX_ITEM_DONTCARE ) 424 eAdj = ((SdrTextVertAdjustItem&)(pSet->Get(SDRATTR_TEXT_VERTADJUST))).GetValue(); 425 426 rSet.Put(SfxBoolItem(SID_TABLE_VERT_BOTTOM, eAdj == SDRTEXTVERTADJUST_BOTTOM)); 427 rSet.Put(SfxBoolItem(SID_TABLE_VERT_CENTER, eAdj == SDRTEXTVERTADJUST_CENTER)); 428 rSet.Put(SfxBoolItem(SID_TABLE_VERT_NONE, eAdj == SDRTEXTVERTADJUST_TOP)); 429 bVertDone = true; 430 } 431 break; 432 } 433 case SID_TABLE_DELETE_ROW: 434 if( !mxTable.is() || !hasSelectedCells() || (mxTable->getRowCount() <= 1) ) 435 rSet.DisableItem(SID_TABLE_DELETE_ROW); 436 break; 437 case SID_TABLE_DELETE_COL: 438 if( !mxTable.is() || !hasSelectedCells() || (mxTable->getColumnCount() <= 1) ) 439 rSet.DisableItem(SID_TABLE_DELETE_COL); 440 break; 441 case SID_TABLE_MERGE_CELLS: 442 if( !mxTable.is() || !hasSelectedCells() ) 443 rSet.DisableItem(SID_TABLE_MERGE_CELLS); 444 break; 445 case SID_TABLE_SPLIT_CELLS: 446 if( !hasSelectedCells() || !mxTable.is() ) 447 rSet.DisableItem(SID_TABLE_SPLIT_CELLS); 448 break; 449 450 case SID_OPTIMIZE_TABLE: 451 case SID_TABLE_DISTRIBUTE_COLUMNS: 452 case SID_TABLE_DISTRIBUTE_ROWS: 453 { 454 bool bDistributeColumns = false; 455 bool bDistributeRows = false; 456 if( mxTable.is() ) 457 { 458 CellPos aStart, aEnd; 459 getSelectedCells( aStart, aEnd ); 460 461 bDistributeColumns = aStart.mnCol != aEnd.mnCol; 462 bDistributeRows = aStart.mnRow != aEnd.mnRow; 463 } 464 if( !bDistributeColumns && !bDistributeRows ) 465 rSet.DisableItem(SID_OPTIMIZE_TABLE); 466 if( !bDistributeColumns ) 467 rSet.DisableItem(SID_TABLE_DISTRIBUTE_COLUMNS); 468 if( !bDistributeRows ) 469 rSet.DisableItem(SID_TABLE_DISTRIBUTE_ROWS); 470 break; 471 } 472 473 case SID_AUTOFORMAT: 474 case SID_TABLE_SORT_DIALOG: 475 case SID_TABLE_AUTOSUM: 476 // if( !mxTable.is() ) 477 // rSet.DisableItem( nWhich ); 478 break; 479 default: 480 break; 481 } 482 nWhich = aIter.NextWhich(); 483 } 484 if( pSet ) 485 delete pSet; 486 } 487 488 // -------------------------------------------------------------------- 489 490 void SvxTableController::onInsert( sal_uInt16 nSId, const SfxItemSet* pArgs ) 491 { 492 ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() ); 493 if( !pTableObj ) 494 return; 495 496 if( mxTable.is() ) try 497 { 498 // 499 bool bInsertAfter = true; 500 sal_uInt16 nCount = 0; 501 if( pArgs ) 502 { 503 const SfxPoolItem* pItem = 0; 504 pArgs->GetItemState(nSId, sal_False, &pItem); 505 if (pItem) 506 { 507 nCount = ((const SfxInt16Item* )pItem)->GetValue(); 508 if(SFX_ITEM_SET == pArgs->GetItemState(SID_TABLE_PARAM_INSERT_AFTER, sal_True, &pItem)) 509 bInsertAfter = ((const SfxBoolItem* )pItem)->GetValue(); 510 } 511 } 512 513 CellPos aStart, aEnd; 514 if( hasSelectedCells() ) 515 { 516 getSelectedCells( aStart, aEnd ); 517 } 518 else 519 { 520 if( bInsertAfter ) 521 { 522 aStart.mnCol = mxTable->getColumnCount() - 1; 523 aStart.mnRow = mxTable->getRowCount() - 1; 524 aEnd = aStart; 525 } 526 } 527 528 if( pTableObj->IsTextEditActive() ) 529 mpView->SdrEndTextEdit(sal_True); 530 531 RemoveSelection(); 532 533 const OUString sSize( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ); 534 535 const bool bUndo = mpModel && mpModel->IsUndoEnabled(); 536 537 switch( nSId ) 538 { 539 case SID_TABLE_INSERT_COL: 540 { 541 TableModelNotifyGuard aGuard( mxTable.get() ); 542 543 if( bUndo ) 544 { 545 mpModel->BegUndo( ImpGetResStr(STR_TABLE_INSCOL) ); 546 mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) ); 547 } 548 549 Reference< XTableColumns > xCols( mxTable->getColumns() ); 550 const sal_Int32 nNewColumns = (nCount == 0) ? (aEnd.mnCol - aStart.mnCol + 1) : nCount; 551 const sal_Int32 nNewStartColumn = aEnd.mnCol + (bInsertAfter ? 1 : 0); 552 xCols->insertByIndex( nNewStartColumn, nNewColumns ); 553 554 for( sal_Int32 nOffset = 0; nOffset < nNewColumns; nOffset++ ) 555 { 556 Reference< XPropertySet >( xCols->getByIndex( aEnd.mnCol + nOffset + 1 ), UNO_QUERY_THROW )-> 557 setPropertyValue( sSize, 558 Reference< XPropertySet >( xCols->getByIndex( aStart.mnCol + nOffset ), UNO_QUERY_THROW )-> 559 getPropertyValue( sSize ) ); 560 } 561 562 if( bUndo ) 563 mpModel->EndUndo(); 564 565 aStart.mnCol = nNewStartColumn; 566 aStart.mnRow = 0; 567 aEnd.mnCol = aStart.mnCol + nNewColumns - 1; 568 aEnd.mnRow = mxTable->getRowCount() - 1; 569 break; 570 } 571 572 case SID_TABLE_INSERT_ROW: 573 { 574 TableModelNotifyGuard aGuard( mxTable.get() ); 575 576 if( bUndo ) 577 { 578 mpModel->BegUndo( ImpGetResStr(STR_TABLE_INSROW ) ); 579 mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) ); 580 } 581 582 Reference< XTableRows > xRows( mxTable->getRows() ); 583 const sal_Int32 nNewRows = (nCount == 0) ? (aEnd.mnRow - aStart.mnRow + 1) : nCount; 584 const sal_Int32 nNewRowStart = aEnd.mnRow + (bInsertAfter ? 1 : 0); 585 xRows->insertByIndex( nNewRowStart, nNewRows ); 586 587 for( sal_Int32 nOffset = 0; nOffset < nNewRows; nOffset++ ) 588 { 589 Reference< XPropertySet >( xRows->getByIndex( aEnd.mnRow + nOffset + 1 ), UNO_QUERY_THROW )-> 590 setPropertyValue( sSize, 591 Reference< XPropertySet >( xRows->getByIndex( aStart.mnRow + nOffset ), UNO_QUERY_THROW )-> 592 getPropertyValue( sSize ) ); 593 } 594 595 if( bUndo ) 596 mpModel->EndUndo(); 597 598 aStart.mnCol = 0; 599 aStart.mnRow = nNewRowStart; 600 aEnd.mnCol = mxTable->getColumnCount() - 1; 601 aEnd.mnRow = aStart.mnRow + nNewRows - 1; 602 break; 603 } 604 } 605 606 StartSelection( aStart ); 607 UpdateSelection( aEnd ); 608 } 609 catch( Exception& e ) 610 { 611 (void)e; 612 DBG_ERROR("svx::SvxTableController::onInsert(), exception caught!"); 613 } 614 } 615 616 // -------------------------------------------------------------------- 617 618 void SvxTableController::onDelete( sal_uInt16 nSId ) 619 { 620 ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() ); 621 if( !pTableObj ) 622 return; 623 624 if( mxTable.is() && hasSelectedCells() ) 625 { 626 CellPos aStart, aEnd; 627 getSelectedCells( aStart, aEnd ); 628 629 if( pTableObj->IsTextEditActive() ) 630 mpView->SdrEndTextEdit(sal_True); 631 632 RemoveSelection(); 633 634 bool bDeleteTable = false; 635 switch( nSId ) 636 { 637 case SID_TABLE_DELETE_COL: 638 { 639 const sal_Int32 nRemovedColumns = aEnd.mnCol - aStart.mnCol + 1; 640 if( nRemovedColumns == mxTable->getColumnCount() ) 641 { 642 bDeleteTable = true; 643 } 644 else 645 { 646 Reference< XTableColumns > xCols( mxTable->getColumns() ); 647 xCols->removeByIndex( aStart.mnCol, nRemovedColumns ); 648 } 649 break; 650 } 651 652 case SID_TABLE_DELETE_ROW: 653 { 654 const sal_Int32 nRemovedRows = aEnd.mnRow - aStart.mnRow + 1; 655 if( nRemovedRows == mxTable->getRowCount() ) 656 { 657 bDeleteTable = true; 658 } 659 else 660 { 661 Reference< XTableRows > xRows( mxTable->getRows() ); 662 xRows->removeByIndex( aStart.mnRow, nRemovedRows ); 663 } 664 break; 665 } 666 } 667 668 if( bDeleteTable ) 669 mpView->DeleteMarkedObj(); 670 else 671 UpdateTableShape(); 672 } 673 } 674 675 // -------------------------------------------------------------------- 676 677 void SvxTableController::onSelect( sal_uInt16 nSId ) 678 { 679 if( mxTable.is() ) 680 { 681 const sal_Int32 nRowCount = mxTable->getRowCount(); 682 const sal_Int32 nColCount = mxTable->getColumnCount(); 683 if( nRowCount && nColCount ) 684 { 685 CellPos aStart, aEnd; 686 getSelectedCells( aStart, aEnd ); 687 688 switch( nSId ) 689 { 690 case SID_TABLE_SELECT_ALL: 691 aEnd.mnCol = 0; aEnd.mnRow = 0; 692 aStart.mnCol = nColCount - 1; aStart.mnRow = nRowCount - 1; 693 break; 694 case SID_TABLE_SELECT_COL: 695 aEnd.mnRow = nRowCount - 1; 696 aStart.mnRow = 0; 697 break; 698 case SID_TABLE_SELECT_ROW: 699 aEnd.mnCol = nColCount - 1; 700 aStart.mnCol = 0; 701 break; 702 } 703 704 StartSelection( aEnd ); 705 gotoCell( aStart, true, 0 ); 706 } 707 } 708 } 709 710 // -------------------------------------------------------------------- 711 void SvxTableController::onFormatTable( SfxRequest& rReq ) 712 { 713 ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() ); 714 if( !pTableObj ) 715 return; 716 717 const SfxItemSet* pArgs = rReq.GetArgs(); 718 719 if( !pArgs && pTableObj->GetModel() ) 720 { 721 SfxItemSet aNewAttr( pTableObj->GetModel()->GetItemPool() ); 722 MergeAttrFromSelectedCells(aNewAttr, sal_False); 723 724 // merge drawing layer text distance items into SvxBoxItem used by the dialog 725 SvxBoxItem aBoxItem( static_cast< const SvxBoxItem& >( aNewAttr.Get( SDRATTR_TABLE_BORDER ) ) ); 726 aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextLeftDistItem&)(aNewAttr.Get(SDRATTR_TEXT_LEFTDIST))).GetValue()), BOX_LINE_LEFT ); 727 aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextRightDistItem&)(aNewAttr.Get(SDRATTR_TEXT_RIGHTDIST))).GetValue()), BOX_LINE_RIGHT ); 728 aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextUpperDistItem&)(aNewAttr.Get(SDRATTR_TEXT_UPPERDIST))).GetValue()), BOX_LINE_TOP ); 729 aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextLowerDistItem&)(aNewAttr.Get(SDRATTR_TEXT_LOWERDIST))).GetValue()), BOX_LINE_BOTTOM ); 730 aNewAttr.Put( aBoxItem ); 731 732 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); 733 std::auto_ptr< SfxAbstractTabDialog > pDlg( pFact ? pFact->CreateSvxFormatCellsDialog( NULL, &aNewAttr, pTableObj->GetModel(), pTableObj) : 0 ); 734 if( pDlg.get() && pDlg->Execute() ) 735 { 736 SfxItemSet aNewSet( *(pDlg->GetOutputItemSet ()) ); 737 738 SvxBoxItem aNewBoxItem( static_cast< const SvxBoxItem& >( aNewSet.Get( SDRATTR_TABLE_BORDER ) ) ); 739 740 if( aNewBoxItem.GetDistance( BOX_LINE_LEFT ) != aBoxItem.GetDistance( BOX_LINE_LEFT ) ) 741 aNewSet.Put(SdrTextLeftDistItem( aNewBoxItem.GetDistance( BOX_LINE_LEFT ) ) ); 742 743 if( aNewBoxItem.GetDistance( BOX_LINE_RIGHT ) != aBoxItem.GetDistance( BOX_LINE_RIGHT ) ) 744 aNewSet.Put(SdrTextRightDistItem( aNewBoxItem.GetDistance( BOX_LINE_RIGHT ) ) ); 745 746 if( aNewBoxItem.GetDistance( BOX_LINE_TOP ) != aBoxItem.GetDistance( BOX_LINE_TOP ) ) 747 aNewSet.Put(SdrTextUpperDistItem( aNewBoxItem.GetDistance( BOX_LINE_TOP ) ) ); 748 749 if( aNewBoxItem.GetDistance( BOX_LINE_BOTTOM ) != aBoxItem.GetDistance( BOX_LINE_BOTTOM ) ) 750 aNewSet.Put(SdrTextLowerDistItem( aNewBoxItem.GetDistance( BOX_LINE_BOTTOM ) ) ); 751 752 SetAttrToSelectedCells(aNewSet, sal_False); 753 } 754 UpdateTableShape(); 755 } 756 } 757 758 // -------------------------------------------------------------------- 759 760 void SvxTableController::Execute( SfxRequest& rReq ) 761 { 762 const sal_uInt16 nSId = rReq.GetSlot(); 763 switch( nSId ) 764 { 765 case SID_TABLE_INSERT_ROW: 766 case SID_TABLE_INSERT_COL: 767 onInsert( nSId, rReq.GetArgs() ); 768 break; 769 case SID_TABLE_DELETE_ROW: 770 case SID_TABLE_DELETE_COL: 771 onDelete( nSId ); 772 break; 773 case SID_TABLE_SELECT_ALL: 774 case SID_TABLE_SELECT_COL: 775 case SID_TABLE_SELECT_ROW: 776 onSelect( nSId ); 777 break; 778 case SID_FORMAT_TABLE_DLG: 779 onFormatTable( rReq ); 780 break; 781 782 case SID_FRAME_LINESTYLE: 783 case SID_FRAME_LINECOLOR: 784 case SID_ATTR_BORDER: 785 { 786 const SfxItemSet* pArgs = rReq.GetArgs(); 787 if( pArgs ) 788 ApplyBorderAttr( *pArgs ); 789 } 790 break; 791 792 case SID_ATTR_FILL_STYLE: 793 { 794 const SfxItemSet* pArgs = rReq.GetArgs(); 795 if( pArgs ) 796 SetAttributes( *pArgs, false ); 797 } 798 break; 799 800 case SID_TABLE_MERGE_CELLS: 801 MergeMarkedCells(); 802 break; 803 804 case SID_TABLE_SPLIT_CELLS: 805 SplitMarkedCells(); 806 break; 807 808 case SID_TABLE_DISTRIBUTE_COLUMNS: 809 DistributeColumns(); 810 break; 811 812 case SID_TABLE_DISTRIBUTE_ROWS: 813 DistributeRows(); 814 break; 815 816 case SID_TABLE_VERT_BOTTOM: 817 case SID_TABLE_VERT_CENTER: 818 case SID_TABLE_VERT_NONE: 819 SetVertical( nSId ); 820 break; 821 822 case SID_AUTOFORMAT: 823 case SID_TABLE_SORT_DIALOG: 824 case SID_TABLE_AUTOSUM: 825 default: 826 break; 827 828 case SID_TABLE_STYLE: 829 SetTableStyle( rReq.GetArgs() ); 830 break; 831 832 case SID_TABLE_STYLE_SETTINGS: 833 SetTableStyleSettings( rReq.GetArgs() ); 834 break; 835 } 836 } 837 838 void SvxTableController::SetTableStyle( const SfxItemSet* pArgs ) 839 { 840 SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() ); 841 SdrModel* pModel = pTableObj ? pTableObj->GetModel() : 0; 842 843 if( !pTableObj || !pModel || !pArgs || (SFX_ITEM_SET != pArgs->GetItemState(SID_TABLE_STYLE, sal_False)) ) 844 return; 845 846 const SfxStringItem* pArg = dynamic_cast< const SfxStringItem* >( &pArgs->Get( SID_TABLE_STYLE ) ); 847 if( pArg && mxTable.is() ) try 848 { 849 Reference< XStyleFamiliesSupplier > xSFS( pModel->getUnoModel(), UNO_QUERY_THROW ); 850 Reference< XNameAccess > xFamilyNameAccess( xSFS->getStyleFamilies(), UNO_QUERY_THROW ); 851 const OUString sFamilyName( RTL_CONSTASCII_USTRINGPARAM( "table" ) ); 852 Reference< XNameAccess > xTableFamilyAccess( xFamilyNameAccess->getByName( sFamilyName ), UNO_QUERY_THROW ); 853 854 if( xTableFamilyAccess->hasByName( pArg->GetValue() ) ) 855 { 856 // found table style with the same name 857 Reference< XIndexAccess > xNewTableStyle( xTableFamilyAccess->getByName( pArg->GetValue() ), UNO_QUERY_THROW ); 858 859 const bool bUndo = pModel->IsUndoEnabled(); 860 861 if( bUndo ) 862 { 863 pModel->BegUndo( ImpGetResStr(STR_TABLE_STYLE) ); 864 pModel->AddUndo( new TableStyleUndo( *pTableObj ) ); 865 } 866 867 pTableObj->setTableStyle( xNewTableStyle ); 868 869 const sal_Int32 nRowCount = mxTable->getRowCount(); 870 const sal_Int32 nColCount = mxTable->getColumnCount(); 871 for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ ) 872 { 873 for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ ) try 874 { 875 CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) ); 876 if( xCell.is() ) 877 { 878 SfxItemSet aSet( xCell->GetItemSet() ); 879 bool bChanges = false; 880 const SfxItemSet& rStyleAttribs = xCell->GetStyleSheet()->GetItemSet(); 881 882 for ( sal_uInt16 nWhich = SDRATTR_START; nWhich <= SDRATTR_TABLE_LAST; nWhich++ ) 883 { 884 if( (rStyleAttribs.GetItemState( nWhich ) == SFX_ITEM_ON) && (aSet.GetItemState( nWhich ) == SFX_ITEM_ON) ) 885 { 886 aSet.ClearItem( nWhich ); 887 bChanges = true; 888 } 889 } 890 891 if( bChanges ) 892 { 893 if( bUndo ) 894 xCell->AddUndo(); 895 896 xCell->SetMergedItemSetAndBroadcast( aSet, sal_True ); 897 } 898 } 899 } 900 catch( Exception& e ) 901 { 902 (void)e; 903 DBG_ERROR( "svx::SvxTableController::SetTableStyle(), exception caught!" ); 904 } 905 } 906 907 if( bUndo ) 908 pModel->EndUndo(); 909 } 910 } 911 catch( Exception& e ) 912 { 913 (void)e; 914 DBG_ERROR( "svx::SvxTableController::SetTableStyle(), exception caught!" ); 915 } 916 } 917 918 void SvxTableController::SetTableStyleSettings( const SfxItemSet* pArgs ) 919 { 920 SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() ); 921 SdrModel* pModel = pTableObj ? pTableObj->GetModel() : 0; 922 923 if( !pTableObj || !pModel ) 924 return; 925 926 TableStyleSettings aSettings( pTableObj->getTableStyleSettings() ); 927 928 const SfxPoolItem *pPoolItem=NULL; 929 930 if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEFIRSTROWSTYLE, sal_False,&pPoolItem)) ) 931 aSettings.mbUseFirstRow = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue(); 932 933 if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USELASTROWSTYLE, sal_False,&pPoolItem)) ) 934 aSettings.mbUseLastRow = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue(); 935 936 if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEBANDINGROWSTYLE, sal_False,&pPoolItem)) ) 937 aSettings.mbUseRowBanding = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue(); 938 939 if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEFIRSTCOLUMNSTYLE, sal_False,&pPoolItem)) ) 940 aSettings.mbUseFirstColumn = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue(); 941 942 if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USELASTCOLUMNSTYLE, sal_False,&pPoolItem)) ) 943 aSettings.mbUseLastColumn = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue(); 944 945 if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEBANDINGCOLUMNSTYLE, sal_False,&pPoolItem)) ) 946 aSettings.mbUseColumnBanding = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue(); 947 948 if( aSettings == pTableObj->getTableStyleSettings() ) 949 return; 950 951 const bool bUndo = pModel->IsUndoEnabled(); 952 953 if( bUndo ) 954 { 955 pModel->BegUndo( ImpGetResStr(STR_TABLE_STYLE_SETTINGS) ); 956 pModel->AddUndo( new TableStyleUndo( *pTableObj ) ); 957 } 958 959 pTableObj->setTableStyleSettings( aSettings ); 960 961 if( bUndo ) 962 pModel->EndUndo(); 963 } 964 965 void SvxTableController::SetVertical( sal_uInt16 nSId ) 966 { 967 SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() ); 968 if( mxTable.is() && pTableObj ) 969 { 970 TableModelNotifyGuard aGuard( mxTable.get() ); 971 972 CellPos aStart, aEnd; 973 getSelectedCells( aStart, aEnd ); 974 975 SdrTextVertAdjust eAdj = SDRTEXTVERTADJUST_TOP; 976 977 switch( nSId ) 978 { 979 case SID_TABLE_VERT_BOTTOM: 980 eAdj = SDRTEXTVERTADJUST_BOTTOM; 981 break; 982 case SID_TABLE_VERT_CENTER: 983 eAdj = SDRTEXTVERTADJUST_CENTER; 984 break; 985 //case SID_TABLE_VERT_NONE: 986 default: 987 break; 988 } 989 990 SdrTextVertAdjustItem aItem( eAdj ); 991 992 for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ ) 993 { 994 for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ ) 995 { 996 CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) ); 997 if( xCell.is() ) 998 xCell->SetMergedItem(aItem); 999 } 1000 } 1001 1002 UpdateTableShape(); 1003 } 1004 } 1005 1006 void SvxTableController::MergeMarkedCells() 1007 { 1008 CellPos aStart, aEnd; 1009 getSelectedCells( aStart, aEnd ); 1010 SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() ); 1011 if( pTableObj ) 1012 { 1013 if( pTableObj->IsTextEditActive() ) 1014 mpView->SdrEndTextEdit(sal_True); 1015 1016 TableModelNotifyGuard aGuard( mxTable.get() ); 1017 MergeRange( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow ); 1018 } 1019 } 1020 1021 void SvxTableController::SplitMarkedCells() 1022 { 1023 if( mxTable.is() ) 1024 { 1025 CellPos aStart, aEnd; 1026 getSelectedCells( aStart, aEnd ); 1027 1028 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); 1029 std::auto_ptr< SvxAbstractSplittTableDialog > xDlg( pFact ? pFact->CreateSvxSplittTableDialog( NULL, false, 99, 99 ) : 0 ); 1030 if( xDlg.get() && xDlg->Execute() ) 1031 { 1032 const sal_Int32 nCount = xDlg->GetCount() - 1; 1033 if( nCount < 1 ) 1034 return; 1035 1036 getSelectedCells( aStart, aEnd ); 1037 1038 Reference< XMergeableCellRange > xRange( mxTable->createCursorByRange( mxTable->getCellRangeByPosition( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow ) ), UNO_QUERY_THROW ); 1039 1040 const sal_Int32 nRowCount = mxTable->getRowCount(); 1041 const sal_Int32 nColCount = mxTable->getColumnCount(); 1042 1043 1044 SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() ); 1045 if( pTableObj ) 1046 { 1047 if( pTableObj->IsTextEditActive() ) 1048 mpView->SdrEndTextEdit(sal_True); 1049 1050 TableModelNotifyGuard aGuard( mxTable.get() ); 1051 1052 const bool bUndo = mpModel && mpModel->IsUndoEnabled(); 1053 if( bUndo ) 1054 { 1055 mpModel->BegUndo( ImpGetResStr(STR_TABLE_SPLIT) ); 1056 mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) ); 1057 } 1058 1059 if( xDlg->IsHorizontal() ) 1060 { 1061 xRange->split( 0, nCount ); 1062 } 1063 else 1064 { 1065 xRange->split( nCount, 0 ); 1066 } 1067 1068 if( bUndo ) 1069 mpModel->EndUndo(); 1070 } 1071 aEnd.mnRow += mxTable->getRowCount() - nRowCount; 1072 aEnd.mnCol += mxTable->getColumnCount() - nColCount; 1073 1074 setSelectedCells( aStart, aEnd ); 1075 } 1076 } 1077 } 1078 1079 void SvxTableController::DistributeColumns() 1080 { 1081 SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() ); 1082 if( pTableObj ) 1083 { 1084 const bool bUndo = mpModel && mpModel->IsUndoEnabled(); 1085 if( bUndo ) 1086 { 1087 mpModel->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_COLUMNS) ); 1088 mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) ); 1089 } 1090 1091 CellPos aStart, aEnd; 1092 getSelectedCells( aStart, aEnd ); 1093 pTableObj->DistributeColumns( aStart.mnCol, aEnd.mnCol ); 1094 1095 if( bUndo ) 1096 mpModel->EndUndo(); 1097 } 1098 } 1099 1100 void SvxTableController::DistributeRows() 1101 { 1102 SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() ); 1103 if( pTableObj ) 1104 { 1105 const bool bUndo = mpModel && mpModel->IsUndoEnabled(); 1106 if( bUndo ) 1107 { 1108 mpModel->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_ROWS) ); 1109 mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) ); 1110 } 1111 1112 CellPos aStart, aEnd; 1113 getSelectedCells( aStart, aEnd ); 1114 pTableObj->DistributeRows( aStart.mnRow, aEnd.mnRow ); 1115 1116 if( bUndo ) 1117 mpModel->EndUndo(); 1118 } 1119 } 1120 1121 bool SvxTableController::DeleteMarked() 1122 { 1123 if( mbCellSelectionMode ) 1124 { 1125 if( mxTable.is() ) 1126 { 1127 CellPos aStart, aEnd; 1128 getSelectedCells( aStart, aEnd ); 1129 for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ ) 1130 { 1131 for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ ) 1132 { 1133 CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) ); 1134 if( xCell.is() ) 1135 xCell->SetOutlinerParaObject( 0 ); 1136 } 1137 } 1138 1139 UpdateTableShape(); 1140 return true; 1141 } 1142 } 1143 1144 return false; 1145 } 1146 1147 bool SvxTableController::GetStyleSheet( SfxStyleSheet*& rpStyleSheet ) const 1148 { 1149 if( hasSelectedCells() ) 1150 { 1151 rpStyleSheet = 0; 1152 1153 if( mxTable.is() ) 1154 { 1155 SfxStyleSheet* pRet=0; 1156 bool b1st=true; 1157 1158 CellPos aStart, aEnd; 1159 const_cast<SvxTableController&>(*this).getSelectedCells( aStart, aEnd ); 1160 1161 for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ ) 1162 { 1163 for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ ) 1164 { 1165 CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) ); 1166 if( xCell.is() ) 1167 { 1168 SfxStyleSheet* pSS=xCell->GetStyleSheet(); 1169 if(b1st) 1170 { 1171 pRet=pSS; 1172 } 1173 else if(pRet != pSS) 1174 { 1175 return true; 1176 } 1177 b1st=false; 1178 } 1179 } 1180 } 1181 rpStyleSheet = pRet; 1182 return true; 1183 } 1184 } 1185 return false; 1186 } 1187 1188 bool SvxTableController::SetStyleSheet( SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr ) 1189 { 1190 if( hasSelectedCells() && (!pStyleSheet || pStyleSheet->GetFamily() == SFX_STYLE_FAMILY_FRAME) ) 1191 { 1192 if( mxTable.is() ) 1193 { 1194 CellPos aStart, aEnd; 1195 getSelectedCells( aStart, aEnd ); 1196 1197 for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ ) 1198 { 1199 for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ ) 1200 { 1201 CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) ); 1202 if( xCell.is() ) 1203 xCell->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr); 1204 } 1205 } 1206 1207 UpdateTableShape(); 1208 return true; 1209 } 1210 } 1211 return false; 1212 } 1213 1214 // -------------------------------------------------------------------- 1215 // internals 1216 // -------------------------------------------------------------------- 1217 1218 bool SvxTableController::checkTableObject() 1219 { 1220 return mxTableObj.is(); 1221 } 1222 1223 // -------------------------------------------------------------------- 1224 1225 sal_uInt16 SvxTableController::getKeyboardAction( const KeyEvent& rKEvt, Window* /*pWindow*/ ) 1226 { 1227 const bool bMod1 = rKEvt.GetKeyCode().IsMod1(); // ctrl 1228 const bool bMod2 = rKEvt.GetKeyCode().IsMod2() != 0; // Alt 1229 1230 const bool bTextEdit = mpView->IsTextEdit(); 1231 1232 sal_uInt16 nAction = ACTION_HANDLED_BY_VIEW; 1233 1234 ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() ); 1235 if( !pTableObj ) 1236 return nAction; 1237 1238 // handle special keys 1239 const sal_Int16 nCode = rKEvt.GetKeyCode().GetCode(); 1240 switch( nCode ) 1241 { 1242 case awt::Key::ESCAPE: // handle escape 1243 { 1244 if( bTextEdit ) 1245 { 1246 // escape during text edit ends text edit 1247 nAction = ACTION_STOP_TEXT_EDIT; 1248 } 1249 if( mbCellSelectionMode ) 1250 { 1251 // escape with selected cells removes selection 1252 nAction = ACTION_REMOVE_SELECTION; 1253 } 1254 break; 1255 } 1256 case awt::Key::RETURN: // handle return 1257 { 1258 if( !bMod1 && !bMod2 && !bTextEdit ) 1259 { 1260 // when not already editing, return starts text edit 1261 setSelectionStart( pTableObj->getFirstCell() ); 1262 nAction = ACTION_EDIT_CELL; 1263 } 1264 break; 1265 } 1266 case awt::Key::F2: // f2 toggles text edit 1267 { 1268 if( bMod1 || bMod2 ) // f2 with modifiers is handled by the view 1269 { 1270 } 1271 else if( bTextEdit ) 1272 { 1273 // f2 during text edit stops text edit 1274 nAction = ACTION_STOP_TEXT_EDIT; 1275 } 1276 else if( mbCellSelectionMode ) 1277 { 1278 // f2 with selected cells removes selection 1279 nAction = ACTION_REMOVE_SELECTION; 1280 } 1281 else 1282 { 1283 // f2 with no selection and no text edit starts text edit 1284 setSelectionStart( pTableObj->getFirstCell() ); 1285 nAction = ACTION_EDIT_CELL; 1286 } 1287 break; 1288 } 1289 case awt::Key::HOME: 1290 case awt::Key::NUM7: 1291 { 1292 if( (bMod1 || bMod2) && (bTextEdit || mbCellSelectionMode) ) 1293 { 1294 if( bMod1 && !bMod2 ) 1295 { 1296 // strg + home jumps to first cell 1297 nAction = ACTION_GOTO_FIRST_CELL; 1298 } 1299 else if( !bMod1 && bMod2 ) 1300 { 1301 // alt + home jumps to first column 1302 nAction = ACTION_GOTO_FIRST_COLUMN; 1303 } 1304 } 1305 break; 1306 } 1307 case awt::Key::END: 1308 case awt::Key::NUM1: 1309 { 1310 if( (bMod1 || bMod2) && (bTextEdit || mbCellSelectionMode) ) 1311 { 1312 if( bMod1 && !bMod2 ) 1313 { 1314 // strg + end jumps to last cell 1315 nAction = ACTION_GOTO_LAST_CELL; 1316 } 1317 else if( !bMod1 && bMod2 ) 1318 { 1319 // alt + home jumps to last column 1320 nAction = ACTION_GOTO_LAST_COLUMN; 1321 } 1322 } 1323 break; 1324 } 1325 1326 case awt::Key::TAB: 1327 { 1328 if( bTextEdit || mbCellSelectionMode ) 1329 nAction = ACTION_TAB; 1330 break; 1331 } 1332 1333 case awt::Key::UP: 1334 case awt::Key::NUM8: 1335 case awt::Key::DOWN: 1336 case awt::Key::NUM2: 1337 case awt::Key::LEFT: 1338 case awt::Key::NUM4: 1339 case awt::Key::RIGHT: 1340 case awt::Key::NUM6: 1341 { 1342 bool bTextMove = false; 1343 1344 if( !bMod1 && bMod2 ) 1345 { 1346 if( (nCode == awt::Key::UP) || (nCode == awt::Key::NUM8) ) 1347 { 1348 nAction = ACTION_GOTO_LEFT_CELL; 1349 } 1350 else if( (nCode == awt::Key::DOWN) || (nCode == awt::Key::NUM2) ) 1351 { 1352 nAction = ACTION_GOTO_RIGHT_CELL; 1353 } 1354 break; 1355 } 1356 1357 if( !bTextMove ) 1358 { 1359 OutlinerView* pOLV = mpView->GetTextEditOutlinerView(); 1360 if( pOLV ) 1361 { 1362 RemoveSelection(); 1363 // during text edit, check if we navigate out of the cell 1364 ESelection aOldSelection = pOLV->GetSelection(); 1365 pOLV->PostKeyEvent(rKEvt); 1366 bTextMove = pOLV && ( aOldSelection.IsEqual(pOLV->GetSelection()) ); 1367 if( !bTextMove ) 1368 { 1369 nAction = ACTION_NONE; 1370 } 1371 } 1372 } 1373 1374 if( mbCellSelectionMode || bTextMove ) 1375 { 1376 // no text edit, navigate in cells if selection active 1377 switch( nCode ) 1378 { 1379 case awt::Key::LEFT: 1380 case awt::Key::NUM4: 1381 nAction = ACTION_GOTO_LEFT_CELL; 1382 break; 1383 case awt::Key::RIGHT: 1384 case awt::Key::NUM6: 1385 nAction = ACTION_GOTO_RIGHT_CELL; 1386 break; 1387 case awt::Key::DOWN: 1388 case awt::Key::NUM2: 1389 nAction = ACTION_GOTO_DOWN_CELL; 1390 break; 1391 case awt::Key::UP: 1392 case awt::Key::NUM8: 1393 nAction = ACTION_GOTO_UP_CELL; 1394 break; 1395 } 1396 } 1397 break; 1398 } 1399 case awt::Key::PAGEUP: 1400 if( bMod2 ) 1401 nAction = ACTION_GOTO_FIRST_ROW; 1402 break; 1403 1404 case awt::Key::PAGEDOWN: 1405 if( bMod2 ) 1406 nAction = ACTION_GOTO_LAST_ROW; 1407 break; 1408 } 1409 return nAction; 1410 } 1411 1412 bool SvxTableController::executeAction( sal_uInt16 nAction, bool bSelect, Window* pWindow ) 1413 { 1414 ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() ); 1415 if( !pTableObj ) 1416 return false; 1417 1418 switch( nAction ) 1419 { 1420 case ACTION_GOTO_FIRST_CELL: 1421 { 1422 gotoCell( pTableObj->getFirstCell(), bSelect, pWindow, nAction ); 1423 break; 1424 } 1425 1426 case ACTION_GOTO_LEFT_CELL: 1427 { 1428 gotoCell( pTableObj->getLeftCell( getSelectionEnd(), !bSelect ), bSelect, pWindow, nAction ); 1429 break; 1430 } 1431 1432 case ACTION_GOTO_RIGHT_CELL: 1433 { 1434 gotoCell( pTableObj->getRightCell( getSelectionEnd(), !bSelect ), bSelect, pWindow, nAction); 1435 break; 1436 } 1437 1438 case ACTION_GOTO_LAST_CELL: 1439 { 1440 gotoCell( pTableObj->getLastCell(), bSelect, pWindow, nAction ); 1441 break; 1442 } 1443 1444 case ACTION_GOTO_FIRST_COLUMN: 1445 { 1446 CellPos aPos( pTableObj->getFirstCell().mnCol, getSelectionEnd().mnRow ); 1447 gotoCell( aPos, bSelect, pWindow, nAction ); 1448 break; 1449 } 1450 1451 case ACTION_GOTO_LAST_COLUMN: 1452 { 1453 CellPos aPos( pTableObj->getLastCell().mnCol, getSelectionEnd().mnRow ); 1454 gotoCell( aPos, bSelect, pWindow, nAction ); 1455 break; 1456 } 1457 1458 case ACTION_GOTO_FIRST_ROW: 1459 { 1460 CellPos aPos( getSelectionEnd().mnCol, pTableObj->getFirstCell().mnRow ); 1461 gotoCell( aPos, bSelect, pWindow, nAction ); 1462 break; 1463 } 1464 1465 case ACTION_GOTO_UP_CELL: 1466 { 1467 gotoCell( pTableObj->getUpCell(getSelectionEnd(), !bSelect), bSelect, pWindow, nAction ); 1468 break; 1469 } 1470 1471 case ACTION_GOTO_DOWN_CELL: 1472 { 1473 gotoCell( pTableObj->getDownCell(getSelectionEnd(), !bSelect), bSelect, pWindow, nAction ); 1474 break; 1475 } 1476 1477 case ACTION_GOTO_LAST_ROW: 1478 { 1479 CellPos aPos( getSelectionEnd().mnCol, pTableObj->getLastCell().mnRow ); 1480 gotoCell( aPos, bSelect, pWindow, nAction ); 1481 break; 1482 } 1483 1484 case ACTION_EDIT_CELL: 1485 EditCell( getSelectionStart(), pWindow, 0, nAction ); 1486 break; 1487 1488 case ACTION_STOP_TEXT_EDIT: 1489 StopTextEdit(); 1490 break; 1491 1492 case ACTION_REMOVE_SELECTION: 1493 RemoveSelection(); 1494 break; 1495 1496 case ACTION_START_SELECTION: 1497 StartSelection( getSelectionStart() ); 1498 break; 1499 1500 case ACTION_TAB: 1501 { 1502 if( bSelect ) 1503 gotoCell( pTableObj->getPreviousCell( getSelectionEnd(), true ), false, pWindow, nAction ); 1504 else 1505 { 1506 CellPos aSelectionEnd( getSelectionEnd() ); 1507 CellPos aNextCell( pTableObj->getNextCell( aSelectionEnd, true ) ); 1508 if( aSelectionEnd == aNextCell ) 1509 { 1510 onInsert( SID_TABLE_INSERT_ROW, 0 ); 1511 aNextCell = pTableObj->getNextCell( aSelectionEnd, true ); 1512 } 1513 gotoCell( aNextCell, false, pWindow, nAction ); 1514 } 1515 break; 1516 } 1517 } 1518 1519 return nAction != ACTION_HANDLED_BY_VIEW; 1520 } 1521 1522 // -------------------------------------------------------------------- 1523 1524 void SvxTableController::gotoCell( const CellPos& rPos, bool bSelect, Window* pWindow, sal_uInt16 nAction ) 1525 { 1526 if( mxTableObj.is() && static_cast<SdrTableObj*>(mxTableObj.get())->IsTextEditActive() ) 1527 mpView->SdrEndTextEdit(sal_True); 1528 1529 if( bSelect ) 1530 { 1531 maCursorLastPos = rPos; 1532 if( mxTableObj.is() ) 1533 static_cast< SdrTableObj* >( mxTableObj.get() )->setActiveCell( rPos ); 1534 1535 if( !mbCellSelectionMode ) 1536 { 1537 setSelectedCells( maCursorFirstPos, rPos ); 1538 } 1539 else 1540 { 1541 UpdateSelection( rPos ); 1542 } 1543 } 1544 else 1545 { 1546 RemoveSelection(); 1547 EditCell( rPos, pWindow, 0, nAction ); 1548 } 1549 } 1550 1551 // -------------------------------------------------------------------- 1552 1553 const CellPos& SvxTableController::getSelectionStart() 1554 { 1555 checkCell( maCursorFirstPos ); 1556 return maCursorFirstPos; 1557 } 1558 1559 // -------------------------------------------------------------------- 1560 1561 void SvxTableController::setSelectionStart( const CellPos& rPos ) 1562 { 1563 maCursorFirstPos = rPos; 1564 } 1565 1566 // -------------------------------------------------------------------- 1567 1568 const CellPos& SvxTableController::getSelectionEnd() 1569 { 1570 checkCell( maCursorLastPos ); 1571 return maCursorLastPos; 1572 } 1573 1574 // -------------------------------------------------------------------- 1575 1576 Reference< XCellCursor > SvxTableController::getSelectionCursor() 1577 { 1578 Reference< XCellCursor > xCursor; 1579 1580 if( mxTable.is() ) 1581 { 1582 if( hasSelectedCells() ) 1583 { 1584 CellPos aStart, aEnd; 1585 getSelectedCells( aStart, aEnd ); 1586 xCursor = mxTable->createCursorByRange( mxTable->getCellRangeByPosition( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow ) ); 1587 } 1588 else 1589 { 1590 xCursor = mxTable->createCursor(); 1591 } 1592 } 1593 1594 return xCursor; 1595 } 1596 1597 void SvxTableController::MergeRange( sal_Int32 nFirstCol, sal_Int32 nFirstRow, sal_Int32 nLastCol, sal_Int32 nLastRow ) 1598 { 1599 if( mxTable.is() ) try 1600 { 1601 Reference< XMergeableCellRange > xRange( mxTable->createCursorByRange( mxTable->getCellRangeByPosition( nFirstCol, nFirstRow,nLastCol, nLastRow ) ), UNO_QUERY_THROW ); 1602 if( xRange->isMergeable() ) 1603 { 1604 const bool bUndo = mpModel && mpModel->IsUndoEnabled(); 1605 if( bUndo ) 1606 { 1607 mpModel->BegUndo( ImpGetResStr(STR_TABLE_MERGE) ); 1608 mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*mxTableObj.get()) ); 1609 } 1610 1611 xRange->merge(); 1612 1613 if( bUndo ) 1614 mpModel->EndUndo(); 1615 } 1616 } 1617 catch( Exception& ) 1618 { 1619 DBG_ASSERT( false, "sdr::table::SvxTableController::MergeRange(), exception caught!" ); 1620 } 1621 } 1622 1623 1624 1625 // -------------------------------------------------------------------- 1626 1627 void SvxTableController::checkCell( CellPos& rPos ) 1628 { 1629 if( mxTable.is() ) try 1630 { 1631 if( rPos.mnCol >= mxTable->getColumnCount() ) 1632 rPos.mnCol = mxTable->getColumnCount()-1; 1633 1634 if( rPos.mnRow >= mxTable->getRowCount() ) 1635 rPos.mnRow = mxTable->getRowCount()-1; 1636 } 1637 catch( Exception& e ) 1638 { 1639 (void)e; 1640 DBG_ERROR("sdr::table::SvxTableController::checkCell(), exception caught!" ); 1641 } 1642 } 1643 1644 // -------------------------------------------------------------------- 1645 1646 void SvxTableController::findMergeOrigin( CellPos& rPos ) 1647 { 1648 if( mxTable.is() ) try 1649 { 1650 Reference< XMergeableCell > xCell( mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ), UNO_QUERY_THROW ); 1651 if( xCell.is() && xCell->isMerged() ) 1652 { 1653 ::findMergeOrigin( mxTable, rPos.mnCol, rPos.mnRow, rPos.mnCol, rPos.mnRow ); 1654 } 1655 } 1656 catch( Exception& e ) 1657 { 1658 (void)e; 1659 DBG_ERROR("sdr::table::SvxTableController::findMergeOrigin(), exception caught!" ); 1660 } 1661 } 1662 1663 // -------------------------------------------------------------------- 1664 1665 void SvxTableController::EditCell( const CellPos& rPos, ::Window* pWindow, const awt::MouseEvent* pMouseEvent /*= 0*/, sal_uInt16 nAction /*= ACTION_NONE */ ) 1666 { 1667 SdrPageView* pPV = mpView->GetSdrPageView(); 1668 1669 ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() ); 1670 if( pTableObj && pTableObj->GetPage() == pPV->GetPage() ) 1671 { 1672 bool bEmptyOutliner = false; 1673 1674 if(!pTableObj->GetOutlinerParaObject() && mpView->GetTextEditOutliner()) 1675 { 1676 ::Outliner* pOutl = mpView->GetTextEditOutliner(); 1677 sal_uIntPtr nParaAnz = pOutl->GetParagraphCount(); 1678 Paragraph* p1stPara = pOutl->GetParagraph( 0 ); 1679 1680 if(nParaAnz==1 && p1stPara) 1681 { 1682 // Bei nur einem Pararaph 1683 if (pOutl->GetText(p1stPara).Len() == 0) 1684 { 1685 bEmptyOutliner = true; 1686 } 1687 } 1688 } 1689 1690 CellPos aPos( rPos ); 1691 findMergeOrigin( aPos ); 1692 1693 if( pTableObj != mpView->GetTextEditObject() || bEmptyOutliner || !pTableObj->IsTextEditActive( aPos ) ) 1694 { 1695 if( pTableObj->IsTextEditActive() ) 1696 mpView->SdrEndTextEdit(sal_True); 1697 1698 pTableObj->setActiveCell( aPos ); 1699 1700 // create new outliner, owner will be the SdrObjEditView 1701 SdrOutliner* pOutl = SdrMakeOutliner( OUTLINERMODE_OUTLINEOBJECT, mpModel ); 1702 if( pTableObj->IsVerticalWriting() ) 1703 pOutl->SetVertical( sal_True ); 1704 1705 if(mpView->SdrBeginTextEdit(pTableObj, pPV, pWindow, sal_True, pOutl)) 1706 { 1707 maCursorLastPos = maCursorFirstPos = rPos; 1708 1709 OutlinerView* pOLV = mpView->GetTextEditOutlinerView(); 1710 1711 bool bNoSel = true; 1712 1713 if( pMouseEvent ) 1714 { 1715 ::MouseEvent aMEvt( *pMouseEvent ); 1716 1717 SdrViewEvent aVEvt; 1718 SdrHitKind eHit = mpView->PickAnything(aMEvt, SDRMOUSEBUTTONDOWN, aVEvt); 1719 1720 if (eHit == SDRHIT_TEXTEDIT) 1721 { 1722 // Text getroffen 1723 pOLV->MouseButtonDown(aMEvt); 1724 pOLV->MouseMove(aMEvt); 1725 pOLV->MouseButtonUp(aMEvt); 1726 // pOLV->MouseButtonDown(aMEvt); 1727 bNoSel = false; 1728 } 1729 else 1730 { 1731 nAction = ACTION_GOTO_LEFT_CELL; 1732 } 1733 } 1734 1735 if( bNoSel ) 1736 { 1737 // Move cursor to end of text 1738 ESelection aNewSelection; 1739 1740 const WritingMode eMode = pTableObj->GetWritingMode(); 1741 if( ((nAction == ACTION_GOTO_LEFT_CELL) || (nAction == ACTION_GOTO_RIGHT_CELL)) && (eMode != WritingMode_TB_RL) ) 1742 { 1743 const bool bLast = ((nAction == ACTION_GOTO_LEFT_CELL) && (eMode == WritingMode_LR_TB)) || 1744 ((nAction == ACTION_GOTO_RIGHT_CELL) && (eMode == WritingMode_RL_TB)); 1745 1746 if( bLast ) 1747 aNewSelection = ESelection(EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND, EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND); 1748 } 1749 pOLV->SetSelection(aNewSelection); 1750 } 1751 } 1752 } 1753 } 1754 } 1755 1756 // -------------------------------------------------------------------- 1757 1758 bool SvxTableController::StopTextEdit() 1759 { 1760 if(mpView->IsTextEdit()) 1761 { 1762 mpView->SdrEndTextEdit(); 1763 mpView->SetCurrentObj(OBJ_TABLE); 1764 mpView->SetEditMode(SDREDITMODE_EDIT); 1765 return true; 1766 } 1767 else 1768 { 1769 return false; 1770 } 1771 } 1772 1773 // -------------------------------------------------------------------- 1774 1775 void SvxTableController::DeleteTable() 1776 { 1777 // 1778 } 1779 1780 // -------------------------------------------------------------------- 1781 1782 void SvxTableController::getSelectedCells( CellPos& rFirst, CellPos& rLast ) 1783 { 1784 if( mbCellSelectionMode ) 1785 { 1786 checkCell( maCursorFirstPos ); 1787 checkCell( maCursorLastPos ); 1788 1789 rFirst.mnCol = std::min( maCursorFirstPos.mnCol, maCursorLastPos.mnCol ); 1790 rFirst.mnRow = std::min( maCursorFirstPos.mnRow, maCursorLastPos.mnRow ); 1791 rLast.mnCol = std::max( maCursorFirstPos.mnCol, maCursorLastPos.mnCol ); 1792 rLast.mnRow = std::max( maCursorFirstPos.mnRow, maCursorLastPos.mnRow ); 1793 1794 bool bExt = false; 1795 if( mxTable.is() ) do 1796 { 1797 bExt = false; 1798 for( sal_Int32 nRow = rFirst.mnRow; nRow <= rLast.mnRow && !bExt; nRow++ ) 1799 { 1800 for( sal_Int32 nCol = rFirst.mnCol; nCol <= rLast.mnCol && !bExt; nCol++ ) 1801 { 1802 Reference< XMergeableCell > xCell( mxTable->getCellByPosition( nCol, nRow ), UNO_QUERY ); 1803 if( !xCell.is() ) 1804 continue; 1805 1806 if( xCell->isMerged() ) 1807 { 1808 CellPos aPos( nCol, nRow ); 1809 findMergeOrigin( aPos ); 1810 if( (aPos.mnCol < rFirst.mnCol) || (aPos.mnRow < rFirst.mnRow) ) 1811 { 1812 rFirst.mnCol = std::min( rFirst.mnCol, aPos.mnCol ); 1813 rFirst.mnRow = std::min( rFirst.mnRow, aPos.mnRow ); 1814 bExt = true; 1815 } 1816 } 1817 else 1818 { 1819 if( ((nCol + xCell->getColumnSpan() - 1) > rLast.mnCol) || (nRow + xCell->getRowSpan() - 1 ) > rLast.mnRow ) 1820 { 1821 rLast.mnCol = std::max( rLast.mnCol, nCol + xCell->getColumnSpan() - 1 ); 1822 rLast.mnRow = std::max( rLast.mnRow, nRow + xCell->getRowSpan() - 1 ); 1823 bExt = true; 1824 } 1825 } 1826 } 1827 } 1828 } 1829 while(bExt); 1830 } 1831 else if( mpView && mpView->IsTextEdit() ) 1832 { 1833 rFirst = getSelectionStart(); 1834 findMergeOrigin( rFirst ); 1835 rLast = rFirst; 1836 1837 if( mxTable.is() ) 1838 { 1839 Reference< XMergeableCell > xCell( mxTable->getCellByPosition( rLast.mnCol, rLast.mnRow ), UNO_QUERY ); 1840 if( xCell.is() ) 1841 { 1842 rLast.mnCol += xCell->getColumnSpan() - 1; 1843 rLast.mnRow += xCell->getRowSpan() - 1; 1844 } 1845 } 1846 } 1847 else 1848 { 1849 rFirst.mnCol = 0; 1850 rFirst.mnRow = 0; 1851 if( mxTable.is() ) 1852 { 1853 rLast.mnRow = mxTable->getRowCount()-1; 1854 rLast.mnCol = mxTable->getColumnCount()-1; 1855 } 1856 else 1857 { 1858 rLast.mnRow = 0; 1859 rLast.mnCol = 0; 1860 } 1861 } 1862 } 1863 1864 // -------------------------------------------------------------------- 1865 1866 void SvxTableController::StartSelection( const CellPos& rPos ) 1867 { 1868 StopTextEdit(); 1869 mbCellSelectionMode = true; 1870 maCursorLastPos = maCursorFirstPos = rPos; 1871 mpView->MarkListHasChanged(); 1872 } 1873 1874 // -------------------------------------------------------------------- 1875 1876 void SvxTableController::setSelectedCells( const CellPos& rStart, const CellPos& rEnd ) 1877 { 1878 StopTextEdit(); 1879 mbCellSelectionMode = true; 1880 maCursorFirstPos = rStart; 1881 UpdateSelection( rEnd ); 1882 } 1883 1884 // -------------------------------------------------------------------- 1885 1886 void SvxTableController::UpdateSelection( const CellPos& rPos ) 1887 { 1888 maCursorLastPos = rPos; 1889 mpView->MarkListHasChanged(); 1890 } 1891 1892 // -------------------------------------------------------------------- 1893 1894 void SvxTableController::clearSelection() 1895 { 1896 RemoveSelection(); 1897 } 1898 1899 // -------------------------------------------------------------------- 1900 1901 void SvxTableController::selectAll() 1902 { 1903 if( mxTable.is() ) 1904 { 1905 CellPos aPos1, aPos2( mxTable->getColumnCount()-1, mxTable->getRowCount()-1 ); 1906 if( (aPos2.mnCol >= 0) && (aPos2.mnRow >= 0) ) 1907 { 1908 setSelectedCells( aPos1, aPos2 ); 1909 } 1910 } 1911 } 1912 1913 // -------------------------------------------------------------------- 1914 1915 void SvxTableController::RemoveSelection() 1916 { 1917 if( mbCellSelectionMode ) 1918 { 1919 mbCellSelectionMode = false; 1920 mpView->MarkListHasChanged(); 1921 } 1922 } 1923 1924 // -------------------------------------------------------------------- 1925 1926 void SvxTableController::onTableModified() 1927 { 1928 if( mnUpdateEvent == 0 ) 1929 mnUpdateEvent = Application::PostUserEvent( LINK( this, SvxTableController, UpdateHdl ) ); 1930 } 1931 // -------------------------------------------------------------------- 1932 1933 void SvxTableController::updateSelectionOverlay() 1934 { 1935 destroySelectionOverlay(); 1936 if( mbCellSelectionMode ) 1937 { 1938 ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() ); 1939 if( pTableObj ) 1940 { 1941 sdr::overlay::OverlayObjectCell::RangeVector aRanges; 1942 1943 Rectangle aRect; 1944 CellPos aStart,aEnd; 1945 getSelectedCells( aStart, aEnd ); 1946 pTableObj->getCellBounds( aStart, aRect ); 1947 1948 basegfx::B2DRange a2DRange( basegfx::B2DPoint(aRect.Left(), aRect.Top()) ); 1949 a2DRange.expand( basegfx::B2DPoint(aRect.Right(), aRect.Bottom()) ); 1950 1951 findMergeOrigin( aEnd ); 1952 pTableObj->getCellBounds( aEnd, aRect ); 1953 a2DRange.expand( basegfx::B2DPoint(aRect.Left(), aRect.Top()) ); 1954 a2DRange.expand( basegfx::B2DPoint(aRect.Right(), aRect.Bottom()) ); 1955 aRanges.push_back( a2DRange ); 1956 1957 ::Color aHighlight( COL_BLUE ); 1958 OutputDevice* pOutDev = mpView->GetFirstOutputDevice(); 1959 if( pOutDev ) 1960 aHighlight = pOutDev->GetSettings().GetStyleSettings().GetHighlightColor(); 1961 1962 const sal_uInt32 nCount = mpView->PaintWindowCount(); 1963 for( sal_uInt32 nIndex = 0; nIndex < nCount; nIndex++ ) 1964 { 1965 SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow(nIndex); 1966 if( pPaintWindow ) 1967 { 1968 ::sdr::overlay::OverlayManager* pOverlayManager = pPaintWindow->GetOverlayManager(); 1969 if( pOverlayManager ) 1970 { 1971 // sdr::overlay::CellOverlayType eType = sdr::overlay::CELL_OVERLAY_INVERT; 1972 sdr::overlay::CellOverlayType eType = sdr::overlay::CELL_OVERLAY_TRANSPARENT; 1973 1974 sdr::overlay::OverlayObjectCell* pOverlay = new sdr::overlay::OverlayObjectCell( eType, aHighlight, aRanges ); 1975 1976 pOverlayManager->add(*pOverlay); 1977 mpSelectionOverlay = new ::sdr::overlay::OverlayObjectList; 1978 mpSelectionOverlay->append(*pOverlay); 1979 } 1980 } 1981 } 1982 } 1983 } 1984 } 1985 1986 // -------------------------------------------------------------------- 1987 1988 void SvxTableController::destroySelectionOverlay() 1989 { 1990 if( mpSelectionOverlay ) 1991 { 1992 delete mpSelectionOverlay; 1993 mpSelectionOverlay = 0; 1994 } 1995 } 1996 1997 // -------------------------------------------------------------------- 1998 1999 void SvxTableController::MergeAttrFromSelectedCells(SfxItemSet& rAttr, bool bOnlyHardAttr) const 2000 { 2001 if( mxTable.is() ) 2002 { 2003 CellPos aStart, aEnd; 2004 const_cast<SvxTableController&>(*this).getSelectedCells( aStart, aEnd ); 2005 2006 for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ ) 2007 { 2008 for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ ) 2009 { 2010 CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) ); 2011 if( xCell.is() && !xCell->isMerged() ) 2012 { 2013 const SfxItemSet& rSet = xCell->GetItemSet(); 2014 SfxWhichIter aIter(rSet); 2015 sal_uInt16 nWhich(aIter.FirstWhich()); 2016 while(nWhich) 2017 { 2018 if(!bOnlyHardAttr) 2019 { 2020 if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, sal_False)) 2021 rAttr.InvalidateItem(nWhich); 2022 else 2023 rAttr.MergeValue(rSet.Get(nWhich), sal_True); 2024 } 2025 else if(SFX_ITEM_SET == rSet.GetItemState(nWhich, sal_False)) 2026 { 2027 const SfxPoolItem& rItem = rSet.Get(nWhich); 2028 rAttr.MergeValue(rItem, sal_True); 2029 } 2030 2031 nWhich = aIter.NextWhich(); 2032 } 2033 } 2034 } 2035 } 2036 } 2037 2038 if( mpView->IsTextEdit() ) 2039 { 2040 } 2041 } 2042 2043 // -------------------------------------------------------------------- 2044 2045 const sal_uInt16 CELL_BEFORE = 0x0001; 2046 const sal_uInt16 CELL_LEFT = 0x0002; 2047 const sal_uInt16 CELL_RIGHT = 0x0004; 2048 const sal_uInt16 CELL_AFTER = 0x0008; 2049 2050 const sal_uInt16 CELL_UPPER = 0x0010; 2051 const sal_uInt16 CELL_TOP = 0x0020; 2052 const sal_uInt16 CELL_BOTTOM = 0x0040; 2053 const sal_uInt16 CELL_LOWER = 0x0080; 2054 2055 // -------------------------------------------------------------------- 2056 2057 static void ImplSetLinePreserveColor( SvxBoxItem& rNewFrame, const SvxBorderLine* pNew, sal_uInt16 nLine ) 2058 { 2059 if( pNew ) 2060 { 2061 const SvxBorderLine* pOld = rNewFrame.GetLine(nLine); 2062 if( pOld ) 2063 { 2064 SvxBorderLine aNewLine( *pNew ); 2065 aNewLine.SetColor( pOld->GetColor() ); 2066 rNewFrame.SetLine( &aNewLine, nLine ); 2067 return; 2068 } 2069 } 2070 rNewFrame.SetLine( pNew, nLine ); 2071 } 2072 2073 // -------------------------------------------------------------------- 2074 2075 static void ImplApplyBoxItem( sal_uInt16 nCellFlags, const SvxBoxItem* pBoxItem, const SvxBoxInfoItem* pBoxInfoItem, SvxBoxItem& rNewFrame ) 2076 { 2077 if( (nCellFlags & (CELL_BEFORE|CELL_AFTER|CELL_UPPER|CELL_LOWER)) != 0 ) 2078 { 2079 // current cell is outside the selection 2080 2081 if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER)) == 0 ) // check if its not nw or ne corner 2082 { 2083 if( nCellFlags & CELL_UPPER ) 2084 { 2085 if( pBoxInfoItem->IsValid(VALID_TOP) ) 2086 rNewFrame.SetLine(0, BOX_LINE_BOTTOM ); 2087 } 2088 else if( nCellFlags & CELL_LOWER ) 2089 { 2090 if( pBoxInfoItem->IsValid(VALID_BOTTOM) ) 2091 rNewFrame.SetLine( 0, BOX_LINE_TOP ); 2092 } 2093 } 2094 else if( (nCellFlags & ( CELL_UPPER|CELL_LOWER)) == 0 ) // check if its not sw or se corner 2095 { 2096 if( nCellFlags & CELL_BEFORE ) 2097 { 2098 if( pBoxInfoItem->IsValid(VALID_LEFT) ) 2099 rNewFrame.SetLine( 0, BOX_LINE_RIGHT ); 2100 } 2101 else if( nCellFlags & CELL_AFTER ) 2102 { 2103 if( pBoxInfoItem->IsValid(VALID_RIGHT) ) 2104 rNewFrame.SetLine( 0, BOX_LINE_LEFT ); 2105 } 2106 } 2107 } 2108 else 2109 { 2110 // current cell is inside the selection 2111 2112 if( (nCellFlags & CELL_LEFT) ? pBoxInfoItem->IsValid(VALID_LEFT) : pBoxInfoItem->IsValid(VALID_VERT) ) 2113 rNewFrame.SetLine( (nCellFlags & CELL_LEFT) ? pBoxItem->GetLeft() : pBoxInfoItem->GetVert(), BOX_LINE_LEFT ); 2114 2115 if( (nCellFlags & CELL_RIGHT) ? pBoxInfoItem->IsValid(VALID_RIGHT) : pBoxInfoItem->IsValid(VALID_VERT) ) 2116 rNewFrame.SetLine( (nCellFlags & CELL_RIGHT) ? pBoxItem->GetRight() : pBoxInfoItem->GetVert(), BOX_LINE_RIGHT ); 2117 2118 if( (nCellFlags & CELL_TOP) ? pBoxInfoItem->IsValid(VALID_TOP) : pBoxInfoItem->IsValid(VALID_HORI) ) 2119 rNewFrame.SetLine( (nCellFlags & CELL_TOP) ? pBoxItem->GetTop() : pBoxInfoItem->GetHori(), BOX_LINE_TOP ); 2120 2121 if( (nCellFlags & CELL_BOTTOM) ? pBoxInfoItem->IsValid(VALID_BOTTOM) : pBoxInfoItem->IsValid(VALID_HORI) ) 2122 rNewFrame.SetLine( (nCellFlags & CELL_BOTTOM) ? pBoxItem->GetBottom() : pBoxInfoItem->GetHori(), BOX_LINE_BOTTOM ); 2123 2124 // apply distance to borders 2125 if( pBoxInfoItem->IsValid( VALID_DISTANCE ) ) 2126 for( sal_uInt16 nLine = 0; nLine < 4; ++nLine ) 2127 rNewFrame.SetDistance( pBoxItem->GetDistance( nLine ), nLine ); 2128 } 2129 } 2130 2131 // -------------------------------------------------------------------- 2132 2133 static void ImplSetLineColor( SvxBoxItem& rNewFrame, sal_uInt16 nLine, const Color& rColor ) 2134 { 2135 const SvxBorderLine* pSourceLine = rNewFrame.GetLine( nLine ); 2136 if( pSourceLine ) 2137 { 2138 SvxBorderLine aLine( *pSourceLine ); 2139 aLine.SetColor( rColor ); 2140 rNewFrame.SetLine( &aLine, nLine ); 2141 } 2142 } 2143 2144 // -------------------------------------------------------------------- 2145 2146 static void ImplApplyLineColorItem( sal_uInt16 nCellFlags, const SvxColorItem* pLineColorItem, SvxBoxItem& rNewFrame ) 2147 { 2148 const Color aColor( pLineColorItem->GetValue() ); 2149 2150 if( (nCellFlags & (CELL_LOWER|CELL_BEFORE|CELL_AFTER)) == 0 ) 2151 ImplSetLineColor( rNewFrame, BOX_LINE_BOTTOM, aColor ); 2152 2153 if( (nCellFlags & (CELL_UPPER|CELL_BEFORE|CELL_AFTER)) == 0 ) 2154 ImplSetLineColor( rNewFrame, BOX_LINE_TOP, aColor ); 2155 2156 if( (nCellFlags & (CELL_UPPER|CELL_LOWER|CELL_AFTER)) == 0 ) 2157 ImplSetLineColor( rNewFrame, BOX_LINE_RIGHT, aColor ); 2158 2159 if( (nCellFlags & (CELL_UPPER|CELL_LOWER|CELL_BEFORE)) == 0 ) 2160 ImplSetLineColor( rNewFrame, BOX_LINE_LEFT, aColor ); 2161 } 2162 2163 // -------------------------------------------------------------------- 2164 2165 static void ImplApplyBorderLineItem( sal_uInt16 nCellFlags, const SvxBorderLine* pBorderLineItem, SvxBoxItem& rNewFrame ) 2166 { 2167 if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER|CELL_UPPER|CELL_LOWER)) != 0 ) 2168 { 2169 if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER)) == 0 ) // check if its not nw or ne corner 2170 { 2171 if( nCellFlags & CELL_UPPER ) 2172 { 2173 if( rNewFrame.GetBottom() ) 2174 ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_BOTTOM ); 2175 } 2176 else if( nCellFlags & CELL_LOWER ) 2177 { 2178 if( rNewFrame.GetTop() ) 2179 ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_TOP ); 2180 } 2181 } 2182 else if( (nCellFlags & ( CELL_UPPER|CELL_LOWER)) == 0 ) // check if its not sw or se corner 2183 { 2184 if( nCellFlags & CELL_BEFORE ) 2185 { 2186 if( rNewFrame.GetRight() ) 2187 ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_RIGHT ); 2188 } 2189 else if( nCellFlags & CELL_AFTER ) 2190 { 2191 if( rNewFrame.GetLeft() ) 2192 ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_LEFT ); 2193 } 2194 } 2195 } 2196 else 2197 { 2198 if( rNewFrame.GetBottom() ) 2199 ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_BOTTOM ); 2200 if( rNewFrame.GetTop() ) 2201 ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_TOP ); 2202 if( rNewFrame.GetRight() ) 2203 ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_RIGHT ); 2204 if( rNewFrame.GetLeft() ) 2205 ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_LEFT ); 2206 } 2207 } 2208 2209 // -------------------------------------------------------------------- 2210 2211 void SvxTableController::ApplyBorderAttr( const SfxItemSet& rAttr ) 2212 { 2213 if( mxTable.is() ) 2214 { 2215 const sal_Int32 nRowCount = mxTable->getRowCount(); 2216 const sal_Int32 nColCount = mxTable->getColumnCount(); 2217 if( nRowCount && nColCount ) 2218 { 2219 const SvxBoxItem* pBoxItem = 0; 2220 if(SFX_ITEM_SET == rAttr.GetItemState(SDRATTR_TABLE_BORDER, sal_False) ) 2221 pBoxItem = dynamic_cast< const SvxBoxItem* >( &rAttr.Get( SDRATTR_TABLE_BORDER ) ); 2222 2223 const SvxBoxInfoItem* pBoxInfoItem = 0; 2224 if(SFX_ITEM_SET == rAttr.GetItemState(SDRATTR_TABLE_BORDER_INNER, sal_False) ) 2225 pBoxInfoItem = dynamic_cast< const SvxBoxInfoItem* >( &rAttr.Get( SDRATTR_TABLE_BORDER_INNER ) ); 2226 2227 const SvxColorItem* pLineColorItem = 0; 2228 if(SFX_ITEM_SET == rAttr.GetItemState(SID_FRAME_LINECOLOR, sal_False) ) 2229 pLineColorItem = dynamic_cast< const SvxColorItem* >( &rAttr.Get( SID_FRAME_LINECOLOR ) ); 2230 2231 const SvxBorderLine* pBorderLineItem = 0; 2232 if(SFX_ITEM_SET == rAttr.GetItemState(SID_FRAME_LINESTYLE, sal_False) ) 2233 pBorderLineItem = ((const SvxLineItem&)rAttr.Get( SID_FRAME_LINESTYLE )).GetLine(); 2234 2235 if( pBoxInfoItem && !pBoxItem ) 2236 { 2237 const static SvxBoxItem gaEmptyBoxItem( SDRATTR_TABLE_BORDER ); 2238 pBoxItem = &gaEmptyBoxItem; 2239 } 2240 else if( pBoxItem && !pBoxInfoItem ) 2241 { 2242 const static SvxBoxInfoItem gaEmptyBoxInfoItem( SDRATTR_TABLE_BORDER_INNER ); 2243 pBoxInfoItem = &gaEmptyBoxInfoItem; 2244 } 2245 2246 CellPos aStart, aEnd; 2247 getSelectedCells( aStart, aEnd ); 2248 2249 const sal_Int32 nLastRow = std::min( aEnd.mnRow + 2, nRowCount ); 2250 const sal_Int32 nLastCol = std::min( aEnd.mnCol + 2, nColCount ); 2251 2252 for( sal_Int32 nRow = std::max( aStart.mnRow - 1, (sal_Int32)0 ); nRow < nLastRow; nRow++ ) 2253 { 2254 sal_uInt16 nRowFlags = 0; 2255 nRowFlags |= (nRow == aStart.mnRow) ? CELL_TOP : 0; 2256 nRowFlags |= (nRow == aEnd.mnRow) ? CELL_BOTTOM : 0; 2257 nRowFlags |= (nRow < aStart.mnRow) ? CELL_UPPER : 0; 2258 nRowFlags |= (nRow > aEnd.mnRow) ? CELL_LOWER : 0; 2259 2260 for( sal_Int32 nCol = std::max( aStart.mnCol - 1, (sal_Int32)0 ); nCol < nLastCol; nCol++ ) 2261 { 2262 CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) ); 2263 if( !xCell.is() ) 2264 continue; 2265 2266 const SfxItemSet& rSet = xCell->GetItemSet(); 2267 const SvxBoxItem* pOldOuter = (const SvxBoxItem*) &rSet.Get( SDRATTR_TABLE_BORDER ); 2268 2269 SvxBoxItem aNewFrame( *pOldOuter ); 2270 2271 sal_uInt16 nCellFlags = nRowFlags; 2272 nCellFlags |= (nCol == aStart.mnCol) ? CELL_LEFT : 0; 2273 nCellFlags |= (nCol == aEnd.mnCol) ? CELL_RIGHT : 0; 2274 nCellFlags |= (nCol < aStart.mnCol) ? CELL_BEFORE : 0; 2275 nCellFlags |= (nCol > aEnd.mnCol) ? CELL_AFTER : 0; 2276 2277 if( pBoxItem && pBoxInfoItem ) 2278 ImplApplyBoxItem( nCellFlags, pBoxItem, pBoxInfoItem, aNewFrame ); 2279 2280 if( pLineColorItem ) 2281 ImplApplyLineColorItem( nCellFlags, pLineColorItem, aNewFrame ); 2282 2283 if( pBorderLineItem ) 2284 ImplApplyBorderLineItem( nCellFlags, pBorderLineItem, aNewFrame ); 2285 2286 if (aNewFrame != *pOldOuter) 2287 { 2288 SfxItemSet aAttr(*rSet.GetPool(), rSet.GetRanges()); 2289 aAttr.Put(aNewFrame); 2290 xCell->SetMergedItemSetAndBroadcast( aAttr, false ); 2291 } 2292 } 2293 } 2294 } 2295 } 2296 } 2297 2298 // -------------------------------------------------------------------- 2299 2300 void SvxTableController::UpdateTableShape() 2301 { 2302 SdrObject* pTableObj = mxTableObj.get(); 2303 if( pTableObj ) 2304 { 2305 pTableObj->ActionChanged(); 2306 pTableObj->BroadcastObjectChange(); 2307 } 2308 updateSelectionOverlay(); 2309 } 2310 2311 2312 // -------------------------------------------------------------------- 2313 2314 void SvxTableController::SetAttrToSelectedCells(const SfxItemSet& rAttr, bool bReplaceAll) 2315 { 2316 if( mxTable.is() ) 2317 { 2318 const bool bUndo = mpModel && mpModel->IsUndoEnabled(); 2319 2320 if( bUndo ) 2321 mpModel->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT) ); 2322 2323 CellPos aStart, aEnd; 2324 getSelectedCells( aStart, aEnd ); 2325 2326 SfxItemSet aAttr(*rAttr.GetPool(), rAttr.GetRanges()); 2327 aAttr.Put(rAttr, sal_True); 2328 2329 const bool bFrame = (rAttr.GetItemState( SDRATTR_TABLE_BORDER ) == SFX_ITEM_SET) || (rAttr.GetItemState( SDRATTR_TABLE_BORDER_INNER ) == SFX_ITEM_SET); 2330 2331 if( bFrame ) 2332 { 2333 aAttr.ClearItem( SDRATTR_TABLE_BORDER ); 2334 aAttr.ClearItem( SDRATTR_TABLE_BORDER_INNER ); 2335 } 2336 2337 for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ ) 2338 { 2339 for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ ) 2340 { 2341 CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) ); 2342 if( xCell.is() ) 2343 { 2344 if( bUndo ) 2345 xCell->AddUndo(); 2346 xCell->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll); 2347 } 2348 } 2349 } 2350 2351 if( bFrame ) 2352 { 2353 ApplyBorderAttr( rAttr ); 2354 } 2355 2356 UpdateTableShape(); 2357 2358 if( bUndo ) 2359 mpModel->EndUndo(); 2360 2361 } 2362 } 2363 2364 // -------------------------------------------------------------------- 2365 2366 bool SvxTableController::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const 2367 { 2368 if( mxTableObj.is() && hasSelectedCells() ) 2369 { 2370 MergeAttrFromSelectedCells( rTargetSet, bOnlyHardAttr ); 2371 2372 if( mpView->IsTextEdit() ) 2373 { 2374 if( mxTableObj->GetOutlinerParaObject() ) 2375 rTargetSet.Put( SvxScriptTypeItem( mxTableObj->GetOutlinerParaObject()->GetTextObject().GetScriptType() ) ); 2376 2377 OutlinerView* pTextEditOutlinerView = mpView->GetTextEditOutlinerView(); 2378 if(pTextEditOutlinerView) 2379 { 2380 // FALSE= InvalidItems nicht al Default, sondern als "Loecher" betrachten 2381 rTargetSet.Put(pTextEditOutlinerView->GetAttribs(), sal_False); 2382 rTargetSet.Put( SvxScriptTypeItem( pTextEditOutlinerView->GetSelectedScriptType() ), sal_False ); 2383 } 2384 } 2385 2386 return true; 2387 } 2388 else 2389 { 2390 return false; 2391 } 2392 } 2393 2394 // -------------------------------------------------------------------- 2395 2396 bool SvxTableController::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll) 2397 { 2398 if( mbCellSelectionMode || mpView->IsTextEdit() ) 2399 { 2400 SetAttrToSelectedCells( rSet, bReplaceAll ); 2401 return true; 2402 } 2403 return false; 2404 } 2405 2406 // -------------------------------------------------------------------- 2407 2408 bool SvxTableController::GetMarkedObjModel( SdrPage* pNewPage ) 2409 { 2410 if( mxTableObj.is() && mbCellSelectionMode && pNewPage ) try 2411 { 2412 ::sdr::table::SdrTableObj& rTableObj = *static_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() ); 2413 2414 CellPos aStart, aEnd; 2415 getSelectedCells( aStart, aEnd ); 2416 2417 SdrTableObj* pNewTableObj = rTableObj.CloneRange( aStart, aEnd ); 2418 2419 pNewTableObj->SetPage( pNewPage ); 2420 pNewTableObj->SetModel( pNewPage->GetModel() ); 2421 2422 SdrInsertReason aReason(SDRREASON_VIEWCALL); 2423 pNewPage->InsertObject(pNewTableObj,CONTAINER_APPEND,&aReason); 2424 2425 return true; 2426 } 2427 catch( Exception& ) 2428 { 2429 DBG_ERROR( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" ); 2430 } 2431 return false; 2432 } 2433 2434 // -------------------------------------------------------------------- 2435 2436 bool SvxTableController::PasteObjModel( const SdrModel& rModel ) 2437 { 2438 if( mxTableObj.is() && mpView && (rModel.GetPageCount() >= 1) ) 2439 { 2440 const SdrPage* pPastePage = rModel.GetPage(0); 2441 if( pPastePage && pPastePage->GetObjCount() == 1 ) 2442 { 2443 SdrTableObj* pPasteTableObj = dynamic_cast< SdrTableObj* >( pPastePage->GetObj(0) ); 2444 if( pPasteTableObj ) 2445 { 2446 return PasteObject( pPasteTableObj ); 2447 } 2448 } 2449 } 2450 2451 return false; 2452 } 2453 2454 // -------------------------------------------------------------------- 2455 2456 bool SvxTableController::PasteObject( SdrTableObj* pPasteTableObj ) 2457 { 2458 if( !pPasteTableObj ) 2459 return false; 2460 2461 Reference< XTable > xPasteTable( pPasteTableObj->getTable() ); 2462 if( !xPasteTable.is() ) 2463 return false; 2464 2465 if( !mxTable.is() ) 2466 return false; 2467 2468 sal_Int32 nPasteColumns = xPasteTable->getColumnCount(); 2469 sal_Int32 nPasteRows = xPasteTable->getRowCount(); 2470 2471 CellPos aStart, aEnd; 2472 getSelectedCells( aStart, aEnd ); 2473 2474 if( mpView->IsTextEdit() ) 2475 mpView->SdrEndTextEdit(sal_True); 2476 2477 sal_Int32 nColumns = mxTable->getColumnCount(); 2478 sal_Int32 nRows = mxTable->getRowCount(); 2479 2480 const sal_Int32 nMissing = nPasteRows - ( nRows - aStart.mnRow ); 2481 if( nMissing > 0 ) 2482 { 2483 Reference< XTableRows > xRows( mxTable->getRows() ); 2484 xRows->insertByIndex( nRows, nMissing ); 2485 nRows = mxTable->getRowCount(); 2486 } 2487 2488 nPasteRows = std::min( nPasteRows, nRows - aStart.mnRow ); 2489 nPasteColumns = std::min( nPasteColumns, nColumns - aStart.mnCol ); 2490 2491 // copy cell contents 2492 for( sal_Int32 nRow = 0; nRow < nPasteRows; ++nRow ) 2493 { 2494 for( sal_Int32 nCol = 0; nCol < nPasteColumns; ++nCol ) 2495 { 2496 CellRef xTargetCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( aStart.mnCol + nCol, aStart.mnRow + nRow ).get() ) ); 2497 if( xTargetCell.is() && !xTargetCell->isMerged() ) 2498 { 2499 xTargetCell->AddUndo(); 2500 xTargetCell->cloneFrom( dynamic_cast< Cell* >( xPasteTable->getCellByPosition( nCol, nRow ).get() ) ); 2501 nCol += xTargetCell->getColumnSpan() - 1; 2502 } 2503 } 2504 } 2505 2506 UpdateTableShape(); 2507 2508 return true; 2509 } 2510 2511 bool SvxTableController::TakeFormatPaintBrush( boost::shared_ptr< SfxItemSet >& /*rFormatSet*/ ) 2512 { 2513 // SdrView::TakeFormatPaintBrush() is enough 2514 return false; 2515 } 2516 2517 bool SvxTableController::ApplyFormatPaintBrush( SfxItemSet& rFormatSet, bool bNoCharacterFormats, bool bNoParagraphFormats ) 2518 { 2519 if( mbCellSelectionMode ) 2520 { 2521 SdrTextObj* pTableObj = dynamic_cast<SdrTextObj*>( mxTableObj.get() ); 2522 if( !pTableObj ) 2523 return false; 2524 2525 const bool bUndo = mpModel && mpModel->IsUndoEnabled(); 2526 2527 if( bUndo ) 2528 mpModel->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT) ); 2529 2530 CellPos aStart, aEnd; 2531 getSelectedCells( aStart, aEnd ); 2532 2533 SfxItemSet aAttr(*rFormatSet.GetPool(), rFormatSet.GetRanges()); 2534 aAttr.Put(rFormatSet, sal_True); 2535 2536 const bool bFrame = (rFormatSet.GetItemState( SDRATTR_TABLE_BORDER ) == SFX_ITEM_SET) || (rFormatSet.GetItemState( SDRATTR_TABLE_BORDER_INNER ) == SFX_ITEM_SET); 2537 2538 if( bFrame ) 2539 { 2540 aAttr.ClearItem( SDRATTR_TABLE_BORDER ); 2541 aAttr.ClearItem( SDRATTR_TABLE_BORDER_INNER ); 2542 } 2543 2544 const sal_uInt16* pRanges = rFormatSet.GetRanges(); 2545 bool bTextOnly = true; 2546 2547 while( *pRanges ) 2548 { 2549 if( (*pRanges != EE_PARA_START) && (*pRanges != EE_CHAR_START) ) 2550 { 2551 bTextOnly = true; 2552 break; 2553 } 2554 pRanges += 2; 2555 } 2556 2557 const bool bReplaceAll = false; 2558 for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ ) 2559 { 2560 for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ ) 2561 { 2562 CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) ); 2563 if( xCell.is() ) 2564 { 2565 if( bUndo ) 2566 xCell->AddUndo(); 2567 if( !bTextOnly ) 2568 xCell->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll); 2569 2570 SdrText* pText = static_cast< SdrText* >( xCell.get() ); 2571 mpView->ApplyFormatPaintBrushToText( rFormatSet, *pTableObj, pText, bNoCharacterFormats, bNoParagraphFormats ); 2572 } 2573 } 2574 } 2575 2576 if( bFrame ) 2577 { 2578 ApplyBorderAttr( rFormatSet ); 2579 } 2580 2581 UpdateTableShape(); 2582 2583 if( bUndo ) 2584 mpModel->EndUndo(); 2585 2586 return true; 2587 2588 } 2589 return false; 2590 } 2591 2592 2593 // -------------------------------------------------------------------- 2594 2595 IMPL_LINK( SvxTableController, UpdateHdl, void *, EMPTYARG ) 2596 { 2597 mnUpdateEvent = 0; 2598 2599 if( mbCellSelectionMode ) 2600 { 2601 CellPos aStart( maCursorFirstPos ); 2602 CellPos aEnd( maCursorLastPos ); 2603 checkCell(aStart); 2604 checkCell(aEnd); 2605 if( aStart != maCursorFirstPos || aEnd != maCursorLastPos ) 2606 { 2607 setSelectedCells( aStart, aEnd ); 2608 } 2609 } 2610 updateSelectionOverlay(); 2611 2612 return 0; 2613 } 2614 2615 } } 2616