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