LCOV - code coverage report
Current view: top level - svx/source/table - tablecontroller.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 1488 0.1 %
Date: 2014-11-03 Functions: 2 90 2.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10