summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--svx/source/table/svdotable.cxx3224
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 0000000000..0efd8fd933
--- /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();
+}
+
+// --------------------------------------------------------------------
+
+
+
+} }