diff options
author | Rüdiger Timm <rt@openoffice.org> | 2008-03-12 09:02:20 +0000 |
---|---|---|
committer | Rüdiger Timm <rt@openoffice.org> | 2008-03-12 09:02:20 +0000 |
commit | 48ea88c8c8194d65105aa22108583369575926e1 (patch) | |
tree | b14e974202f3a9d7bc24feb30de1450d4e30f433 /svx/source/table | |
parent | 85bc16451742a9bb09dd0389e53b423197992b41 (diff) |
INTEGRATION: CWS impresstables2 (1.1.2); FILE ADDED
2008/03/04 18:06:57 cl 1.1.2.35: #i68103# fixing auto color
2008/02/29 11:49:43 cl 1.1.2.34: #i68103# fixed vertical alignment
2008/02/28 16:01:37 cl 1.1.2.33: #i68103# fixes in mousebutton handling
2008/02/28 15:55:05 cl 1.1.2.32: #i68103# fixes in mousebutton handling
2008/02/27 10:42:48 cl 1.1.2.31: #i68103# fixed context menu handling for tables
2008/02/25 14:19:18 cl 1.1.2.30: #i68103# fixed table borders in rtl mode
2008/02/24 12:09:09 cl 1.1.2.29: #i68103# working on clipboard
2008/02/20 16:52:05 cl 1.1.2.28: #i68103# some work on notifications
2008/02/15 14:22:22 cl 1.1.2.27: #i68103#
2008/02/07 20:05:30 cl 1.1.2.26: #i68103# fixed assign operator
2008/02/06 18:18:48 cl 1.1.2.25: #i68103# fixing some split/merge issues
2008/02/01 17:58:26 cl 1.1.2.24: #i68103# reworked bidi support
2008/01/31 18:08:11 cl 1.1.2.23: #i68103# new defaults for table style settings
2008/01/30 11:22:52 cl 1.1.2.22: #i68103# added XUnoTunnel to SfxUnoStyleSheet for safer conversion
2008/01/29 18:12:42 cl 1.1.2.21: #i68103# added SfxUnoStyleSheet to fix a dynamic_cast issue under linux
2008/01/28 18:08:41 cl 1.1.2.20: #i68103# working on i18n
2008/01/24 17:07:52 cl 1.1.2.19: #i68103# reworked table layouter
2008/01/23 14:54:39 cl 1.1.2.18: #i68103# implementing border properties for tables
2008/01/13 19:57:16 cl 1.1.2.17: #i68103# working on i18n
2008/01/01 18:37:42 cl 1.1.2.16: #i68103# working on tables
2007/12/16 17:52:44 cl 1.1.2.15: #i72702# working on table clipboard
2007/12/14 14:18:26 cl 1.1.2.14: #i68103# working on tables
2007/12/12 12:48:45 cl 1.1.2.13: #i68103# added name for table shapes
2007/12/02 01:51:11 cl 1.1.2.12: fixed merge conflict
2007/12/02 01:45:08 cl 1.1.2.11: fixed merge conflict
2007/12/01 15:35:20 cl 1.1.2.10: #i68103# working on layout
2007/11/29 19:03:16 cl 1.1.2.9: #i68103# working on table templates
2007/10/11 15:18:51 cl 1.1.2.8: #i68103# added undo for tables
2007/08/07 12:00:12 cl 1.1.2.7: fixed merge conflicts
2007/08/06 19:38:03 cl 1.1.2.6: #i68103# worked on cell merging for tables in impress&draw
2007/07/26 21:24:07 cl 1.1.2.5: #i68103# working on tables in draw
2007/05/03 09:05:13 cl 1.1.2.4: #i68103# more table work
2007/04/18 15:06:56 cl 1.1.2.3: #i72702# updated api for table shapes
2007/03/20 12:54:50 cl 1.1.2.2: fixed unix compile errors
2007/03/15 17:13:54 cl 1.1.2.1: #i68103# adding a shape for tables
Diffstat (limited to 'svx/source/table')
-rw-r--r-- | svx/source/table/svdotable.cxx | 3224 |
1 files changed, 3224 insertions, 0 deletions
diff --git a/svx/source/table/svdotable.cxx b/svx/source/table/svdotable.cxx new file mode 100644 index 000000000000..7547b895cac5 --- /dev/null +++ b/svx/source/table/svdotable.cxx @@ -0,0 +1,3224 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svdotable.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2008-03-12 10:02:20 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#define ITEMID_BOX SDRATTR_TABLE_BORDER +#define ITEMID_BOXINFO SDRATTR_TABLE_BORDER_INNER + +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> + +#include <vcl/canvastools.hxx> +#include <com/sun/star/style/XStyle.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <svtools/style.hxx> +#include "editstat.hxx" +#include "svx/outlobj.hxx" +#include "svx/svdview.hxx" +#include "svx/sdr/properties/textproperties.hxx" +#include "svx/svdotable.hxx" +#include "svx/svdhdl.hxx" +#include "viewcontactoftableobj.hxx" +#include "svx/svdoutl.hxx" +#include "svx/svddrag.hxx" +#include "svx/svdpagv.hxx" +#include "svx/xoutx.hxx" +#include "tablemodel.hxx" +#include "cell.hxx" +#include "svx/xflclit.hxx" +#include "tablelayouter.hxx" +#include "svx/svdetc.hxx" +#include "tablehandles.hxx" +#include "svx/boxitem.hxx" +#include "svx/framelink.hxx" +#include "svx/sdr/table/tabledesign.hxx" +#include "svx/svdundo.hxx" +#include "svdstr.hrc" +#include "svdglob.hxx" +#include "svx/writingmodeitem.hxx" +#include "svx/frmdiritem.hxx" +#include "svx/xflhtit.hxx" +#include "svx/xflftrit.hxx" +#include "svx/xfltrit.hxx" + +// ----------------------------------------------------------------------------- + +using ::rtl::OUString; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::XInterface; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::container::XIndexAccess; +using ::com::sun::star::style::XStyle; +using ::com::sun::star::table::XTableRows; +using ::com::sun::star::table::XTableColumns; +using ::com::sun::star::table::XTable; +using ::com::sun::star::beans::XPropertySet; +using ::com::sun::star::util::XModifyBroadcaster; +using sdr::properties::TextProperties; +using sdr::properties::BaseProperties; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::style; + +namespace sdr { namespace table { + +class TableProperties : public TextProperties +{ +protected: + // create a new itemset + SfxItemSet& CreateObjectSpecificItemSet(SfxItemPool& rPool); + +public: + // basic constructor + TableProperties(SdrObject& rObj ); + + // constructor for copying, but using new object + TableProperties(const TableProperties& rProps, SdrObject& rObj ); + + // destructor + ~TableProperties(); + + // Clone() operator, normally just calls the local copy constructor + BaseProperties& Clone(SdrObject& rObj) const; + + virtual void ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem); +}; + +TableProperties::TableProperties(SdrObject& rObj) +: TextProperties(rObj) +{ +} + +TableProperties::TableProperties(const TableProperties& rProps, SdrObject& rObj) +: TextProperties(rProps, rObj) +{ +} + +TableProperties::~TableProperties() +{ +} + +BaseProperties& TableProperties::Clone(SdrObject& rObj) const +{ + return *(new TableProperties(*this, rObj)); +} + +void TableProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem) +{ + if( nWhich == SDRATTR_TEXTDIRECTION ) + AttributeProperties::ItemChange( nWhich, pNewItem ); + else + TextProperties::ItemChange( nWhich, pNewItem ); +} + +// create a new itemset +SfxItemSet& TableProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) +{ + return *(new SfxItemSet(rPool, + + // range from SdrAttrObj + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, + SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + + // range for SdrTableObj + SDRATTR_TABLE_FIRST, SDRATTR_TABLE_LAST, + + // range from SdrTextObj + EE_ITEMS_START, EE_ITEMS_END, + + // end + 0, 0)); +} + +class TableObjectGeoData : public SdrTextObjGeoData +{ +public: + Rectangle maLogicRect; +}; + +//------------------------------------------------------------------------ +// TableStyleSettings +//------------------------------------------------------------------------ + +TableStyleSettings::TableStyleSettings() +: mbUseFirstRow(true) +, mbUseLastRow(false) +, mbUseFirstColumn(false) +, mbUseLastColumn(false) +, mbUseRowBanding(true) +, mbUseColumnBanding(false) +{ +} + +TableStyleSettings::TableStyleSettings( const TableStyleSettings& rStyle ) +{ + (*this) = rStyle; +} + +TableStyleSettings& TableStyleSettings::operator=(const TableStyleSettings& rStyle) +{ + mbUseFirstRow = rStyle.mbUseFirstRow; + mbUseLastRow = rStyle.mbUseLastRow; + mbUseFirstColumn = rStyle.mbUseFirstColumn; + mbUseLastColumn = rStyle.mbUseLastColumn; + mbUseRowBanding = rStyle.mbUseRowBanding; + mbUseColumnBanding = rStyle.mbUseColumnBanding; + return *this; +} + +bool TableStyleSettings::operator==( const TableStyleSettings& rStyle ) const +{ + return + (mbUseFirstRow == rStyle.mbUseFirstRow) && + (mbUseLastRow == rStyle.mbUseLastRow) && + (mbUseFirstColumn == rStyle.mbUseFirstColumn) && + (mbUseLastColumn == rStyle.mbUseLastColumn) && + (mbUseRowBanding == rStyle.mbUseRowBanding) && + (mbUseColumnBanding == rStyle.mbUseColumnBanding); +} + +// ----------------------------------------------------------------------------- + +class SdrTableObjImpl : public TableDesignUser, public ::cppu::WeakImplHelper1< ::com::sun::star::util::XModifyListener > +{ +public: + CellRef mxActiveCell; + TableModelRef mxTable; + SdrTableObj* mpTableObj; + TableLayouter* mpLayouter; + CellPos maEditPos; + TableStyleSettings maTableStyle; + Reference< XIndexAccess > mxTableStyle; + bool mbModifyPending; +// sal_Int32 mnSavedEditRowHeight; + + void SetModel(SdrModel* pOldModel, SdrModel* pNewModel); + + CellRef getCell( const CellPos& rPos ) const; + void LayoutTable( Rectangle& rArea, bool bFitWidth, bool bFitHeight ); + + bool ApplyCellStyles(); + void UpdateCells( Rectangle& rArea ); + + SdrTableObjImpl(); + virtual ~SdrTableObjImpl(); + + void init( SdrTableObj* pTable, sal_Int32 nColumns, sal_Int32 nRows ); + void dispose(); + + sal_Int32 getColumnCount() const; + sal_Int32 getRowCount() const; + + void DragEdge( bool mbHorizontal, int nEdge, sal_Int32 nOffset ); + + const SfxPoolItem* GetCellItem( const CellPos& rPos, sal_uInt16 nWhich ) const; +// void GetBorderLines( const CellPos& rPos, const SvxBorderLine** ppLeft, const SvxBorderLine** ppTop, const SvxBorderLine** ppRight, const SvxBorderLine** ppBottom ) const; + + void operator=( const SdrTableObjImpl& rSource ); + + // XModifyListener + virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); + + void update(); + + void connectTableStyle(); + void disconnectTableStyle(); + virtual bool isInUse(); + + bool UpdateWritingMode(); +}; + +// ----------------------------------------------------------------------------- + +SdrTableObjImpl::SdrTableObjImpl() +: mpTableObj( 0 ) +, mpLayouter( 0 ) +{ +} + +// ----------------------------------------------------------------------------- + +SdrTableObjImpl::~SdrTableObjImpl() +{ +} + +// ----------------------------------------------------------------------------- + +void SdrTableObjImpl::init( SdrTableObj* pTable, sal_Int32 nColumns, sal_Int32 nRows ) +{ + mpTableObj = pTable; + mxTable = new TableModel( pTable ); + mxTable->init( nColumns, nRows ); + mpLayouter = new TableLayouter( mxTable ); + Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) ); + mxTable->addModifyListener( xListener ); + UpdateWritingMode(); + LayoutTable( mpTableObj->aRect, true, true ); + mpTableObj->maLogicRect = mpTableObj->aRect; +} + +// ----------------------------------------------------------------------------- + +void SdrTableObjImpl::operator=( const SdrTableObjImpl& rSource ) +{ + if( mpLayouter ) + { + delete mpLayouter; + mpLayouter = 0; + } + + if( mxTable.is() ) + { + Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) ); + mxTable->removeModifyListener( xListener ); + mxTable->dispose(); + mxTable.clear(); + } + + maTableStyle = rSource.maTableStyle; + + mxTable = new TableModel( mpTableObj, rSource.mxTable ); + mpLayouter = new TableLayouter( mxTable ); + Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) ); + mxTable->addModifyListener( xListener ); + mxTableStyle = rSource.mxTableStyle; + UpdateWritingMode(); + ApplyCellStyles(); + mpTableObj->aRect = mpTableObj->maLogicRect; + LayoutTable( mpTableObj->aRect, false, false ); +} + +// ----------------------------------------------------------------------------- + +void SdrTableObjImpl::SetModel(SdrModel* /*pOldModel*/, SdrModel* pNewModel) +{ + // try to find new table style + + Reference< XIndexAccess > xNewTableStyle; + if( mxTableStyle.is() ) try + { + const OUString sStyleName( Reference< XNamed >( mxTableStyle, UNO_QUERY_THROW )->getName() ); + + Reference< XStyleFamiliesSupplier > xSFS( pNewModel->getUnoModel(), UNO_QUERY_THROW ); + Reference< XNameAccess > xFamilyNameAccess( xSFS->getStyleFamilies(), UNO_QUERY_THROW ); + const rtl::OUString sFamilyName( RTL_CONSTASCII_USTRINGPARAM( "table" ) ); + Reference< XNameAccess > xTableFamilyAccess( xFamilyNameAccess->getByName( sFamilyName ), UNO_QUERY_THROW ); + + if( xTableFamilyAccess->hasByName( sStyleName ) ) + { + // found table style with the same name + xTableFamilyAccess->getByName( sStyleName ) >>= xNewTableStyle; + } + else + { + // copy or? + Reference< XIndexAccess > xIndexAccess( xTableFamilyAccess, UNO_QUERY_THROW ); + xIndexAccess->getByIndex( 0 ) >>= xNewTableStyle; + } + } + catch( Exception& ) + { + DBG_ERROR("svx::SdrTableObjImpl::SetModel(), exception caught!"); + } + + mxTableStyle = xNewTableStyle; + + update(); +} + +// ----------------------------------------------------------------------------- + +bool SdrTableObjImpl::ApplyCellStyles() +{ + if( !mxTable.is() || !mxTable.is() || !mxTableStyle.is() ) + return false; + + bool bChanges = false; + + const sal_Int32 nColCount = getColumnCount(); + const sal_Int32 nRowCount = getRowCount(); + + const TableStyleSettings& rStyle = maTableStyle; + + CellPos aPos; + for( aPos.mnRow = 0; aPos.mnRow < nRowCount; ++aPos.mnRow ) + { + const bool bFirstRow = (aPos.mnRow == 0) && rStyle.mbUseFirstRow; + const bool bLastRow = (aPos.mnRow == nRowCount-1) && rStyle.mbUseLastRow; + + for( aPos.mnCol = 0; aPos.mnCol < nColCount; ++aPos.mnCol ) + { + Reference< XStyle > xStyle; + + // first and last row win first, if used and available + if( bFirstRow ) + { + mxTableStyle->getByIndex(first_row_style) >>= xStyle; + } + else if( bLastRow ) + { + mxTableStyle->getByIndex(last_row_style) >>= xStyle; + } + + if( !xStyle.is() ) + { + // next come first and last column, if used and available + if( rStyle.mbUseFirstColumn && (aPos.mnCol == 0) ) + { + mxTableStyle->getByIndex(first_column_style) >>= xStyle; + } + else if( rStyle.mbUseLastColumn && (aPos.mnCol == nColCount-1) ) + { + mxTableStyle->getByIndex(last_column_style) >>= xStyle; + } + } + + if( !xStyle.is() && rStyle.mbUseRowBanding ) + { + if( (aPos.mnRow & 1) == 0 ) + { + mxTableStyle->getByIndex(even_rows_style) >>= xStyle; + } + else + { + mxTableStyle->getByIndex(odd_rows_style) >>= xStyle; + } + } + + if( !xStyle.is() && rStyle.mbUseColumnBanding ) + { + if( (aPos.mnCol & 1) == 0 ) + { + mxTableStyle->getByIndex(even_columns_style) >>= xStyle; + } + else + { + mxTableStyle->getByIndex(odd_columns_style) >>= xStyle; + } + } + + if( !xStyle.is() ) + { + // use default cell style if non found yet + mxTableStyle->getByIndex(body_style) >>= xStyle; + } + + + if( xStyle.is() ) + { + SfxUnoStyleSheet* pStyle = SfxUnoStyleSheet::getUnoStyleSheet(xStyle); + + if( pStyle ) + { + CellRef xCell( getCell( aPos ) ); + if( xCell.is() && ( xCell->GetStyleSheet() != pStyle ) ) + { + bChanges = true; + xCell->SetStyleSheet( pStyle, sal_True ); + } + } + } + } + } + + return bChanges; +} + +// ----------------------------------------------------------------------------- + +void SdrTableObjImpl::dispose() +{ + if( mxTable.is() ) + mxTable->dispose(); +} + +// ----------------------------------------------------------------------------- + +void SdrTableObjImpl::DragEdge( bool mbHorizontal, int nEdge, sal_Int32 nOffset ) +{ + if( (nEdge > 0) && mxTable.is()) try + { + const OUString sSize( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ); + nEdge--; + if( mbHorizontal ) + { + if( (nEdge >= 0) && (nEdge < getRowCount()) ) + { + sal_Int32 nHeigth = mpLayouter->getRowHeight( nEdge ); + nHeigth += nOffset; + Reference< XIndexAccess > xRows( mxTable->getRows(), UNO_QUERY_THROW ); + Reference< XPropertySet > xRowSet( xRows->getByIndex( nEdge ), UNO_QUERY_THROW ); + xRowSet->setPropertyValue( sSize, Any( nHeigth ) ); + } + } + else + { + if( (nEdge >= 0) && (nEdge < getColumnCount()) ) + { + sal_Int32 nWidth = mpLayouter->getColumnWidth( nEdge ); + nWidth += nOffset; + + Reference< XIndexAccess > xCols( mxTable->getColumns(), UNO_QUERY_THROW ); + Reference< XPropertySet > xColSet( xCols->getByIndex( nEdge ), UNO_QUERY_THROW ); + xColSet->setPropertyValue( sSize, Any( nWidth ) ); + + if( nEdge > 0 && nEdge < mxTable->getColumnCount() ) + { + const bool bRTL = mpLayouter->GetWritingMode() == WritingMode_RL_TB; + + if( bRTL ) + nEdge--; + else + nEdge++; + + if( (bRTL && (nEdge >= 0)) || (!bRTL && (nEdge < mxTable->getColumnCount())) ) + { + nWidth = mpLayouter->getColumnWidth( nEdge ); + nWidth = std::max( (sal_Int32)(nWidth - nOffset), (sal_Int32)0 ); + + xColSet = Reference< XPropertySet >( xCols->getByIndex( nEdge ), UNO_QUERY_THROW ); + xColSet->setPropertyValue( sSize, Any( nWidth ) ); + } + } + } + } + } + catch( Exception& ) + { + DBG_ERROR( "svx::SdrTableObjImpl::DragEdge(), exception caught!" ); + } +} + +// ----------------------------------------------------------------------------- +// XModifyListener +// ----------------------------------------------------------------------------- + +void SAL_CALL SdrTableObjImpl::modified( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException) +{ + update(); +} + +void SdrTableObjImpl::update() +{ + // source can be the table model itself or the assigned table template + TableModelNotifyGuard aGuard( mxTable.get() ); + if( mpTableObj ) + { + if( (maEditPos.mnRow >= getRowCount()) || (maEditPos.mnCol >= getColumnCount()) || (getCell( maEditPos ) != mxActiveCell) ) + { + if(maEditPos.mnRow >= getRowCount()) + maEditPos.mnRow = getRowCount()-1; + + if(maEditPos.mnCol >= getColumnCount()) + maEditPos.mnCol = getColumnCount()-1; + + mpTableObj->setActiveCell( maEditPos ); + } + + ApplyCellStyles(); + + mpTableObj->aRect = mpTableObj->maLogicRect; + LayoutTable( mpTableObj->aRect, false, false ); + + mpTableObj->SetRectsDirty(); + mpTableObj->ActionChanged(); + mpTableObj->BroadcastObjectChange(); + } +} + +// ----------------------------------------------------------------------------- + +void SdrTableObjImpl::connectTableStyle() +{ + if( mxTableStyle.is() ) + { + Reference< XModifyBroadcaster > xBroadcaster( mxTableStyle, UNO_QUERY ); + if( xBroadcaster.is() ) + { + Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) ); + xBroadcaster->addModifyListener( xListener ); + } + } +} + +// ----------------------------------------------------------------------------- + +void SdrTableObjImpl::disconnectTableStyle() +{ + if( mxTableStyle.is() ) + { + Reference< XModifyBroadcaster > xBroadcaster( mxTableStyle, UNO_QUERY ); + if( xBroadcaster.is() ) + { + Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) ); + xBroadcaster->removeModifyListener( xListener ); + } + } +} + +// ----------------------------------------------------------------------------- + +bool SdrTableObjImpl::isInUse() +{ + return mpTableObj && mpTableObj->IsInserted(); +} + +// ----------------------------------------------------------------------------- +// XEventListener +// ----------------------------------------------------------------------------- + +void SAL_CALL SdrTableObjImpl::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException) +{ + mxActiveCell.clear(); + mxTable.clear(); + if( mpLayouter ) + { + delete mpLayouter; + mpLayouter = 0; + } + mpTableObj = 0; +} + +// ----------------------------------------------------------------------------- + +CellRef SdrTableObjImpl::getCell( const CellPos& rPos ) const +{ + CellRef xCell; + if( mxTable.is() ) try + { + xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ).get() ) ); + } + catch( Exception& ) + { + DBG_ERROR( "svx::SdrTableObjImpl::getCell(), exception caught!" ); + } + return xCell; +} + +// ----------------------------------------------------------------------------- + +sal_Int32 SdrTableObjImpl::getColumnCount() const +{ + return mxTable.is() ? mxTable->getColumnCount() : 0; +} + +// ----------------------------------------------------------------------------- + +sal_Int32 SdrTableObjImpl::getRowCount() const +{ + return mxTable.is() ? mxTable->getRowCount() : 0; +} + +// ----------------------------------------------------------------------------- + +void SdrTableObjImpl::LayoutTable( Rectangle& rArea, bool bFitWidth, bool bFitHeight ) +{ + if( mpLayouter && mpTableObj->GetModel() ) + { + TableModelNotifyGuard aGuard( mxTable.get() ); + mpLayouter->LayoutTable( rArea, bFitWidth, bFitHeight ); + } +} + +// ----------------------------------------------------------------------------- + +bool SdrTableObjImpl::UpdateWritingMode() +{ + if( mpTableObj && mpLayouter ) + { + WritingMode eWritingMode = (WritingMode)static_cast< const SvxWritingModeItem& >( mpTableObj->GetObjectItem( SDRATTR_TEXTDIRECTION ) ).GetValue(); + + if( eWritingMode != WritingMode_TB_RL ) + { + if( static_cast< const SvxFrameDirectionItem& >( mpTableObj->GetObjectItem( EE_PARA_WRITINGDIR ) ).GetValue() == FRMDIR_HORI_LEFT_TOP ) + eWritingMode = WritingMode_LR_TB; + else + eWritingMode = WritingMode_RL_TB; + } + + if( eWritingMode != mpLayouter->GetWritingMode() ) + { + mpLayouter->SetWritingMode( eWritingMode ); + return true; + } + } + return false; +} + +// ----------------------------------------------------------------------------- + +void SdrTableObjImpl::UpdateCells( Rectangle& rArea ) +{ + if( mpLayouter && mxTable.is() ) + { + TableModelNotifyGuard aGuard( mxTable.get() ); + mpLayouter->updateCells( rArea ); + mxTable->setModified(sal_True); + } +} + +// ----------------------------------------------------------------------------- + +const SfxPoolItem* SdrTableObjImpl::GetCellItem( const CellPos& rPos, sal_uInt16 nWhich ) const +{ + CellRef xCell( getCell( rPos ) ); + if( xCell.is() ) + return xCell->GetItemSet().GetItem( nWhich ); + else + return 0; +} + +// ----------------------------------------------------------------------------- +// BaseProperties section +// ----------------------------------------------------------------------------- + +sdr::properties::BaseProperties* SdrTableObj::CreateObjectSpecificProperties() +{ + return new TableProperties(*this); +} + +// ----------------------------------------------------------------------------- +// DrawContact section +// ----------------------------------------------------------------------------- + +sdr::contact::ViewContact* SdrTableObj::CreateObjectSpecificViewContact() +{ + return new sdr::contact::ViewContactOfTableObj(*this); +} + +// -------------------------------------------------------------------- + +TYPEINIT1(SdrTableObj,SdrTextObj); + +// -------------------------------------------------------------------- + +SdrTableObj::SdrTableObj(SdrModel* _pModel) +{ + pModel = _pModel; + init( 1, 1 ); +} + +// -------------------------------------------------------------------- + +SdrTableObj::SdrTableObj(SdrModel* _pModel, const ::Rectangle& rNewRect, sal_Int32 nColumns, sal_Int32 nRows) +: SdrTextObj( rNewRect ) +, maLogicRect( rNewRect ) +{ + pModel = _pModel; + + if( nColumns <= 0 ) + nColumns = 1; + + if( nRows <= 0 ) + nRows = 1; + + init( nColumns, nRows ); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::init( sal_Int32 nColumns, sal_Int32 nRows ) +{ + bClosedObj = TRUE; + + mpImpl = new SdrTableObjImpl; + mpImpl->acquire(); + mpImpl->init( this, nColumns, nRows ); +} + +// -------------------------------------------------------------------- + +SdrTableObj::~SdrTableObj() +{ + mpImpl->dispose(); + mpImpl->release(); +} + +// -------------------------------------------------------------------- +// table stuff +// -------------------------------------------------------------------- + +Reference< XTable > SdrTableObj::getTable() const +{ + return Reference< XTable >( mpImpl->mxTable.get() ); +} + +// -------------------------------------------------------------------- + +bool SdrTableObj::isValid( const CellPos& rPos ) const +{ + return (rPos.mnCol >= 0) && (rPos.mnCol < mpImpl->getColumnCount()) && (rPos.mnRow >= 0) && (rPos.mnRow < mpImpl->getRowCount()); +} + +// -------------------------------------------------------------------- + +CellPos SdrTableObj::getFirstCell() const +{ + return CellPos( 0,0 ); +} + +// -------------------------------------------------------------------- + +CellPos SdrTableObj::getLastCell() const +{ + CellPos aPos; + if( mpImpl->mxTable.is() ) + { + aPos.mnCol = mpImpl->getColumnCount()-1; + aPos.mnRow = mpImpl->getRowCount()-1; + } + return aPos; +} + +// -------------------------------------------------------------------- + +CellPos SdrTableObj::getLeftCell( const CellPos& rPos, bool bEdgeTravel ) const +{ + switch( GetWritingMode() ) + { + default: + case WritingMode_LR_TB: + return getPreviousCell( rPos, bEdgeTravel ); + case WritingMode_RL_TB: + return getNextCell( rPos, bEdgeTravel ); + case WritingMode_TB_RL: + return getPreviousRow( rPos, bEdgeTravel ); + } +} + +// -------------------------------------------------------------------- + +CellPos SdrTableObj::getRightCell( const CellPos& rPos, bool bEdgeTravel ) const +{ + switch( GetWritingMode() ) + { + default: + case WritingMode_LR_TB: + return getNextCell( rPos, bEdgeTravel ); + case WritingMode_RL_TB: + return getPreviousCell( rPos, bEdgeTravel ); + case WritingMode_TB_RL: + return getNextRow( rPos, bEdgeTravel ); + } +} + +// -------------------------------------------------------------------- + +CellPos SdrTableObj::getUpCell( const CellPos& rPos, bool bEdgeTravel ) const +{ + switch( GetWritingMode() ) + { + default: + case WritingMode_LR_TB: + case WritingMode_RL_TB: + return getPreviousRow( rPos, bEdgeTravel ); + case WritingMode_TB_RL: + return getPreviousCell( rPos, bEdgeTravel ); + } +} + +// -------------------------------------------------------------------- + +CellPos SdrTableObj::getDownCell( const CellPos& rPos, bool bEdgeTravel ) const +{ + switch( GetWritingMode() ) + { + default: + case WritingMode_LR_TB: + case WritingMode_RL_TB: + return getNextRow( rPos, bEdgeTravel ); + case WritingMode_TB_RL: + return getNextCell( rPos, bEdgeTravel ); + } +} + +// -------------------------------------------------------------------- + +CellPos SdrTableObj::getPreviousCell( const CellPos& rPos, bool bEdgeTravel ) const +{ + CellPos aPos( rPos ); + if( mpImpl ) + { + CellRef xCell( mpImpl->getCell( aPos ) ); + if( xCell.is() && xCell->isMerged() ) + { + sal_Int32 nTemp = 0; + findMergeOrigin( mpImpl->mxTable.get(), aPos.mnCol, aPos.mnRow, aPos.mnCol, nTemp ); + } + + if( aPos.mnCol > 0 ) + { + --aPos.mnCol; + } + + else if( bEdgeTravel && (aPos.mnRow > 0) ) + { + aPos.mnCol = mpImpl->mxTable->getColumnCount()-1; + --aPos.mnRow; + } + } + return aPos; +} + +// -------------------------------------------------------------------- + +CellPos SdrTableObj::getNextCell( const CellPos& rPos, bool bEdgeTravel ) const +{ + CellPos aPos( rPos ); + if( mpImpl ) + { + CellRef xCell( mpImpl->getCell( aPos ) ); + if( xCell.is() ) + { + if( xCell->isMerged() ) + { + findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, aPos.mnCol, aPos.mnRow ); + + xCell = mpImpl->getCell(aPos); + + if( xCell.is() ) + { + aPos.mnCol += xCell->getColumnSpan(); + aPos.mnRow = rPos.mnRow; + } + } + else + { + aPos.mnCol += xCell->getColumnSpan(); + } + + if( aPos.mnCol < mpImpl->mxTable->getColumnCount() ) + return aPos; + + if( bEdgeTravel && ((aPos.mnRow + 1) < mpImpl->getRowCount()) ) + { + aPos.mnCol = 0; + aPos.mnRow += 1; + return aPos; + } + } + } + + // last cell reached, no traveling possible + return rPos; +} + +// -------------------------------------------------------------------- + +CellPos SdrTableObj::getPreviousRow( const CellPos& rPos, bool bEdgeTravel ) const +{ + CellPos aPos( rPos ); + if( mpImpl ) + { + CellRef xCell( mpImpl->getCell( aPos ) ); + if( xCell.is() ) + { + if( xCell->isMerged() ) + { + sal_Int32 nTemp = 0; + findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, nTemp, aPos.mnRow ); + } + } + + if( aPos.mnRow > 0 ) + { + --aPos.mnRow; + } + else if( bEdgeTravel && (aPos.mnCol > 0) ) + { + aPos.mnRow = mpImpl->mxTable->getRowCount()-1; + --aPos.mnCol; + } + } + return aPos; +} + +// -------------------------------------------------------------------- + +CellPos SdrTableObj::getNextRow( const CellPos& rPos, bool bEdgeTravel ) const +{ + CellPos aPos( rPos ); + + if( mpImpl ) + { + CellRef xCell( mpImpl->getCell( rPos ) ); + if( xCell.is() ) + { + if( xCell->isMerged() ) + { + findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, aPos.mnCol, aPos.mnRow ); + xCell = mpImpl->getCell(aPos); + aPos.mnCol = rPos.mnCol; + } + + if( xCell.is() ) + aPos.mnRow += xCell->getRowSpan(); + + if( aPos.mnRow < mpImpl->mxTable->getRowCount() ) + return aPos; + + if( bEdgeTravel && (aPos.mnCol + 1) < mpImpl->mxTable->getColumnCount() ) + { + aPos.mnRow = 0; + aPos.mnCol += 1; + + while( aPos.mnCol < mpImpl->mxTable->getColumnCount() ) + { + xCell = mpImpl->getCell( aPos ); + if( xCell.is() && !xCell->isMerged() ) + return aPos; + aPos.mnCol += 1; + } + } + } + } + + // last position reached, no more traveling possible + return rPos; +} + +// -------------------------------------------------------------------- + +const TableStyleSettings& SdrTableObj::getTableStyleSettings() const +{ + if( mpImpl ) + { + return mpImpl->maTableStyle; + } + else + { + static TableStyleSettings aTmp; + return aTmp; + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::setTableStyleSettings( const TableStyleSettings& rStyle ) +{ + if( mpImpl ) + { + mpImpl->maTableStyle = rStyle; + mpImpl->update(); + } +} + +// -------------------------------------------------------------------- + +TableHitKind SdrTableObj::CheckTableHit( const Point& rPos, sal_Int32& rnX, sal_Int32& rnY, int nTol ) const +{ + if( !mpImpl || !mpImpl->mxTable.is() ) + return SDRTABLEHIT_NONE; + + rnX = 0; + rnY = 0; + + const sal_Int32 nColCount = mpImpl->getColumnCount(); + const sal_Int32 nRowCount = mpImpl->getRowCount(); + + sal_Int32 nX = rPos.X() + nTol - aRect.nLeft; + sal_Int32 nY = rPos.Y() + nTol - aRect.nTop; + + if( (nX < 0) || (nX > (aRect.GetWidth() + nTol)) || (nY < 0) || (nY > (aRect.GetHeight() + nTol) ) ) + return SDRTABLEHIT_NONE; + + // get vertical edge number and check for a hit + const bool bRTL = GetWritingMode() == WritingMode_RL_TB; + bool bVrtHit = false; + if( nX >= 0 ) + { + if( !bRTL ) + { + while( rnX <= nColCount ) + { + if( nX <= (2*nTol) ) + { + bVrtHit = true; + break; + } + + if( rnX == nColCount ) + break; + + nX -= mpImpl->mpLayouter->getColumnWidth( rnX ); + if( nX < 0 ) + break; + rnX++; + } + } + else + { + rnX = nColCount; + while( rnX >= 0 ) + { + if( nX <= (2*nTol) ) + { + bVrtHit = true; + break; + } + + if( rnX == 0 ) + break; + + rnX--; + nX -= mpImpl->mpLayouter->getColumnWidth( rnX ); + if( nX < 0 ) + break; + } + } + } + + // rnX is now the edge number left to the pointer, if it was hit bHrzHit is also true + + // get vertical edge number and check for a hit + bool bHrzHit = false; + if( nY >= 0 ) + { + while( rnY <= nRowCount ) + { + if( nY <= (2*nTol) ) + { + bHrzHit = true; + break; + } + + if( rnY == nRowCount ) + break; + + nY -= mpImpl->mpLayouter->getRowHeight(rnY); + if( nY < 0 ) + break; + rnY++; + } + } + + // rnY is now the edge number above the pointer, if it was hit bVrtHit is also true + + if( bVrtHit && mpImpl->mpLayouter->isEdgeVisible( rnX, rnY, false ) ) + return SDRTABLEHIT_VERTICAL_BORDER; + + if( bHrzHit && mpImpl->mpLayouter->isEdgeVisible( rnX, rnY, true ) ) + return SDRTABLEHIT_HORIZONTAL_BORDER; + + CellRef xCell( mpImpl->getCell( CellPos( rnX, rnY ) ) ); + if( xCell.is() && xCell->isMerged() ) + findMergeOrigin( mpImpl->mxTable.get(), rnX, rnY, rnX, rnY ); + + if( xCell.is() ) + { + nX += mpImpl->mpLayouter->getColumnWidth( rnX ); + if( nX < xCell->GetTextLeftDistance() ) + return SDRTABLEHIT_CELL; + } + + return SDRTABLEHIT_CELLTEXTAREA; +} + +const SfxItemSet& SdrTableObj::GetActiveCellItemSet() const +{ + return getActiveCell()->GetItemSet(); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::InsertRows( sal_Int32 nIndex, sal_Int32 nCount /*= 1*/ ) +{ + if( mpImpl->mxTable.is() ) try + { + Reference< XTableRows > xRows( mpImpl->mxTable->getRows(), UNO_QUERY_THROW ); + xRows->insertByIndex( nIndex, nCount ); + } + catch( Exception& ) + { + DBG_ERROR("SdrTableObj::InsertRows(), exception caught!"); + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::InsertColumns( sal_Int32 nIndex, sal_Int32 nCount /*= 1*/ ) +{ + if( mpImpl->mxTable.is() ) try + { + Reference< XTableColumns > xColumns( mpImpl->mxTable->getColumns(), UNO_QUERY_THROW ); + xColumns->insertByIndex( nIndex, nCount ); + } + catch( Exception& ) + { + DBG_ERROR("SdrTableObj::InsertColumns(), exception caught!"); + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::DeleteRows( sal_Int32 nIndex, sal_Int32 nCount /*= 1*/ ) +{ + if( mpImpl->mxTable.is() ) try + { + Reference< XTableRows > xRows( mpImpl->mxTable->getRows(), UNO_QUERY_THROW ); + xRows->removeByIndex( nIndex, nCount ); + } + catch( Exception& ) + { + DBG_ERROR("SdrTableObj::DeleteRows(), exception caught!"); + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::DeleteColumns( sal_Int32 nIndex, sal_Int32 nCount /*= 1*/ ) +{ + if( mpImpl->mxTable.is() ) try + { + Reference< XTableColumns > xColumns( mpImpl->mxTable->getColumns(), UNO_QUERY_THROW ); + xColumns->removeByIndex( nIndex, nCount ); + } + catch( Exception& ) + { + DBG_ERROR("SdrTableObj::DeleteColumns(), exception caught!"); + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::setTableStyle( const Reference< XIndexAccess >& xTableStyle ) +{ + if( mpImpl && (mpImpl->mxTableStyle != xTableStyle) ) + { + mpImpl->disconnectTableStyle(); + mpImpl->mxTableStyle = xTableStyle; + mpImpl->connectTableStyle(); + mpImpl->update(); + } +} + +// -------------------------------------------------------------------- + +const Reference< XIndexAccess >& SdrTableObj::getTableStyle() const +{ + if( mpImpl ) + { + return mpImpl->mxTableStyle; + } + else + { + static Reference< XIndexAccess > aTmp; + return aTmp; + } +} + +// -------------------------------------------------------------------- +// text stuff +// -------------------------------------------------------------------- + +/** returns the currently active text. */ +SdrText* SdrTableObj::getActiveText() const +{ + return dynamic_cast< SdrText* >( getActiveCell().get() ); +} + +// -------------------------------------------------------------------- + +/** returns the nth available text. */ +SdrText* SdrTableObj::getText( sal_Int32 nIndex ) const +{ + if( mpImpl->mxTable.is() ) + { + const sal_Int32 nColCount = mpImpl->getColumnCount(); + if( nColCount ) + { + CellPos aPos( nIndex % nColCount, nIndex / nColCount ); + + CellRef xCell( mpImpl->getCell( aPos ) ); + return dynamic_cast< SdrText* >( xCell.get() ); + } + } + return 0; +} + +// -------------------------------------------------------------------- + +/** returns the number of texts available for this object. */ +sal_Int32 SdrTableObj::getTextCount() const +{ + if( mpImpl->mxTable.is() ) + { + const sal_Int32 nColCount = mpImpl->getColumnCount(); + const sal_Int32 nRowCount = mpImpl->getRowCount(); + + return nColCount * nRowCount; + } + else + { + return 0; + } +} + +// -------------------------------------------------------------------- + +/** changes the current active text */ +void SdrTableObj::setActiveText( sal_Int32 nIndex ) +{ + if( mpImpl && mpImpl->mxTable.is() ) + { + const sal_Int32 nColCount = mpImpl->mxTable->getColumnCount(); + if( nColCount ) + { + CellPos aPos( nIndex % nColCount, nIndex / nColCount ); + if( isValid( aPos ) ) + setActiveCell( aPos ); + } + } +} + +// -------------------------------------------------------------------- + +/** returns the index of the text that contains the given point or -1 */ +sal_Int32 SdrTableObj::CheckTextHit(const Point& rPnt) const +{ + if( mpImpl && mpImpl->mxTable.is() ) + { + CellPos aPos; + if( CheckTableHit( rPnt, aPos.mnCol, aPos.mnRow, 0 ) == SDRTABLEHIT_CELLTEXTAREA ) + return aPos.mnRow * mpImpl->mxTable->getColumnCount() + aPos.mnCol; + } + + return 0; +} + +// -------------------------------------------------------------------- + +SdrOutliner* SdrTableObj::GetCellTextEditOutliner( const Cell& rCell ) const +{ + if( mpImpl && (mpImpl->getCell( mpImpl->maEditPos ).get() == &rCell) ) + return pEdtOutl; + else + return 0; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::FitFrameToTextSize() +{ + // todo +} + +// -------------------------------------------------------------------- + +FASTBOOL SdrTableObj::IsAutoGrowHeight() const +{ + return TRUE; +} + +// -------------------------------------------------------------------- + +FASTBOOL SdrTableObj::IsAutoGrowWidth() const +{ + return TRUE; +} + +// -------------------------------------------------------------------- + +bool SdrTableObj::HasText() const +{ + return true; +} + +// -------------------------------------------------------------------- + +bool SdrTableObj::IsTextEditActive( const CellPos& rPos ) +{ + return pEdtOutl && mpImpl && (rPos == mpImpl->maEditPos); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus ) +{ + if( (pEditStatus->GetStatusWord() & EE_STAT_TEXTHEIGHTCHANGED) && mpImpl && mpImpl->mpLayouter ) + { + Rectangle aRect0( aRect ); + aRect = maLogicRect; +// mpImpl->mpLayouter->setRowHeight( mpImpl->maEditPos.mnRow, mpImpl->mnSavedEditRowHeight ); + mpImpl->LayoutTable( aRect, false, false ); + SetRectsDirty(); + ActionChanged(); + BroadcastObjectChange(); + if( aRect0 != aRect ) + SendUserCall(SDRUSERCALL_RESIZE,aRect0); + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const +{ + rInfo.bResizeFreeAllowed=TRUE; + rInfo.bResizePropAllowed=TRUE; + rInfo.bRotateFreeAllowed=FALSE; + rInfo.bRotate90Allowed =FALSE; + rInfo.bMirrorFreeAllowed=FALSE; + rInfo.bMirror45Allowed =FALSE; + rInfo.bMirror90Allowed =FALSE; + + // allow transparence + rInfo.bTransparenceAllowed = TRUE; + + // gradient depends on fillstyle + XFillStyle eFillStyle = ((XFillStyleItem&)(GetObjectItem(XATTR_FILLSTYLE))).GetValue(); + rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT); + rInfo.bShearAllowed =FALSE; + rInfo.bEdgeRadiusAllowed=FALSE; + rInfo.bCanConvToPath =FALSE; + rInfo.bCanConvToPoly =FALSE; + rInfo.bCanConvToPathLineToArea=FALSE; + rInfo.bCanConvToPolyLineToArea=FALSE; + rInfo.bCanConvToContour = FALSE; +} + +// -------------------------------------------------------------------- + +UINT16 SdrTableObj::GetObjIdentifier() const +{ + return static_cast<UINT16>(OBJ_TABLE); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::SetPage(SdrPage* pNewPage) +{ + SdrTextObj::SetPage(pNewPage); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::SetModel(SdrModel* pNewModel) +{ + SdrModel* pOldModel = GetModel(); + if( pNewModel != pOldModel ) + { + SdrTextObj::SetModel(pNewModel); + + if( mpImpl ) + { + mpImpl->SetModel( pOldModel, pNewModel ); + + if( !maLogicRect.IsEmpty() ) + { + aRect = maLogicRect; + mpImpl->LayoutTable( aRect, false, false ); + } + } + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText, Rectangle* pAnchorRect, BOOL bLineWidth ) const +{ + if( mpImpl ) + TakeTextRect( mpImpl->maEditPos, rOutliner, rTextRect, bNoEditText, pAnchorRect, bLineWidth ); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::TakeTextRect( const CellPos& rPos, SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText, Rectangle* pAnchorRect, BOOL /*bLineWidth*/ ) const +{ + if( !mpImpl ) + return; + + CellRef xCell( mpImpl->getCell( rPos ) ); + if( !xCell.is() ) + return; + + Rectangle aAnkRect; + TakeTextAnchorRect( rPos, aAnkRect ); + + SdrTextVertAdjust eVAdj=xCell->GetTextVerticalAdjust(); +// SdrTextHorzAdjust eHAdj=xCell->GetTextHorizontalAdjust(); + + ULONG nStat0=rOutliner.GetControlWord(); + Size aNullSize; + nStat0 |= EE_CNTRL_AUTOPAGESIZE; + rOutliner.SetControlWord(nStat0); + rOutliner.SetMinAutoPaperSize(aNullSize); + rOutliner.SetMaxAutoPaperSize(aAnkRect.GetSize()); + rOutliner.SetPaperSize(aAnkRect.GetSize()); + + // #103516# New try with _BLOCK for hor and ver after completely + // supporting full width for vertical text. +// if( SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting()) +// { + rOutliner.SetMinAutoPaperSize(Size(aAnkRect.GetWidth(), 0)); +// } +// else if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting()) +// { +// rOutliner.SetMinAutoPaperSize(Size(0, aAnkRect.GetHeight())); +// } + + // --- + + // set text at outliner, maybe from edit outliner + OutlinerParaObject* pPara= xCell->GetOutlinerParaObject(); + if (pEdtOutl && !bNoEditText && mpImpl->mxActiveCell == xCell ) + pPara=pEdtOutl->CreateParaObject(); + + if (pPara) + { + const bool bHitTest = pModel && (&pModel->GetHitTestOutliner() == &rOutliner); + + const SdrTextObj* pTestObj = rOutliner.GetTextObj(); + if( !pTestObj || !bHitTest || (pTestObj != this) || (pTestObj->GetOutlinerParaObject() != xCell->GetOutlinerParaObject()) ) + { + if( bHitTest ) // #i33696# take back fix #i27510# + rOutliner.SetTextObj( this ); + + rOutliner.SetUpdateMode(TRUE); + rOutliner.SetText(*pPara); + } + } + else + { + rOutliner.SetTextObj( NULL ); + } + + if (pEdtOutl && !bNoEditText && pPara && mpImpl->mxActiveCell == xCell ) + delete pPara; + + rOutliner.SetUpdateMode(TRUE); + rOutliner.SetControlWord(nStat0); + + Point aTextPos(aAnkRect.TopLeft()); + Size aTextSiz(rOutliner.GetPaperSize()); +/* + if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT) + { + long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width(); + if (eHAdj==SDRTEXTHORZADJUST_CENTER) + aTextPos.X()+=nFreeWdt/2; + if (eHAdj==SDRTEXTHORZADJUST_RIGHT) + aTextPos.X()+=nFreeWdt; + } +*/ + if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM) + { + long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height(); + if (eVAdj==SDRTEXTVERTADJUST_CENTER) + aTextPos.Y()+=nFreeHgt/2; + if (eVAdj==SDRTEXTVERTADJUST_BOTTOM) + aTextPos.Y()+=nFreeHgt; + } + + if (pAnchorRect) + *pAnchorRect=aAnkRect; + + rTextRect=Rectangle(aTextPos,aTextSiz); +} + +// -------------------------------------------------------------------- + +const CellRef& SdrTableObj::getActiveCell() const +{ + if( mpImpl ) + { + if( !mpImpl->mxActiveCell.is() ) + { + CellPos aPos; + const_cast< SdrTableObj* >(this)->setActiveCell( aPos ); + } + return mpImpl->mxActiveCell; + } + else + { + static CellRef xCell; + return xCell; + } +} + +// -------------------------------------------------------------------- + +sal_Int32 SdrTableObj::getRowCount() const +{ + return mpImpl ? mpImpl->getRowCount() : 0; +} + +// -------------------------------------------------------------------- + +sal_Int32 SdrTableObj::getColumnCount() const +{ + return mpImpl ? mpImpl->getColumnCount() : 0; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::setActiveCell( const CellPos& rPos ) +{ + if( mpImpl && mpImpl->mxTable.is() ) try + { + mpImpl->mxActiveCell.set( dynamic_cast< Cell* >( mpImpl->mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ).get() ) ); + if( mpImpl->mxActiveCell.is() && mpImpl->mxActiveCell->isMerged() ) + { + CellPos aOrigin; + findMergeOrigin( mpImpl->mxTable.get(), rPos.mnCol, rPos.mnRow, aOrigin.mnCol, aOrigin.mnRow ); + mpImpl->mxActiveCell.set( dynamic_cast< Cell* >( mpImpl->mxTable->getCellByPosition( aOrigin.mnCol, aOrigin.mnRow ).get() ) ); + mpImpl->maEditPos = aOrigin; + } + else + { + mpImpl->maEditPos = rPos; + } + } + catch( Exception& ) + { + DBG_ERROR("SdrTableObj::setActiveCell(), exception caught!"); + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::getActiveCellPos( CellPos& rPos ) const +{ + rPos = mpImpl->maEditPos; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::getCellBounds( const CellPos& rPos, ::Rectangle& rCellRect ) +{ + if( mpImpl ) + { + CellRef xCell( mpImpl->getCell( rPos ) ); + if( xCell.is() ) + rCellRect = xCell->getCellRect(); + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const +{ + if( mpImpl ) + TakeTextAnchorRect( mpImpl->maEditPos, rAnchorRect ); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::TakeTextAnchorRect( const CellPos& rPos, Rectangle& rAnchorRect ) const +{ + Rectangle aAnkRect(aRect); + + if( mpImpl ) + { + CellRef xCell( mpImpl->getCell( rPos ) ); + if( xCell.is() ) + xCell->TakeTextAnchorRect( aAnkRect ); + } + + ImpJustifyRect(aAnkRect); + rAnchorRect=aAnkRect; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const +{ + if( mpImpl ) + TakeTextEditArea( mpImpl->maEditPos, pPaperMin, pPaperMax, pViewInit, pViewMin ); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::TakeTextEditArea( const CellPos& rPos, Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin ) const +{ + Size aPaperMin,aPaperMax; + Rectangle aViewInit; + TakeTextAnchorRect( rPos, aViewInit ); + + Size aAnkSiz(aViewInit.GetSize()); + aAnkSiz.Width()--; aAnkSiz.Height()--; // weil GetSize() ein draufaddiert + + Size aMaxSiz(aAnkSiz.Width(),1000000); + if (pModel!=NULL) + { + Size aTmpSiz(pModel->GetMaxObjSize()); + if (aTmpSiz.Height()!=0) + aMaxSiz.Height()=aTmpSiz.Height(); + } + + CellRef xCell( mpImpl->getCell( rPos ) ); + SdrTextVertAdjust eVAdj = xCell.is() ? xCell->GetTextVerticalAdjust() : SDRTEXTVERTADJUST_TOP; +// SdrTextHorzAdjust eHAdj = xCell.is() ? xCell->GetTextHorizontalAdjust() : SDRTEXTHORZADJUST_LEFT; + + aPaperMax=aMaxSiz; + +// if((SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting()) || (SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())) + aPaperMin.Width() = aAnkSiz.Width(); + + if (pViewMin!=NULL) + { + *pViewMin=aViewInit; +/* + long nXFree=aAnkSiz.Width()-aPaperMin.Width(); + + if (eHAdj==SDRTEXTHORZADJUST_LEFT) + { + pViewMin->Right()-=nXFree; + } + else if (eHAdj==SDRTEXTHORZADJUST_RIGHT) + { + pViewMin->Left()+=nXFree; + } + else + { + pViewMin->Left()+=nXFree/2; + pViewMin->Right()=pViewMin->Left()+aPaperMin.Width(); + } +*/ + long nYFree=aAnkSiz.Height()-aPaperMin.Height(); + + if (eVAdj==SDRTEXTVERTADJUST_TOP) + { + pViewMin->Bottom()-=nYFree; + } + else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM) + { + pViewMin->Top()+=nYFree; + } + else + { + pViewMin->Top()+=nYFree/2; + pViewMin->Bottom()=pViewMin->Top()+aPaperMin.Height(); + } + } + + + if(IsVerticalWriting()) + aPaperMin.Width() = 0; + else + aPaperMin.Height() = 0; + + if (pPaperMin!=NULL) *pPaperMin=aPaperMin; + if (pPaperMax!=NULL) *pPaperMax=aPaperMax; + if (pViewInit!=NULL) *pViewInit=aViewInit; +} + +// -------------------------------------------------------------------- + +USHORT SdrTableObj::GetOutlinerViewAnchorMode() const +{ + EVAnchorMode eRet=ANCHOR_TOP_LEFT; + CellRef xCell( getActiveCell() ); + if( xCell.is() ) + { + SdrTextVertAdjust eV=xCell->GetTextVerticalAdjust(); +// SdrTextHorzAdjust eH=xCell->GetTextHorizontalAdjust(); + +// if (eH==SDRTEXTHORZADJUST_LEFT) + { + if (eV==SDRTEXTVERTADJUST_TOP) + { + eRet=ANCHOR_TOP_LEFT; + } + else if (eV==SDRTEXTVERTADJUST_BOTTOM) + { + eRet=ANCHOR_BOTTOM_LEFT; + } + else + { + eRet=ANCHOR_VCENTER_LEFT; + } + } +/* + else if (eH==SDRTEXTHORZADJUST_RIGHT) + { + if (eV==SDRTEXTVERTADJUST_TOP) + { + eRet=ANCHOR_TOP_RIGHT; + } + else if (eV==SDRTEXTVERTADJUST_BOTTOM) + { + eRet=ANCHOR_BOTTOM_RIGHT; + } + else + { + eRet=ANCHOR_VCENTER_RIGHT; + } + } + else + { + if (eV==SDRTEXTVERTADJUST_TOP) + { + eRet=ANCHOR_TOP_HCENTER; + } + else if (eV==SDRTEXTVERTADJUST_BOTTOM) + { + eRet=ANCHOR_BOTTOM_HCENTER; + } + else + { + eRet=ANCHOR_VCENTER_HCENTER; + } + } +*/ + } + return (USHORT)eRet; +} + +// -------------------------------------------------------------------- + +OutlinerParaObject* SdrTableObj::GetEditOutlinerParaObject() const +{ + return SdrTextObj::GetEditOutlinerParaObject(); +} + +// -------------------------------------------------------------------- + +SdrOutliner* SdrTableObj::GetCellTextEditOutliner( const CellPos& rPos ) const +{ + if( pEdtOutl && mpImpl && (mpImpl->maEditPos == rPos) ) + return pEdtOutl; + else + return 0; +} + +// -------------------------------------------------------------------- + +struct ImplTableShadowPaintInfo +{ + Color maShadowColor; + sal_uInt32 mnXDistance; + sal_uInt32 mnYDistance; + sal_uInt16 mnShadowTransparence; + + ImplTableShadowPaintInfo( const SfxItemSet& rSet ) + { + const SdrShadowColorItem& rShadColItem = ((const SdrShadowColorItem&)(rSet.Get(SDRATTR_SHADOWCOLOR))); + maShadowColor = rShadColItem.GetColorValue(); + mnShadowTransparence = ((const SdrShadowTransparenceItem&)(rSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue(); + + mnXDistance = ((SdrShadowXDistItem&)(rSet.Get(SDRATTR_SHADOWXDIST))).GetValue(); + mnYDistance = ((SdrShadowYDistItem&)(rSet.Get(SDRATTR_SHADOWYDIST))).GetValue(); + } +}; + +// -------------------------------------------------------------------- + +sal_Bool SdrTableObj::DoPaintObject(XOutputDevice& rXOut, const SdrPaintInfoRec& rPaintInfo ) const +{ + if( !mpImpl->mxTable.is() ) + return sal_False; + + // draw cells + const sal_Int32 nRowCount = mpImpl->getRowCount(); + const sal_Int32 nColCount = mpImpl->getColumnCount(); + + CellPos aPos; + + const SfxItemSet& rSet = GetObjectItemSet(); + if( ((SdrShadowItem&)(rSet.Get(SDRATTR_SHADOW))).GetValue() ) + { + ImplTableShadowPaintInfo aShadowInfo( rSet ); + + // draw cell backgrounds and borders + for( aPos.mnRow = 0; aPos.mnRow < nRowCount; ++aPos.mnRow ) + for( aPos.mnCol = 0; aPos.mnCol < nColCount; ++aPos.mnCol ) + ImpDoPaintTableCell( aPos, rXOut, &aShadowInfo ); + + // TODO: ImplDoPaintBorders( rXOut, &aShadowInfo ); + } + + // draw cell backgrounds and borders + for( aPos.mnRow = 0; aPos.mnRow < nRowCount; ++aPos.mnRow ) + for( aPos.mnCol = 0; aPos.mnCol < nColCount; ++aPos.mnCol ) + ImpDoPaintTableCell( aPos, rXOut ); + + ImplDoPaintBorders( rXOut ); + + // draw cell text, if there is any + for( aPos.mnRow = 0; aPos.mnRow < nRowCount; ++aPos.mnRow ) + for( aPos.mnCol = 0; aPos.mnCol < nColCount; ++aPos.mnCol ) + ImpDoPaintCellText( aPos, rXOut, rPaintInfo ); + + return sal_True; +} + +void lcl_VertLineEnds( OutputDevice& rDev, const Point& rTop, const Point& rBottom, + const Color& rColor, long nXOffs, long nWidth, + const svx::frame::Style& rTopLine, const svx::frame::Style& rBottomLine ) +{ + rDev.SetLineColor(rColor); // PEN_NULL ??? + rDev.SetFillColor(rColor); + + // Position oben/unten muss unabhaengig von der Liniendicke sein, + // damit der Winkel stimmt (oder X-Position auch anpassen) + long nTopPos = rTop.Y(); + long nBotPos = rBottom.Y(); + + long nTopLeft = rTop.X() + nXOffs; + long nTopRight = nTopLeft + nWidth - 1; + + long nBotLeft = rBottom.X() + nXOffs; + long nBotRight = nBotLeft + nWidth - 1; + + // oben abschliessen + + if ( rTopLine.Prim() ) + { + long nLineW = rTopLine.GetWidth(); + if (nLineW >= 2) + { + Point aTriangle[3]; + aTriangle[0] = Point( nTopLeft, nTopPos ); // wie aPoints[0] + aTriangle[1] = Point( nTopRight, nTopPos ); // wie aPoints[1] + aTriangle[2] = Point( rTop.X(), nTopPos - (nLineW - 1) / 2 ); + Polygon aTriPoly( 3, aTriangle ); + rDev.DrawPolygon( aTriPoly ); + } + } + + // unten abschliessen + + if ( rBottomLine.Prim() ) + { + long nLineW = rBottomLine.GetWidth(); + if (nLineW >= 2) + { + Point aTriangle[3]; + aTriangle[0] = Point( nBotLeft, nBotPos ); // wie aPoints[3] + aTriangle[1] = Point( nBotRight, nBotPos ); // wie aPoints[2] + aTriangle[2] = Point( rBottom.X(), nBotPos - (nLineW - 1) / 2 + nLineW - 1 ); + Polygon aTriPoly( 3, aTriangle ); + rDev.DrawPolygon( aTriPoly ); + } + } +} + +void lcl_VertLine( OutputDevice& rDev, const Point& rTop, const Point& rBottom, + const svx::frame::Style& rLine, + const svx::frame::Style& rTopLine, const svx::frame::Style& rBottomLine, + const Color* pForceColor ) +{ + if( rLine.Prim() ) + { + svx::frame::DrawVerFrameBorderSlanted( rDev, rTop, rBottom, rLine, pForceColor ); + + svx::frame::Style aScaled( rLine ); + aScaled.ScaleSelf( 1.0 / cos( svx::frame::GetVerDiagAngle( rTop, rBottom ) ) ); + if( pForceColor ) + aScaled.SetColor( *pForceColor ); + + long nXOffs = (aScaled.GetWidth() - 1) / -2L; + + lcl_VertLineEnds( rDev, rTop, rBottom, aScaled.GetColor(), + nXOffs, aScaled.Prim(), rTopLine, rBottomLine ); + + if( aScaled.Secn() ) + lcl_VertLineEnds( rDev, rTop, rBottom, aScaled.GetColor(), + nXOffs + aScaled.Prim() + aScaled.Dist(), aScaled.Secn(), rTopLine, rBottomLine ); + } +} + +void SdrTableObj::ImplDoPaintBorders( XOutputDevice& rXOut, const ImplTableShadowPaintInfo* /*pShadowInfo*/ ) const +{ + if( !mpImpl || !mpImpl->mpLayouter ) + return; + + TableLayouter& rLayouter = *mpImpl->mpLayouter; + + OutputDevice* pDev = rXOut.GetOutDev(); + Color* pForceColor = 0; + + int nPPTX = 1; // nPixelPerTwipsX + int nPPTY = 1; // nPixelPerTwipsY + + const sal_Int32 nRowCount = mpImpl->getRowCount(); + const sal_Int32 nColCount = mpImpl->getColumnCount(); + + const bool bRTL = GetWritingMode() == WritingMode_RL_TB; + + Point aTopStart( aRect.TopLeft() ); + Point aTopEnd(aTopStart), aBottomLeft(aTopStart); + + sal_Int32 nCol = 0; + for( sal_Int32 nRow = 0; nRow <= nRowCount; ++nRow ) + { + const sal_Int32 nRowHeight = (nRow == nRowCount) ? 0 : rLayouter.getRowHeight(nRow); + + aBottomLeft.Y() = aTopStart.Y() + nRowHeight; + + RangeIterator<sal_Int32> aColIter( 0, nColCount+1, !bRTL ); + while( aColIter.next( nCol ) ) + { + const sal_Int32 nColWidth = bRTL ? + ((nCol == 0) ? 0 : rLayouter.getColumnWidth(nCol-1)) : + ((nCol == nColCount) ? 0 : rLayouter.getColumnWidth(nCol)); + + aTopEnd.X() = aTopStart.X() + nColWidth; + + svx::frame::Style aTopLine, aBottomLine, aLeftLine; + + const SvxBorderLine* pLeftLine = (nRow < nRowCount) ? rLayouter.getBorderLine( nCol, nRow, false ) : 0; + + if( bRTL ) + nCol--; + const SvxBorderLine* pTopLine = ((nCol >= 0) && (nCol < nColCount)) ? rLayouter.getBorderLine( nCol, nRow, true ) : 0; + const SvxBorderLine* pBottomLine = (((nCol >= 0) && (nCol < nColCount)) && (nRow < nRowCount)) ? rLayouter.getBorderLine( nCol, nRow+1, true ) : 0; + if( bRTL ) + nCol++; + + aTopLine.Set( pTopLine, nPPTY ); + if( pTopLine ) + svx::frame::DrawHorFrameBorder( *pDev, aTopStart, aTopEnd, aTopLine, pForceColor ); + + if( pLeftLine ) + { + aBottomLine.Set( pBottomLine, nPPTY ); + aLeftLine.Set( pLeftLine, nPPTX ); + lcl_VertLine( *pDev, aTopStart, aBottomLeft, aLeftLine, aTopLine, aBottomLine, pForceColor ); + } + + aTopStart.X() += nColWidth; + aBottomLeft.X() = aTopStart.X(); + } + + aTopStart.X() = aBottomLeft.X() = aRect.TopLeft().X(); + aTopStart.Y() = aTopEnd.Y() = aBottomLeft.Y(); + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::ImpDoPaintCellText( const CellPos& rPos, XOutputDevice& rXOut, const SdrPaintInfoRec& rInfoRec ) const +{ + const bool bPrinter=rXOut.GetOutDev()->GetOutDevType()==OUTDEV_PRINTER; + const bool bPrintPreView=rXOut.GetOutDev()->GetOutDevViewType()==OUTDEV_VIEWTYPE_PRINTPREVIEW; + + if (!bPrinter && pEdtOutl!=NULL && rInfoRec.pPV!=NULL && rInfoRec.pPV->GetView().GetTextEditObject()==(SdrObject*)this) + { + if( mpImpl->maEditPos == rPos ) + return; // cell is currently edited in this view + } + + CellRef xCell( mpImpl->getCell( rPos ) ); + if( xCell.is() && !xCell->isMerged() ) + { + OutlinerParaObject* pOutlinerParaObject = xCell->GetOutlinerParaObject(); + + if (pOutlinerParaObject!=NULL || (pEdtOutl!=NULL && HasEditText())) + { + SdrOutliner& rOutliner=ImpGetDrawOutliner(); + + Color aBackground; + if( GetDraftFillColor(xCell->GetItemSet(), aBackground ) ) + rOutliner.SetBackgroundColor( aBackground ); + + { + SvtAccessibilityOptions aOptions; + bool bForceAutoColor = aOptions.GetIsAutomaticFontColor(); + //#106611# don't use automatic colors in WYSIWYG Print Previews + if(bPrintPreView&& !aOptions.GetIsForPagePreviews()) + bForceAutoColor = false; + rOutliner.ForceAutoColor( bForceAutoColor ); + } + + rOutliner.SetPaintInfoRec( &rInfoRec ); + + Rectangle aTextRect; + Rectangle aAnchorRect; + Fraction aFitXKorreg(1,1); + TakeTextRect( rPos, rOutliner, aTextRect, FALSE, &aAnchorRect ); + Rectangle aPaintRect( aTextRect ); + + OutputDevice* pOutDev = rXOut.GetOutDev(); + + if(IsVerticalWriting()) + { + if(aAnchorRect.GetWidth() > aPaintRect.GetWidth()) + { + aPaintRect.nLeft = aPaintRect.nRight - aAnchorRect.GetWidth(); + } + + } + else + { + if(aAnchorRect.GetHeight() > aPaintRect.GetHeight()) + { + aPaintRect.nBottom = aPaintRect.nTop + aAnchorRect.GetHeight(); + } + } + + rOutliner.Draw(pOutDev, aPaintRect); + rOutliner.Clear(); + rOutliner.ClearPaintInfoRec(); + } + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::ImpDoPaintTableCell(const CellPos& rPos, XOutputDevice& rXOut, const ImplTableShadowPaintInfo* pShadowInfo ) const +{ + CellRef xCell( mpImpl->getCell( rPos ) ); + if( xCell.is() && !xCell->isMerged() ) + { + const SfxItemSet& rSet = xCell->GetItemSet(); + SfxItemSet aEmptySet(*rSet.GetPool()); + aEmptySet.Put(XLineStyleItem(XLINE_NONE)); + aEmptySet.Put(XFillStyleItem(XFILL_NONE)); + rXOut.SetLineAttr(aEmptySet); + + if( pShadowInfo ) + { + SfxItemSet aShadowSet( rSet ); + + XFillStyle eStyle = ((const XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue(); + + if(eStyle==XFILL_HATCH) + { + XHatch aHatch = ((XFillHatchItem&)(rSet.Get(XATTR_FILLHATCH))).GetHatchValue(); + aHatch.SetColor(pShadowInfo->maShadowColor); + aShadowSet.Put(XFillHatchItem(String(), aHatch)); + } + else + { + if(eStyle != XFILL_NONE && eStyle != XFILL_SOLID) + aShadowSet.Put(XFillStyleItem(XFILL_SOLID)); + + aShadowSet.Put(XFillColorItem(String(),pShadowInfo->maShadowColor)); + + if(pShadowInfo->mnShadowTransparence) + { + const XFillFloatTransparenceItem& rFillFloatTransparence = + (const XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE); + if(!rFillFloatTransparence.IsEnabled()) + aShadowSet.Put(XFillTransparenceItem(pShadowInfo->mnShadowTransparence)); + } + } + rXOut.SetFillAttr( aShadowSet ); + } + else + { + rXOut.SetFillAttr( rSet ); + } + + basegfx::B2IRectangle aArea; + if( mpImpl->mpLayouter->getCellArea( rPos, aArea ) ) + { + Rectangle aCellRect( aArea.getMinX(), aArea.getMinY(), aArea.getMaxX(), aArea.getMaxY() ); + const Point aPos( aRect.TopLeft() ); + aCellRect.Move( aPos.X(), aPos.Y() ); + if( pShadowInfo ) + aCellRect.Move( pShadowInfo->mnXDistance, pShadowInfo->mnYDistance ); + + rXOut.DrawRect(aCellRect); + } + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::RecalcBoundRect() +{ + if( mpImpl ) + mpImpl->LayoutTable( aRect, false, false ); + aOutRect=GetSnapRect(); + + ImpAddBorderLinesToBoundRect(); + ImpAddShadowToBoundRect(); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::ImpAddBorderLinesToBoundRect() +{ + TableLayouter& rLayouter = *mpImpl->mpLayouter; + const sal_Int32 nRowCount = mpImpl->getRowCount(); + const sal_Int32 nColCount = mpImpl->getColumnCount(); + + long nUpper = 0, nLower = 0, nLeft = 0, nRight = 0; + + // upper&lower border + for( sal_Int32 nCol = 0; nCol <= nColCount; ++nCol ) + { + SvxBorderLine* pLine = rLayouter.getBorderLine( nCol, 0, true ); + + if( pLine ) + { + const long nSize = pLine->GetOutWidth() + pLine->GetDistance() + pLine->GetInWidth(); + if( nSize > nUpper ) + nUpper = nSize; + } + + pLine = rLayouter.getBorderLine( nCol, nRowCount, true ); + if( pLine ) + { + const long nSize = pLine->GetOutWidth() + pLine->GetDistance() + pLine->GetInWidth(); + if( nSize > nLower ) + nLower = nSize; + } + } + + // left&right border + for( sal_Int32 nRow = 0; nRow <= nRowCount; ++nRow ) + { + SvxBorderLine* pLine = rLayouter.getBorderLine( 0, nRow, false ); + + if( pLine ) + { + const long nSize = pLine->GetOutWidth() + pLine->GetDistance() + pLine->GetInWidth(); + if( nSize > nLeft ) + nLeft = nSize; + } + + pLine = rLayouter.getBorderLine( nColCount, nRow, false ); + if( pLine ) + { + const long nSize = pLine->GetOutWidth() + pLine->GetDistance() + pLine->GetInWidth(); + if( nSize > nRight ) + nRight = nSize; + } + } + + aOutRect.Left () -= nLeft; + aOutRect.Top () -= nUpper; + aOutRect.Right () += nRight; + aOutRect.Bottom() += nLower; +} + +// -------------------------------------------------------------------- + +SdrObject* SdrTableObj::CheckHit(const Point& rPnt, USHORT /*nTol*/, const SetOfByte* pVisiLayer) const +{ + if(pVisiLayer && !pVisiLayer->IsSet(sal::static_int_cast< sal_uInt8 >(GetLayer()))) + { + return NULL; + } + + if( (rPnt.X() >= aOutRect.Left()) && (rPnt.X() <= aOutRect.Right()) && (rPnt.Y() >= aOutRect.Top()) && rPnt.Y() <= aOutRect.Bottom() ) + return const_cast<SdrObject*>(static_cast<const SdrObject*>(this)); + + return NULL; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::TakeObjNameSingul(XubString& rName) const +{ + rName = ImpGetResStr(STR_ObjNameSingulTable); + + String aName( GetName() ); + if(aName.Len()) + { + rName += sal_Unicode(' '); + rName += sal_Unicode('\''); + rName += aName; + rName += sal_Unicode('\''); + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::TakeObjNamePlural(XubString& rName) const +{ + rName = ImpGetResStr(STR_ObjNamePluralTable); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::operator=(const SdrObject& rObj) +{ + // call parent + SdrObject::operator=(rObj); + + const SdrTableObj* pTableObj = dynamic_cast< const SdrTableObj* >( &rObj ); + if (pTableObj!=NULL) + { + TableModelNotifyGuard aGuard( mpImpl ? mpImpl->mxTable.get() : 0 ); + + maLogicRect = pTableObj->maLogicRect; + aRect = pTableObj->aRect; + aGeo = pTableObj->aGeo; + eTextKind = pTableObj->eTextKind; + bTextFrame = pTableObj->bTextFrame; + aTextSize = pTableObj->aTextSize; + bTextSizeDirty = pTableObj->bTextSizeDirty; + bNoShear = pTableObj->bNoShear; + bNoRotate = pTableObj->bNoRotate; + bNoMirror = pTableObj->bNoMirror; + bDisableAutoWidthOnDragging = pTableObj->bDisableAutoWidthOnDragging; + + if( pTableObj->mpImpl ) + *mpImpl = *pTableObj->mpImpl; + } +} + +// -------------------------------------------------------------------- + +basegfx::B2DPolyPolygon SdrTableObj::TakeXorPoly(sal_Bool bDetail ) const +{ + return SdrTextObj::TakeXorPoly( bDetail ); +} + +// -------------------------------------------------------------------- + +basegfx::B2DPolyPolygon SdrTableObj::TakeContour() const +{ + return SdrTextObj::TakeContour(); +} + +// -------------------------------------------------------------------- + +const Rectangle& SdrTableObj::GetSnapRect() const +{ + return aRect; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::NbcSetSnapRect(const Rectangle& rRect) +{ + NbcSetLogicRect( rRect ); +} + +// -------------------------------------------------------------------- + +const Rectangle& SdrTableObj::GetLogicRect() const +{ + return maLogicRect; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::RecalcSnapRect() +{ +} + +// -------------------------------------------------------------------- + +sal_uInt32 SdrTableObj::GetSnapPointCount() const +{ + return SdrTextObj::GetSnapPointCount(); +} + +// -------------------------------------------------------------------- + + +Point SdrTableObj::GetSnapPoint(sal_uInt32 i) const +{ + return SdrTextObj::GetSnapPoint(i); +} + +// -------------------------------------------------------------------- + +sal_Bool SdrTableObj::BegTextEdit(SdrOutliner& rOutl) +{ + if( pEdtOutl != NULL ) + return sal_False; + + pEdtOutl=&rOutl; + +// ForceOutlinerParaObject(); + + mbInEditMode = TRUE; + + rOutl.Init( OUTLINERMODE_TEXTOBJECT ); + rOutl.SetRefDevice( pModel->GetRefDevice() ); + +// -- + FASTBOOL bUpdMerk=rOutl.GetUpdateMode(); + if (bUpdMerk) rOutl.SetUpdateMode(FALSE); + Size aPaperMin; + Size aPaperMax; + Rectangle aEditArea; + TakeTextEditArea(&aPaperMin,&aPaperMax,&aEditArea,NULL); + + rOutl.SetMinAutoPaperSize(aPaperMin); + rOutl.SetMaxAutoPaperSize(aPaperMax); + rOutl.SetPaperSize(aPaperMax); + + if (bUpdMerk) rOutl.SetUpdateMode(TRUE); +//--- + + ULONG nStat=rOutl.GetControlWord(); +// nStat &= ~EE_CNTRL_AUTOPAGESIZE; + nStat |= EE_CNTRL_AUTOPAGESIZE; + nStat &=~EE_CNTRL_STRETCHING; + rOutl.SetControlWord(nStat); + + OutlinerParaObject* pPara = GetOutlinerParaObject(); + if(pPara) + rOutl.SetText(*pPara); + + rOutl.UpdateFields(); + rOutl.ClearModifyFlag(); + +// mpImpl->mnSavedEditRowHeight = mpImpl->mpLayouter->getRowHeight( mpImpl->maEditPos.mnRow ); + + return sal_True; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::EndTextEdit(SdrOutliner& rOutl) +{ + if(rOutl.IsModified()) + { + if( GetModel() ) + GetModel()->AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*this) ); + + OutlinerParaObject* pNewText = 0; + Paragraph* p1stPara = rOutl.GetParagraph( 0 ); + UINT32 nParaAnz = rOutl.GetParagraphCount(); + + if(p1stPara) + { + if(nParaAnz == 1) + { + // if its only one paragraph, check if it is empty + XubString aStr(rOutl.GetText(p1stPara)); + + if(!aStr.Len()) + { + // gotcha! + nParaAnz = 0; + } + } + + // to remove the grey field background + rOutl.UpdateFields(); + + if(nParaAnz != 0) + { + // create new text object + pNewText = rOutl.CreateParaObject( 0, (sal_uInt16)nParaAnz ); + } + } + SetOutlinerParaObject(pNewText); + } + + pEdtOutl = 0; + rOutl.Clear(); + UINT32 nStat = rOutl.GetControlWord(); + nStat &= ~EE_CNTRL_AUTOPAGESIZE; + rOutl.SetControlWord(nStat); + + mbInEditMode = FALSE; +} + +// -------------------------------------------------------------------- + +OutlinerParaObject* SdrTableObj::GetOutlinerParaObject() const +{ + CellRef xCell( getActiveCell() ); + if( xCell.is() ) + return xCell->GetOutlinerParaObject(); + else + return 0; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::NbcSetOutlinerParaObject( OutlinerParaObject* pTextObject) +{ + CellRef xCell( getActiveCell() ); + if( xCell.is() ) + { + if( pModel ) + { + // Update HitTestOutliner + const SdrTextObj* pTestObj = pModel->GetHitTestOutliner().GetTextObj(); + if( pTestObj && pTestObj->GetOutlinerParaObject() == xCell->GetOutlinerParaObject() ) + pModel->GetHitTestOutliner().SetTextObj( NULL ); + } + + xCell->SetOutlinerParaObject( pTextObject ); + + SetTextSizeDirty(); + NbcAdjustTextFrameWidthAndHeight(); +// ImpSetTextStyleSheetListeners(); +// ImpCheckMasterCachable(); + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::NbcSetLogicRect(const Rectangle& rRect) +{ + maLogicRect=rRect; + ImpJustifyRect(maLogicRect); + const bool bWidth = maLogicRect.getWidth() != aRect.getWidth(); + const bool bHeight = maLogicRect.getHeight() != aRect.getHeight(); + aRect=maLogicRect; + NbcAdjustTextFrameWidthAndHeight( !bHeight, !bWidth ); + SetRectsDirty(); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::NbcMove(const Size& rSiz) +{ + MoveRect(maLogicRect,rSiz); + SdrTextObj::NbcMove( rSiz ); + if( mpImpl ) + mpImpl->UpdateCells( aRect ); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) +{ + Rectangle aOldRect( maLogicRect ); + ResizeRect(maLogicRect,rRef,xFact,yFact); + + aRect = maLogicRect; + NbcAdjustTextFrameWidthAndHeight( maLogicRect.GetHeight() == aOldRect.GetHeight(), maLogicRect.GetWidth() == aOldRect.GetWidth() ); + SetRectsDirty(); +} + +// -------------------------------------------------------------------- + +FASTBOOL SdrTableObj::AdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt) +{ + Rectangle aNeuRect(maLogicRect); + FASTBOOL bRet=AdjustTextFrameWidthAndHeight(aNeuRect,bHgt,bWdt); + if (bRet) + { + Rectangle aBoundRect0; + if (pUserCall!=NULL) + aBoundRect0=GetLastBoundRect(); + aRect=aNeuRect; + SetRectsDirty(); + SetChanged(); + BroadcastObjectChange(); + SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0); + } + return bRet; +} + +// -------------------------------------------------------------------- + +FASTBOOL SdrTableObj::AdjustTextFrameWidthAndHeight(Rectangle& rR, FASTBOOL bHeight, FASTBOOL bWidth) const +{ + if((pModel == NULL) || rR.IsEmpty() || !mpImpl || !mpImpl->mxTable.is() ) + return FALSE; + + Rectangle aRectangle( rR ); + mpImpl->LayoutTable( aRectangle, !bWidth, !bHeight ); + + if( aRectangle != rR ) + { + rR = aRectangle; + return TRUE; + } + else + { + return FALSE; + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::NbcReformatText() +{ + NbcAdjustTextFrameWidthAndHeight(); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::ReformatText() +{ + Rectangle aBoundRect0; + if (pUserCall!=NULL) + aBoundRect0=GetLastBoundRect(); + NbcReformatText(); + SetChanged(); + BroadcastObjectChange(); + SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0); +} + +// -------------------------------------------------------------------- + +sal_Bool SdrTableObj::IsVerticalWriting() const +{ + const SvxWritingModeItem* pModeItem = dynamic_cast< const SvxWritingModeItem* >( &GetObjectItem( SDRATTR_TEXTDIRECTION ) ); + return pModeItem && pModeItem->GetValue() == com::sun::star::text::WritingMode_TB_RL; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::SetVerticalWriting(sal_Bool bVertical ) +{ + if( bVertical != IsVerticalWriting() ) + { + SvxWritingModeItem aModeItem( com::sun::star::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION ); + SetObjectItem( aModeItem ); + } +} + +// -------------------------------------------------------------------- + +WritingMode SdrTableObj::GetWritingMode() const +{ + WritingMode eMode = WritingMode_LR_TB; + if( mpImpl && mpImpl->mpLayouter ) + eMode = mpImpl->mpLayouter->GetWritingMode(); + return eMode; +} + +// -------------------------------------------------------------------- + +// gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon +// with the base geometry and returns TRUE. Otherwise it returns FALSE. +sal_Bool SdrTableObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& rPolyPolygon ) const +{ + return SdrTextObj::TRGetBaseGeometry( rMatrix, rPolyPolygon ); +} + +// -------------------------------------------------------------------- + +// sets the base geometry of the object using infos contained in the homogen 3x3 matrix. +// If it's an SdrPathObj it will use the provided geometry information. The Polygon has +// to use (0,0) as upper left and will be scaled to the given size in the matrix. +void SdrTableObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon ) +{ + SdrTextObj::TRSetBaseGeometry( rMatrix, rPolyPolygon ); +} + +// -------------------------------------------------------------------- + +bool SdrTableObj::IsRealyEdited() const +{ + return pEdtOutl && pEdtOutl->IsModified(); +} + +// -------------------------------------------------------------------- + +FASTBOOL SdrTableObj::IsFontwork() const +{ + return FALSE; +} + +// -------------------------------------------------------------------- + +sal_uInt32 SdrTableObj::GetHdlCount() const +{ + sal_uInt32 nCount = SdrTextObj::GetHdlCount(); + const sal_Int32 nRowCount = mpImpl->getRowCount(); + const sal_Int32 nColCount = mpImpl->getColumnCount(); + + if( nRowCount && nColCount ) + nCount += nRowCount + nColCount + 2 + 1; + + return nCount; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::AddToHdlList(SdrHdlList& rHdlList) const +{ + const sal_Int32 nRowCount = mpImpl->getRowCount(); + const sal_Int32 nColCount = mpImpl->getColumnCount(); + + // first add row handles + std::vector< TableEdgeHdl* > aRowEdges( nRowCount + 1 ); + + for( sal_Int32 nRow = 0; nRow <= nRowCount; nRow++ ) + { + sal_Int32 nEdgeMin, nEdgeMax; + const sal_Int32 nEdge = mpImpl->mpLayouter->getHorizontalEdge( nRow, &nEdgeMin, &nEdgeMax ); + nEdgeMin -= nEdge; + nEdgeMax -= nEdge; + + Point aPoint( aRect.TopLeft() ); + aPoint.Y() += nEdge; + + TableEdgeHdl* pHdl= new TableEdgeHdl(aPoint,true,nEdgeMin,nEdgeMax,nColCount+1); + pHdl->SetPointNum( nRow ); + rHdlList.AddHdl( pHdl ); + aRowEdges[nRow] = pHdl; + } + + // second add column handles + std::vector< TableEdgeHdl* > aColEdges( nColCount + 1 ); + + for( sal_Int32 nCol = 0; nCol <= nColCount; nCol++ ) + { + sal_Int32 nEdgeMin, nEdgeMax; + const sal_Int32 nEdge = mpImpl->mpLayouter->getVerticalEdge( nCol, &nEdgeMin, &nEdgeMax ); + nEdgeMin -= nEdge; + nEdgeMax -= nEdge; + + Point aPoint( aRect.TopLeft() ); + aPoint.X() += nEdge; + + TableEdgeHdl* pHdl = new TableEdgeHdl(aPoint,false,nEdgeMin,nEdgeMax, nRowCount+1); + pHdl->SetPointNum( nCol ); + rHdlList.AddHdl( pHdl ); + aColEdges[nCol] = pHdl; + } + + // now add visible edges to row and column handles + if( mpImpl && mpImpl->mpLayouter ) + { + TableLayouter& rLayouter = *mpImpl->mpLayouter; + + sal_Int32 nY = 0; + + for( sal_Int32 nRow = 0; nRow <= nRowCount; ++nRow ) + { + const sal_Int32 nRowHeight = (nRow == nRowCount) ? 0 : rLayouter.getRowHeight(nRow); + sal_Int32 nX = 0; + + for( sal_Int32 nCol = 0; nCol <= nColCount; ++nCol ) + { + const sal_Int32 nColWidth = (nCol == nColCount) ? 0 : rLayouter.getColumnWidth(nCol); + + if( nRowHeight > 0 ) + { + if( rLayouter.isEdgeVisible( nCol, nRow, false ) ) + aColEdges[nCol]->SetEdge( nRow, nY, nY + nRowHeight, (rLayouter.getBorderLine( nCol, nRow, false ) == 0) ? Visible : Invisible); + } + + if( nColWidth > 0 ) + { + if( rLayouter.isEdgeVisible( nCol, nRow, true ) ) + aRowEdges[nRow]->SetEdge( nCol, nX, nX + nColWidth, (rLayouter.getBorderLine( nCol, nRow, true ) == 0) ? Visible : Invisible); + } + + nX += nColWidth; + } + + nY += nRowHeight; + } + } + + // add remaining handles + SdrHdl* pH=0; + rHdlList.AddHdl( pH = new TableBorderHdl( aRect ) ); pH->SetMoveOutside( true ); + rHdlList.AddHdl( pH = new SdrHdl(aRect.TopLeft(),HDL_UPLFT) ); pH->SetMoveOutside( true ); + rHdlList.AddHdl( pH = new SdrHdl(aRect.TopCenter(),HDL_UPPER) ); pH->SetMoveOutside( true ); + rHdlList.AddHdl( pH = new SdrHdl(aRect.TopRight(),HDL_UPRGT) ); pH->SetMoveOutside( true ); + rHdlList.AddHdl( pH = new SdrHdl(aRect.LeftCenter(),HDL_LEFT) ); pH->SetMoveOutside( true ); + rHdlList.AddHdl( pH = new SdrHdl(aRect.RightCenter(),HDL_RIGHT) ); pH->SetMoveOutside( true ); + rHdlList.AddHdl( pH = new SdrHdl(aRect.BottomLeft(),HDL_LWLFT) ); pH->SetMoveOutside( true ); + rHdlList.AddHdl( pH = new SdrHdl(aRect.BottomCenter(),HDL_LOWER) ); pH->SetMoveOutside( true ); + rHdlList.AddHdl( pH = new SdrHdl(aRect.BottomRight(),HDL_LWRGT) ); pH->SetMoveOutside( true ); + + ULONG nHdlCount = rHdlList.GetHdlCount(); + for( ULONG nHdl = 0; nHdl < nHdlCount; nHdl++ ) + rHdlList.GetHdl(nHdl)->SetObj((SdrObject*)this); +} + +// -------------------------------------------------------------------- + +SdrHdl* SdrTableObj::GetHdl(sal_uInt32 nHdlNum) const +{ + // #i73248# + // Warn the user that this is ineffective and show alternatives. Should not be used at all. + OSL_ENSURE(false, "SdrTableObj::GetHdl(): ineffective, use AddToHdlList instead (!)"); + + // to have an alternative, get single handle using the ineffective way + SdrHdl* pRetval = 0; + SdrHdlList aLocalList(0); + AddToHdlList(aLocalList); + const sal_uInt32 nHdlCount(aLocalList.GetHdlCount()); + + if(nHdlCount && nHdlNum < nHdlCount) + { + // remove and remember. The other created handles will be deleted again with the + // destruction of the local list + pRetval = aLocalList.RemoveHdl(nHdlNum); + } + + return pRetval; +} + +// -------------------------------------------------------------------- +// Draging +// -------------------------------------------------------------------- + +FASTBOOL SdrTableObj::HasSpecialDrag() const +{ + return TRUE; +} + +// -------------------------------------------------------------------- + +struct ImpSdrTableObjDragUser : public SdrDragStatUserData +{ + Rectangle maRectangle; +}; + +// -------------------------------------------------------------------- + +FASTBOOL SdrTableObj::BegDrag(SdrDragStat& rDrag) const +{ + FASTBOOL bRet = TRUE; + + const SdrHdl* pHdl = rDrag.GetHdl(); + SdrHdlKind eHdl = pHdl == NULL ? HDL_MOVE : pHdl->GetKind(); + switch( eHdl ) + { + case HDL_UPLFT: + case HDL_UPPER: + case HDL_UPRGT: + case HDL_LEFT: + case HDL_RIGHT: + case HDL_LWLFT: + case HDL_LOWER: + case HDL_LWRGT: + case HDL_MOVE: + break; + + case HDL_USER: + rDrag.SetEndDragChangesAttributes( sal_False ); + rDrag.SetNoSnap( TRUE ); + break; + + default: + bRet = FALSE; + } + + if( bRet ) + { + ImpSdrTableObjDragUser* pUser = static_cast<ImpSdrTableObjDragUser*>(rDrag.GetUser()); + + if(!pUser) + pUser = new ImpSdrTableObjDragUser; + + pUser->maRectangle = aRect; + rDrag.SetUser(pUser); + } + + return bRet; +} + +// -------------------------------------------------------------------- + +FASTBOOL SdrTableObj::MovDrag(SdrDragStat& rDrag) const +{ + FASTBOOL bRet = TRUE; + + const SdrHdl* pHdl = rDrag.GetHdl(); + SdrHdlKind eHdl = pHdl == NULL ? HDL_MOVE : pHdl->GetKind(); + ImpSdrTableObjDragUser* pUser = static_cast<ImpSdrTableObjDragUser*>(rDrag.GetUser()); + + if( pUser ) switch( eHdl ) + { + case HDL_UPLFT: + case HDL_UPPER: + case HDL_UPRGT: + case HDL_LEFT: + case HDL_RIGHT: + case HDL_LWLFT: + case HDL_LOWER: + case HDL_LWRGT: + { + pUser->maRectangle = ImpDragCalcRect( rDrag ); + break; + } + case HDL_MOVE: + { + pUser->maRectangle = aRect; + pUser->maRectangle.Move( rDrag.GetDX(), rDrag.GetDY() ); + break; + } + + case HDL_USER: + { + rDrag.SetEndDragChangesAttributes( sal_False ); + rDrag.SetNoSnap( TRUE ); + break; + } + + default: + bRet = FALSE; + } + + return bRet; +} + +// -------------------------------------------------------------------- + +FASTBOOL SdrTableObj::EndDrag(SdrDragStat& rDrag) +{ + FASTBOOL bRet = TRUE; + + const SdrHdl* pHdl = rDrag.GetHdl(); + SdrHdlKind eHdl = pHdl == NULL ? HDL_MOVE : pHdl->GetKind(); + ImpSdrTableObjDragUser* pUser = static_cast<ImpSdrTableObjDragUser*>(rDrag.GetUser()); + + if( pUser ) + { + + switch( eHdl ) + { + case HDL_UPLFT: + case HDL_UPPER: + case HDL_UPRGT: + case HDL_LEFT: + case HDL_RIGHT: + case HDL_LWLFT: + case HDL_LOWER: + case HDL_LWRGT: + if(pUser->maRectangle != aRect) + SetLogicRect(pUser->maRectangle); + break; + + case HDL_MOVE: + Move( Size( rDrag.GetDX(), rDrag.GetDY() ) ); + break; + + case HDL_USER: + { + const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl ); + if( pEdgeHdl ) + { + if( GetModel() && IsInserted() ) + GetModel()->AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*this) ); + + mpImpl->DragEdge( pEdgeHdl->IsHorizontalEdge(), pEdgeHdl->GetPointNum(), pEdgeHdl->GetValidDragOffset( rDrag ) ); + } + break; + } + + default: + bRet = FALSE; + } + + rDrag.SetUser(NULL); + delete pUser; + } + + return bRet; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::BrkDrag(SdrDragStat& rDrag ) const +{ + ImpSdrTableObjDragUser* pUser = static_cast<ImpSdrTableObjDragUser*>(rDrag.GetUser()); + if( pUser ) + { + delete pUser; + rDrag.SetUser(NULL); + } +} + +// -------------------------------------------------------------------- + +XubString SdrTableObj::GetDragComment(const SdrDragStat& rDrag, FASTBOOL bUndoDragComment, FASTBOOL bCreateComment) const +{ + return SdrTextObj::GetDragComment( rDrag, bUndoDragComment, bCreateComment ); +} + +// -------------------------------------------------------------------- + +basegfx::B2DPolyPolygon SdrTableObj::TakeDragPoly(const SdrDragStat& rDrag) const +{ + basegfx::B2DPolyPolygon aRetVal; + + const SdrHdl* pHdl = rDrag.GetHdl(); + SdrHdlKind eHdl = pHdl == NULL ? HDL_MOVE : pHdl->GetKind(); + ImpSdrTableObjDragUser* pUser = static_cast<ImpSdrTableObjDragUser*>(rDrag.GetUser()); + + if( pUser ) switch( eHdl ) + { + case HDL_UPLFT: + case HDL_UPPER: + case HDL_UPRGT: + case HDL_LEFT: + case HDL_RIGHT: + case HDL_LWLFT: + case HDL_LOWER: + case HDL_LWRGT: + case HDL_MOVE: + { + aRetVal.append( + basegfx::tools::createPolygonFromRect( + vcl::unotools::b2DRectangleFromRectangle( pUser->maRectangle ) ) ); + break; + } + + case HDL_USER : + { + const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl ); + if( pEdgeHdl ) + aRetVal = pEdgeHdl->TakeDragPoly( &rDrag ); + break; + } + + default: break; + } + return aRetVal; +} + +// -------------------------------------------------------------------- +// Create +// -------------------------------------------------------------------- + +FASTBOOL SdrTableObj::BegCreate(SdrDragStat& rStat) +{ + rStat.SetOrtho4Possible(); + Rectangle aRect1(rStat.GetStart(), rStat.GetNow()); + aRect1.Justify(); + rStat.SetActionRect(aRect1); + aRect = aRect1; + return TRUE; +} + +// -------------------------------------------------------------------- + +FASTBOOL SdrTableObj::MovCreate(SdrDragStat& rStat) +{ + Rectangle aRect1; + rStat.TakeCreateRect(aRect1); + ImpJustifyRect(aRect1); + rStat.SetActionRect(aRect1); + aRect=aRect1; // fuer ObjName + bBoundRectDirty=TRUE; + bSnapRectDirty=TRUE; + return TRUE; +} + +// -------------------------------------------------------------------- + +FASTBOOL SdrTableObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd) +{ + rStat.TakeCreateRect(aRect); + ImpJustifyRect(aRect); + return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2); +} + +void SdrTableObj::BrkCreate(SdrDragStat& /*rStat*/) +{ +} + +// -------------------------------------------------------------------- + +FASTBOOL SdrTableObj::BckCreate(SdrDragStat& /*rStat*/) +{ + return TRUE; +} + +// -------------------------------------------------------------------- + +basegfx::B2DPolyPolygon SdrTableObj::TakeCreatePoly(const SdrDragStat& rDrag) const +{ + Rectangle aRect1; + rDrag.TakeCreateRect(aRect1); + aRect1.Justify(); + + basegfx::B2DPolyPolygon aRetval; + const basegfx::B2DRange aRange(aRect1.Left(), aRect1.Top(), aRect1.Right(), aRect1.Bottom()); + aRetval.append(basegfx::tools::createPolygonFromRect(aRange)); + return aRetval; +} + +// -------------------------------------------------------------------- + +Pointer SdrTableObj::GetCreatePointer() const +{ + return Pointer(POINTER_CROSS); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::createCell( CellRef& xNewCell ) +{ + xNewCell.set( new Cell( *this, 0 ) ); +} + +// -------------------------------------------------------------------- + +SdrObjGeoData *SdrTableObj::NewGeoData() const +{ + return new TableObjectGeoData; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::SaveGeoData(SdrObjGeoData& rGeo) const +{ + DBG_ASSERT( dynamic_cast< TableObjectGeoData* >( &rGeo ), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" ); + SdrTextObj::SaveGeoData (rGeo); + + ((TableObjectGeoData &) rGeo).maLogicRect = maLogicRect; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::RestGeoData(const SdrObjGeoData& rGeo) +{ + DBG_ASSERT( dynamic_cast< const TableObjectGeoData* >( &rGeo ), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" ); + + maLogicRect = ((TableObjectGeoData &) rGeo).maLogicRect; + + SdrTextObj::RestGeoData (rGeo); + + if( mpImpl ) + mpImpl->LayoutTable( aRect, false, false ); + ActionChanged(); +} + +// -------------------------------------------------------------------- + +SdrTableObj* SdrTableObj::CloneRange( const CellPos& rStart, const CellPos& rEnd ) +{ + const sal_Int32 nColumns = rEnd.mnCol - rStart.mnCol + 1; + const sal_Int32 nRows = rEnd.mnRow - rStart.mnRow + 1; + + SdrTableObj* pNewTableObj = new SdrTableObj( GetModel(), GetCurrentBoundRect(), nColumns, nRows); + pNewTableObj->setTableStyleSettings( getTableStyleSettings() ); + pNewTableObj->setTableStyle( getTableStyle() ); + + Reference< XTable > xTable( getTable() ); + Reference< XTable > xNewTable( pNewTableObj->getTable() ); + + if( !xTable.is() || !xNewTable.is() ) + { + delete pNewTableObj; + return 0; + } + + // copy cells + for( sal_Int32 nRow = 0; nRow < nRows; ++nRow ) + { + for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol ) try + { + CellRef xTargetCell( dynamic_cast< Cell* >( xNewTable->getCellByPosition( nCol, nRow ).get() ) ); + if( xTargetCell.is() ) + xTargetCell->cloneFrom( dynamic_cast< Cell* >( xTable->getCellByPosition( rStart.mnCol + nCol, rStart.mnRow + nRow ).get() ) ); + } + catch( Exception& ) + { + DBG_ERROR( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" ); + } + } + + // copy row heights + Reference< XTableRows > xNewRows( xNewTable->getRows(), UNO_QUERY_THROW ); + const OUString sHeight( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ); + for( sal_Int32 nRow = 0; nRow < nRows; ++nRow ) + { + Reference< XPropertySet > xNewSet( xNewRows->getByIndex( nRow ), UNO_QUERY_THROW ); + xNewSet->setPropertyValue( sHeight, Any( mpImpl->mpLayouter->getRowHeight( rStart.mnRow + nRow ) ) ); + } + + // copy column widths + Reference< XTableColumns > xNewColumns( xNewTable->getColumns(), UNO_QUERY_THROW ); + const OUString sWidth( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ); + for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol ) + { + Reference< XPropertySet > xNewSet( xNewColumns->getByIndex( nCol ), UNO_QUERY_THROW ); + xNewSet->setPropertyValue( sWidth, Any( mpImpl->mpLayouter->getColumnWidth( rStart.mnCol + nCol ) ) ); + } + + pNewTableObj->NbcReformatText(); + pNewTableObj->SetLogicRect( pNewTableObj->GetCurrentBoundRect() ); + + return pNewTableObj; +} + +// -------------------------------------------------------------------- + +void SdrTableObj::DistributeColumns( sal_Int32 nFirstColumn, sal_Int32 nLastColumn ) +{ + if( mpImpl && mpImpl->mpLayouter ) + { + TableModelNotifyGuard aGuard( mpImpl->mxTable.get() ); + mpImpl->mpLayouter->DistributeColumns( aRect, nFirstColumn, nLastColumn ); + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::DistributeRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) +{ + if( mpImpl && mpImpl->mpLayouter ) + { + TableModelNotifyGuard aGuard( mpImpl->mxTable.get() ); + mpImpl->mpLayouter->DistributeRows( aRect, nFirstRow, nLastRow ); + } +} + +// -------------------------------------------------------------------- + +void SdrTableObj::SetChanged() +{ + if( mpImpl ) + { + if( mpImpl->UpdateWritingMode() ) + mpImpl->LayoutTable( aRect, false, false ); + } + + ::SdrTextObj::SetChanged(); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::uno_lock() +{ + if( mpImpl && mpImpl->mxTable.is() ) + mpImpl->mxTable->lockBroadcasts(); +} + +// -------------------------------------------------------------------- + +void SdrTableObj::uno_unlock() +{ + if( mpImpl && mpImpl->mxTable.is() ) + mpImpl->mxTable->unlockBroadcasts(); +} + +// -------------------------------------------------------------------- + + + +} } |