summaryrefslogtreecommitdiff
path: root/svx/source/table
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/table')
-rw-r--r--svx/source/table/accessiblecell.cxx584
-rw-r--r--svx/source/table/accessiblecell.hxx149
-rw-r--r--svx/source/table/accessibletableshape.cxx723
-rw-r--r--svx/source/table/cell.cxx1809
-rw-r--r--svx/source/table/cell.hxx244
-rw-r--r--svx/source/table/cellcursor.cxx590
-rw-r--r--svx/source/table/cellcursor.hxx83
-rw-r--r--svx/source/table/celleditsource.cxx1056
-rw-r--r--svx/source/table/celleditsource.hxx89
-rw-r--r--svx/source/table/cellrange.cxx132
-rw-r--r--svx/source/table/cellrange.hxx72
-rw-r--r--svx/source/table/celltypes.hxx109
-rw-r--r--svx/source/table/makefile.mk80
-rw-r--r--svx/source/table/propertyset.cxx259
-rw-r--r--svx/source/table/propertyset.hxx109
-rw-r--r--svx/source/table/svdotable.cxx2820
-rw-r--r--svx/source/table/table.src34
-rw-r--r--svx/source/table/tablecolumn.cxx305
-rw-r--r--svx/source/table/tablecolumn.hxx88
-rw-r--r--svx/source/table/tablecolumns.cxx141
-rw-r--r--svx/source/table/tablecolumns.hxx71
-rw-r--r--svx/source/table/tablecontroller.cxx2618
-rw-r--r--svx/source/table/tablecontroller.hxx170
-rw-r--r--svx/source/table/tabledesign.cxx808
-rw-r--r--svx/source/table/tablehandles.cxx314
-rw-r--r--svx/source/table/tablehandles.hxx96
-rw-r--r--svx/source/table/tablelayouter.cxx1300
-rw-r--r--svx/source/table/tablelayouter.hxx178
-rw-r--r--svx/source/table/tablemodel.cxx1258
-rw-r--r--svx/source/table/tablemodel.hxx225
-rw-r--r--svx/source/table/tablerow.cxx381
-rw-r--r--svx/source/table/tablerow.hxx92
-rw-r--r--svx/source/table/tablerows.cxx136
-rw-r--r--svx/source/table/tablerows.hxx71
-rw-r--r--svx/source/table/tablertfexporter.cxx284
-rw-r--r--svx/source/table/tablertfimporter.cxx447
-rw-r--r--svx/source/table/tableundo.cxx559
-rw-r--r--svx/source/table/tableundo.hxx259
-rw-r--r--svx/source/table/viewcontactoftableobj.cxx736
-rw-r--r--svx/source/table/viewcontactoftableobj.hxx72
40 files changed, 19551 insertions, 0 deletions
diff --git a/svx/source/table/accessiblecell.cxx b/svx/source/table/accessiblecell.cxx
new file mode 100644
index 000000000000..71b94d021650
--- /dev/null
+++ b/svx/source/table/accessiblecell.cxx
@@ -0,0 +1,584 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <accessiblecell.hxx>
+
+#include "DescriptionGenerator.hxx"
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+#include <vcl/svapp.hxx>
+
+#include <unotools/accessiblestatesethelper.hxx>
+
+#include <editeng/outlobj.hxx>
+#include <svx/unoshtxt.hxx>
+#include <svx/svdotext.hxx>
+
+using ::rtl::OUString;
+using namespace ::sdr::table;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+
+namespace accessibility {
+
+// --------------------------------------------------------------------
+// AccessibleCell
+// --------------------------------------------------------------------
+
+AccessibleCell::AccessibleCell( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible>& rxParent, const sdr::table::CellRef& rCell, sal_Int32 nIndex, const AccessibleShapeTreeInfo& rShapeTreeInfo )
+: AccessibleCellBase( rxParent, AccessibleRole::TABLE_CELL )
+, maShapeTreeInfo( rShapeTreeInfo )
+, mnIndexInParent( nIndex )
+, mpText( NULL )
+, mxCell( rCell )
+{
+}
+
+// --------------------------------------------------------------------
+
+AccessibleCell::~AccessibleCell (void)
+{
+ DBG_ASSERT( mpText == 0, "svx::AccessibleCell::~AccessibleCell(), not disposed!?" );
+}
+
+// --------------------------------------------------------------------
+
+void AccessibleCell::Init (void)
+{
+ SdrView* pView = maShapeTreeInfo.GetSdrView();
+ const Window* pWindow = maShapeTreeInfo.GetWindow ();
+ if( (pView != NULL) && (pWindow != NULL) && mxCell.is())
+ {
+ OutlinerParaObject* pOutlinerParaObject = mxCell->GetEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active
+
+ bool bOwnParaObject = pOutlinerParaObject != 0;
+
+ if( !pOutlinerParaObject )
+ pOutlinerParaObject = mxCell->GetOutlinerParaObject();
+
+ // create AccessibleTextHelper to handle this shape's text
+ if( pOutlinerParaObject )
+ {
+ // non-empty text -> use full-fledged edit source right away
+ ::std::auto_ptr<SvxEditSource> pEditSource( new SvxTextEditSource( mxCell->GetObject(), mxCell.get(), *pView, *pWindow) );
+ mpText = new AccessibleTextHelper( pEditSource );
+ mpText->SetEventSource(this);
+ }
+
+ if( bOwnParaObject)
+ delete pOutlinerParaObject;
+ }
+}
+
+// --------------------------------------------------------------------
+
+sal_Bool AccessibleCell::SetState (sal_Int16 aState)
+{
+ sal_Bool bStateHasChanged = sal_False;
+
+ if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
+ {
+ // Offer FOCUSED state to edit engine and detect whether the state
+ // changes.
+ sal_Bool bIsFocused = mpText->HaveFocus ();
+ mpText->SetFocus (sal_True);
+ bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
+ }
+ else
+ bStateHasChanged = AccessibleContextBase::SetState (aState);
+
+ return bStateHasChanged;
+}
+
+// --------------------------------------------------------------------
+
+sal_Bool AccessibleCell::ResetState (sal_Int16 aState)
+{
+ sal_Bool bStateHasChanged = sal_False;
+
+ if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
+ {
+ // Try to remove FOCUSED state from the edit engine and detect
+ // whether the state changes.
+ sal_Bool bIsFocused = mpText->HaveFocus ();
+ mpText->SetFocus (sal_False);
+ bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
+ }
+ else
+ bStateHasChanged = AccessibleContextBase::ResetState (aState);
+
+ return bStateHasChanged;
+}
+
+// --------------------------------------------------------------------
+
+sal_Bool AccessibleCell::GetState (sal_Int16 aState)
+{
+ if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
+ {
+ // Just delegate the call to the edit engine. The state is not
+ // merged into the state set.
+ return mpText->HaveFocus();
+ }
+ else
+ return AccessibleContextBase::GetState (aState);
+}
+
+//-----------------------------------------------------------------------------
+
+bool AccessibleCell::operator== (const AccessibleCell& rAccessibleCell)
+{
+ return this == &rAccessibleCell;
+}
+
+//-----------------------------------------------------------------------------
+// XInterface
+//-----------------------------------------------------------------------------
+
+Any SAL_CALL AccessibleCell::queryInterface( const Type& aType ) throw (RuntimeException)
+{
+ return AccessibleCellBase::queryInterface( aType );
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL AccessibleCell::acquire( ) throw ()
+{
+ AccessibleCellBase::acquire();
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL AccessibleCell::release( ) throw ()
+{
+ AccessibleCellBase::release();
+}
+
+// --------------------------------------------------------------------
+// XAccessibleContext
+// --------------------------------------------------------------------
+
+/** The children of this cell come from the paragraphs of text.
+*/
+sal_Int32 SAL_CALL AccessibleCell::getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ ThrowIfDisposed ();
+ return mpText != NULL ? mpText->GetChildCount () : 0;
+}
+
+// --------------------------------------------------------------------
+
+/** Forward the request to the shape. Return the requested shape or throw
+ an exception for a wrong index.
+*/
+Reference<XAccessible> SAL_CALL AccessibleCell::getAccessibleChild (sal_Int32 nIndex) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ ThrowIfDisposed ();
+
+ // todo: does GetChild throw IndexOutOfBoundsException?
+ return mpText->GetChild (nIndex);
+}
+
+// --------------------------------------------------------------------
+
+/** Return a copy of the state set.
+ Possible states are:
+ ENABLED
+ SHOWING
+ VISIBLE
+*/
+Reference<XAccessibleStateSet> SAL_CALL AccessibleCell::getAccessibleStateSet (void) throw (RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ ::osl::MutexGuard aGuard (maMutex);
+ Reference<XAccessibleStateSet> xStateSet;
+
+ if (rBHelper.bDisposed || mpText == NULL)
+ {
+ // Return a minimal state set that only contains the DEFUNC state.
+ xStateSet = AccessibleContextBase::getAccessibleStateSet ();
+ }
+ else
+ {
+ ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
+
+ if(pStateSet)
+ {
+ // Merge current FOCUSED state from edit engine.
+ if (mpText != NULL)
+ {
+ if (mpText->HaveFocus())
+ pStateSet->AddState (AccessibleStateType::FOCUSED);
+ else
+ pStateSet->RemoveState (AccessibleStateType::FOCUSED);
+ }
+
+ // Create a copy of the state set that may be modified by the
+ // caller without affecting the current state set.
+ xStateSet = Reference<XAccessibleStateSet>(new ::utl::AccessibleStateSetHelper (*pStateSet));
+ }
+ }
+
+ return xStateSet;
+}
+
+// --------------------------------------------------------------------
+// XAccessibleComponent
+// --------------------------------------------------------------------
+
+sal_Bool SAL_CALL AccessibleCell::containsPoint( const ::com::sun::star::awt::Point& aPoint) throw (::com::sun::star::uno::RuntimeException)
+{
+ return AccessibleComponentBase::containsPoint( aPoint );
+}
+
+/** The implementation below is at the moment straightforward. It iterates
+ over all children (and thereby instances all children which have not
+ been already instatiated) until a child covering the specifed point is
+ found.
+ This leaves room for improvement. For instance, first iterate only over
+ the already instantiated children and only if no match is found
+ instantiate the remaining ones.
+*/
+Reference<XAccessible > SAL_CALL AccessibleCell::getAccessibleAtPoint ( const ::com::sun::star::awt::Point& aPoint) throw(RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ ::osl::MutexGuard aGuard (maMutex);
+
+ sal_Int32 nChildCount = getAccessibleChildCount ();
+ for (sal_Int32 i=0; i<nChildCount; ++i)
+ {
+ Reference<XAccessible> xChild (getAccessibleChild (i));
+ if (xChild.is())
+ {
+ Reference<XAccessibleComponent> xChildComponent (xChild->getAccessibleContext(), uno::UNO_QUERY);
+ if (xChildComponent.is())
+ {
+ awt::Rectangle aBBox (xChildComponent->getBounds());
+ if ( (aPoint.X >= aBBox.X)
+ && (aPoint.Y >= aBBox.Y)
+ && (aPoint.X < aBBox.X+aBBox.Width)
+ && (aPoint.Y < aBBox.Y+aBBox.Height) )
+ return xChild;
+ }
+ }
+ }
+
+ // Have not found a child under the given point. Returning empty
+ // reference to indicate this.
+ return uno::Reference<XAccessible>();
+}
+
+// --------------------------------------------------------------------
+
+::com::sun::star::awt::Rectangle SAL_CALL AccessibleCell::getBounds(void) throw(RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ ::osl::MutexGuard aGuard (maMutex);
+
+ ThrowIfDisposed ();
+ ::com::sun::star::awt::Rectangle aBoundingBox;
+ if( mxCell.is() )
+ {
+ // Get the cell's bounding box in internal coordinates (in 100th of mm)
+ const ::Rectangle aCellRect( mxCell->getCellRect() );
+
+ // Transform coordinates from internal to pixel.
+ if (maShapeTreeInfo.GetViewForwarder() == NULL)
+ throw uno::RuntimeException (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleCell has no valid view forwarder")),static_cast<uno::XWeak*>(this));
+
+ ::Size aPixelSize( maShapeTreeInfo.GetViewForwarder()->LogicToPixel(::Size(aCellRect.GetWidth(), aCellRect.GetHeight())) );
+ ::Point aPixelPosition( maShapeTreeInfo.GetViewForwarder()->LogicToPixel( aCellRect.TopLeft() ));
+
+ // Clip the shape's bounding box with the bounding box of its parent.
+ Reference<XAccessibleComponent> xParentComponent ( getAccessibleParent(), uno::UNO_QUERY);
+ if (xParentComponent.is())
+ {
+ // Make the coordinates relative to the parent.
+ awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
+ int x = aPixelPosition.getX() - aParentLocation.X;
+ int y = aPixelPosition.getY() - aParentLocation.Y;
+
+ // Clip with parent (with coordinates relative to itself).
+ ::Rectangle aBBox ( x, y, x + aPixelSize.getWidth(), y + aPixelSize.getHeight());
+ awt::Size aParentSize (xParentComponent->getSize());
+ ::Rectangle aParentBBox (0,0, aParentSize.Width, aParentSize.Height);
+ aBBox = aBBox.GetIntersection (aParentBBox);
+ aBoundingBox = awt::Rectangle ( aBBox.getX(), aBBox.getY(), aBBox.getWidth(), aBBox.getHeight());
+ }
+ else
+ {
+ OSL_TRACE ("parent does not support component");
+ aBoundingBox = awt::Rectangle (aPixelPosition.getX(), aPixelPosition.getY(),aPixelSize.getWidth(), aPixelSize.getHeight());
+ }
+ }
+
+ return aBoundingBox;
+}
+
+// --------------------------------------------------------------------
+
+::com::sun::star::awt::Point SAL_CALL AccessibleCell::getLocation(void) throw (RuntimeException)
+{
+ ThrowIfDisposed ();
+ ::com::sun::star::awt::Rectangle aBoundingBox(getBounds());
+ return ::com::sun::star::awt::Point(aBoundingBox.X, aBoundingBox.Y);
+}
+
+// --------------------------------------------------------------------
+
+::com::sun::star::awt::Point SAL_CALL AccessibleCell::getLocationOnScreen(void) throw(RuntimeException)
+{
+ ThrowIfDisposed ();
+
+ // Get relative position...
+ ::com::sun::star::awt::Point aLocation(getLocation ());
+
+ // ... and add absolute position of the parent.
+ Reference<XAccessibleComponent> xParentComponent( getAccessibleParent(), uno::UNO_QUERY);
+ if(xParentComponent.is())
+ {
+ ::com::sun::star::awt::Point aParentLocation(xParentComponent->getLocationOnScreen());
+ aLocation.X += aParentLocation.X;
+ aLocation.Y += aParentLocation.Y;
+ }
+ else
+ {
+ OSL_TRACE ("getLocation: parent does not support XAccessibleComponent");
+ }
+
+ return aLocation;
+}
+
+// --------------------------------------------------------------------
+
+awt::Size SAL_CALL AccessibleCell::getSize (void) throw (RuntimeException)
+{
+ ThrowIfDisposed ();
+ awt::Rectangle aBoundingBox (getBounds());
+ return awt::Size (aBoundingBox.Width, aBoundingBox.Height);
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL AccessibleCell::addFocusListener ( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener) throw (::com::sun::star::uno::RuntimeException)
+{
+ AccessibleComponentBase::addFocusListener( xListener );
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL AccessibleCell::removeFocusListener (const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ AccessibleComponentBase::removeFocusListener( xListener );
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL AccessibleCell::grabFocus (void) throw (::com::sun::star::uno::RuntimeException)
+{
+ AccessibleComponentBase::grabFocus();
+}
+
+// --------------------------------------------------------------------
+
+sal_Int32 SAL_CALL AccessibleCell::getForeground(void) throw (RuntimeException)
+{
+ ThrowIfDisposed ();
+ sal_Int32 nColor (0x0ffffffL);
+
+ // todo
+ return nColor;
+}
+
+// --------------------------------------------------------------------
+
+sal_Int32 SAL_CALL AccessibleCell::getBackground (void) throw (RuntimeException)
+{
+ ThrowIfDisposed ();
+ sal_Int32 nColor (0L);
+
+ // todo
+ return nColor;
+}
+
+// --------------------------------------------------------------------
+// XAccessibleExtendedComponent
+// --------------------------------------------------------------------
+
+::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont > SAL_CALL AccessibleCell::getFont (void) throw (::com::sun::star::uno::RuntimeException)
+{
+//todo
+ return AccessibleComponentBase::getFont();
+}
+
+// --------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL AccessibleCell::getTitledBorderText (void) throw (::com::sun::star::uno::RuntimeException)
+{
+ return AccessibleComponentBase::getTitledBorderText();
+}
+
+// --------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL AccessibleCell::getToolTipText (void) throw (::com::sun::star::uno::RuntimeException)
+{
+ return AccessibleComponentBase::getToolTipText();
+}
+
+// --------------------------------------------------------------------
+// XAccessibleEventBroadcaster
+// --------------------------------------------------------------------
+
+void SAL_CALL AccessibleCell::addEventListener( const Reference<XAccessibleEventListener >& rxListener) throw (RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ ::osl::MutexGuard aGuard (maMutex);
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ Reference<XInterface> xSource( static_cast<XComponent *>(this) );
+ lang::EventObject aEventObj(xSource);
+ rxListener->disposing(aEventObj);
+ }
+ else
+ {
+ AccessibleContextBase::addEventListener (rxListener);
+ if (mpText != NULL)
+ mpText->AddEventListener (rxListener);
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL AccessibleCell::removeEventListener( const Reference<XAccessibleEventListener >& rxListener) throw (RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ AccessibleContextBase::removeEventListener(rxListener);
+ if (mpText != NULL)
+ mpText->RemoveEventListener (rxListener);
+}
+
+// --------------------------------------------------------------------
+// XServiceInfo
+// --------------------------------------------------------------------
+
+OUString SAL_CALL AccessibleCell::getImplementationName(void) throw (RuntimeException)
+{
+ return OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleCell"));
+}
+
+// --------------------------------------------------------------------
+
+Sequence<OUString> SAL_CALL AccessibleCell::getSupportedServiceNames(void) throw (RuntimeException)
+{
+ ThrowIfDisposed ();
+
+ // Get list of supported service names from base class...
+ uno::Sequence<OUString> aServiceNames = AccessibleContextBase::getSupportedServiceNames();
+ sal_Int32 nCount (aServiceNames.getLength());
+
+ // ...and add additional names.
+ aServiceNames.realloc (nCount + 1);
+ static const OUString sAdditionalServiceName (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.AccessibleCell"));
+ aServiceNames[nCount] = sAdditionalServiceName;
+
+ return aServiceNames;
+}
+
+// --------------------------------------------------------------------
+// IAccessibleViewForwarderListener
+// --------------------------------------------------------------------
+
+void AccessibleCell::ViewForwarderChanged (ChangeType /*aChangeType*/, const IAccessibleViewForwarder* /*pViewForwarder*/)
+{
+ // Inform all listeners that the graphical representation (i.e. size
+ // and/or position) of the shape has changed.
+ CommitChange(AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any());
+
+ // update our children that our screen position might have changed
+ if( mpText )
+ mpText->UpdateChildren();
+}
+
+// --------------------------------------------------------------------
+// protected
+// --------------------------------------------------------------------
+
+void AccessibleCell::disposing (void)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ ::osl::MutexGuard aGuard (maMutex);
+
+ // Make sure to send an event that this object looses the focus in the
+ // case that it has the focus.
+ ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
+ if (pStateSet != NULL)
+ pStateSet->RemoveState(AccessibleStateType::FOCUSED);
+
+ if (mpText != NULL)
+ {
+ mpText->Dispose();
+ delete mpText;
+ mpText = NULL;
+ }
+
+ // Cleanup. Remove references to objects to allow them to be
+ // destroyed.
+ mxCell.clear();
+ maShapeTreeInfo = AccessibleShapeTreeInfo();
+
+ // Call base classes.
+ AccessibleContextBase::dispose ();
+}
+
+sal_Int32 SAL_CALL AccessibleCell::getAccessibleIndexInParent (void) throw (RuntimeException)
+{
+ ThrowIfDisposed ();
+ return mnIndexInParent;
+}
+
+::rtl::OUString SAL_CALL AccessibleCell::getAccessibleName (void) throw (::com::sun::star::uno::RuntimeException)
+{
+ ThrowIfDisposed ();
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+
+ if( mxCell.is() )
+ return mxCell->getName();
+
+ return AccessibleCellBase::getAccessibleName();
+}
+
+} // end of namespace accessibility
diff --git a/svx/source/table/accessiblecell.hxx b/svx/source/table/accessiblecell.hxx
new file mode 100644
index 000000000000..9d7a3deef5f4
--- /dev/null
+++ b/svx/source/table/accessiblecell.hxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_ACCESSIBILITY_ACCESSIBLE_CELL_HXX
+#define _SVX_ACCESSIBILITY_ACCESSIBLE_CELL_HXX
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleExtendedComponent.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+
+#include <rtl/ref.hxx>
+
+#include <editeng/AccessibleContextBase.hxx>
+#include <editeng/AccessibleComponentBase.hxx>
+#include <svx/IAccessibleViewForwarderListener.hxx>
+#include <svx/AccessibleTextHelper.hxx>
+#include <svx/AccessibleShapeTreeInfo.hxx>
+
+#include <cppuhelper/implbase1.hxx>
+
+#include "cell.hxx"
+
+#include <boost/noncopyable.hpp>
+
+class SdrObject;
+
+
+namespace accessibility
+{
+
+class AccessibleShapeInfo;
+class AccessibleShapeTreeInfo;
+class IAccessibleParent;
+
+typedef ::cppu::ImplInheritanceHelper1< AccessibleContextBase, ::com::sun::star::accessibility::XAccessibleExtendedComponent > AccessibleCellBase;
+
+class AccessibleCell : boost::noncopyable, public AccessibleCellBase, public AccessibleComponentBase, public IAccessibleViewForwarderListener
+{
+public:
+ AccessibleCell( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible>& rxParent, const sdr::table::CellRef& rCell, sal_Int32 nIndex, const AccessibleShapeTreeInfo& rShapeTreeInfo);
+ virtual ~AccessibleCell (void);
+
+ virtual void Init (void);
+
+ virtual bool operator== (const AccessibleCell& rAccessibleCell);
+
+ virtual sal_Bool SetState (sal_Int16 aState);
+ virtual sal_Bool ResetState (sal_Int16 aState);
+ sal_Bool GetState (sal_Int16 aState);
+
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire( ) throw ();
+ virtual void SAL_CALL release( ) throw ();
+
+ // XAccessibleContext
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount(void) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL getAccessibleChild(sal_Int32 nIndex) throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL getAccessibleStateSet(void) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent(void) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleName (void) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleComponent
+ virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint(const ::com::sun::star::awt::Point& aPoint) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds(void) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocation(void) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen(void) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Size SAL_CALL getSize(void) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addFocusListener ( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeFocusListener (const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL grabFocus (void) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getForeground(void) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getBackground(void) throw(::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleExtendedComponent
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont > SAL_CALL getFont (void) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getTitledBorderText (void) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getToolTipText (void) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleEventBroadcaster
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& rxListener) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& rxListener) throw(::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName (void) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL getSupportedServiceNames (void) throw(::com::sun::star::uno::RuntimeException);
+
+ // IAccessibleViewForwarderListener
+ virtual void ViewForwarderChanged (ChangeType aChangeType, const IAccessibleViewForwarder* pViewForwarder);
+
+ using cppu::WeakComponentImplHelperBase::addEventListener;
+ using cppu::WeakComponentImplHelperBase::removeEventListener;
+
+ // Misc
+
+ /** set the index _nIndex at the accessible cell param _nIndex The new index in parent.
+ */
+ inline void setIndexInParent(sal_Int32 _nIndex) { mnIndexInParent = _nIndex; }
+
+protected:
+ /// Bundle of information passed to all shapes in a document tree.
+ AccessibleShapeTreeInfo maShapeTreeInfo;
+
+ /// the index in parent.
+ sal_Int32 mnIndexInParent;
+
+ /// The accessible text engine. May be NULL if it can not be created.
+ AccessibleTextHelper* mpText;
+
+ sdr::table::CellRef mxCell;
+
+ /// This method is called from the component helper base class while disposing.
+ virtual void SAL_CALL disposing (void);
+
+private:
+ explicit AccessibleCell(void); // not implemented
+ explicit AccessibleCell(const AccessibleCell&); // not implemented
+ AccessibleCell& operator=(const AccessibleCell&); // not implemented
+};
+
+} // end of namespace accessibility
+
+#endif
diff --git a/svx/source/table/accessibletableshape.cxx b/svx/source/table/accessibletableshape.cxx
new file mode 100644
index 000000000000..4dd7a4b58b47
--- /dev/null
+++ b/svx/source/table/accessibletableshape.cxx
@@ -0,0 +1,723 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <com/sun/star/table/XMergeableCell.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+#include <comphelper/accessiblewrapper.hxx>
+#include <vos/mutex.hxx>
+#include <tools/debug.hxx>
+#include <vcl/svapp.hxx>
+
+#include <svx/AccessibleTableShape.hxx>
+#include "tablecontroller.hxx"
+#include "accessiblecell.hxx"
+
+#include <algorithm>
+
+#include <cppuhelper/implbase1.hxx>
+
+using ::rtl::OUString;
+
+using namespace ::accessibility;
+using namespace ::sdr::table;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::container;
+
+#define C2U(x) OUString(RTL_CONSTASCII_USTRINGPARAM(x))
+
+namespace accessibility
+{
+
+struct hash
+{
+ std::size_t operator()( const Reference< XCell >& xCell ) const
+ {
+ return std::size_t( xCell.get() );
+ }
+};
+
+typedef std::hash_map< Reference< XCell >, rtl::Reference< AccessibleCell >, hash > AccessibleCellMap;
+
+//-----------------------------------------------------------------------------
+// AccessibleTableShapeImpl
+//-----------------------------------------------------------------------------
+
+class AccessibleTableShapeImpl : public cppu::WeakImplHelper1< XModifyListener >
+{
+public:
+ AccessibleTableShapeImpl( AccessibleShapeTreeInfo& rShapeTreeInfo );
+
+ void init( const Reference< XAccessible>& xAccessible, const Reference< XTable >& xTable );
+ void dispose();
+
+ Reference< XAccessible > getAccessibleChild( sal_Int32 i ) throw(IndexOutOfBoundsException);
+ void getColumnAndRow( sal_Int32 nChildIndex, sal_Int32& rnColumn, sal_Int32& rnRow ) throw (IndexOutOfBoundsException );
+
+ // XModifyListener
+ virtual void SAL_CALL modified( const EventObject& aEvent ) throw (RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
+
+ AccessibleShapeTreeInfo& mrShapeTreeInfo;
+ Reference< XTable > mxTable;
+ AccessibleCellMap maChildMap;
+ Reference< XAccessible> mxAccessible;
+};
+
+//-----------------------------------------------------------------------------
+
+AccessibleTableShapeImpl::AccessibleTableShapeImpl( AccessibleShapeTreeInfo& rShapeTreeInfo )
+: mrShapeTreeInfo( rShapeTreeInfo )
+{
+}
+
+//-----------------------------------------------------------------------------
+
+void AccessibleTableShapeImpl::init( const Reference< XAccessible>& xAccessible, const Reference< XTable >& xTable )
+{
+ mxAccessible = xAccessible;
+ mxTable = xTable;
+
+ if( mxTable.is() )
+ {
+ Reference< XModifyListener > xListener( this );
+ mxTable->addModifyListener( xListener );
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void AccessibleTableShapeImpl::dispose()
+{
+ if( mxTable.is() )
+ {
+ Reference< XModifyListener > xListener( this );
+ mxTable->removeModifyListener( xListener );
+ mxTable.clear();
+ }
+ mxAccessible.clear();
+}
+
+//-----------------------------------------------------------------------------
+
+Reference< XAccessible > AccessibleTableShapeImpl::getAccessibleChild( sal_Int32 nChildIndex ) throw(IndexOutOfBoundsException)
+{
+ sal_Int32 nColumn = 0, nRow = 0;
+ getColumnAndRow( nChildIndex, nColumn, nRow );
+
+ Reference< XCell > xCell( mxTable->getCellByPosition( nColumn, nRow ) );
+ AccessibleCellMap::iterator iter( maChildMap.find( xCell ) );
+
+ if( iter != maChildMap.end() )
+ {
+ Reference< XAccessible > xChild( (*iter).second.get() );
+ return xChild;
+ }
+ else
+ {
+ CellRef xCellRef( dynamic_cast< Cell* >( xCell.get() ) );
+
+ rtl::Reference< AccessibleCell > xAccessibleCell( new AccessibleCell( mxAccessible, xCellRef, nChildIndex, mrShapeTreeInfo ) );
+
+ maChildMap[xCell] = xAccessibleCell;
+
+ xAccessibleCell->Init();
+
+ Reference< XAccessible > xChild( xAccessibleCell.get() );
+ return xChild;
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void AccessibleTableShapeImpl::getColumnAndRow( sal_Int32 nChildIndex, sal_Int32& rnColumn, sal_Int32& rnRow ) throw (IndexOutOfBoundsException )
+{
+ rnRow = 0;
+ rnColumn = nChildIndex;
+
+ if( mxTable.is() )
+ {
+ const sal_Int32 nColumnCount = mxTable->getColumnCount();
+ while( rnColumn >= nColumnCount )
+ {
+ rnRow++;
+ rnColumn -= nColumnCount;
+ }
+
+ if( rnRow < mxTable->getRowCount() )
+ return;
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// XModifyListener
+void SAL_CALL AccessibleTableShapeImpl::modified( const EventObject& /*aEvent*/ ) throw (RuntimeException)
+{
+ if( mxTable.is() ) try
+ {
+ // structural changes may have happened to the table, validate all accessible cell instances
+ AccessibleCellMap aTempChildMap;
+ aTempChildMap.swap( maChildMap );
+
+ // first move all still existing cells to maChildMap again and update their index
+
+ const sal_Int32 nRowCount = mxTable->getRowCount();
+ const sal_Int32 nColCount = mxTable->getColumnCount();
+
+ sal_Int32 nChildIndex = 0;
+
+ for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol )
+ {
+ Reference< XCell > xCell( mxTable->getCellByPosition( nCol, nRow ) );
+ AccessibleCellMap::iterator iter( aTempChildMap.find( xCell ) );
+
+ if( iter != aTempChildMap.end() )
+ {
+ rtl::Reference< AccessibleCell > xAccessibleCell( (*iter).second );
+ xAccessibleCell->setIndexInParent( nChildIndex );
+ xAccessibleCell->CommitChange(AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any());
+
+ // move still existing cell from temporary child map to our child map
+ maChildMap[xCell] = xAccessibleCell;
+ aTempChildMap.erase( iter );
+ }
+
+ ++nChildIndex;
+ }
+ }
+
+ // all accessible cell instances still left in aTempChildMap must be disposed
+ // as they are no longer part of the table
+
+ for( AccessibleCellMap::iterator iter( aTempChildMap.begin() ); iter != aTempChildMap.end(); iter++ )
+ {
+ (*iter).second->dispose();
+ }
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("svx::AccessibleTableShape::modified(), exception caught!");
+ }
+}
+
+// XEventListener
+void SAL_CALL AccessibleTableShapeImpl::disposing( const EventObject& /*Source*/ ) throw (RuntimeException)
+{
+}
+
+//-----------------------------------------------------------------------------
+// AccessibleTableShape
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+
+AccessibleTableShape::AccessibleTableShape( const AccessibleShapeInfo& rShapeInfo, const AccessibleShapeTreeInfo& rShapeTreeInfo)
+: AccessibleTableShape_Base(rShapeInfo, rShapeTreeInfo)
+, mxImpl( new AccessibleTableShapeImpl( maShapeTreeInfo ) )
+{
+}
+
+//-----------------------------------------------------------------------------
+
+AccessibleTableShape::~AccessibleTableShape (void)
+{
+}
+
+//-----------------------------------------------------------------------------
+
+void AccessibleTableShape::Init()
+{
+ try
+ {
+
+ Reference< XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
+ Reference< XTable > xTable( xSet->getPropertyValue(C2U("Model")), UNO_QUERY_THROW );
+
+ mxImpl->init( this, xTable );
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("AccessibleTableShape::init(), exception caught?");
+ }
+
+ AccessibleTableShape_Base::Init();
+}
+
+//-----------------------------------------------------------------------------
+
+SvxTableController* AccessibleTableShape::getTableController()
+{
+ SdrView* pView = maShapeTreeInfo.GetSdrView ();
+ if( pView )
+ return dynamic_cast< SvxTableController* >( pView->getSelectionController().get() );
+ else
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// XInterface
+//-----------------------------------------------------------------------------
+
+Any SAL_CALL AccessibleTableShape::queryInterface( const Type& aType ) throw (RuntimeException)
+{
+ return AccessibleTableShape_Base::queryInterface( aType );
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL AccessibleTableShape::acquire( ) throw ()
+{
+ AccessibleTableShape_Base::acquire();
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL AccessibleTableShape::release( ) throw ()
+{
+ AccessibleTableShape_Base::release();
+}
+
+//-----------------------------------------------------------------------------
+// XAccessible
+//-----------------------------------------------------------------------------
+
+Reference< XAccessibleContext > SAL_CALL AccessibleTableShape::getAccessibleContext(void) throw (RuntimeException)
+{
+ return AccessibleShape::getAccessibleContext ();
+}
+
+//-----------------------------------------------------------------------------
+OUString SAL_CALL AccessibleTableShape::getImplementationName(void) throw (RuntimeException)
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.accessibility.AccessibleTableShape" ) );
+}
+
+//-----------------------------------------------------------------------------
+
+OUString AccessibleTableShape::CreateAccessibleBaseName(void) throw (RuntimeException)
+{
+ return OUString (RTL_CONSTASCII_USTRINGPARAM("TableShape"));;
+}
+
+//--------------------------------------------------------------------
+
+sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleChildCount( ) throw(RuntimeException)
+{
+ ::vos::OGuard aSolarGuard(::Application::GetSolarMutex());
+ return mxImpl->mxTable.is() ? mxImpl->mxTable->getRowCount() * mxImpl->mxTable->getColumnCount() : 0;
+}
+
+//--------------------------------------------------------------------
+Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleChild( sal_Int32 i ) throw(IndexOutOfBoundsException, RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ ThrowIfDisposed();
+
+ return mxImpl->getAccessibleChild( i );
+}
+
+//--------------------------------------------------------------------
+Reference< XAccessibleRelationSet > SAL_CALL AccessibleTableShape::getAccessibleRelationSet( ) throw (RuntimeException)
+{
+ return AccessibleShape::getAccessibleRelationSet( );
+}
+
+//--------------------------------------------------------------------
+
+sal_Int16 SAL_CALL AccessibleTableShape::getAccessibleRole (void) throw (RuntimeException)
+{
+ return AccessibleRole::TABLE;
+}
+
+//--------------------------------------------------------------------
+
+void SAL_CALL AccessibleTableShape::disposing (void)
+{
+ mxImpl->dispose();
+
+ // let the base do it's stuff
+ AccessibleShape::disposing();
+}
+
+//--------------------------------------------------------------------
+// XAccessibleTable
+//--------------------------------------------------------------------
+
+sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRowCount() throw (RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ return mxImpl->mxTable.is() ? mxImpl->mxTable->getRowCount() : 0;
+}
+
+//--------------------------------------------------------------------
+
+sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumnCount( ) throw (RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ return mxImpl->mxTable.is() ? mxImpl->mxTable->getColumnCount() : 0;
+}
+
+//--------------------------------------------------------------------
+
+OUString SAL_CALL AccessibleTableShape::getAccessibleRowDescription( sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ checkCellPosition( 0, nRow );
+ return OUString();
+}
+
+//--------------------------------------------------------------------
+
+OUString SAL_CALL AccessibleTableShape::getAccessibleColumnDescription( sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ checkCellPosition( nColumn, 0 );
+ return OUString();
+}
+
+//--------------------------------------------------------------------
+
+sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ checkCellPosition( nColumn, nRow );
+ if( mxImpl->mxTable.is() )
+ {
+ Reference< XMergeableCell > xCell( mxImpl->mxTable->getCellByPosition( nColumn, nRow ), UNO_QUERY );
+ if( xCell.is() )
+ return xCell->getRowSpan();
+ }
+ return 1;
+}
+
+//--------------------------------------------------------------------
+
+sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ checkCellPosition( nColumn, nRow );
+ if( mxImpl->mxTable.is() )
+ {
+ Reference< XMergeableCell > xCell( mxImpl->mxTable->getCellByPosition( nColumn, nRow ), UNO_QUERY );
+ if( xCell.is() )
+ return xCell->getColumnSpan();
+ }
+ return 1;
+}
+
+//--------------------------------------------------------------------
+
+Reference< XAccessibleTable > SAL_CALL AccessibleTableShape::getAccessibleRowHeaders( ) throw (RuntimeException)
+{
+ Reference< XAccessibleTable > xRet( this ); // todo
+ return xRet;
+}
+
+//--------------------------------------------------------------------
+
+Reference< XAccessibleTable > SAL_CALL AccessibleTableShape::getAccessibleColumnHeaders( ) throw (RuntimeException)
+{
+ Reference< XAccessibleTable > xRet( this ); // todo
+ return xRet;
+}
+
+//--------------------------------------------------------------------
+
+Sequence< sal_Int32 > SAL_CALL AccessibleTableShape::getSelectedAccessibleRows( ) throw (RuntimeException)
+{
+ Sequence< sal_Int32 > aRet;
+ return aRet;
+}
+
+//--------------------------------------------------------------------
+
+Sequence< sal_Int32 > SAL_CALL AccessibleTableShape::getSelectedAccessibleColumns( ) throw (RuntimeException)
+{
+ Sequence< sal_Int32 > aRet;
+ return aRet;
+}
+
+//--------------------------------------------------------------------
+
+sal_Bool SAL_CALL AccessibleTableShape::isAccessibleRowSelected( sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ checkCellPosition( 0, nRow );
+ return sal_False;
+}
+
+//--------------------------------------------------------------------
+
+sal_Bool SAL_CALL AccessibleTableShape::isAccessibleColumnSelected( sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ checkCellPosition( nColumn, 0 );
+ return sal_False;
+}
+
+//--------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ checkCellPosition( nColumn, nRow );
+
+ sal_Int32 nChildIndex = 0;
+ if( mxImpl->mxTable.is() )
+ nChildIndex = mxImpl->mxTable->getColumnCount() * nRow + nColumn;
+
+ return getAccessibleChild( nChildIndex );
+}
+
+//--------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleCaption( ) throw (RuntimeException)
+{
+ Reference< XAccessible > xRet;
+ return xRet;
+}
+
+//--------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleSummary( ) throw (RuntimeException)
+{
+ Reference< XAccessible > xRet;
+ return xRet;
+}
+
+//--------------------------------------------------------------------
+
+sal_Bool SAL_CALL AccessibleTableShape::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ checkCellPosition( nColumn, nRow );
+
+ SvxTableController* pController = getTableController();
+ if( pController && pController->hasSelectedCells() )
+ {
+ CellPos aFirstPos, aLastPos;
+ pController->getSelectedCells( aFirstPos, aLastPos );
+ if( (aFirstPos.mnRow <= nRow) && (aFirstPos.mnCol <= nColumn) && (nRow <= aLastPos.mnRow) && (nColumn <= aLastPos.mnCol) )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+//--------------------------------------------------------------------
+
+sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ checkCellPosition( nColumn, nRow );
+ return mxImpl->mxTable.is() ? (nRow * mxImpl->mxTable->getColumnCount() + nColumn) : 0;
+}
+
+//--------------------------------------------------------------------
+
+sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRow( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ sal_Int32 nColumn = 0, nRow = 0;
+ mxImpl->getColumnAndRow( nChildIndex, nColumn, nRow );
+ return nRow;
+}
+
+//--------------------------------------------------------------------
+
+sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumn( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ sal_Int32 nColumn = 0, nRow = 0;
+ mxImpl->getColumnAndRow( nChildIndex, nColumn, nRow );
+ return nChildIndex;
+}
+
+//--------------------------------------------------------------------
+// XAccessibleSelection
+//--------------------------------------------------------------------
+
+void SAL_CALL AccessibleTableShape::selectAccessibleChild( sal_Int32 nChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException )
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ CellPos aPos;
+ mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow );
+
+ // todo, select table shape?!?
+ SvxTableController* pController = getTableController();
+ if( pController )
+ {
+ CellPos aFirstPos( aPos ), aLastPos( aPos );
+ if( pController->hasSelectedCells() )
+ {
+ pController->getSelectedCells( aFirstPos, aLastPos );
+
+ aFirstPos.mnRow = std::min( aFirstPos.mnRow, aPos.mnRow );
+ aFirstPos.mnCol = std::min( aFirstPos.mnCol, aPos.mnCol );
+ aLastPos.mnRow = std::max( aLastPos.mnRow, aPos.mnRow );
+ aLastPos.mnCol = std::max( aLastPos.mnCol, aPos.mnCol );
+ }
+ pController->setSelectedCells( aFirstPos, aLastPos );
+ }
+}
+
+//--------------------------------------------------------------------
+
+sal_Bool SAL_CALL AccessibleTableShape::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException )
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ CellPos aPos;
+ mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow );
+
+ return isAccessibleSelected(aPos.mnCol, aPos.mnRow);
+}
+
+//--------------------------------------------------------------------
+
+void SAL_CALL AccessibleTableShape::clearAccessibleSelection() throw ( RuntimeException )
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+
+ SvxTableController* pController = getTableController();
+ if( pController )
+ pController->clearSelection();
+}
+//--------------------------------------------------------------------
+
+void SAL_CALL AccessibleTableShape::selectAllAccessibleChildren() throw ( RuntimeException )
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+
+ // todo: force selection of shape?
+ SvxTableController* pController = getTableController();
+ if( pController )
+ pController->selectAll();
+}
+
+//--------------------------------------------------------------------
+
+sal_Int32 SAL_CALL AccessibleTableShape::getSelectedAccessibleChildCount() throw ( RuntimeException )
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+
+ SvxTableController* pController = getTableController();
+ if( pController && pController->hasSelectedCells() )
+ {
+ CellPos aFirstPos, aLastPos;
+ pController->getSelectedCells( aFirstPos, aLastPos );
+
+ const sal_Int32 nSelectedColumns = std::max( (sal_Int32)0, aLastPos.mnCol - aFirstPos.mnCol ) + 1;
+ const sal_Int32 nSelectedRows = std::max( (sal_Int32)0, aLastPos.mnRow - aFirstPos.mnRow ) + 1;
+ return nSelectedRows * nSelectedColumns;
+ }
+
+ return 0;
+}
+
+//--------------------------------------------------------------------
+
+Reference< XAccessible > SAL_CALL AccessibleTableShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException)
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+
+ SvxTableController* pController = getTableController();
+ if( pController && pController->hasSelectedCells() )
+ {
+ CellPos aFirstPos, aLastPos;
+ pController->getSelectedCells( aFirstPos, aLastPos );
+
+ const sal_Int32 nSelectedColumns = std::max( (sal_Int32)0, aLastPos.mnCol - aFirstPos.mnCol ) + 1;
+ const sal_Int32 nSelectedRows = std::max( (sal_Int32)0, aLastPos.mnRow - aFirstPos.mnRow ) + 1;
+
+ if( nSelectedChildIndex < (nSelectedRows * nSelectedColumns) )
+ {
+ while( nSelectedChildIndex >= nSelectedColumns )
+ {
+ aFirstPos.mnRow++;
+ nSelectedChildIndex -= nSelectedColumns;
+ }
+ return getAccessibleCellAt( nSelectedColumns, aFirstPos.mnRow );
+ }
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+//--------------------------------------------------------------------
+
+void SAL_CALL AccessibleTableShape::deselectAccessibleChild( sal_Int32 nChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException )
+{
+ ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
+ CellPos aPos;
+ mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow );
+
+ // todo, select table shape?!?
+ SvxTableController* pController = getTableController();
+ if( pController && pController->hasSelectedCells() )
+ {
+ CellPos aFirstPos, aLastPos;
+ pController->getSelectedCells( aFirstPos, aLastPos );
+
+ // create a selection where aPos is not part of anymore
+ aFirstPos.mnRow = std::min( aFirstPos.mnRow, aPos.mnRow+1 );
+ aFirstPos.mnCol = std::min( aFirstPos.mnCol, aPos.mnCol+1 );
+ aLastPos.mnRow = std::max( aLastPos.mnRow, aPos.mnRow-1 );
+ aLastPos.mnCol = std::max( aLastPos.mnCol, aPos.mnCol-1 );
+
+ // new selection may be invalid (child to deselect is not at a border of the selection but in between)
+ if( (aFirstPos.mnRow > aLastPos.mnRow) || (aFirstPos.mnCol > aLastPos.mnCol) )
+ pController->clearSelection(); // if selection is invalid, clear all
+ else
+ pController->setSelectedCells( aFirstPos, aLastPos );
+ }
+}
+
+//--------------------------------------------------------------------
+
+void AccessibleTableShape::checkCellPosition( sal_Int32 nCol, sal_Int32 nRow ) throw ( IndexOutOfBoundsException )
+{
+ if( (nCol >= 0) && (nRow >= 0) && mxImpl->mxTable.is() && (nCol < mxImpl->mxTable->getColumnCount()) && (nRow < mxImpl->mxTable->getRowCount()) )
+ return;
+
+ throw IndexOutOfBoundsException();
+}
+
+}
diff --git a/svx/source/table/cell.cxx b/svx/source/table/cell.cxx
new file mode 100644
index 000000000000..0f5467c99721
--- /dev/null
+++ b/svx/source/table/cell.cxx
@@ -0,0 +1,1809 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/text/WritingMode.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
+
+#include <cppuhelper/typeprovider.hxx>
+#include <svl/style.hxx>
+#include <svl/itemset.hxx>
+
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+#include "svx/sdr/properties/textproperties.hxx"
+#include "editeng/outlobj.hxx"
+#include "editeng/writingmodeitem.hxx"
+#include "svx/svdotable.hxx"
+#include "svx/svdoutl.hxx"
+#include "svx/unoshtxt.hxx"
+#include "svx/svdmodel.hxx"
+
+#include "tableundo.hxx"
+#include "cell.hxx"
+#include "svx/svdotable.hxx"
+#include "svx/svdoutl.hxx"
+#include "svx/unoshtxt.hxx"
+#include "svx/unoshprp.hxx"
+#include "svx/unoshape.hxx"
+#include "editeng/editobj.hxx"
+#include "editeng/boxitem.hxx"
+#include "svx/xflbstit.hxx"
+#include "svx/xflbmtit.hxx"
+#include <svx/svdpool.hxx>
+
+// -----------------------------------------------------------------------------
+
+using ::rtl::OUString;
+using ::vos::OGuard;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::container;
+
+// -----------------------------------------------------------------------------
+
+static const SvxItemPropertySet* ImplGetSvxCellPropertySet()
+{
+ // Propertymap fuer einen Outliner Text
+ static const SfxItemPropertyMapEntry aSvxCellPropertyMap[] =
+ {
+ FILL_PROPERTIES
+// { MAP_CHAR_LEN("HasLevels"), OWN_ATTR_HASLEVELS, &::getBooleanCppuType(), ::com::sun::star::beans::PropertyAttribute::READONLY, 0},
+ { MAP_CHAR_LEN("Style"), OWN_ATTR_STYLE, &::com::sun::star::style::XStyle::static_type(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_CHAR_LEN(UNO_NAME_TEXT_WRITINGMODE), SDRATTR_TEXTDIRECTION, &::getCppuType( (::com::sun::star::text::WritingMode*) 0 ), 0, 0},
+ { MAP_CHAR_LEN(UNO_NAME_TEXT_HORZADJUST), SDRATTR_TEXT_HORZADJUST, &::getCppuType((const ::com::sun::star::drawing::TextHorizontalAdjust*)0), 0, 0}, \
+ { MAP_CHAR_LEN(UNO_NAME_TEXT_LEFTDIST), SDRATTR_TEXT_LEFTDIST, &::getCppuType((const sal_Int32*)0), 0, SFX_METRIC_ITEM}, \
+ { MAP_CHAR_LEN(UNO_NAME_TEXT_LOWERDIST), SDRATTR_TEXT_LOWERDIST, &::getCppuType((const sal_Int32*)0), 0, SFX_METRIC_ITEM}, \
+ { MAP_CHAR_LEN(UNO_NAME_TEXT_RIGHTDIST), SDRATTR_TEXT_RIGHTDIST, &::getCppuType((const sal_Int32*)0), 0, SFX_METRIC_ITEM}, \
+ { MAP_CHAR_LEN(UNO_NAME_TEXT_UPPERDIST), SDRATTR_TEXT_UPPERDIST, &::getCppuType((const sal_Int32*)0), 0, SFX_METRIC_ITEM}, \
+ { MAP_CHAR_LEN(UNO_NAME_TEXT_VERTADJUST), SDRATTR_TEXT_VERTADJUST, &::getCppuType((const ::com::sun::star::drawing::TextVerticalAdjust*)0), 0, 0},\
+ { MAP_CHAR_LEN(UNO_NAME_TEXT_WORDWRAP), SDRATTR_TEXT_WORDWRAP, &::getBooleanCppuType(), 0, 0}, \
+
+ { MAP_CHAR_LEN("TableBorder"), OWN_ATTR_TABLEBORDER, &::getCppuType((const TableBorder*)0), 0, 0 }, \
+ { MAP_CHAR_LEN("TopBorder"), SDRATTR_TABLE_BORDER, &::getCppuType((const BorderLine*)0), 0, TOP_BORDER }, \
+ { MAP_CHAR_LEN("BottomBorder"), SDRATTR_TABLE_BORDER, &::getCppuType((const BorderLine*)0), 0, BOTTOM_BORDER }, \
+ { MAP_CHAR_LEN("LeftBorder"), SDRATTR_TABLE_BORDER, &::getCppuType((const BorderLine*)0), 0, LEFT_BORDER }, \
+ { MAP_CHAR_LEN("RightBorder"), SDRATTR_TABLE_BORDER, &::getCppuType((const BorderLine*)0), 0, RIGHT_BORDER }, \
+
+ SVX_UNOEDIT_OUTLINER_PROPERTIES,
+ SVX_UNOEDIT_CHAR_PROPERTIES,
+ SVX_UNOEDIT_PARA_PROPERTIES,
+ {0,0,0,0,0,0}
+ };
+
+ static SvxItemPropertySet aSvxCellPropertySet( aSvxCellPropertyMap, SdrObject::GetGlobalDrawObjectItemPool() );
+ return &aSvxCellPropertySet;
+}
+
+namespace sdr
+{
+ namespace properties
+ {
+ class CellProperties : public TextProperties
+ {
+ protected:
+ // create a new itemset
+ SfxItemSet& CreateObjectSpecificItemSet(SfxItemPool& rPool);
+
+ public:
+ // basic constructor
+ CellProperties(SdrObject& rObj, sdr::table::Cell* pCell );
+
+ // constructor for copying, but using new object
+ CellProperties(const CellProperties& rProps, SdrObject& rObj, sdr::table::Cell* pCell);
+
+ // destructor
+ ~CellProperties();
+
+ // Clone() operator, normally just calls the local copy constructor
+ BaseProperties& Clone(SdrObject& rObj) const;
+
+ void ForceDefaultAttributes();
+
+ void ItemSetChanged(const SfxItemSet& rSet);
+
+ void ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem);
+
+ void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr);
+
+ sdr::table::CellRef mxCell;
+ };
+
+ // create a new itemset
+ SfxItemSet& CellProperties::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));
+ }
+
+ CellProperties::CellProperties(SdrObject& rObj, sdr::table::Cell* pCell)
+ : TextProperties(rObj)
+ , mxCell(pCell)
+ {
+ }
+
+ CellProperties::CellProperties(const CellProperties& rProps, SdrObject& rObj, sdr::table::Cell* pCell)
+ : TextProperties(rProps, rObj)
+ , mxCell( pCell )
+ {
+ }
+
+ CellProperties::~CellProperties()
+ {
+ }
+
+ BaseProperties& CellProperties::Clone(SdrObject& rObj) const
+ {
+ DBG_ERROR("CellProperties::Clone(), does not work yet!");
+ return *(new CellProperties(*this, rObj,0));
+ }
+
+ void CellProperties::ForceDefaultAttributes()
+ {
+ }
+
+ void CellProperties::ItemSetChanged(const SfxItemSet& rSet )
+ {
+ SdrTextObj& rObj = (SdrTextObj&)GetSdrObject();
+
+ if( mxCell.is() )
+ {
+ OutlinerParaObject* pParaObj = mxCell->GetEditOutlinerParaObject();
+
+ bool bOwnParaObj = pParaObj != 0;
+
+ if( pParaObj == 0 )
+ pParaObj = mxCell->GetOutlinerParaObject();
+
+ if(pParaObj)
+ {
+ // handle outliner attributes
+ Outliner* pOutliner = 0;
+
+ if(mxCell->IsTextEditActive())
+ {
+ pOutliner = rObj.GetTextEditOutliner();
+ }
+ else
+ {
+ pOutliner = &rObj.ImpGetDrawOutliner();
+ pOutliner->SetText(*pParaObj);
+ }
+
+ sal_uInt32 nParaCount(pOutliner->GetParagraphCount());
+
+ for(sal_uInt16 nPara = 0; nPara < nParaCount; nPara++)
+ {
+ SfxItemSet aSet(pOutliner->GetParaAttribs(nPara));
+ aSet.Put(rSet);
+ pOutliner->SetParaAttribs(nPara, aSet);
+ }
+
+ if(!mxCell->IsTextEditActive())
+ {
+ if(nParaCount)
+ {
+ // force ItemSet
+ GetObjectItemSet();
+
+ SfxItemSet aNewSet(pOutliner->GetParaAttribs(0L));
+ mpItemSet->Put(aNewSet);
+ }
+
+ OutlinerParaObject* pTemp = pOutliner->CreateParaObject(0, (sal_uInt16)nParaCount);
+ pOutliner->Clear();
+
+ mxCell->SetOutlinerParaObject(pTemp);
+ }
+
+ if( bOwnParaObj )
+ delete pParaObj;
+ }
+ }
+
+ // call parent
+ AttributeProperties::ItemSetChanged(rSet);
+
+ if( mxCell.is() )
+ mxCell->notifyModified();
+ }
+
+ void CellProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem)
+ {
+ if(pNewItem && (SDRATTR_TEXTDIRECTION == nWhich))
+ {
+ sal_Bool bVertical(com::sun::star::text::WritingMode_TB_RL == ((SvxWritingModeItem*)pNewItem)->GetValue());
+
+ sdr::table::SdrTableObj& rObj = (sdr::table::SdrTableObj&)GetSdrObject();
+ if( rObj.IsVerticalWriting() != bVertical )
+ rObj.SetVerticalWriting(bVertical);
+ }
+
+ // call parent
+ AttributeProperties::ItemChange( nWhich, pNewItem );
+ }
+
+ void CellProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr)
+ {
+ TextProperties::SetStyleSheet( pNewStyleSheet, bDontRemoveHardAttr );
+ }
+ } // end of namespace properties
+} // end of namespace sdr
+
+namespace sdr { namespace table {
+
+// -----------------------------------------------------------------------------
+// Cell
+// -----------------------------------------------------------------------------
+
+rtl::Reference< Cell > Cell::create( SdrTableObj& rTableObj, OutlinerParaObject* pOutlinerParaObject )
+{
+ rtl::Reference< Cell > xCell( new Cell( rTableObj, pOutlinerParaObject ) );
+ if( xCell->mxTable.is() )
+ {
+ Reference< XEventListener > xListener( xCell.get() );
+ xCell->mxTable->addEventListener( xListener );
+ }
+ return xCell;
+}
+
+// -----------------------------------------------------------------------------
+
+Cell::Cell( SdrTableObj& rTableObj, OutlinerParaObject* pOutlinerParaObject ) throw()
+: SdrText( rTableObj, pOutlinerParaObject )
+, SvxUnoTextBase( ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() )
+, mpPropSet( ImplGetSvxCellPropertySet() )
+, mpProperties( new sdr::properties::CellProperties( rTableObj, this ) )
+, mnCellContentType( CellContentType_EMPTY )
+, mfValue( 0.0 )
+, mnError( 0 )
+, mbMerged( sal_False )
+, mnRowSpan( 1 )
+, mnColSpan( 1 )
+, mxTable( rTableObj.getTable() )
+{
+ if( rTableObj.GetModel() )
+ SetModel( rTableObj.GetModel() );
+}
+
+// -----------------------------------------------------------------------------
+
+Cell::~Cell() throw()
+{
+ dispose();
+}
+
+// -----------------------------------------------------------------------------
+
+void Cell::dispose()
+{
+ if( mxTable.is() )
+ {
+ try
+ {
+ Reference< XEventListener > xThis( this );
+ mxTable->removeEventListener( xThis );
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("Cell::dispose(), exception caught!");
+ }
+ mxTable.clear();
+ }
+
+ if( mpProperties )
+ {
+ delete mpProperties;
+ mpProperties = 0;
+ }
+ SetOutlinerParaObject( 0 );
+}
+
+// -----------------------------------------------------------------------------
+
+void Cell::SetModel(SdrModel* pNewModel)
+{
+ SvxTextEditSource* pTextEditSource = dynamic_cast< SvxTextEditSource* >( GetEditSource() );
+ if( (GetModel() != pNewModel) || ( pNewModel && !pTextEditSource) )
+ {
+ if( mpProperties )
+ {
+ SfxItemPool* pItemPool = mpProperties->GetObjectItemSet().GetPool();
+
+ // test for correct pool in ItemSet; move to new pool if necessary
+ if( pNewModel && pItemPool && pItemPool != &pNewModel->GetItemPool())
+ mpProperties->MoveToItemPool(pItemPool, &pNewModel->GetItemPool(), pNewModel);
+ }
+
+ if( pTextEditSource )
+ {
+ pTextEditSource->ChangeModel( pNewModel );
+ }
+ else
+ {
+ SetEditSource( new SvxTextEditSource( &GetObject(), this, static_cast< XWeak * >( this ) ) );
+ }
+
+ SetStyleSheet( 0, sal_True );
+ SdrText::SetModel( pNewModel );
+ ForceOutlinerParaObject( OUTLINERMODE_TEXTOBJECT );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void Cell::merge( sal_Int32 nColumnSpan, sal_Int32 nRowSpan )
+{
+ if( (mnColSpan != nColumnSpan) || (mnRowSpan != nRowSpan) || (mbMerged != sal_False) )
+ {
+ mnColSpan = nColumnSpan;
+ mnRowSpan = nRowSpan;
+ mbMerged = sal_False;
+ notifyModified();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void Cell::mergeContent( const CellRef& xSourceCell )
+{
+ SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
+
+ if( xSourceCell->hasText() )
+ {
+ SdrOutliner& rOutliner=rTableObj.ImpGetDrawOutliner();
+ rOutliner.SetUpdateMode(TRUE);
+
+ if( hasText() )
+ {
+ rOutliner.SetText(*GetOutlinerParaObject());
+ rOutliner.AddText(*xSourceCell->GetOutlinerParaObject());
+ }
+ else
+ {
+ rOutliner.SetText(*xSourceCell->GetOutlinerParaObject());
+ }
+
+ SetOutlinerParaObject( rOutliner.CreateParaObject() );
+ rOutliner.Clear();
+ xSourceCell->SetOutlinerParaObject(rOutliner.CreateParaObject());
+ rOutliner.Clear();
+ SetStyleSheet( GetStyleSheet(), sal_True );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void Cell::cloneFrom( const CellRef& xCell )
+{
+ if( xCell.is() )
+ {
+ replaceContentAndFormating( xCell );
+
+ mnCellContentType = xCell->mnCellContentType;
+
+ msFormula = xCell->msFormula;
+ mfValue = xCell->mfValue;
+ mnError = xCell->mnError;
+
+ mbMerged = xCell->mbMerged;
+ mnRowSpan = xCell->mnRowSpan;
+ mnColSpan = xCell->mnColSpan;
+
+ }
+ notifyModified();
+}
+
+void Cell::replaceContentAndFormating( const CellRef& xSourceCell )
+{
+ if( xSourceCell.is() && mpProperties )
+ {
+ mpProperties->SetMergedItemSet( xSourceCell->GetObjectItemSet() );
+ SetOutlinerParaObject( new OutlinerParaObject(*xSourceCell->GetOutlinerParaObject()) );
+
+ SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
+ SdrTableObj& rSourceTableObj = dynamic_cast< SdrTableObj& >( xSourceCell->GetObject() );
+
+ if(rSourceTableObj.GetModel() != rTableObj.GetModel())
+ {
+ SetStyleSheet( 0, sal_True );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void Cell::setMerged()
+{
+ if( !mbMerged )
+ {
+ mbMerged = sal_True;
+ notifyModified();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void Cell::notifyModified()
+{
+ if( mxTable.is() )
+ mxTable->setModified( sal_True );
+}
+
+// -----------------------------------------------------------------------------
+// SdrTextShape proxy
+// -----------------------------------------------------------------------------
+
+bool Cell::IsTextEditActive()
+{
+ bool isActive = false;
+ SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
+ if(rTableObj.getActiveCell().get() == this )
+ {
+ OutlinerParaObject* pParaObj = rTableObj.GetEditOutlinerParaObject();
+ if( pParaObj != 0 )
+ {
+ isActive = true;
+ delete pParaObj;
+ }
+ }
+ return isActive;
+}
+
+// -----------------------------------------------------------------------------
+
+bool Cell::hasText() const
+{
+ OutlinerParaObject* pParaObj = GetOutlinerParaObject();
+ if( pParaObj )
+ {
+ const EditTextObject& rTextObj = pParaObj->GetTextObject();
+ if( rTextObj.GetParagraphCount() >= 1 )
+ {
+ if( rTextObj.GetParagraphCount() == 1 )
+ {
+ if( rTextObj.GetText(0).Len() == 0 )
+ return false;
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// -----------------------------------------------------------------------------
+
+OutlinerParaObject* Cell::GetEditOutlinerParaObject() const
+{
+ SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
+ if( rTableObj.getActiveCell().get() == this )
+ return rTableObj.GetEditOutlinerParaObject();
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+void Cell::SetStyleSheet( SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr )
+{
+ // only allow cell styles for cells
+ if( pStyleSheet && pStyleSheet->GetFamily() != SFX_STYLE_FAMILY_FRAME )
+ return;
+
+ if( mpProperties && (mpProperties->GetStyleSheet() != pStyleSheet) )
+ {
+ mpProperties->SetStyleSheet( pStyleSheet, bDontRemoveHardAttr );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+const SfxItemSet& Cell::GetObjectItemSet()
+{
+ if( mpProperties )
+ {
+ return mpProperties->GetObjectItemSet();
+ }
+ else
+ {
+ DBG_ERROR("Cell::GetObjectItemSet(), called without properties!");
+ return GetObject().GetObjectItemSet();
+ }
+}
+
+void Cell::SetObjectItem(const SfxPoolItem& rItem)
+{
+ if( mpProperties )
+ {
+ mpProperties->SetObjectItem( rItem );
+ notifyModified();
+ }
+}
+
+void Cell::SetMergedItem(const SfxPoolItem& rItem)
+{
+ SetObjectItem(rItem);
+}
+
+SfxStyleSheet* Cell::GetStyleSheet() const
+{
+ if( mpProperties )
+ return mpProperties->GetStyleSheet();
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+SfxStyleSheetPool* Cell::GetStyleSheetPool() const
+{
+ if( mpProperties && mpProperties->GetStyleSheet() )
+ return dynamic_cast< SfxStyleSheetPool* >( &mpProperties->GetStyleSheet()->GetPool() );
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+const Rectangle& Cell::GetCurrentBoundRect() const
+{
+ return maCellRect;
+}
+
+// -----------------------------------------------------------------------------
+
+void Cell::TakeTextAnchorRect(Rectangle& rAnchorRect) const
+{
+ rAnchorRect.nLeft = maCellRect.nLeft + GetTextLeftDistance();
+ rAnchorRect.nRight = maCellRect.nRight - GetTextRightDistance();
+ rAnchorRect.nTop = maCellRect.nTop + GetTextUpperDistance();
+ rAnchorRect.nBottom = maCellRect.nBottom - GetTextLowerDistance();
+}
+
+// -----------------------------------------------------------------------------
+
+const SfxItemSet& Cell::GetItemSet() const
+{
+ return mpProperties->GetObjectItemSet();
+}
+
+// -----------------------------------------------------------------------------
+
+void Cell::SetMergedItemSetAndBroadcast(const SfxItemSet& rSet, sal_Bool bClearAllItems)
+{
+ if( mpProperties )
+ {
+ mpProperties->SetMergedItemSetAndBroadcast(rSet, bClearAllItems);
+ notifyModified();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 Cell::getMinimumWidth()
+{
+ return GetTextLeftDistance() + GetTextRightDistance() + 100;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 Cell::getMinimumHeight()
+{
+ if( !mpProperties )
+ return 0;
+
+ SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
+ sal_Int32 nMinimumHeight = 0;
+
+ Rectangle aTextRect;
+ TakeTextAnchorRect( aTextRect );
+ Size aSize( aTextRect.GetSize() );
+ aSize.Height()=0x0FFFFFFF;
+
+ SdrOutliner* pEditOutliner = rTableObj.GetCellTextEditOutliner( *this );
+ if(pEditOutliner)
+ {
+ pEditOutliner->SetMaxAutoPaperSize(aSize);
+ nMinimumHeight = pEditOutliner->GetTextHeight()+1;
+ }
+ else /*if ( hasText() )*/
+ {
+ Outliner& rOutliner=rTableObj.ImpGetDrawOutliner();
+ rOutliner.SetPaperSize(aSize);
+ rOutliner.SetUpdateMode(TRUE);
+ ForceOutlinerParaObject( OUTLINERMODE_TEXTOBJECT );
+
+ if( GetOutlinerParaObject() )
+ {
+ rOutliner.SetText(*GetOutlinerParaObject());
+ }
+ nMinimumHeight=rOutliner.GetTextHeight()+1;
+ rOutliner.Clear();
+ }
+
+ nMinimumHeight += GetTextUpperDistance() + GetTextLowerDistance();
+ return nMinimumHeight;
+}
+
+// -----------------------------------------------------------------------------
+
+long Cell::GetTextLeftDistance() const
+{
+ return ((SdrTextLeftDistItem&)(GetItemSet().Get(SDRATTR_TEXT_LEFTDIST))).GetValue();
+}
+
+// -----------------------------------------------------------------------------
+
+long Cell::GetTextRightDistance() const
+{
+ return ((SdrTextRightDistItem&)(GetItemSet().Get(SDRATTR_TEXT_RIGHTDIST))).GetValue();
+}
+
+// -----------------------------------------------------------------------------
+
+long Cell::GetTextUpperDistance() const
+{
+ return ((SdrTextUpperDistItem&)(GetItemSet().Get(SDRATTR_TEXT_UPPERDIST))).GetValue();
+}
+
+// -----------------------------------------------------------------------------
+
+long Cell::GetTextLowerDistance() const
+{
+ return ((SdrTextLowerDistItem&)(GetItemSet().Get(SDRATTR_TEXT_LOWERDIST))).GetValue();
+}
+
+// -----------------------------------------------------------------------------
+
+SdrTextVertAdjust Cell::GetTextVerticalAdjust() const
+{
+ return ((SdrTextVertAdjustItem&)(GetItemSet().Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
+}
+
+// -----------------------------------------------------------------------------
+
+SdrTextHorzAdjust Cell::GetTextHorizontalAdjust() const
+{
+ return ((SdrTextHorzAdjustItem&)(GetItemSet().Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
+}
+
+// -----------------------------------------------------------------------------
+
+void Cell::SetOutlinerParaObject( OutlinerParaObject* pTextObject )
+{
+ SdrText::SetOutlinerParaObject( pTextObject );
+ maSelection.nStartPara = 0xffff;
+
+ if( pTextObject == 0 )
+ ForceOutlinerParaObject( OUTLINERMODE_TEXTOBJECT );
+}
+
+// -----------------------------------------------------------------------------
+
+void Cell::AddUndo()
+{
+ SdrObject& rObj = GetObject();
+ if( rObj.IsInserted() && GetModel() && GetModel()->IsUndoEnabled() )
+ {
+ CellRef xCell( this );
+ GetModel()->AddUndo( new CellUndo( &rObj, xCell ) );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sdr::properties::TextProperties* Cell::CloneProperties( sdr::properties::TextProperties* pProperties, SdrObject& rNewObj, Cell& rNewCell )
+{
+ if( pProperties )
+ return new sdr::properties::CellProperties( *static_cast<sdr::properties::CellProperties*>(pProperties), rNewObj, &rNewCell );
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+sdr::properties::TextProperties* Cell::CloneProperties( SdrObject& rNewObj, Cell& rNewCell )
+{
+ return CloneProperties(mpProperties,rNewObj,rNewCell);
+}
+
+// -----------------------------------------------------------------------------
+// XInterface
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL Cell::queryInterface( const Type & rType ) throw(RuntimeException)
+{
+ if( rType == XMergeableCell::static_type() )
+ return Any( Reference< XMergeableCell >( this ) );
+
+ if( rType == XCell::static_type() )
+ return Any( Reference< XCell >( this ) );
+
+ if( rType == XLayoutConstrains::static_type() )
+ return Any( Reference< XLayoutConstrains >( this ) );
+
+ if( rType == XEventListener::static_type() )
+ return Any( Reference< XEventListener >( this ) );
+
+ Any aRet( SvxUnoTextBase::queryAggregation( rType ) );
+ if( aRet.hasValue() )
+ return aRet;
+
+ return ::cppu::OWeakObject::queryInterface( rType );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::acquire() throw ()
+{
+ ::cppu::OWeakObject::acquire();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::release() throw ()
+{
+ ::cppu::OWeakObject::release();
+}
+
+// -----------------------------------------------------------------------------
+// XTypeProvider
+// -----------------------------------------------------------------------------
+
+Sequence< Type > SAL_CALL Cell::getTypes( ) throw (RuntimeException)
+{
+ Sequence< Type > aTypes( SvxUnoTextBase::getTypes() );
+
+ sal_Int32 nLen = aTypes.getLength();
+ aTypes.realloc(nLen + 2);
+ aTypes[nLen++] = XMergeableCell::static_type();
+ aTypes[nLen++] = XLayoutConstrains::static_type();
+
+ return aTypes;
+}
+
+// -----------------------------------------------------------------------------
+
+Sequence< sal_Int8 > SAL_CALL Cell::getImplementationId( ) throw (RuntimeException)
+{
+ static ::cppu::OImplementationId* pId = 0;
+ if (! pId)
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static ::cppu::OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+
+// -----------------------------------------------------------------------------
+// XServiceInfo
+// -----------------------------------------------------------------------------
+
+OUString SAL_CALL Cell::getImplementationName( ) throw (RuntimeException)
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svx.table.Cell" ) );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL Cell::supportsService( const OUString& ServiceName ) throw (RuntimeException)
+{
+ if( ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.table.cell" ) ) == 0 )
+ return sal_True;
+
+ if( ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.cell" ) ) == 0 )
+ return sal_True;
+
+ return SvxUnoTextBase::supportsService( ServiceName );
+}
+
+// -----------------------------------------------------------------------------
+
+Sequence< OUString > SAL_CALL Cell::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ Sequence< OUString > aSeq( SvxUnoTextBase::getSupportedServiceNames() );
+ sal_Int32 nIndex = aSeq.getLength();
+ aSeq.realloc( nIndex + 2 );
+ aSeq[nIndex++] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.table.cell" ) );
+ aSeq[nIndex++] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.cell" ) );
+ return aSeq;
+}
+
+// -----------------------------------------------------------------------------
+// XLayoutConstrains
+// -----------------------------------------------------------------------------
+
+::com::sun::star::awt::Size SAL_CALL Cell::getMinimumSize( ) throw (RuntimeException)
+{
+ return ::com::sun::star::awt::Size( getMinimumWidth(), getMinimumHeight() );
+}
+
+// -----------------------------------------------------------------------------
+
+::com::sun::star::awt::Size SAL_CALL Cell::getPreferredSize( ) throw (RuntimeException)
+{
+ return getMinimumSize();
+}
+
+// -----------------------------------------------------------------------------
+
+::com::sun::star::awt::Size SAL_CALL Cell::calcAdjustedSize( const ::com::sun::star::awt::Size& aNewSize ) throw (RuntimeException)
+{
+ return aNewSize;
+}
+
+// -----------------------------------------------------------------------------
+// XMergeableCell
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL Cell::getRowSpan() throw (RuntimeException)
+{
+ return mnRowSpan;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL Cell::getColumnSpan() throw (RuntimeException)
+{
+ return mnColSpan;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL Cell::isMerged() throw (RuntimeException)
+{
+ return mbMerged;
+}
+
+// -----------------------------------------------------------------------------
+// XCell
+// -----------------------------------------------------------------------------
+
+OUString SAL_CALL Cell::getFormula( ) throw (RuntimeException)
+{
+ return msFormula;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::setFormula( const OUString& aFormula ) throw (RuntimeException)
+{
+ if( msFormula != aFormula )
+ {
+ msFormula = aFormula;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+double SAL_CALL Cell::getValue( ) throw (RuntimeException)
+{
+ return mfValue;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::setValue( double nValue ) throw (RuntimeException)
+{
+ if( mfValue == nValue )
+ {
+ mfValue = nValue;
+ mnCellContentType = CellContentType_VALUE;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+CellContentType SAL_CALL Cell::getType() throw (RuntimeException)
+{
+ return mnCellContentType;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL Cell::getError( ) throw (RuntimeException)
+{
+ return mnError;
+}
+
+// -----------------------------------------------------------------------------
+// XPropertySet
+// -----------------------------------------------------------------------------
+
+Any Cell::GetAnyForItem( SfxItemSet& aSet, const SfxItemPropertySimpleEntry* pMap )
+{
+ Any aAny( SvxItemPropertySet_getPropertyValue( *mpPropSet, pMap, aSet ) );
+
+ if( *pMap->pType != aAny.getValueType() )
+ {
+ // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here
+ if( ( *pMap->pType == ::getCppuType((const sal_Int16*)0)) && aAny.getValueType() == ::getCppuType((const sal_Int32*)0) )
+ {
+ sal_Int32 nValue = 0;
+ aAny >>= nValue;
+ aAny <<= (sal_Int16)nValue;
+ }
+ else
+ {
+ DBG_ERROR("GetAnyForItem() Returnvalue has wrong Type!" );
+ }
+ }
+
+ return aAny;
+}
+
+Reference< XPropertySetInfo > SAL_CALL Cell::getPropertySetInfo() throw(RuntimeException)
+{
+ return mpPropSet->getPropertySetInfo();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::setPropertyValue( const OUString& rPropertyName, const Any& rValue ) throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( (mpProperties == 0) || (GetModel() == 0) )
+ throw DisposedException();
+
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(rPropertyName);
+ if( pMap )
+ {
+ if( (pMap->nFlags & PropertyAttribute::READONLY ) != 0 )
+ throw PropertyVetoException();
+
+ switch( pMap->nWID )
+ {
+ case OWN_ATTR_STYLE:
+ {
+ Reference< XStyle > xStyle;
+ if( !( rValue >>= xStyle ) )
+ throw IllegalArgumentException();
+
+ SfxUnoStyleSheet* pStyle = SfxUnoStyleSheet::getUnoStyleSheet(xStyle);
+ SetStyleSheet( pStyle, sal_True );
+ return;
+ }
+ case OWN_ATTR_TABLEBORDER:
+ {
+ if(rValue.getValueType() != ::getCppuType((const TableBorder*)0) )
+ break;
+
+ const TableBorder* pBorder = (const TableBorder* )rValue.getValue();
+ if( pBorder == NULL )
+ break;
+
+ SvxBoxItem aBox( SDRATTR_TABLE_BORDER );
+ SvxBoxInfoItem aBoxInfo( SDRATTR_TABLE_BORDER_INNER );
+ SvxBorderLine aLine;
+
+ sal_Bool bSet = SvxBoxItem::LineToSvxLine(pBorder->TopLine, aLine, false);
+ aBox.SetLine(bSet ? &aLine : 0, BOX_LINE_TOP);
+ aBoxInfo.SetValid(VALID_TOP, pBorder->IsTopLineValid);
+
+ bSet = SvxBoxItem::LineToSvxLine(pBorder->BottomLine, aLine, false);
+ aBox.SetLine(bSet ? &aLine : 0, BOX_LINE_BOTTOM);
+ aBoxInfo.SetValid(VALID_BOTTOM, pBorder->IsBottomLineValid);
+
+ bSet = SvxBoxItem::LineToSvxLine(pBorder->LeftLine, aLine, false);
+ aBox.SetLine(bSet ? &aLine : 0, BOX_LINE_LEFT);
+ aBoxInfo.SetValid(VALID_LEFT, pBorder->IsLeftLineValid);
+
+ bSet = SvxBoxItem::LineToSvxLine(pBorder->RightLine, aLine, false);
+ aBox.SetLine(bSet ? &aLine : 0, BOX_LINE_RIGHT);
+ aBoxInfo.SetValid(VALID_RIGHT, pBorder->IsRightLineValid);
+
+ bSet = SvxBoxItem::LineToSvxLine(pBorder->HorizontalLine, aLine, false);
+ aBoxInfo.SetLine(bSet ? &aLine : 0, BOXINFO_LINE_HORI);
+ aBoxInfo.SetValid(VALID_HORI, pBorder->IsHorizontalLineValid);
+
+ bSet = SvxBoxItem::LineToSvxLine(pBorder->VerticalLine, aLine, false);
+ aBoxInfo.SetLine(bSet ? &aLine : 0, BOXINFO_LINE_VERT);
+ aBoxInfo.SetValid(VALID_VERT, pBorder->IsVerticalLineValid);
+
+ aBox.SetDistance(pBorder->Distance, false);
+ aBoxInfo.SetValid(VALID_DISTANCE, pBorder->IsDistanceValid);
+
+ mpProperties->SetObjectItem(aBox);
+ mpProperties->SetObjectItem(aBoxInfo);
+ return;
+ }
+ case OWN_ATTR_FILLBMP_MODE:
+ {
+ BitmapMode eMode;
+ if(!(rValue >>= eMode) )
+ {
+ sal_Int32 nMode = 0;
+ if(!(rValue >>= nMode))
+ throw IllegalArgumentException();
+
+ eMode = (BitmapMode)nMode;
+ }
+
+ mpProperties->SetObjectItem( XFillBmpStretchItem( eMode == BitmapMode_STRETCH ) );
+ mpProperties->SetObjectItem( XFillBmpTileItem( eMode == BitmapMode_REPEAT ) );
+ return;
+ }
+ default:
+ {
+ SfxItemSet aSet( GetModel()->GetItemPool(), pMap->nWID, pMap->nWID);
+ aSet.Put(mpProperties->GetItem(pMap->nWID));
+
+ bool bSpecial = false;
+
+ switch( pMap->nWID )
+ {
+ case XATTR_FILLBITMAP:
+ case XATTR_FILLGRADIENT:
+ case XATTR_FILLHATCH:
+ case XATTR_FILLFLOATTRANSPARENCE:
+ case XATTR_LINEEND:
+ case XATTR_LINESTART:
+ case XATTR_LINEDASH:
+ {
+ if( pMap->nMemberId == MID_NAME )
+ {
+ OUString aApiName;
+ if( rValue >>= aApiName )
+ {
+ if( SvxShape::SetFillAttribute( pMap->nWID, aApiName, aSet, GetModel() ) )
+ bSpecial = true;
+ }
+ }
+ }
+ break;
+ }
+
+ if( !bSpecial )
+ {
+
+ if( !SvxUnoTextRangeBase::SetPropertyValueHelper( aSet, pMap, rValue, aSet ))
+ {
+ if( aSet.GetItemState( pMap->nWID ) != SFX_ITEM_SET )
+ {
+ // Default aus ItemPool holen
+ if(GetModel()->GetItemPool().IsWhich(pMap->nWID))
+ aSet.Put(GetModel()->GetItemPool().GetDefaultItem(pMap->nWID));
+ }
+
+ if( aSet.GetItemState( pMap->nWID ) == SFX_ITEM_SET )
+ {
+ SvxItemPropertySet_setPropertyValue( *mpPropSet, pMap, rValue, aSet );
+ }
+ }
+ }
+
+ GetModel()->SetChanged();
+ mpProperties->SetMergedItemSetAndBroadcast( aSet );
+ return;
+ }
+ }
+ }
+ throw UnknownPropertyException();
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL Cell::getPropertyValue( const OUString& PropertyName ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( (mpProperties == 0) || (GetModel() == 0) )
+ throw DisposedException();
+
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName);
+ if( pMap )
+ {
+ switch( pMap->nWID )
+ {
+/*
+ case OWN_ATTR_HASLEVELS:
+ {
+ return Any( hasLevels() );
+ }
+*/
+ case OWN_ATTR_STYLE:
+ {
+ return Any( Reference< XStyle >( dynamic_cast< SfxUnoStyleSheet* >( GetStyleSheet() ) ) );
+ }
+ case OWN_ATTR_TABLEBORDER:
+ {
+ const SvxBoxInfoItem& rBoxInfoItem = static_cast<const SvxBoxInfoItem&>(mpProperties->GetItem(SDRATTR_TABLE_BORDER_INNER));
+ const SvxBoxItem& rBox = static_cast<const SvxBoxItem&>(mpProperties->GetItem(SDRATTR_TABLE_BORDER));
+
+ TableBorder aTableBorder;
+ aTableBorder.TopLine = SvxBoxItem::SvxLineToLine(rBox.GetTop(), false);
+ aTableBorder.IsTopLineValid = rBoxInfoItem.IsValid(VALID_TOP);
+ aTableBorder.BottomLine = SvxBoxItem::SvxLineToLine(rBox.GetBottom(), false);
+ aTableBorder.IsBottomLineValid = rBoxInfoItem.IsValid(VALID_BOTTOM);
+ aTableBorder.LeftLine = SvxBoxItem::SvxLineToLine(rBox.GetLeft(), false);
+ aTableBorder.IsLeftLineValid = rBoxInfoItem.IsValid(VALID_LEFT);
+ aTableBorder.RightLine = SvxBoxItem::SvxLineToLine(rBox.GetRight(), false);
+ aTableBorder.IsRightLineValid = rBoxInfoItem.IsValid(VALID_RIGHT );
+ aTableBorder.HorizontalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetHori(), false);
+ aTableBorder.IsHorizontalLineValid = rBoxInfoItem.IsValid(VALID_HORI);
+ aTableBorder.VerticalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetVert(), false);
+ aTableBorder.IsVerticalLineValid = rBoxInfoItem.IsValid(VALID_VERT);
+ aTableBorder.Distance = rBox.GetDistance();
+ aTableBorder.IsDistanceValid = rBoxInfoItem.IsValid(VALID_DISTANCE);
+
+ return Any( aTableBorder );
+ }
+ case OWN_ATTR_FILLBMP_MODE:
+ {
+ const XFillBmpStretchItem& rStretchItem = static_cast<const XFillBmpStretchItem&>(mpProperties->GetItem(XATTR_FILLBMP_STRETCH));
+ const XFillBmpTileItem& rTileItem = static_cast<const XFillBmpTileItem&>(mpProperties->GetItem(XATTR_FILLBMP_TILE));
+ if( rTileItem.GetValue() )
+ {
+ return Any( BitmapMode_REPEAT );
+ }
+ else if( rStretchItem.GetValue() )
+ {
+ return Any( BitmapMode_STRETCH );
+ }
+ else
+ {
+ return Any( BitmapMode_NO_REPEAT );
+ }
+ }
+ default:
+ {
+ SfxItemSet aSet( GetModel()->GetItemPool(), pMap->nWID, pMap->nWID);
+ aSet.Put(mpProperties->GetItem(pMap->nWID));
+
+ Any aAny;
+ if(!SvxUnoTextRangeBase::GetPropertyValueHelper( aSet, pMap, aAny ))
+ {
+ if(!aSet.Count())
+ {
+ // Default aus ItemPool holen
+ if(GetModel()->GetItemPool().IsWhich(pMap->nWID))
+ aSet.Put(GetModel()->GetItemPool().GetDefaultItem(pMap->nWID));
+ }
+
+ if( aSet.Count() )
+ aAny = GetAnyForItem( aSet, pMap );
+ }
+
+ return aAny;
+ }
+ }
+ }
+ throw UnknownPropertyException();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::addPropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::removePropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*aListener*/ ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::addVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::removeVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+// XMultiPropertySet
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::setPropertyValues( const Sequence< OUString >& aPropertyNames, const Sequence< Any >& aValues ) throw (PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ if( (mpProperties == 0) || (GetModel() == 0) )
+ throw DisposedException();
+
+ const sal_Int32 nCount = aPropertyNames.getLength();
+
+ const OUString* pNames = aPropertyNames.getConstArray();
+ const Any* pValues = aValues.getConstArray();
+
+ for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pNames++, pValues++ )
+ {
+ try
+ {
+ setPropertyValue( *pNames, *pValues );
+ }
+ catch( UnknownPropertyException& )
+ {
+ DBG_ERROR("svx::Cell::setPropertyValues(), unknown property!" );
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("svx::Cell::setPropertyValues(), Exception caught!" );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+Sequence< Any > SAL_CALL Cell::getPropertyValues( const Sequence< OUString >& aPropertyNames ) throw (RuntimeException)
+{
+ OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ if( (mpProperties == 0) || (GetModel() == 0) )
+ throw DisposedException();
+
+ const sal_Int32 nCount = aPropertyNames.getLength();
+ const OUString* pNames = aPropertyNames.getConstArray();
+
+ Sequence< Any > aRet( nCount );
+ Any* pValue = aRet.getArray();
+
+ for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pValue++, pNames++ )
+ {
+ try
+ {
+ *pValue = getPropertyValue( *pNames );
+ }
+ catch( UnknownPropertyException& )
+ {
+ DBG_ERROR("svx::Cell::setPropertyValues(), unknown property!" );
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR( "svx::Cell::getPropertyValues(), Exception caught!" );
+ }
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::addPropertiesChangeListener( const Sequence< OUString >& /*aPropertyNames*/, const Reference< XPropertiesChangeListener >& /*xListener*/ ) throw (RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& /*xListener*/ ) throw (RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::firePropertiesChangeEvent( const Sequence< OUString >& /*aPropertyNames*/, const Reference< XPropertiesChangeListener >& /*xListener*/ ) throw (RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+// XPropertyState
+// -----------------------------------------------------------------------------
+
+PropertyState SAL_CALL Cell::getPropertyState( const OUString& PropertyName ) throw(UnknownPropertyException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( (mpProperties == 0) || (GetModel() == 0) )
+ throw DisposedException();
+
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName);
+
+ if( pMap )
+ {
+ PropertyState eState;
+ switch( pMap->nWID )
+ {
+ case OWN_ATTR_FILLBMP_MODE:
+ {
+ const SfxItemSet& rSet = mpProperties->GetMergedItemSet();
+
+ const bool bStretch = rSet.GetItemState( XATTR_FILLBMP_STRETCH, false ) == SFX_ITEM_SET;
+ const bool bTile = rSet.GetItemState( XATTR_FILLBMP_TILE, false ) == SFX_ITEM_SET;
+ if( bStretch || bTile )
+ {
+ eState = PropertyState_DIRECT_VALUE;
+ }
+ else
+ {
+ eState = PropertyState_DEFAULT_VALUE;
+ }
+ }
+/*
+ case OWN_ATTR_HASLEVELS:
+ {
+ return PropertyState_DIRECT_VALUE;
+ }
+*/
+ case OWN_ATTR_STYLE:
+ {
+ return PropertyState_DIRECT_VALUE;
+ }
+ case OWN_ATTR_TABLEBORDER:
+ {
+ const SfxItemSet& rSet = mpProperties->GetMergedItemSet();
+ if( (rSet.GetItemState( SDRATTR_TABLE_BORDER_INNER, sal_False ) == SFX_ITEM_DEFAULT) && (rSet.GetItemState( SDRATTR_TABLE_BORDER, sal_False ) == SFX_ITEM_DEFAULT) )
+ return PropertyState_DEFAULT_VALUE;
+
+ return PropertyState_DIRECT_VALUE;
+ }
+ default:
+ {
+ const SfxItemSet& rSet = mpProperties->GetMergedItemSet();
+
+ switch( rSet.GetItemState( pMap->nWID, sal_False ) )
+ {
+ case SFX_ITEM_READONLY:
+ case SFX_ITEM_SET:
+ eState = PropertyState_DIRECT_VALUE;
+ break;
+ case SFX_ITEM_DEFAULT:
+ eState = PropertyState_DEFAULT_VALUE;
+ break;
+ // case SFX_ITEM_UNKNOWN:
+ // case SFX_ITEM_DONTCARE:
+ // case SFX_ITEM_DISABLED:
+ default:
+ eState = PropertyState_AMBIGUOUS_VALUE;
+ break;
+ }
+
+ // if a item is set, this doesn't mean we want it :)
+ if( ( PropertyState_DIRECT_VALUE == eState ) )
+ {
+ switch( pMap->nWID )
+ {
+ // the following items are disabled by changing the
+ // fill style or the line style. so there is no need
+ // to export items without names which should be empty
+ case XATTR_FILLBITMAP:
+ case XATTR_FILLGRADIENT:
+ case XATTR_FILLHATCH:
+ case XATTR_LINEDASH:
+ {
+ NameOrIndex* pItem = (NameOrIndex*)rSet.GetItem((USHORT)pMap->nWID);
+ if( ( pItem == NULL ) || ( pItem->GetName().Len() == 0) )
+ eState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+
+ // #i36115#
+ // If e.g. the LineStart is on NONE and thus the string has length 0, it still
+ // may be a hard attribute covering the set LineStart of the parent (Style).
+ // #i37644#
+ // same is for fill float transparency
+ case XATTR_LINEEND:
+ case XATTR_LINESTART:
+ case XATTR_FILLFLOATTRANSPARENCE:
+ {
+ NameOrIndex* pItem = (NameOrIndex*)rSet.GetItem((USHORT)pMap->nWID);
+ if( ( pItem == NULL ) )
+ eState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+ }
+ }
+ }
+ }
+ return eState;
+ }
+ throw UnknownPropertyException();
+}
+
+// -----------------------------------------------------------------------------
+
+Sequence< PropertyState > SAL_CALL Cell::getPropertyStates( const Sequence< OUString >& aPropertyName ) throw(UnknownPropertyException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( (mpProperties == 0) || (GetModel() == 0) )
+ throw DisposedException();
+
+ const sal_Int32 nCount = aPropertyName.getLength();
+
+ Sequence< PropertyState > aRet( nCount );
+
+ const OUString* pNames = aPropertyName.getConstArray();
+ PropertyState* pState = aRet.getArray();
+
+ for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pNames++, pState++ )
+ {
+ try
+ {
+ *pState = getPropertyState( *pNames );
+ }
+ catch( Exception& )
+ {
+ *pState = PropertyState_AMBIGUOUS_VALUE;
+ }
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::setPropertyToDefault( const OUString& PropertyName ) throw(UnknownPropertyException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( (mpProperties == 0) || (GetModel() == 0) )
+ throw DisposedException();
+
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName);
+ if( pMap )
+ {
+ switch( pMap->nWID )
+ {
+ case OWN_ATTR_FILLBMP_MODE:
+ {
+ mpProperties->ClearObjectItem( XATTR_FILLBMP_STRETCH );
+ mpProperties->ClearObjectItem( XATTR_FILLBMP_TILE );
+ break;
+ }
+// case OWN_ATTR_HASLEVELS:
+ case OWN_ATTR_STYLE:
+ break;
+
+ case OWN_ATTR_TABLEBORDER:
+ {
+ mpProperties->ClearObjectItem( SDRATTR_TABLE_BORDER_INNER );
+ mpProperties->ClearObjectItem( SDRATTR_TABLE_BORDER );
+ break;
+ }
+
+ default:
+ {
+ mpProperties->ClearObjectItem( pMap->nWID );
+ }
+ }
+
+ GetModel()->SetChanged();
+ return;
+ }
+ throw UnknownPropertyException();
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL Cell::getPropertyDefault( const OUString& aPropertyName ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( (mpProperties == 0) || (GetModel() == 0) )
+ throw DisposedException();
+
+ const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(aPropertyName);
+ if( pMap )
+ {
+ switch( pMap->nWID )
+ {
+ case OWN_ATTR_FILLBMP_MODE:
+ return Any( BitmapMode_NO_REPEAT );
+
+/*
+ case OWN_ATTR_HASLEVELS:
+ return Any( sal_False );
+*/
+ case OWN_ATTR_STYLE:
+ {
+ Reference< XStyle > xStyle;
+ return Any( xStyle );
+ }
+
+ case OWN_ATTR_TABLEBORDER:
+ {
+ TableBorder aBorder;
+ return Any( aBorder );
+ }
+
+ default:
+ {
+ if( GetModel()->GetItemPool().IsWhich(pMap->nWID) )
+ {
+ SfxItemSet aSet( GetModel()->GetItemPool(), pMap->nWID, pMap->nWID);
+ aSet.Put(GetModel()->GetItemPool().GetDefaultItem(pMap->nWID));
+ return GetAnyForItem( aSet, pMap );
+ }
+ }
+ }
+ }
+ throw UnknownPropertyException();
+}
+
+// -----------------------------------------------------------------------------
+// XMultiPropertyStates
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::setAllPropertiesToDefault( ) throw (RuntimeException)
+{
+ if( mpProperties )
+ delete mpProperties;
+ mpProperties = new sdr::properties::CellProperties( static_cast< SdrTableObj& >( GetObject() ), this );
+
+ SdrOutliner& rOutliner = GetObject().ImpGetDrawOutliner();
+
+ OutlinerParaObject* pParaObj = GetOutlinerParaObject();
+ if( pParaObj )
+ {
+ rOutliner.SetText(*pParaObj);
+ sal_uInt32 nParaCount(rOutliner.GetParagraphCount());
+
+ if(nParaCount)
+ {
+ ESelection aSelection( 0, 0, EE_PARA_ALL, EE_PARA_ALL);
+ rOutliner.RemoveAttribs(aSelection, sal_True, 0);
+
+ OutlinerParaObject* pTemp = rOutliner.CreateParaObject(0, (sal_uInt16)nParaCount);
+ rOutliner.Clear();
+
+ SetOutlinerParaObject(pTemp);
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::setPropertiesToDefault( const Sequence< OUString >& aPropertyNames ) throw (UnknownPropertyException, RuntimeException)
+{
+ sal_Int32 nCount = aPropertyNames.getLength();
+ const OUString* pName = aPropertyNames.getConstArray();
+
+ while(nCount--)
+ setPropertyToDefault( *pName++ );
+}
+
+// -----------------------------------------------------------------------------
+
+Sequence< Any > SAL_CALL Cell::getPropertyDefaults( const Sequence< OUString >& aPropertyNames ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ sal_Int32 nCount = aPropertyNames.getLength();
+ Sequence< Any > aDefaults( nCount );
+ Any* pDefaults = aDefaults.getArray();
+ const OUString* pName = aPropertyNames.getConstArray();
+
+ while(nCount--)
+ *pDefaults++ = getPropertyDefault( *pName++ );
+
+ return aDefaults;
+}
+
+// -----------------------------------------------------------------------------
+// XFastPropertySet
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::setFastPropertyValue( sal_Int32 nHandle, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ (void)aValue;
+ (void)nHandle;
+ throw UnknownPropertyException();
+}
+
+// -----------------------------------------------------------------------------
+// TODO: Refactor this method!
+Any SAL_CALL Cell::getFastPropertyValue( sal_Int32 nHandle ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ (void)nHandle;
+ throw UnknownPropertyException();
+}
+
+// -----------------------------------------------------------------------------
+// XText
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::insertTextContent( const Reference< XTextRange >& xRange, const Reference< XTextContent >& xContent, sal_Bool bAbsorb ) throw (IllegalArgumentException, RuntimeException)
+{
+ SvxUnoTextBase::insertTextContent( xRange, xContent, bAbsorb );
+ notifyModified();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::removeTextContent( const Reference< XTextContent >& xContent ) throw (NoSuchElementException, RuntimeException)
+{
+ SvxUnoTextBase::removeTextContent( xContent );
+ notifyModified();
+}
+
+// -----------------------------------------------------------------------------
+// XSimpleText
+// -----------------------------------------------------------------------------
+
+Reference< XTextCursor > SAL_CALL Cell::createTextCursor( ) throw (RuntimeException)
+{
+ return SvxUnoTextBase::createTextCursor();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XTextCursor > SAL_CALL Cell::createTextCursorByRange( const Reference< XTextRange >& aTextPosition ) throw (RuntimeException)
+{
+ return SvxUnoTextBase::createTextCursorByRange( aTextPosition );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::insertString( const Reference< XTextRange >& xRange, const OUString& aString, sal_Bool bAbsorb ) throw (RuntimeException)
+{
+ SvxUnoTextBase::insertString( xRange, aString, bAbsorb );
+ notifyModified();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::insertControlCharacter( const Reference< XTextRange >& xRange, sal_Int16 nControlCharacter, sal_Bool bAbsorb ) throw (IllegalArgumentException, RuntimeException)
+{
+ SvxUnoTextBase::insertControlCharacter( xRange, nControlCharacter, bAbsorb );
+ notifyModified();
+}
+
+// -----------------------------------------------------------------------------
+// XTextRange
+// -----------------------------------------------------------------------------
+
+Reference< XText > SAL_CALL Cell::getText( ) throw (RuntimeException)
+{
+ return SvxUnoTextBase::getText();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XTextRange > SAL_CALL Cell::getStart( ) throw (RuntimeException)
+{
+ return SvxUnoTextBase::getStart();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XTextRange > SAL_CALL Cell::getEnd( ) throw (RuntimeException)
+{
+ return SvxUnoTextBase::getEnd();
+}
+
+// -----------------------------------------------------------------------------
+
+OUString SAL_CALL Cell::getString( ) throw (RuntimeException)
+{
+ maSelection.nStartPara = 0xffff;
+ return SvxUnoTextBase::getString();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL Cell::setString( const OUString& aString ) throw (RuntimeException)
+{
+ SvxUnoTextBase::setString( aString );
+ notifyModified();
+}
+
+// XEventListener
+void SAL_CALL Cell::disposing( const EventObject& /*Source*/ ) throw (RuntimeException)
+{
+ mxTable.clear();
+ dispose();
+}
+
+static OUString getCellName( sal_Int32 nCol, sal_Int32 nRow )
+{
+ rtl::OUStringBuffer aBuf;
+
+ if (nCol < 26*26)
+ {
+ if (nCol < 26)
+ aBuf.append( static_cast<sal_Unicode>( 'A' +
+ static_cast<sal_uInt16>(nCol)));
+ else
+ {
+ aBuf.append( static_cast<sal_Unicode>( 'A' +
+ (static_cast<sal_uInt16>(nCol) / 26) - 1));
+ aBuf.append( static_cast<sal_Unicode>( 'A' +
+ (static_cast<sal_uInt16>(nCol) % 26)));
+ }
+ }
+ else
+ {
+ String aStr;
+ while (nCol >= 26)
+ {
+ sal_Int32 nC = nCol % 26;
+ aStr += static_cast<sal_Unicode>( 'A' +
+ static_cast<sal_uInt16>(nC));
+ nCol = nCol - nC;
+ nCol = nCol / 26 - 1;
+ }
+ aStr += static_cast<sal_Unicode>( 'A' +
+ static_cast<sal_uInt16>(nCol));
+ aStr.Reverse();
+ aBuf.append( aStr);
+ }
+ aBuf.append( OUString::valueOf(nRow+1) );
+ return aBuf.makeStringAndClear();
+}
+
+OUString Cell::getName()
+{
+ // todo: optimize!
+ OUString sName;
+ if( mxTable.is() ) try
+ {
+ Reference< XCell > xThis( static_cast< XCell* >( this ) );
+
+ sal_Int32 nRowCount = mxTable->getRowCount();
+ sal_Int32 nColCount = mxTable->getColumnCount();
+ for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
+ {
+ for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ )
+ {
+ Reference< XCell > xCell( mxTable->getCellByPosition( nCol, nRow ) );
+ if( xCell == xThis )
+ {
+ return getCellName( nCol, nRow );
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ return sName;
+}
+
+} }
+
diff --git a/svx/source/table/cell.hxx b/svx/source/table/cell.hxx
new file mode 100644
index 000000000000..9bd2e9440d8c
--- /dev/null
+++ b/svx/source/table/cell.hxx
@@ -0,0 +1,244 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_CELL_HXX_
+#define _SVX_CELL_HXX_
+
+#include <com/sun/star/table/XMergeableCell.hpp>
+#include <com/sun/star/awt/XLayoutConstrains.hpp>
+#include <com/sun/star/beans/XMultiPropertyStates.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+
+#include <rtl/ref.hxx>
+#include <svl/style.hxx>
+#include "svx/sdtaitm.hxx"
+#include "tablemodel.hxx"
+#include "editeng/unotext.hxx"
+#include "svx/svdtext.hxx"
+
+// -----------------------------------------------------------------------------
+
+class SfxItemSet;
+class OutlinerParaObject;
+class SdrObject;
+
+namespace sdr { namespace properties {
+ class TextProperties;
+} }
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+// -----------------------------------------------------------------------------
+
+class SVX_DLLPUBLIC Cell : public SdrText,
+ public SvxUnoTextBase,
+ public ::com::sun::star::table::XMergeableCell,
+ public ::com::sun::star::awt::XLayoutConstrains,
+ public ::com::sun::star::lang::XEventListener,
+ public ::cppu::OWeakObject
+{
+ friend class CellUndo;
+
+public:
+ SVX_DLLPRIVATE static rtl::Reference< Cell > create( SdrTableObj& rTableObj, OutlinerParaObject* pOutlinerParaObject );
+
+ // private
+ SVX_DLLPRIVATE void dispose();
+
+ // SdrTextShape proxy
+ bool IsTextEditActive();
+ SVX_DLLPRIVATE bool hasText() const;
+
+ SVX_DLLPRIVATE void cloneFrom( const CellRef& rCell );
+
+ SVX_DLLPRIVATE void setCellRect( ::Rectangle& rCellRect ) { maCellRect = rCellRect; }
+ SVX_DLLPRIVATE const ::Rectangle& getCellRect() const { return maCellRect; }
+ SVX_DLLPRIVATE ::Rectangle& getCellRect() { return maCellRect; }
+
+ OutlinerParaObject* GetEditOutlinerParaObject() const;
+ SVX_DLLPRIVATE void SetStyleSheet( SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr );
+ SVX_DLLPRIVATE virtual SfxStyleSheet* GetStyleSheet() const;
+ SfxStyleSheetPool* GetStyleSheetPool() const;
+ SVX_DLLPRIVATE virtual const Rectangle& GetCurrentBoundRect() const;
+ SVX_DLLPRIVATE virtual void TakeTextAnchorRect(Rectangle& rAnchorRect) const;
+
+ SVX_DLLPRIVATE virtual const SfxItemSet& GetItemSet() const;
+ SVX_DLLPRIVATE void SetMergedItemSetAndBroadcast(const SfxItemSet& rSet, sal_Bool bClearAllItems);
+ void SetMergedItem(const SfxPoolItem& rItem);
+
+ SVX_DLLPRIVATE sal_Int32 getMinimumWidth();
+ SVX_DLLPRIVATE sal_Int32 getMinimumHeight();
+
+ SVX_DLLPRIVATE long GetTextLeftDistance() const;
+ SVX_DLLPRIVATE long GetTextRightDistance() const;
+ SVX_DLLPRIVATE long GetTextUpperDistance() const;
+ SVX_DLLPRIVATE long GetTextLowerDistance() const;
+
+ SVX_DLLPRIVATE SdrTextVertAdjust GetTextVerticalAdjust() const;
+ SdrTextHorzAdjust GetTextHorizontalAdjust() const;
+
+ SVX_DLLPRIVATE virtual void SetModel(SdrModel* pNewModel);
+
+ SVX_DLLPRIVATE void merge( sal_Int32 nColumnSpan, sal_Int32 nRowSpan );
+ SVX_DLLPRIVATE void mergeContent( const CellRef& xSourceCell );
+ SVX_DLLPRIVATE void replaceContentAndFormating( const CellRef& xSourceCell );
+
+ SVX_DLLPRIVATE void setMerged();
+
+ // XInterface
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& Type ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL acquire() throw ();
+ SVX_DLLPRIVATE virtual void SAL_CALL release() throw ();
+
+ // XTypeProvider
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL getImplementationId( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ SVX_DLLPRIVATE virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XLayoutConstrains
+ SVX_DLLPRIVATE virtual ::com::sun::star::awt::Size SAL_CALL getMinimumSize( ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::awt::Size SAL_CALL getPreferredSize( ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::awt::Size SAL_CALL calcAdjustedSize( const ::com::sun::star::awt::Size& aNewSize ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XMergeableCell
+ SVX_DLLPRIVATE virtual ::sal_Int32 SAL_CALL getRowSpan() throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::sal_Int32 SAL_CALL getColumnSpan() throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::sal_Bool SAL_CALL isMerged() throw (::com::sun::star::uno::RuntimeException);
+
+ // XCell
+ SVX_DLLPRIVATE virtual ::rtl::OUString SAL_CALL getFormula() throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL setFormula( const ::rtl::OUString& aFormula ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual double SAL_CALL getValue() throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL setValue( double nValue ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::table::CellContentType SAL_CALL getType() throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual sal_Int32 SAL_CALL getError() throw (::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::beans::XPropertySet
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XMultiPropertySet
+ SVX_DLLPRIVATE virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aValues ) throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL getPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL addPropertiesChangeListener( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL removePropertiesChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL firePropertiesChangeEvent( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::beans::XPropertyState
+ SVX_DLLPRIVATE virtual ::com::sun::star::beans::PropertyState SAL_CALL getPropertyState( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > SAL_CALL getPropertyStates( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL setPropertyToDefault( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Any SAL_CALL getPropertyDefault( const ::rtl::OUString& aPropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XMultiPropertyStates
+ SVX_DLLPRIVATE virtual void SAL_CALL setAllPropertiesToDefault( ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL setPropertiesToDefault( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL getPropertyDefaults( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XFastPropertySet
+ SVX_DLLPRIVATE virtual void SAL_CALL setFastPropertyValue( ::sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue( ::sal_Int32 nHandle ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XText
+ SVX_DLLPRIVATE virtual void SAL_CALL insertTextContent( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >& xRange, const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent >& xContent, ::sal_Bool bAbsorb ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL removeTextContent( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent >& xContent ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
+
+ // XSimpleText
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextCursor > SAL_CALL createTextCursor( ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextCursor > SAL_CALL createTextCursorByRange( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >& aTextPosition ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL insertString( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >& xRange, const ::rtl::OUString& aString, ::sal_Bool bAbsorb ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL insertControlCharacter( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >& xRange, ::sal_Int16 nControlCharacter, ::sal_Bool bAbsorb ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ // XTextRange
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XText > SAL_CALL getText( ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL getStart( ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL getEnd( ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual ::rtl::OUString SAL_CALL getString( ) throw (::com::sun::star::uno::RuntimeException);
+ SVX_DLLPRIVATE virtual void SAL_CALL setString( const ::rtl::OUString& aString ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ SVX_DLLPRIVATE virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+
+ SVX_DLLPRIVATE virtual void SetOutlinerParaObject( OutlinerParaObject* pTextObject );
+
+ SVX_DLLPRIVATE void AddUndo();
+
+ using SvxUnoTextRangeBase::setPropertyValue;
+ using SvxUnoTextRangeBase::getPropertyValue;
+
+ SVX_DLLPRIVATE sdr::properties::TextProperties* CloneProperties( SdrObject& rNewObj, Cell& rNewCell );
+
+ SVX_DLLPRIVATE static sdr::properties::TextProperties* CloneProperties( sdr::properties::TextProperties* pProperties, SdrObject& rNewObj, Cell& rNewCell );
+
+ SVX_DLLPRIVATE void notifyModified();
+
+ ::rtl::OUString getName();
+
+protected:
+ SVX_DLLPRIVATE virtual const SfxItemSet& GetObjectItemSet();
+ SVX_DLLPRIVATE virtual void SetObjectItem(const SfxPoolItem& rItem);
+
+ SVX_DLLPRIVATE ::com::sun::star::uno::Any GetAnyForItem( SfxItemSet& aSet, const SfxItemPropertySimpleEntry* pMap );
+
+private:
+ SVX_DLLPRIVATE Cell( SdrTableObj& rTableObj, OutlinerParaObject* pOutlinerParaObject ) throw();
+ SVX_DLLPRIVATE virtual ~Cell() throw();
+
+ const SvxItemPropertySet* mpPropSet;
+
+ sdr::properties::TextProperties* mpProperties;
+
+ ::com::sun::star::table::CellContentType mnCellContentType;
+
+ ::rtl::OUString msFormula;
+ double mfValue;
+ ::sal_Int32 mnError;
+ ::sal_Bool mbMerged;
+ ::sal_Int32 mnRowSpan;
+ ::sal_Int32 mnColSpan;
+
+ Rectangle maCellRect;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XTable > mxTable;
+};
+
+// -----------------------------------------------------------------------------
+
+} }
+
+#endif
diff --git a/svx/source/table/cellcursor.cxx b/svx/source/table/cellcursor.cxx
new file mode 100644
index 000000000000..70329213d01a
--- /dev/null
+++ b/svx/source/table/cellcursor.cxx
@@ -0,0 +1,590 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "svx/svdotable.hxx"
+#include "cellcursor.hxx"
+#include "tablelayouter.hxx"
+#include "cell.hxx"
+#include "svx/svdmodel.hxx"
+#include "svdstr.hrc"
+#include "svdglob.hxx"
+
+// -----------------------------------------------------------------------------
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::table;
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+// -----------------------------------------------------------------------------
+// CellCursor
+// -----------------------------------------------------------------------------
+
+CellCursor::CellCursor( const TableModelRef & xTable, sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom )
+: CellCursorBase( xTable, nLeft, nTop, nRight, nBottom )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+CellCursor::~CellCursor()
+{
+}
+
+// -----------------------------------------------------------------------------
+// XCellCursor
+// -----------------------------------------------------------------------------
+
+Reference< XCell > SAL_CALL CellCursor::getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ return CellRange::getCellByPosition( nColumn, nRow );
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XCellRange > SAL_CALL CellCursor::getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ return CellRange::getCellRangeByPosition( nLeft, nTop, nRight, nBottom );
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XCellRange > SAL_CALL CellCursor::getCellRangeByName( const OUString& aRange ) throw (RuntimeException)
+{
+ return CellRange::getCellRangeByName( aRange );
+}
+
+// -----------------------------------------------------------------------------
+// XCellCursor
+// -----------------------------------------------------------------------------
+
+void SAL_CALL CellCursor::gotoStart( ) throw (RuntimeException)
+{
+ mnRight = mnLeft;
+ mnBottom = mnTop;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL CellCursor::gotoEnd( ) throw (RuntimeException)
+{
+ mnLeft = mnRight;
+ mnTop = mnBottom;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL CellCursor::gotoNext( ) throw (RuntimeException)
+{
+ if( mxTable.is() )
+ {
+ mnRight++;
+ if( mnRight >= mxTable->getColumnCount() )
+ {
+ // if we past the last column, try skip to the row line
+ mnTop++;
+ if( mnTop >= mxTable->getRowCount() )
+ {
+ // if we past the last row, do not move cursor at all
+ mnTop--;
+ mnRight--;
+ }
+ else
+ {
+ // restart at the first column on the next row
+ mnRight = 0;
+ }
+ }
+ }
+
+ mnLeft = mnRight;
+ mnTop = mnBottom;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL CellCursor::gotoPrevious( ) throw (RuntimeException)
+{
+ if( mxTable.is() )
+ {
+ if( mnLeft > 0 )
+ {
+ --mnLeft;
+ }
+ else if( mnTop > 0 )
+ {
+ --mnTop;
+ mnLeft = mxTable->getColumnCount() - 1;
+ }
+ }
+
+ mnRight = mnLeft;
+ mnBottom = mnTop;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL CellCursor::gotoOffset( ::sal_Int32 nColumnOffset, ::sal_Int32 nRowOffset ) throw (RuntimeException)
+{
+ if( mxTable.is() )
+ {
+ const sal_Int32 nLeft = mnLeft + nColumnOffset;
+ if( (nLeft >= 0) && (nLeft < mxTable->getColumnCount() ) )
+ mnRight = mnLeft = nLeft;
+
+ const sal_Int32 nTop = mnTop + nRowOffset;
+ if( (nTop >= 0) && (nTop < mxTable->getRowCount()) )
+ mnTop = mnBottom = nTop;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// XMergeableCellCursor
+// -----------------------------------------------------------------------------
+
+/** returns true and the merged cell positions if a merge is valid or false if a merge is
+ not valid for that range */
+bool CellCursor::GetMergedSelection( CellPos& rStart, CellPos& rEnd )
+{
+ rStart.mnCol = mnLeft; rStart.mnRow = mnTop;
+ rEnd.mnCol = mnRight; rEnd.mnRow = mnBottom;
+
+ // single cell merge is never valid
+ if( mxTable.is() && ((mnLeft != mnRight) || (mnTop != mnBottom)) ) try
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( mnLeft, mnTop ).get() ) );
+
+ // check if first cell is merged
+ if( xCell.is() && xCell->isMerged() )
+ findMergeOrigin( mxTable, mnLeft, mnTop, rStart.mnCol, rStart.mnRow );
+
+ // check if last cell is merged
+ xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( mnRight, mnBottom ).get() ) );
+ if( xCell.is() )
+ {
+ if( xCell->isMerged() )
+ {
+ findMergeOrigin( mxTable, mnRight, mnBottom, rEnd.mnCol, rEnd.mnRow );
+ // merge not possible if selection is only one cell and all its merges
+ if( rEnd == rStart )
+ return false;
+ xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( rEnd.mnCol, rEnd.mnRow ).get() ) );
+ }
+ }
+ if( xCell.is() )
+ {
+ rEnd.mnCol += xCell->getColumnSpan()-1;
+ rEnd.mnRow += xCell->getRowSpan()-1;
+ }
+
+ // now check if everything is inside the given bounds
+ sal_Int32 nRow, nCol;
+ for( nRow = rStart.mnRow; nRow <= rEnd.mnRow; nRow++ )
+ {
+ for( nCol = rStart.mnCol; nCol <= rEnd.mnCol; nCol++ )
+ {
+ xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( !xCell.is() )
+ continue;
+
+ if( xCell->isMerged() )
+ {
+ sal_Int32 nOriginCol, nOriginRow;
+ if( findMergeOrigin( mxTable, nCol, nRow, nOriginCol, nOriginRow ) )
+ {
+ if( (nOriginCol < rStart.mnCol) || (nOriginRow < rStart.mnRow) )
+ return false;
+
+ xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( nOriginCol, nOriginRow ).get() ) );
+ if( xCell.is() )
+ {
+ nOriginCol += xCell->getColumnSpan()-1;
+ nOriginRow += xCell->getRowSpan()-1;
+
+ if( (nOriginCol > rEnd.mnCol) || (nOriginRow > rEnd.mnRow) )
+ return false;
+ }
+ }
+ }
+ else if( ((nCol + xCell->getColumnSpan() - 1) > rEnd.mnCol) || ((nRow + xCell->getRowSpan() - 1 ) > rEnd.mnRow) )
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("sdr::table::SvmxTableController::GetMergedSelection(), exception caught!");
+ }
+ return false;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL CellCursor::merge( ) throw (NoSupportException, RuntimeException)
+{
+ CellPos aStart, aEnd;
+ if( !GetMergedSelection( aStart, aEnd ) )
+ throw NoSupportException();
+
+ if( !mxTable.is() || (mxTable->getSdrTableObj() == 0) )
+ throw DisposedException();
+
+ SdrModel* pModel = mxTable->getSdrTableObj()->GetModel();
+ const bool bUndo = pModel && mxTable->getSdrTableObj()->IsInserted() && pModel->IsUndoEnabled();
+
+ if( bUndo )
+ pModel->BegUndo( ImpGetResStr(STR_TABLE_MERGE) );
+
+ try
+ {
+ mxTable->merge( aStart.mnCol, aStart.mnRow, aEnd.mnCol - aStart.mnCol + 1, aEnd.mnRow - aStart.mnRow + 1 );
+ mxTable->optimize();
+ mxTable->setModified(sal_True);
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("sdr::table::CellCursor::merge(), exception caught!");
+ }
+
+ if( bUndo )
+ pModel->EndUndo();
+
+ if( pModel )
+ pModel->SetChanged();
+}
+
+// -----------------------------------------------------------------------------
+
+void CellCursor::split_column( sal_Int32 nCol, sal_Int32 nColumns, std::vector< sal_Int32 >& rLeftOvers )
+{
+ const sal_Int32 nRowCount = mxTable->getRowCount();
+
+ sal_Int32 nNewCols = 0, nRow;
+
+ // first check how many columns we need to add
+ for( nRow = mnTop; nRow <= mnBottom; ++nRow )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( xCell.is() && !xCell->isMerged() )
+ nNewCols = std::max( nNewCols, nColumns - xCell->getColumnSpan() + 1 - rLeftOvers[nRow] );
+ }
+
+ if( nNewCols > 0 )
+ {
+ const OUString sWidth( RTL_CONSTASCII_USTRINGPARAM("Width") );
+ Reference< XTableColumns > xCols( mxTable->getColumns(), UNO_QUERY_THROW );
+ Reference< XPropertySet > xRefColumn( xCols->getByIndex( nCol ), UNO_QUERY_THROW );
+ sal_Int32 nWidth = 0;
+ xRefColumn->getPropertyValue( sWidth ) >>= nWidth;
+ const sal_Int32 nNewWidth = nWidth / (nNewCols + 1);
+
+ // reference column gets new width + rounding errors
+ xRefColumn->setPropertyValue( sWidth, Any( nWidth - (nNewWidth * nNewCols) ) );
+
+ xCols->insertByIndex( nCol + 1, nNewCols );
+ mnRight += nNewCols;
+
+ // distribute new width
+ for( sal_Int32 nNewCol = nCol + nNewCols; nNewCol > nCol; --nNewCol )
+ {
+ Reference< XPropertySet > xNewCol( xCols->getByIndex( nNewCol ), UNO_QUERY_THROW );
+ xNewCol->setPropertyValue( sWidth, Any( nNewWidth ) );
+ }
+ }
+
+ for( nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( !xCell.is() || xCell->isMerged() )
+ {
+ if( nNewCols > 0 )
+ {
+ // merged cells are ignored, but newly added columns will be added to leftovers
+ xCell.set( dynamic_cast< Cell* >(mxTable->getCellByPosition( nCol+1, nRow ).get() ) );
+ if( !xCell.is() || !xCell->isMerged() )
+ rLeftOvers[nRow] += nNewCols;
+ }
+ }
+ else
+ {
+ sal_Int32 nRowSpan = xCell->getRowSpan() - 1;
+ sal_Int32 nColSpan = xCell->getColumnSpan() - 1;
+
+ if( (nRow >= mnTop) && (nRow <= mnBottom) )
+ {
+ sal_Int32 nCellsAvailable = 1 + nColSpan + rLeftOvers[nRow];
+ if( nColSpan == 0 )
+ nCellsAvailable += nNewCols;
+
+ DBG_ASSERT( nCellsAvailable > nColumns, "sdr::table::CellCursor::split_column(), somethings wrong" );
+
+ sal_Int32 nSplitSpan = (nCellsAvailable / (nColumns + 1)) - 1;
+
+ sal_Int32 nSplitCol = nCol;
+ sal_Int32 nSplits = nColumns + 1;
+ while( nSplits-- )
+ {
+ // last split eats rounding cells
+ if( nSplits == 0 )
+ nSplitSpan = nCellsAvailable - ((nSplitSpan+1) * nColumns) - 1;
+
+ mxTable->merge( nSplitCol, nRow, nSplitSpan + 1, nRowSpan + 1);
+ if( nSplits > 0 )
+ nSplitCol += nSplitSpan + 1;
+ }
+
+ do
+ {
+ rLeftOvers[nRow++] = 0;
+ }
+ while( nRowSpan-- );
+ --nRow;
+ }
+ else
+ {
+ // cope with outside cells, merge if needed
+ if( nColSpan < (rLeftOvers[nRow] + nNewCols) )
+ mxTable->merge( nCol, nRow, (rLeftOvers[nRow] + nNewCols) + 1, nRowSpan + 1 );
+
+ do
+ {
+ rLeftOvers[nRow++] = 0; // consumed
+ }
+ while( nRowSpan-- );
+ --nRow;
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void CellCursor::split_horizontal( sal_Int32 nColumns )
+{
+ const sal_Int32 nRowCount = mxTable->getRowCount();
+
+ std::vector< sal_Int32 > aLeftOvers( nRowCount );
+
+ for( sal_Int32 nCol = mnRight; nCol >= mnLeft; --nCol )
+ split_column( nCol, nColumns, aLeftOvers );
+}
+
+// -----------------------------------------------------------------------------
+
+void CellCursor::split_row( sal_Int32 nRow, sal_Int32 nRows, std::vector< sal_Int32 >& rLeftOvers )
+{
+ const sal_Int32 nColCount = mxTable->getColumnCount();
+
+ sal_Int32 nNewRows = 0, nCol;
+
+ // first check how many columns we need to add
+ for( nCol = mnLeft; nCol <= mnRight; ++nCol )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( xCell.is() && !xCell->isMerged() )
+ nNewRows = std::max( nNewRows, nRows - xCell->getRowSpan() + 1 - rLeftOvers[nCol] );
+ }
+
+ if( nNewRows > 0 )
+ {
+ const OUString sHeight( RTL_CONSTASCII_USTRINGPARAM("Height") );
+ Reference< XTableRows > xRows( mxTable->getRows(), UNO_QUERY_THROW );
+ Reference< XPropertySet > xRefRow( xRows->getByIndex( nRow ), UNO_QUERY_THROW );
+ sal_Int32 nHeight = 0;
+ xRefRow->getPropertyValue( sHeight ) >>= nHeight;
+ const sal_Int32 nNewHeight = nHeight / (nNewRows + 1);
+
+ // reference row gets new height + rounding errors
+ xRefRow->setPropertyValue( sHeight, Any( nHeight - (nNewHeight * nNewRows) ) );
+
+ xRows->insertByIndex( nRow + 1, nNewRows );
+ mnBottom += nNewRows;
+
+ // distribute new width
+ for( sal_Int32 nNewRow = nRow + nNewRows; nNewRow > nRow; --nNewRow )
+ {
+ Reference< XPropertySet > xNewRow( xRows->getByIndex( nNewRow ), UNO_QUERY_THROW );
+ xNewRow->setPropertyValue( sHeight, Any( nNewHeight ) );
+ }
+ }
+
+ for( nCol = 0; nCol < nColCount; ++nCol )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( !xCell.is() || xCell->isMerged() )
+ {
+ if( nNewRows )
+ {
+ // merged cells are ignored, but newly added columns will be added to leftovers
+ xCell.set( dynamic_cast< Cell* >(mxTable->getCellByPosition( nCol, nRow+1 ).get() ) );
+ if( !xCell.is() || !xCell->isMerged() )
+ rLeftOvers[nCol] += nNewRows;
+ }
+ }
+ else
+ {
+ sal_Int32 nRowSpan = xCell->getRowSpan() - 1;
+ sal_Int32 nColSpan = xCell->getColumnSpan() - 1;
+
+ if( (nCol >= mnLeft) && (nCol <= mnRight) )
+ {
+ sal_Int32 nCellsAvailable = 1 + nRowSpan + rLeftOvers[nCol];
+ if( nRowSpan == 0 )
+ nCellsAvailable += nNewRows;
+
+ DBG_ASSERT( nCellsAvailable > nRows, "sdr::table::CellCursor::split_row(), somethings wrong" );
+
+ sal_Int32 nSplitSpan = (nCellsAvailable / (nRows + 1)) - 1;
+
+ sal_Int32 nSplitRow = nRow;
+ sal_Int32 nSplits = nRows + 1;
+ while( nSplits-- )
+ {
+ // last split eats rounding cells
+ if( nSplits == 0 )
+ nSplitSpan = nCellsAvailable - ((nSplitSpan+1) * nRows) - 1;
+
+ mxTable->merge( nCol, nSplitRow, nColSpan + 1, nSplitSpan + 1 );
+ if( nSplits > 0 )
+ nSplitRow += nSplitSpan + 1;
+ }
+
+ do
+ {
+ rLeftOvers[nCol++] = 0;
+ }
+ while( nColSpan-- );
+ --nCol;
+ }
+ else
+ {
+ // cope with outside cells, merge if needed
+ if( nRowSpan < (rLeftOvers[nCol] + nNewRows) )
+ mxTable->merge( nCol, nRow, nColSpan + 1, (rLeftOvers[nCol] + nNewRows) + 1 );
+
+ do
+ {
+ rLeftOvers[nCol++] = 0; // consumed
+ }
+ while( nColSpan-- );
+ --nCol;
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void CellCursor::split_vertical( sal_Int32 nRows )
+{
+ const sal_Int32 nColCount = mxTable->getColumnCount();
+
+ std::vector< sal_Int32 > aLeftOvers( nColCount );
+
+ for( sal_Int32 nRow = mnBottom; nRow >= mnTop; --nRow )
+ split_row( nRow, nRows, aLeftOvers );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL CellCursor::split( sal_Int32 nColumns, sal_Int32 nRows ) throw (NoSupportException, IllegalArgumentException, RuntimeException)
+{
+ if( (nColumns < 0) || (nRows < 0) )
+ throw IllegalArgumentException();
+
+ if( !mxTable.is() || (mxTable->getSdrTableObj() == 0) )
+ throw DisposedException();
+
+ SdrModel* pModel = mxTable->getSdrTableObj()->GetModel();
+ const bool bUndo = pModel && mxTable->getSdrTableObj()->IsInserted() && pModel->IsUndoEnabled();
+ if( bUndo )
+ pModel->BegUndo( ImpGetResStr(STR_TABLE_SPLIT) );
+
+ try
+ {
+ if( nColumns > 0 )
+ split_horizontal( nColumns );
+
+ if( nRows > 0 )
+ split_vertical( nRows );
+
+ if( nColumns > 0 ||nRows > 0 )
+ mxTable->setModified(sal_True);
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("sdr::table::CellCursor::split(), exception caught!");
+ throw NoSupportException();
+ }
+
+ if( bUndo )
+ pModel->EndUndo();
+
+ if( pModel )
+ pModel->SetChanged();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CellCursor::isMergeable( ) throw (RuntimeException)
+{
+ CellPos aStart, aEnd;
+ return GetMergedSelection( aStart, aEnd ) ? sal_True : sal_False;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CellCursor::isUnmergeable( ) throw (RuntimeException)
+{
+ // this is true if there is at least one merged cell in the current range
+ for( sal_Int32 nRow = mnTop; nRow <= mnBottom; nRow++ )
+ {
+ for( sal_Int32 nCol = mnLeft; nCol <= mnRight; nCol++ )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( xCell.is() && ( (xCell->getRowSpan() > 1) || (xCell->getColumnSpan() > 1) ) )
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------------
+
+} }
diff --git a/svx/source/table/cellcursor.hxx b/svx/source/table/cellcursor.hxx
new file mode 100644
index 000000000000..39b5a082416c
--- /dev/null
+++ b/svx/source/table/cellcursor.hxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_CELLCURSOR_HXX_
+#define _SVX_CELLCURSOR_HXX_
+
+#include <com/sun/star/table/XMergeableCellRange.hpp>
+#include <com/sun/star/table/XCellCursor.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include "cellrange.hxx"
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+struct CellPos;
+
+// -----------------------------------------------------------------------------
+// CellCursor
+// -----------------------------------------------------------------------------
+
+typedef ::cppu::ImplInheritanceHelper2< CellRange, ::com::sun::star::table::XCellCursor, ::com::sun::star::table::XMergeableCellRange > CellCursorBase;
+
+class CellCursor : public CellCursorBase
+{
+public:
+ CellCursor( const TableModelRef& xTableModel, sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom );
+ virtual ~CellCursor();
+
+ // XCellRange
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell > SAL_CALL getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > SAL_CALL getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > SAL_CALL getCellRangeByName( const ::rtl::OUString& aRange ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XCellCursor
+ virtual void SAL_CALL gotoStart( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL gotoEnd( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL gotoNext( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL gotoPrevious( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL gotoOffset( ::sal_Int32 nColumnOffset, ::sal_Int32 nRowOffset ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XMergeableCellRange
+ virtual void SAL_CALL merge( ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL split( ::sal_Int32 Columns, ::sal_Int32 Rows ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isMergeable( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isUnmergeable( ) throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ bool GetMergedSelection( CellPos& rStart, CellPos& rEnd );
+
+ void split_column( sal_Int32 nCol, sal_Int32 nColumns, std::vector< sal_Int32 >& rLeftOvers );
+ void split_horizontal( sal_Int32 nColumns );
+ void split_row( sal_Int32 nRow, sal_Int32 nRows, std::vector< sal_Int32 >& rLeftOvers );
+ void split_vertical( sal_Int32 nRows );
+};
+
+} }
+
+#endif
diff --git a/svx/source/table/celleditsource.cxx b/svx/source/table/celleditsource.cxx
new file mode 100644
index 000000000000..218d8631cb75
--- /dev/null
+++ b/svx/source/table/celleditsource.cxx
@@ -0,0 +1,1056 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <com/sun/star/linguistic2/XLinguServiceManager.hpp>
+
+#include <rtl/ref.hxx>
+#include <osl/mutex.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/processfactory.hxx>
+#include <svl/lstner.hxx>
+#include <svl/hint.hxx>
+#include <svl/style.hxx>
+
+#include "celleditsource.hxx"
+#include "cell.hxx"
+#include "svx/svdmodel.hxx"
+#include "svx/svdoutl.hxx"
+#include "svx/svdobj.hxx"
+#include "editeng/unoedhlp.hxx"
+#include "svx/svdview.hxx"
+#include "svx/svdetc.hxx"
+#include "editeng/outliner.hxx"
+#include "editeng/unoforou.hxx"
+#include "editeng/unoviwou.hxx"
+#include "editeng/outlobj.hxx"
+#include "svx/svdotext.hxx"
+#include "svx/svdpage.hxx"
+#include "editeng/editeng.hxx"
+#include "editeng/unotext.hxx"
+#include "sdrpaintwindow.hxx"
+
+//------------------------------------------------------------------------
+
+using ::rtl::OUString;
+using namespace ::osl;
+using namespace ::vos;
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::linguistic2;
+using namespace ::com::sun::star::lang;
+
+//------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+//------------------------------------------------------------------------
+// CellEditSourceImpl
+//------------------------------------------------------------------------
+
+/** @descr
+ <p>This class essentially provides the text and view forwarders. If
+ no SdrView is given, this class handles the UNO objects, which are
+ currently not concerned with view issues. In this case,
+ GetViewForwarder() always returns NULL and the underlying
+ EditEngine of the SvxTextForwarder is a background one (i.e. not
+ the official DrawOutliner, but one created exclusively for this
+ object, with no relation to a view).
+ </p>
+
+ <p>If a SdrView is given at construction time, the caller is
+ responsible for destroying this object when the view becomes
+ invalid (the views cannot notify). If GetViewForwarder(sal_True)
+ is called, the underlying shape is put into edit mode, the view
+ forwarder returned encapsulates the OutlinerView and the next call
+ to GetTextForwarder() yields a forwarder encapsulating the actual
+ DrawOutliner. Thus, changes on that Outliner are immediately
+ reflected on the screen. If the object leaves edit mode, the old
+ behaviour is restored.</p>
+ */
+class CellEditSourceImpl : public SfxListener, public SfxBroadcaster
+{
+private:
+ oslInterlockedCount maRefCount;
+
+ SdrView* mpView;
+ const Window* mpWindow;
+ SdrModel* mpModel;
+ SdrOutliner* mpOutliner;
+ SvxOutlinerForwarder* mpTextForwarder;
+ SvxDrawOutlinerViewForwarder* mpViewForwarder;
+ Reference< ::com::sun::star::linguistic2::XLinguServiceManager > mxLinguServiceManager;
+ Point maTextOffset;
+ bool mbDataValid;
+ bool mbDisposed;
+ bool mbIsLocked;
+ bool mbNeedsUpdate;
+ bool mbOldUndoMode;
+ bool mbForwarderIsEditMode; // have to reflect that, since ENDEDIT can happen more often
+ bool mbShapeIsEditMode; // #104157# only true, if HINT_BEGEDIT was received
+ bool mbNotificationsDisabled; // prevent EditEngine/Outliner notifications (e.g. when setting up forwarder)
+
+ CellRef mxCell;
+ SvxUnoTextRangeBaseList maTextRanges;
+
+ SvxTextForwarder* GetBackgroundTextForwarder();
+ SvxTextForwarder* GetEditModeTextForwarder();
+ SvxDrawOutlinerViewForwarder* CreateViewForwarder();
+
+ void SetupOutliner();
+ void UpdateOutliner();
+
+ bool HasView() const { return mpView != 0; }
+ bool IsEditMode() const { return mxCell->IsTextEditActive(); };
+ void dispose();
+
+public:
+ CellEditSourceImpl( const CellRef& xCell );
+ CellEditSourceImpl( const CellRef& xCell, SdrView& rView, const Window& rWindow );
+ ~CellEditSourceImpl();
+
+ void SAL_CALL acquire();
+ void SAL_CALL release();
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ SvxEditSource* Clone() const;
+ SvxTextForwarder* GetTextForwarder();
+ SvxEditViewForwarder* GetEditViewForwarder( sal_Bool );
+ void UpdateData();
+
+ void addRange( SvxUnoTextRangeBase* pNewRange );
+ void removeRange( SvxUnoTextRangeBase* pOldRange );
+ const SvxUnoTextRangeBaseList& getRanges() const;
+
+ void lock();
+ void unlock();
+
+ BOOL IsValid() const;
+
+ Rectangle GetVisArea();
+ Point LogicToPixel( const Point&, const MapMode& rMapMode );
+ Point PixelToLogic( const Point&, const MapMode& rMapMode );
+
+ DECL_LINK( NotifyHdl, EENotify* );
+
+ void ChangeModel( SdrModel* pNewModel );
+};
+
+//------------------------------------------------------------------------
+
+CellEditSourceImpl::CellEditSourceImpl( const CellRef& xCell )
+ : maRefCount ( 0 ),
+ mpView ( NULL ),
+ mpWindow ( NULL ),
+ mpModel ( NULL ),
+ mpOutliner ( NULL ),
+ mpTextForwarder ( NULL ),
+ mpViewForwarder ( NULL ),
+ mbDataValid ( false ),
+ mbDisposed ( false ),
+ mbIsLocked ( false ),
+ mbNeedsUpdate ( false ),
+ mbOldUndoMode ( false ),
+ mbForwarderIsEditMode ( false ),
+ mbShapeIsEditMode ( false ),
+ mbNotificationsDisabled ( false ),
+ mxCell( xCell )
+{
+}
+
+//------------------------------------------------------------------------
+
+CellEditSourceImpl::CellEditSourceImpl( const CellRef& xCell, SdrView& rView, const Window& rWindow )
+ : maRefCount ( 0 ),
+ mpView ( &rView ),
+ mpWindow ( &rWindow ),
+ mpModel ( NULL ),
+ mpOutliner ( NULL ),
+ mpTextForwarder ( NULL ),
+ mpViewForwarder ( NULL ),
+ mbDataValid ( false ),
+ mbDisposed ( false ),
+ mbIsLocked ( false ),
+ mbNeedsUpdate ( false ),
+ mbOldUndoMode ( false ),
+ mbForwarderIsEditMode ( false ),
+ mbShapeIsEditMode ( true ),
+ mbNotificationsDisabled ( false ),
+ mxCell( xCell )
+{
+ if( mpView )
+ StartListening( *mpView );
+
+ // #104157# Init edit mode state from shape info (IsTextEditActive())
+ mbShapeIsEditMode = IsEditMode();
+}
+
+//------------------------------------------------------------------------
+
+CellEditSourceImpl::~CellEditSourceImpl()
+{
+ DBG_ASSERT( mbIsLocked == sal_False, "CellEditSourceImpl::~CellEditSourceImpl(), was not unlocked before dispose!" );
+ dispose();
+}
+
+//------------------------------------------------------------------------
+
+void CellEditSourceImpl::addRange( SvxUnoTextRangeBase* pNewRange )
+{
+ if( pNewRange )
+ if( std::find( maTextRanges.begin(), maTextRanges.end(), pNewRange ) == maTextRanges.end() )
+ maTextRanges.push_back( pNewRange );
+}
+
+//------------------------------------------------------------------------
+
+void CellEditSourceImpl::removeRange( SvxUnoTextRangeBase* pOldRange )
+{
+ if( pOldRange )
+ maTextRanges.remove( pOldRange );
+}
+
+//------------------------------------------------------------------------
+
+const SvxUnoTextRangeBaseList& CellEditSourceImpl::getRanges() const
+{
+ return maTextRanges;
+}
+
+//------------------------------------------------------------------------
+
+void SAL_CALL CellEditSourceImpl::acquire()
+{
+ osl_incrementInterlockedCount( &maRefCount );
+}
+
+//------------------------------------------------------------------------
+
+void SAL_CALL CellEditSourceImpl::release()
+{
+ if( ! osl_decrementInterlockedCount( &maRefCount ) )
+ delete this;
+}
+
+void CellEditSourceImpl::ChangeModel( SdrModel* pNewModel )
+{
+ if( mpModel != pNewModel )
+ {
+ if( mpOutliner )
+ {
+ if( mpModel )
+ mpModel->disposeOutliner( mpOutliner );
+ else
+ delete mpOutliner;
+ mpOutliner = 0;
+ }
+
+ if( mpView )
+ {
+ EndListening( *mpView );
+ mpView = 0;
+ }
+
+ mpWindow = 0;
+ mxLinguServiceManager.clear();
+
+ mpModel = pNewModel;
+
+ if( mpTextForwarder )
+ {
+ delete mpTextForwarder;
+ mpTextForwarder = 0;
+ }
+
+ if( mpViewForwarder )
+ {
+ delete mpViewForwarder;
+ mpViewForwarder = 0;
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void CellEditSourceImpl::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
+ const SvxViewHint* pViewHint = PTR_CAST( SvxViewHint, &rHint );
+
+ if( pViewHint )
+ {
+ switch( pViewHint->GetHintType() )
+ {
+ case SvxViewHint::SVX_HINT_VIEWCHANGED:
+ Broadcast( *pViewHint );
+ break;
+ }
+ }
+ else if( pSdrHint )
+ {
+ switch( pSdrHint->GetKind() )
+ {
+ case HINT_OBJCHG:
+ {
+ mbDataValid = FALSE; // Text muss neu geholt werden
+
+ if( HasView() )
+ {
+ // #104157# Update maTextOffset, object has changed
+ // #105196#, #105203#: Cannot call that // here,
+ // since TakeTextRect() (called from there) //
+ // changes outliner content.
+ // UpdateOutliner();
+
+ // #101029# Broadcast object changes, as they might change visible attributes
+ SvxViewHint aHint(SvxViewHint::SVX_HINT_VIEWCHANGED);
+ Broadcast( aHint );
+ }
+ break;
+ }
+
+ case HINT_BEGEDIT:
+/* todo
+ if( mpObject == pSdrHint->GetObject() )
+ {
+ // invalidate old forwarder
+ if( !mbForwarderIsEditMode )
+ {
+ delete mpTextForwarder;
+ mpTextForwarder = NULL;
+ }
+
+ // register as listener - need to broadcast state change messages
+ if( mpView && mpView->GetTextEditOutliner() )
+ mpView->GetTextEditOutliner()->SetNotifyHdl( LINK(this, CellEditSourceImpl, NotifyHdl) );
+
+ // #104157# Only now we're really in edit mode
+ mbShapeIsEditMode = TRUE;
+
+ Broadcast( *pSdrHint );
+ }
+*/
+ break;
+
+ case HINT_ENDEDIT:
+/* todo
+ if( mpObject == pSdrHint->GetObject() )
+ {
+ Broadcast( *pSdrHint );
+
+ // #104157# We're no longer in edit mode
+ mbShapeIsEditMode = FALSE;
+
+ // remove as listener - outliner might outlive ourselves
+ if( mpView && mpView->GetTextEditOutliner() )
+ mpView->GetTextEditOutliner()->SetNotifyHdl( Link() );
+
+ // destroy view forwarder, OutlinerView no longer
+ // valid (no need for UpdateData(), it's been
+ // synched on SdrEndTextEdit)
+ delete mpViewForwarder;
+ mpViewForwarder = NULL;
+
+ // #100424# Invalidate text forwarder, we might
+ // not be called again before entering edit mode a
+ // second time! Then, the old outliner might be
+ // invalid.
+ if( mbForwarderIsEditMode )
+ {
+ mbForwarderIsEditMode = sal_False;
+ delete mpTextForwarder;
+ mpTextForwarder = NULL;
+ }
+ }
+*/
+ break;
+
+ case HINT_MODELCLEARED:
+ dispose();
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/* unregister at all objects and set all references to 0 */
+void CellEditSourceImpl::dispose()
+{
+ if( mpTextForwarder )
+ {
+ delete mpTextForwarder;
+ mpTextForwarder = 0;
+ }
+
+ if( mpViewForwarder )
+ {
+ delete mpViewForwarder;
+ mpViewForwarder = 0;
+ }
+
+ if( mpOutliner )
+ {
+ if( mpModel )
+ {
+ mpModel->disposeOutliner( mpOutliner );
+ }
+ else
+ {
+ delete mpOutliner;
+ }
+ mpOutliner = 0;
+ }
+
+ if( mpView )
+ {
+ EndListening( *mpView );
+ mpView = 0;
+ }
+
+ mpModel = 0;
+ mpWindow = 0;
+}
+
+//------------------------------------------------------------------------
+
+void CellEditSourceImpl::SetupOutliner()
+{
+ // #101029#
+ // only for UAA edit source: setup outliner equivalently as in
+ // SdrTextObj::Paint(), such that formatting equals screen
+ // layout
+/* todo
+ if( mpObject && mpOutliner )
+ {
+ SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, mpObject );
+ Rectangle aPaintRect;
+ if( pTextObj )
+ {
+ Rectangle aBoundRect( pTextObj->GetCurrentBoundRect() );
+ pTextObj->SetupOutlinerFormatting( *mpOutliner, aPaintRect );
+
+ // #101029# calc text offset from shape anchor
+ maTextOffset = aPaintRect.TopLeft() - aBoundRect.TopLeft();
+ }
+ }
+*/
+}
+
+//------------------------------------------------------------------------
+
+void CellEditSourceImpl::UpdateOutliner()
+{
+ // #104157#
+ // only for UAA edit source: update outliner equivalently as in
+ // SdrTextObj::Paint(), such that formatting equals screen
+ // layout
+/* todo
+ if( mpObject && mpOutliner )
+ {
+ SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, mpObject );
+ Rectangle aPaintRect;
+ if( pTextObj )
+ {
+ Rectangle aBoundRect( pTextObj->GetCurrentBoundRect() );
+ pTextObj->UpdateOutlinerFormatting( *mpOutliner, aPaintRect );
+
+ // #101029# calc text offset from shape anchor
+ maTextOffset = aPaintRect.TopLeft() - aBoundRect.TopLeft();
+ }
+ }
+*/
+}
+
+//------------------------------------------------------------------------
+
+
+SvxTextForwarder* CellEditSourceImpl::GetBackgroundTextForwarder()
+{
+ sal_Bool bCreated = sal_False;
+
+ // #99840#: prevent EE/Outliner notifications during setup
+ mbNotificationsDisabled = true;
+
+ if (!mpTextForwarder)
+ {
+ if( mpOutliner == NULL )
+ {
+ mpOutliner = mpModel->createOutliner( OUTLINERMODE_TEXTOBJECT );
+
+ // #109151# Do the setup after outliner creation, would be useless otherwise
+ if( HasView() )
+ {
+ // #101029#, #104157# Setup outliner _before_ filling it
+ SetupOutliner();
+ }
+
+// todo? mpOutliner->SetTextObjNoInit( pTextObj );
+
+ if( mbIsLocked )
+ {
+ ((EditEngine*)&(mpOutliner->GetEditEngine()))->SetUpdateMode( sal_False );
+ mbOldUndoMode = ((EditEngine*)&(mpOutliner->GetEditEngine()))->IsUndoEnabled();
+ ((EditEngine*)&(mpOutliner->GetEditEngine()))->EnableUndo( sal_False );
+ }
+
+ if ( !mxLinguServiceManager.is() )
+ {
+ Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
+ mxLinguServiceManager = Reference< XLinguServiceManager >(
+ xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.linguistic2.LinguServiceManager" ))), UNO_QUERY );
+ }
+
+ if ( mxLinguServiceManager.is() )
+ {
+ Reference< XHyphenator > xHyphenator( mxLinguServiceManager->getHyphenator(), UNO_QUERY );
+ if( xHyphenator.is() )
+ mpOutliner->SetHyphenator( xHyphenator );
+ }
+ }
+
+ mpTextForwarder = new SvxOutlinerForwarder( *mpOutliner );
+
+ // delay listener subscription and UAA initialization until Outliner is fully setup
+ bCreated = true;
+ mbForwarderIsEditMode = false;
+ }
+
+ if( !mbDataValid )
+ {
+ mpTextForwarder->flushCache();
+
+ OutlinerParaObject* pOutlinerParaObject = NULL;
+ bool bTextEditActive = false;
+
+ pOutlinerParaObject = mxCell->GetEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active
+
+ if( pOutlinerParaObject )
+ bTextEditActive = true; // text edit active
+ else
+ pOutlinerParaObject = mxCell->GetOutlinerParaObject();
+
+ if( pOutlinerParaObject )
+ {
+ mpOutliner->SetText( *pOutlinerParaObject );
+ }
+ else
+ {
+ bool bVertical = false; // todo?
+
+ // set objects style sheet on empty outliner
+ SfxStyleSheetPool* pPool = mxCell->GetStyleSheetPool();
+ if( pPool )
+ mpOutliner->SetStyleSheetPool( pPool );
+
+ SfxStyleSheet* pStyleSheet = mxCell->GetStyleSheet();
+ if( pStyleSheet )
+ mpOutliner->SetStyleSheet( 0, pStyleSheet );
+
+ if( bVertical )
+ mpOutliner->SetVertical( sal_True );
+ }
+
+ // evtually we have to set the border attributes
+ if (mpOutliner->GetParagraphCount()==1)
+ {
+ // if we only have one paragraph we check if it is empty
+ XubString aStr( mpOutliner->GetText( mpOutliner->GetParagraph( 0 ) ) );
+
+ if(!aStr.Len())
+ {
+ // its empty, so we have to force the outliner to initialise itself
+ mpOutliner->SetText( String(), mpOutliner->GetParagraph( 0 ) );
+
+ if(mxCell->GetStyleSheet())
+ mpOutliner->SetStyleSheet( 0, mxCell->GetStyleSheet());
+ }
+ }
+
+ if( bTextEditActive )
+ delete pOutlinerParaObject;
+
+ mbDataValid = true;
+ }
+
+ if( bCreated && mpOutliner && HasView() )
+ {
+ // register as listener - need to broadcast state change messages
+ // registration delayed until outliner is completely set up
+ mpOutliner->SetNotifyHdl( LINK(this, CellEditSourceImpl, NotifyHdl) );
+ }
+
+ // #99840#: prevent EE/Outliner notifications during setup
+ mbNotificationsDisabled = false;
+
+ return mpTextForwarder;
+}
+
+//------------------------------------------------------------------------
+
+SvxTextForwarder* CellEditSourceImpl::GetEditModeTextForwarder()
+{
+ if( !mpTextForwarder && HasView() )
+ {
+ SdrOutliner* pEditOutliner = mpView->GetTextEditOutliner();
+
+ if( pEditOutliner )
+ {
+ mpTextForwarder = new SvxOutlinerForwarder( *pEditOutliner );
+ mbForwarderIsEditMode = true;
+ }
+ }
+
+ return mpTextForwarder;
+}
+
+//------------------------------------------------------------------------
+
+SvxTextForwarder* CellEditSourceImpl::GetTextForwarder()
+{
+ if( mbDisposed )
+ return NULL;
+
+ if( mpModel == NULL )
+ return NULL;
+
+ // distinguish the cases
+ // a) connected to view, maybe edit mode is active, can work directly on the EditOutliner
+ // b) background Outliner, reflect changes into ParaOutlinerObject (this is exactly the old UNO code)
+ if( HasView() )
+ {
+ if( IsEditMode() != mbForwarderIsEditMode )
+ {
+ // forwarder mismatch - create new
+ delete mpTextForwarder;
+ mpTextForwarder = NULL;
+ }
+
+ if( IsEditMode() )
+ return GetEditModeTextForwarder();
+ else
+ return GetBackgroundTextForwarder();
+ }
+ else
+ return GetBackgroundTextForwarder();
+}
+
+//------------------------------------------------------------------------
+
+SvxDrawOutlinerViewForwarder* CellEditSourceImpl::CreateViewForwarder()
+{
+ if( mpView->GetTextEditOutlinerView() )
+ {
+ // register as listener - need to broadcast state change messages
+ mpView->GetTextEditOutliner()->SetNotifyHdl( LINK(this, CellEditSourceImpl, NotifyHdl) );
+
+ Rectangle aBoundRect( mxCell->GetCurrentBoundRect() );
+ OutlinerView& rOutlView = *mpView->GetTextEditOutlinerView();
+
+ return new SvxDrawOutlinerViewForwarder( rOutlView, aBoundRect.TopLeft() );
+ }
+
+ return NULL;
+}
+
+SvxEditViewForwarder* CellEditSourceImpl::GetEditViewForwarder( sal_Bool bCreate )
+{
+ if( mbDisposed )
+ return NULL;
+
+ if( mpModel == NULL )
+ return NULL;
+
+ // shall we delete?
+ if( mpViewForwarder )
+ {
+ if( !IsEditMode() )
+ {
+ // destroy all forwarders (no need for UpdateData(),
+ // it's been synched on SdrEndTextEdit)
+ delete mpViewForwarder;
+ mpViewForwarder = NULL;
+ }
+ }
+ // which to create? Directly in edit mode, create new, or none?
+ else if( mpView )
+ {
+ if( IsEditMode() )
+ {
+ // create new view forwarder
+ mpViewForwarder = CreateViewForwarder();
+ }
+ else if( bCreate )
+ {
+ // dispose old text forwarder
+ UpdateData();
+
+ delete mpTextForwarder;
+ mpTextForwarder = NULL;
+
+ // enter edit mode
+ mpView->SdrEndTextEdit();
+
+/* todo
+ if(mpView->SdrBeginTextEdit(mpObject, 0L, 0L, sal_False, (SdrOutliner*)0L, 0L, sal_False, sal_False))
+ {
+ if( mxCell->IsTextEditActive() )
+ {
+ // create new view forwarder
+ mpViewForwarder = CreateViewForwarder();
+ }
+ else
+ {
+ // failure. Somehow, SdrBeginTextEdit did not set
+ // our SdrTextObj into edit mode
+ mpView->SdrEndTextEdit();
+ }
+ }
+*/
+ }
+ }
+
+ return mpViewForwarder;
+}
+
+//------------------------------------------------------------------------
+
+void CellEditSourceImpl::UpdateData()
+{
+ // if we have a view and in edit mode, we're working with the
+ // DrawOutliner. Thus, all changes made on the text forwarder are
+ // reflected on the view and committed to the model on
+ // SdrEndTextEdit(). Thus, no need for explicit updates here.
+ if( !HasView() || !IsEditMode() )
+ {
+ if( mbIsLocked )
+ {
+ mbNeedsUpdate = true;
+ }
+ else
+ {
+ if( mpOutliner && !mbDisposed )
+ {
+ if( mpOutliner->GetParagraphCount() != 1 || mpOutliner->GetEditEngine().GetTextLen( 0 ) )
+ {
+ mxCell->SetOutlinerParaObject( mpOutliner->CreateParaObject() );
+ }
+ else
+ {
+ mxCell->SetOutlinerParaObject( NULL );
+ }
+ }
+ }
+ }
+}
+
+void CellEditSourceImpl::lock()
+{
+ mbIsLocked = true;
+ if( mpOutliner )
+ {
+ ((EditEngine*)&(mpOutliner->GetEditEngine()))->SetUpdateMode( sal_False );
+ mbOldUndoMode = ((EditEngine*)&(mpOutliner->GetEditEngine()))->IsUndoEnabled();
+ ((EditEngine*)&(mpOutliner->GetEditEngine()))->EnableUndo( sal_False );
+ }
+}
+
+void CellEditSourceImpl::unlock()
+{
+ mbIsLocked = false;
+
+ if( mbNeedsUpdate )
+ {
+ UpdateData();
+ mbNeedsUpdate = false;
+ }
+
+ if( mpOutliner )
+ {
+ ((EditEngine*)&(mpOutliner->GetEditEngine()))->SetUpdateMode( sal_True );
+ ((EditEngine*)&(mpOutliner->GetEditEngine()))->EnableUndo( mbOldUndoMode );
+ }
+}
+
+BOOL CellEditSourceImpl::IsValid() const
+{
+ return mpView && mpWindow ? TRUE : FALSE;
+}
+
+Rectangle CellEditSourceImpl::GetVisArea()
+{
+ if( IsValid() )
+ {
+ SdrPaintWindow* pPaintWindow = mpView->FindPaintWindow(*mpWindow);
+ Rectangle aVisArea;
+
+ if(pPaintWindow)
+ {
+ aVisArea = pPaintWindow->GetVisibleArea();
+ }
+
+ // offset vis area by edit engine left-top position
+ Rectangle aAnchorRect;
+ mxCell->TakeTextAnchorRect( aAnchorRect );
+ aVisArea.Move( -aAnchorRect.Left(), -aAnchorRect.Top() );
+
+ MapMode aMapMode(mpWindow->GetMapMode());
+ aMapMode.SetOrigin(Point());
+ return mpWindow->LogicToPixel( aVisArea, aMapMode );
+ }
+
+ return Rectangle();
+}
+
+Point CellEditSourceImpl::LogicToPixel( const Point& rPoint, const MapMode& rMapMode )
+{
+ // #101029#: The responsibilities of ViewForwarder happen to be
+ // somewhat mixed in this case. On the one hand, we need the
+ // different interface queries on the SvxEditSource interface,
+ // since we need both VisAreas. On the other hand, if an
+ // EditViewForwarder exists, maTextOffset does not remain static,
+ // but may change with every key press.
+ if( IsEditMode() )
+ {
+ SvxEditViewForwarder* pForwarder = GetEditViewForwarder(sal_False);
+
+ if( pForwarder )
+ return pForwarder->LogicToPixel( rPoint, rMapMode );
+ }
+ else if( IsValid() && mpModel )
+ {
+ // #101029#
+ Point aPoint1( rPoint );
+ aPoint1.X() += maTextOffset.X();
+ aPoint1.Y() += maTextOffset.Y();
+
+ Point aPoint2( OutputDevice::LogicToLogic( aPoint1, rMapMode,
+ MapMode(mpModel->GetScaleUnit()) ) );
+ MapMode aMapMode(mpWindow->GetMapMode());
+ aMapMode.SetOrigin(Point());
+ return mpWindow->LogicToPixel( aPoint2, aMapMode );
+ }
+
+ return Point();
+}
+
+Point CellEditSourceImpl::PixelToLogic( const Point& rPoint, const MapMode& rMapMode )
+{
+ // #101029#: The responsibilities of ViewForwarder happen to be
+ // somewhat mixed in this case. On the one hand, we need the
+ // different interface queries on the SvxEditSource interface,
+ // since we need both VisAreas. On the other hand, if an
+ // EditViewForwarder exists, maTextOffset does not remain static,
+ // but may change with every key press.
+ if( IsEditMode() )
+ {
+ SvxEditViewForwarder* pForwarder = GetEditViewForwarder(sal_False);
+
+ if( pForwarder )
+ return pForwarder->PixelToLogic( rPoint, rMapMode );
+ }
+ else if( IsValid() && mpModel )
+ {
+ MapMode aMapMode(mpWindow->GetMapMode());
+ aMapMode.SetOrigin(Point());
+ Point aPoint1( mpWindow->PixelToLogic( rPoint, aMapMode ) );
+ Point aPoint2( OutputDevice::LogicToLogic( aPoint1,
+ MapMode(mpModel->GetScaleUnit()),
+ rMapMode ) );
+ // #101029#
+ aPoint2.X() -= maTextOffset.X();
+ aPoint2.Y() -= maTextOffset.Y();
+
+ return aPoint2;
+ }
+
+ return Point();
+}
+
+IMPL_LINK(CellEditSourceImpl, NotifyHdl, EENotify*, aNotify)
+{
+ if( aNotify && !mbNotificationsDisabled )
+ {
+ ::std::auto_ptr< SfxHint > aHint( SvxEditSourceHelper::EENotification2Hint( aNotify) );
+
+ if( aHint.get() )
+ Broadcast( *aHint.get() );
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+// --------------------------------------------------------------------
+// CellEditSource
+// --------------------------------------------------------------------
+
+CellEditSource::CellEditSource( const CellRef& xCell )
+{
+ mpImpl = new CellEditSourceImpl( xCell );
+ mpImpl->acquire();
+}
+
+// --------------------------------------------------------------------
+CellEditSource::CellEditSource( const CellRef& xCell, SdrView& rView, const Window& rWindow )
+{
+ mpImpl = new CellEditSourceImpl( xCell, rView, rWindow );
+ mpImpl->acquire();
+}
+
+// --------------------------------------------------------------------
+
+CellEditSource::CellEditSource( CellEditSourceImpl* pImpl )
+{
+ mpImpl = pImpl;
+ mpImpl->acquire();
+}
+
+//------------------------------------------------------------------------
+CellEditSource::~CellEditSource()
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ mpImpl->release();
+}
+
+//------------------------------------------------------------------------
+SvxEditSource* CellEditSource::Clone() const
+{
+ return new CellEditSource( mpImpl );
+}
+
+//------------------------------------------------------------------------
+SvxTextForwarder* CellEditSource::GetTextForwarder()
+{
+ return mpImpl->GetTextForwarder();
+}
+
+//------------------------------------------------------------------------
+SvxEditViewForwarder* CellEditSource::GetEditViewForwarder( sal_Bool bCreate )
+{
+ return mpImpl->GetEditViewForwarder( bCreate );
+}
+
+//------------------------------------------------------------------------
+
+SvxViewForwarder* CellEditSource::GetViewForwarder()
+{
+ return this;
+}
+
+//------------------------------------------------------------------------
+
+void CellEditSource::UpdateData()
+{
+ mpImpl->UpdateData();
+}
+
+//------------------------------------------------------------------------
+
+SfxBroadcaster& CellEditSource::GetBroadcaster() const
+{
+ return *mpImpl;
+}
+
+//------------------------------------------------------------------------
+
+void CellEditSource::lock()
+{
+ mpImpl->lock();
+}
+
+//------------------------------------------------------------------------
+
+void CellEditSource::unlock()
+{
+ mpImpl->unlock();
+}
+
+//------------------------------------------------------------------------
+
+BOOL CellEditSource::IsValid() const
+{
+ return mpImpl->IsValid();
+}
+
+//------------------------------------------------------------------------
+
+Rectangle CellEditSource::GetVisArea() const
+{
+ return mpImpl->GetVisArea();
+}
+
+//------------------------------------------------------------------------
+
+Point CellEditSource::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ return mpImpl->LogicToPixel( rPoint, rMapMode );
+}
+
+//------------------------------------------------------------------------
+
+Point CellEditSource::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ return mpImpl->PixelToLogic( rPoint, rMapMode );
+}
+
+//------------------------------------------------------------------------
+
+void CellEditSource::addRange( SvxUnoTextRangeBase* pNewRange )
+{
+ mpImpl->addRange( pNewRange );
+}
+
+//------------------------------------------------------------------------
+
+void CellEditSource::removeRange( SvxUnoTextRangeBase* pOldRange )
+{
+ mpImpl->removeRange( pOldRange );
+}
+
+//------------------------------------------------------------------------
+
+const SvxUnoTextRangeBaseList& CellEditSource::getRanges() const
+{
+ return mpImpl->getRanges();
+}
+
+//------------------------------------------------------------------------
+
+void CellEditSource::ChangeModel( SdrModel* pNewModel )
+{
+ mpImpl->ChangeModel( pNewModel );
+}
+
+//------------------------------------------------------------------------
+
+} }
diff --git a/svx/source/table/celleditsource.hxx b/svx/source/table/celleditsource.hxx
new file mode 100644
index 000000000000..561086106fbf
--- /dev/null
+++ b/svx/source/table/celleditsource.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SVX_TABLE_CELLEDITSOURCE_HXX
+#define SVX_TABLE_CELLEDITSOURCE_HXX
+
+#include "cell.hxx"
+#include "celltypes.hxx"
+#include "editeng/unoedsrc.hxx"
+
+class SvxTextForwarder;
+class SdrObject;
+class SdrModel;
+class SdrView;
+class Window;
+
+namespace sdr { namespace table {
+
+class CellEditSourceImpl;
+
+class CellEditSource : public SvxEditSource, public SvxViewForwarder
+{
+public:
+ CellEditSource( const CellRef& xCell );
+
+ /** Since the views don't broadcast their dying, make sure that
+ this object gets destroyed if the view becomes invalid
+
+ The window is necessary, since our views can display on multiple windows
+ */
+ CellEditSource( const CellRef& xCell, SdrView& rView, const Window& rViewWindow );
+ virtual ~CellEditSource();
+
+ virtual SvxEditSource* Clone() const;
+ virtual SvxTextForwarder* GetTextForwarder();
+ virtual SvxViewForwarder* GetViewForwarder();
+ virtual SvxEditViewForwarder* GetEditViewForwarder( sal_Bool bCreate = sal_False );
+ virtual void UpdateData();
+
+ virtual void addRange( SvxUnoTextRangeBase* pNewRange );
+ virtual void removeRange( SvxUnoTextRangeBase* pOldRange );
+ virtual const SvxUnoTextRangeBaseList& getRanges() const;
+
+ virtual SfxBroadcaster& GetBroadcaster() const;
+
+ void lock();
+ void unlock();
+
+ // the SvxViewForwarder interface
+ virtual BOOL IsValid() const;
+ virtual Rectangle GetVisArea() const;
+ virtual Point LogicToPixel( const Point&, const MapMode& ) const;
+ virtual Point PixelToLogic( const Point&, const MapMode& ) const;
+
+ void ChangeModel( SdrModel* pNewModel );
+
+private:
+ CellEditSource( CellEditSourceImpl* pImpl );
+
+ CellEditSourceImpl* mpImpl;
+};
+
+} }
+
+#endif
diff --git a/svx/source/table/cellrange.cxx b/svx/source/table/cellrange.cxx
new file mode 100644
index 000000000000..29fc043090a3
--- /dev/null
+++ b/svx/source/table/cellrange.cxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "cellrange.hxx"
+
+// -----------------------------------------------------------------------------
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::table;
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+// -----------------------------------------------------------------------------
+// CellRange
+// -----------------------------------------------------------------------------
+
+CellRange::CellRange( const TableModelRef & xTable, sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom )
+: mxTable( xTable )
+, mnLeft(nLeft)
+, mnTop(nTop)
+, mnRight(nRight)
+, mnBottom(nBottom)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+CellRange::~CellRange()
+{
+}
+
+// -----------------------------------------------------------------------------
+// ICellRange
+// -----------------------------------------------------------------------------
+
+sal_Int32 CellRange::getLeft()
+{
+ return mnLeft;
+}
+
+sal_Int32 CellRange::getTop()
+{
+ return mnTop;
+}
+
+sal_Int32 CellRange::getRight()
+{
+ return mnRight;
+}
+
+sal_Int32 CellRange::getBottom()
+{
+ return mnBottom;
+}
+
+Reference< XTable > CellRange::getTable()
+{
+ return mxTable.get();
+}
+
+// -----------------------------------------------------------------------------
+// XCellRange
+// -----------------------------------------------------------------------------
+
+Reference< XCell > SAL_CALL CellRange::getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ return mxTable->getCellByPosition( mnLeft + nColumn, mnTop + nRow );
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XCellRange > SAL_CALL CellRange::getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ if( (nLeft >= 0 ) && (nTop >= 0) && (nRight >= nLeft) && (nBottom >= nTop) )
+ {
+ nLeft += mnLeft;
+ nTop += mnTop;
+ nRight += mnLeft;
+ nBottom += mnTop;
+
+ const sal_Int32 nMaxColumns = (mnRight == -1) ? mxTable->getColumnCount() : mnLeft;
+ const sal_Int32 nMaxRows = (mnBottom == -1) ? mxTable->getRowCount() : mnBottom;
+ if( (nLeft < nMaxColumns) && (nRight < nMaxColumns) && (nTop < nMaxRows) && (nBottom < nMaxRows) )
+ {
+ return mxTable->getCellRangeByPosition( nLeft, nTop, nRight, nBottom );
+ }
+ }
+ throw IndexOutOfBoundsException();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XCellRange > SAL_CALL CellRange::getCellRangeByName( const OUString& /*aRange*/ ) throw (RuntimeException)
+{
+ return Reference< XCellRange >();
+}
+
+// -----------------------------------------------------------------------------
+
+} }
diff --git a/svx/source/table/cellrange.hxx b/svx/source/table/cellrange.hxx
new file mode 100644
index 000000000000..8932bc735ff7
--- /dev/null
+++ b/svx/source/table/cellrange.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_CELLRANGE_HXX_
+#define _SVX_CELLRANGE_HXX_
+
+#include <com/sun/star/table/XCellRange.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+#include "tablemodel.hxx"
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+// -----------------------------------------------------------------------------
+// CellRange
+// -----------------------------------------------------------------------------
+
+class CellRange : public ::cppu::WeakAggImplHelper1< ::com::sun::star::table::XCellRange >, public ICellRange
+{
+public:
+ CellRange( const TableModelRef & xTable, sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom );
+ virtual ~CellRange();
+
+ // ICellRange
+ virtual sal_Int32 getLeft();
+ virtual sal_Int32 getTop();
+ virtual sal_Int32 getRight();
+ virtual sal_Int32 getBottom();
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XTable > getTable();
+
+ // XCellRange
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell > SAL_CALL getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > SAL_CALL getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > SAL_CALL getCellRangeByName( const ::rtl::OUString& aRange ) throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ TableModelRef mxTable;
+ sal_Int32 mnLeft;
+ sal_Int32 mnTop;
+ sal_Int32 mnRight;
+ sal_Int32 mnBottom;
+};
+
+} }
+
+#endif
diff --git a/svx/source/table/celltypes.hxx b/svx/source/table/celltypes.hxx
new file mode 100644
index 000000000000..78ef7b617968
--- /dev/null
+++ b/svx/source/table/celltypes.hxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_CELLTYPES_HXX_
+#define _SVX_CELLTYPES_HXX_
+
+#include <rtl/ref.hxx>
+#include <vector>
+
+namespace sdr { namespace table {
+
+class Cell;
+class TableModel;
+class TableRow;
+class TableColumn;
+class TableRows;
+class TableColumns;
+typedef rtl::Reference< Cell > CellRef;
+typedef rtl::Reference< TableModel > TableModelRef;
+typedef rtl::Reference< TableRow > TableRowRef;
+typedef rtl::Reference< TableColumn > TableColumnRef;
+typedef rtl::Reference< TableRows > TableRowsRef;
+typedef rtl::Reference< TableColumns > TableColumnsRef;
+typedef std::vector< CellRef > CellVector;
+typedef std::vector< TableRowRef > RowVector;
+typedef std::vector< TableColumnRef > ColumnVector;
+
+class TableDesignUser
+{
+public:
+ virtual bool isInUse() = 0;
+};
+
+template< typename T >
+class RangeIterator
+{
+public:
+ /** creates an iterator from rStart (including) to rEnd (excluding) if
+ bForeward is true or from nEnd (excluding to nStart (including).
+ rStart must be <= rEnd.
+ */
+ RangeIterator( const T& rStart, const T& rEnd, bool bForeward = true )
+ {
+ if( bForeward )
+ {
+ maIter = rStart;
+ maEnd = rEnd;
+ }
+ else
+ {
+ maIter = rEnd-1;
+ maEnd = rStart-1;
+ }
+ }
+
+ /* returns true if the next call to next() will return true also. */
+ bool hasNext() const
+ {
+ return maIter != maEnd;
+ }
+
+ /* iterates in the configured direction and returns true if rValue
+ now contains a valid positon in the range of this iterator */
+ bool next( T& rValue )
+ {
+ if( maIter == maEnd )
+ return false;
+
+ rValue = maIter;
+ if( maIter < maEnd )
+ maIter++;
+ else
+ maIter--;
+ return true;
+ }
+
+private:
+ T maEnd;
+ T maIter;
+};
+
+} }
+
+#endif
+
diff --git a/svx/source/table/makefile.mk b/svx/source/table/makefile.mk
new file mode 100644
index 000000000000..1eaaef12aa02
--- /dev/null
+++ b/svx/source/table/makefile.mk
@@ -0,0 +1,80 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=svxpch
+PROJECTPCHSOURCE=$(PRJ)$/util$/svxpch
+
+PRJNAME=svx
+TARGET=table
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE;
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+LIB1TARGET= $(SLB)$/$(TARGET)-core.lib
+LIB1OBJFILES= \
+ $(SLO)$/propertyset.obj\
+ $(SLO)$/cell.obj\
+ $(SLO)$/cellrange.obj\
+ $(SLO)$/cellcursor.obj\
+ $(SLO)$/tablerow.obj\
+ $(SLO)$/tablerows.obj\
+ $(SLO)$/tablecolumn.obj\
+ $(SLO)$/tablecolumns.obj\
+ $(SLO)$/tablemodel.obj\
+ $(SLO)$/svdotable.obj\
+ $(SLO)$/viewcontactoftableobj.obj\
+ $(SLO)$/tablelayouter.obj\
+ $(SLO)$/tablehandles.obj\
+ $(SLO)$/tablecontroller.obj\
+ $(SLO)$/tableundo.obj
+
+LIB2TARGET= $(SLB)$/$(TARGET).lib
+LIB2OBJFILES= \
+ $(SLO)$/celleditsource.obj \
+ $(SLO)$/tabledesign.obj \
+ $(SLO)$/accessibletableshape.obj \
+ $(SLO)$/accessiblecell.obj \
+ $(SLO)$/tablertfexporter.obj \
+ $(SLO)$/tablertfimporter.obj
+
+SLOFILES = $(LIB1OBJFILES) $(LIB2OBJFILES)
+
+SRS1NAME=table
+SRC1FILES= table.src
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/svx/source/table/propertyset.cxx b/svx/source/table/propertyset.cxx
new file mode 100644
index 000000000000..f5297afc770d
--- /dev/null
+++ b/svx/source/table/propertyset.cxx
@@ -0,0 +1,259 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "propertyset.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+
+namespace comphelper {
+
+// -----------------------------------------------------------------------------
+// FastPropertySetInfo
+// -----------------------------------------------------------------------------
+
+FastPropertySetInfo::FastPropertySetInfo()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+FastPropertySetInfo::FastPropertySetInfo( const PropertyVector& rProps )
+{
+ addProperties( rProps );
+}
+
+// -----------------------------------------------------------------------------
+
+FastPropertySetInfo::~FastPropertySetInfo()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void FastPropertySetInfo::addProperty( const Property& rProperty )
+{
+ maProperties.push_back( rProperty );
+ maMap[ rProperty.Name ] = maProperties.size() - 1;
+}
+
+// -----------------------------------------------------------------------------
+
+void FastPropertySetInfo::addProperties( const PropertyVector& rProps )
+{
+ sal_uInt32 nIndex = maProperties.size();
+ sal_uInt32 nCount = rProps.size();
+ maProperties.resize( nIndex + nCount );
+ PropertyVector::const_iterator aIter( rProps.begin() );
+ while( nCount-- )
+ {
+ const Property& rProperty = (*aIter++);
+ maProperties[nIndex] = rProperty;
+ maMap[ rProperty.Name ] = nIndex++;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+const Property& FastPropertySetInfo::getProperty( const OUString& aName ) throw (UnknownPropertyException )
+{
+ PropertyMap::iterator aIter( maMap.find( aName ) );
+ if( aIter == maMap.end() )
+ throw UnknownPropertyException();
+ return maProperties[(*aIter).second];
+}
+
+// -----------------------------------------------------------------------------
+
+const Property* FastPropertySetInfo::hasProperty( const OUString& aName )
+{
+ PropertyMap::iterator aIter( maMap.find( aName ) );
+ if( aIter == maMap.end() )
+ return 0;
+ else
+ return &maProperties[(*aIter).second];
+}
+
+// -----------------------------------------------------------------------------
+// XPropertySetInfo
+// -----------------------------------------------------------------------------
+
+Sequence< Property > SAL_CALL FastPropertySetInfo::getProperties() throw (RuntimeException)
+{
+ return Sequence< Property >( &maProperties[0], maProperties.size() );
+}
+
+// -----------------------------------------------------------------------------
+
+Property SAL_CALL FastPropertySetInfo::getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException)
+{
+ return getProperty( aName );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL FastPropertySetInfo::hasPropertyByName( const OUString& aName ) throw (RuntimeException)
+{
+ return hasProperty( aName ) != 0 ? sal_True : sal_False;;
+}
+
+// -----------------------------------------------------------------------------
+// FastPropertySet
+// -----------------------------------------------------------------------------
+
+FastPropertySet::FastPropertySet( const rtl::Reference< FastPropertySetInfo >& xInfo )
+: mxInfo( xInfo )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+FastPropertySet::~FastPropertySet()
+{
+}
+
+// -----------------------------------------------------------------------------
+// XPropertySet
+// -----------------------------------------------------------------------------
+
+Reference< XPropertySetInfo > SAL_CALL FastPropertySet::getPropertySetInfo( ) throw (RuntimeException)
+{
+ return Reference< XPropertySetInfo >( mxInfo.get() );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL FastPropertySet::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ setFastPropertyValue( mxInfo->getProperty( aPropertyName ).Handle, aValue );
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL FastPropertySet::getPropertyValue( const OUString& aPropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ return getFastPropertyValue( mxInfo->getProperty( aPropertyName ).Handle );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL FastPropertySet::addPropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL FastPropertySet::removePropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL FastPropertySet::addVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL FastPropertySet::removeVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+// XMultiPropertySet
+// -----------------------------------------------------------------------------
+
+void SAL_CALL FastPropertySet::setPropertyValues( const Sequence< OUString >& aPropertyNames, const Sequence< Any >& aValues ) throw (PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ const OUString* pPropertyNames = aPropertyNames.getConstArray();
+ const Any* pValues = aValues.getConstArray();
+ sal_Int32 nCount = aPropertyNames.getLength();
+ if( nCount != aValues.getLength() )
+ throw IllegalArgumentException();
+
+ while( nCount-- )
+ {
+ const Property* pProperty = mxInfo->hasProperty( *pPropertyNames++ );
+ if( pProperty ) try
+ {
+ setFastPropertyValue( pProperty->Handle, *pValues );
+ }
+ catch( UnknownPropertyException& )
+ {
+ }
+ pValues++;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+Sequence< Any > SAL_CALL FastPropertySet::getPropertyValues( const Sequence< OUString >& aPropertyNames ) throw (RuntimeException)
+{
+ sal_Int32 nCount = aPropertyNames.getLength();
+ Sequence< Any > aValues( nCount );
+
+ const OUString* pPropertyNames = aPropertyNames.getConstArray();
+ Any* pValues = aValues.getArray();
+ while( nCount-- )
+ {
+ const Property* pProperty = mxInfo->hasProperty( *pPropertyNames++ );
+ if( pProperty ) try
+ {
+ *pValues = getFastPropertyValue( pProperty->Handle );
+ }
+ catch( UnknownPropertyException& )
+ {
+ }
+ pValues++;
+ }
+ return aValues;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL FastPropertySet::addPropertiesChangeListener( const Sequence< OUString >&, const Reference< XPropertiesChangeListener >& ) throw (RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL FastPropertySet::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& ) throw (RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL FastPropertySet::firePropertiesChangeEvent( const Sequence< OUString >&, const Reference< XPropertiesChangeListener >& ) throw (RuntimeException)
+{
+}
+
+}
diff --git a/svx/source/table/propertyset.hxx b/svx/source/table/propertyset.hxx
new file mode 100644
index 000000000000..241395272889
--- /dev/null
+++ b/svx/source/table/propertyset.hxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _COMPHELPER_PROPERTYSET_HXX_
+#define _COMPHELPER_PROPERTYSET_HXX_
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/beans/XFastPropertySet.hpp>
+#include <rtl/ref.hxx>
+#include <functional>
+#include <hash_map>
+#include <vector>
+
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase3.hxx>
+
+namespace comphelper {
+
+// -----------------------------------------------------------------------------
+
+typedef std::vector< ::com::sun::star::beans::Property > PropertyVector;
+typedef std::hash_map< ::rtl::OUString, ::sal_uInt32, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > PropertyMap;
+
+// -----------------------------------------------------------------------------
+
+class FastPropertySetInfo : public ::cppu::WeakAggImplHelper1< ::com::sun::star::beans::XPropertySetInfo >
+{
+public:
+ FastPropertySetInfo();
+ FastPropertySetInfo( const PropertyVector& rProps );
+ virtual ~FastPropertySetInfo();
+
+ void addProperty( const ::com::sun::star::beans::Property& rProperty );
+ void addProperties( const PropertyVector& rProps );
+
+ const ::com::sun::star::beans::Property& getProperty( const ::rtl::OUString& aName ) throw (::com::sun::star::beans::UnknownPropertyException );
+ const ::com::sun::star::beans::Property* hasProperty( const ::rtl::OUString& aName );
+
+ // XPropertySetInfo
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getProperties( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ PropertyVector maProperties;
+ PropertyMap maMap;
+};
+
+// -----------------------------------------------------------------------------
+
+class FastPropertySet : public ::cppu::WeakAggImplHelper3< ::com::sun::star::beans::XPropertySet, ::com::sun::star::beans::XMultiPropertySet, ::com::sun::star::beans::XFastPropertySet >
+{
+public:
+ FastPropertySet( const rtl::Reference< FastPropertySetInfo >& xInfo );
+ virtual ~FastPropertySet();
+
+ // XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XMultiPropertySet
+// virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aValues ) throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL getPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addPropertiesChangeListener( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removePropertiesChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL firePropertiesChangeEvent( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XFastPropertySet
+ virtual void SAL_CALL setFastPropertyValue( ::sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) = 0;
+ virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue( ::sal_Int32 nHandle ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) = 0;
+
+private:
+ rtl::Reference< FastPropertySetInfo > mxInfo;
+};
+
+}
+
+#endif
diff --git a/svx/source/table/svdotable.cxx b/svx/source/table/svdotable.cxx
new file mode 100644
index 000000000000..e928f94d88ec
--- /dev/null
+++ b/svx/source/table/svdotable.cxx
@@ -0,0 +1,2820 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// 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 <svl/style.hxx>
+#include "editeng/editstat.hxx"
+#include "editeng/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 "tablemodel.hxx"
+#include "cell.hxx"
+#include "svx/xflclit.hxx"
+#include "tablelayouter.hxx"
+#include "svx/svdetc.hxx"
+#include "tablehandles.hxx"
+#include "editeng/boxitem.hxx"
+#include "svx/framelink.hxx"
+#include "svx/sdr/table/tabledesign.hxx"
+#include "svx/svdundo.hxx"
+#include "svdstr.hrc"
+#include "svdglob.hxx"
+#include "editeng/writingmodeitem.hxx"
+#include "editeng/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;
+}
+
+
+// --------------------------------------------------------------------
+
+const TableLayouter& SdrTableObj::getTableLayouter() const
+{
+ OSL_ENSURE(mpImpl && mpImpl->mpLayouter, "getTableLayouter() error: no mpImpl or mpLayouter (!)");
+ return *(mpImpl->mpLayouter);
+}
+
+// --------------------------------------------------------------------
+
+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();
+ }
+};
+
+// --------------------------------------------------------------------
+
+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::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() const
+{
+ return SdrTextObj::TakeXorPoly();
+}
+
+// --------------------------------------------------------------------
+
+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()->IsUndoEnabled() )
+ 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::AdjustToMaxRect( const Rectangle& rMaxRect, bool /* bShrinkOnly = false */ )
+{
+ Rectangle aAdjustRect( rMaxRect );
+ aAdjustRect.setHeight( GetLogicRect().getHeight() );
+ SetLogicRect( aAdjustRect );
+}
+
+// --------------------------------------------------------------------
+
+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
+
+bool SdrTableObj::hasSpecialDrag() const
+{
+ return true;
+}
+
+bool SdrTableObj::beginSpecialDrag(SdrDragStat& rDrag) const
+{
+ const SdrHdl* pHdl = rDrag.GetHdl();
+ const 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(false);
+ rDrag.SetNoSnap(true);
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SdrTableObj::applySpecialDrag(SdrDragStat& rDrag)
+{
+ bool bRet(true);
+ const SdrHdl* pHdl = rDrag.GetHdl();
+ const 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:
+ {
+ const Rectangle aNewRectangle(ImpDragCalcRect(rDrag));
+
+ if(aNewRectangle != aRect)
+ {
+ NbcSetLogicRect(aNewRectangle);
+ }
+
+ break;
+ }
+
+ case HDL_MOVE:
+ {
+ NbcMove( Size( rDrag.GetDX(), rDrag.GetDY() ) );
+ break;
+ }
+
+ case HDL_USER:
+ {
+ rDrag.SetEndDragChangesAttributes(false);
+ rDrag.SetNoSnap(true);
+ const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl );
+
+ if( pEdgeHdl )
+ {
+ if( GetModel() && IsInserted() )
+ {
+ rDrag.SetEndDragChangesAttributes(true);
+ }
+
+ mpImpl->DragEdge( pEdgeHdl->IsHorizontalEdge(), pEdgeHdl->GetPointNum(), pEdgeHdl->GetValidDragOffset( rDrag ) );
+ }
+ break;
+ }
+
+ default:
+ {
+ bRet = false;
+ }
+ }
+
+ return bRet;
+}
+
+String SdrTableObj::getSpecialDragComment(const SdrDragStat& rDrag) const
+{
+ return SdrTextObj::getSpecialDragComment( rDrag );
+}
+
+basegfx::B2DPolyPolygon SdrTableObj::getSpecialDragPoly(const SdrDragStat& rDrag) const
+{
+ basegfx::B2DPolyPolygon aRetval;
+ const SdrHdl* pHdl = rDrag.GetHdl();
+
+ if( pHdl && (HDL_USER == pHdl->GetKind()) )
+ {
+ const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl );
+
+ if( pEdgeHdl )
+ {
+ aRetval = pEdgeHdl->getSpecialDragPoly( rDrag );
+ }
+ }
+
+ 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
+ SetBoundRectDirty();
+ 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 = Cell::create( *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();
+}
+
+// --------------------------------------------------------------------
+
+
+
+} }
diff --git a/svx/source/table/table.src b/svx/source/table/table.src
new file mode 100644
index 000000000000..9ef928599575
--- /dev/null
+++ b/svx/source/table/table.src
@@ -0,0 +1,34 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "svx/dialogs.hrc"
+
+String RID_SVXSTR_STYLEFAMILY_TABLEDESIGN
+{
+ Text [ en-US ] = "Table Design Styles";
+};
+
diff --git a/svx/source/table/tablecolumn.cxx b/svx/source/table/tablecolumn.cxx
new file mode 100644
index 000000000000..9c0df0e77664
--- /dev/null
+++ b/svx/source/table/tablecolumn.cxx
@@ -0,0 +1,305 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <com/sun/star/lang/DisposedException.hpp>
+
+#include "tablecolumn.hxx"
+#include "tableundo.hxx"
+#include "svx/svdmodel.hxx"
+#include "svx/svdotable.hxx"
+
+// -----------------------------------------------------------------------------
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::beans;
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+const sal_Int32 Property_Width = 0;
+const sal_Int32 Property_OptimalWidth = 1;
+const sal_Int32 Property_IsVisible = 2;
+const sal_Int32 Property_IsStartOfNewPage = 3;
+
+// -----------------------------------------------------------------------------
+// TableRow
+// -----------------------------------------------------------------------------
+
+TableColumn::TableColumn( const TableModelRef& xTableModel, sal_Int32 nColumn )
+: TableColumnBase( getStaticPropertySetInfo() )
+, mxTableModel( xTableModel )
+, mnColumn( nColumn )
+, mnWidth( 0 )
+, mbOptimalWidth( sal_True )
+, mbIsVisible( sal_True )
+, mbIsStartOfNewPage( sal_False )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+TableColumn::~TableColumn()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void TableColumn::dispose()
+{
+ mxTableModel.clear();
+}
+
+// -----------------------------------------------------------------------------
+
+void TableColumn::throwIfDisposed() const throw (::com::sun::star::uno::RuntimeException)
+{
+ if( !mxTableModel.is() )
+ throw DisposedException();
+}
+
+// -----------------------------------------------------------------------------
+
+TableColumn& TableColumn::operator=( const TableColumn& r )
+{
+ mnWidth = r.mnWidth;
+ mbOptimalWidth = r.mbOptimalWidth;
+ mbIsVisible = r.mbIsVisible;
+ mbIsStartOfNewPage = r.mbIsStartOfNewPage;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------------
+// XCellRange
+// -----------------------------------------------------------------------------
+
+Reference< XCell > SAL_CALL TableColumn::getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ throwIfDisposed();
+ if( nColumn != 0 )
+ throw IndexOutOfBoundsException();
+
+ return mxTableModel->getCellByPosition( mnColumn, nRow );
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XCellRange > SAL_CALL TableColumn::getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ throwIfDisposed();
+ if( (nTop >= 0 ) && (nLeft == 0) && (nBottom >= nTop) && (nRight == 0) )
+ {
+ return mxTableModel->getCellRangeByPosition( mnColumn, nTop, mnColumn, nBottom );
+ }
+ throw IndexOutOfBoundsException();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XCellRange > SAL_CALL TableColumn::getCellRangeByName( const OUString& /*aRange*/ ) throw (RuntimeException)
+{
+ return Reference< XCellRange >();
+}
+
+// -----------------------------------------------------------------------------
+// XNamed
+// -----------------------------------------------------------------------------
+
+OUString SAL_CALL TableColumn::getName() throw (RuntimeException)
+{
+ return maName;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableColumn::setName( const OUString& aName ) throw (RuntimeException)
+{
+ maName = aName;
+}
+
+// -----------------------------------------------------------------------------
+// XFastPropertySet
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableColumn::setFastPropertyValue( sal_Int32 nHandle, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, RuntimeException)
+{
+ bool bOk = false;
+ bool bChange = false;
+
+ SdrModel* pModel = mxTableModel->getSdrTableObj()->GetModel();
+
+ TableColumnUndo* pUndo = 0;
+ if( mxTableModel.is() && mxTableModel->getSdrTableObj() && mxTableModel->getSdrTableObj()->IsInserted() && pModel && pModel->IsUndoEnabled() )
+ {
+ TableColumnRef xThis( this );
+ pUndo = new TableColumnUndo( xThis );
+ }
+
+ switch( nHandle )
+ {
+ case Property_Width:
+ {
+ sal_Int32 nWidth = mnWidth;
+ bOk = aValue >>= nWidth;
+ if( bOk && (nWidth != mnWidth) )
+ {
+ mnWidth = nWidth;
+ mbOptimalWidth = mnWidth == 0;
+ bChange = true;
+ }
+ break;
+ }
+ case Property_OptimalWidth:
+ {
+ sal_Bool bOptimalWidth = mbOptimalWidth;
+ bOk = aValue >>= bOptimalWidth;
+ if( bOk && (mbOptimalWidth != bOptimalWidth) )
+ {
+ mbOptimalWidth = bOptimalWidth;
+ if( bOptimalWidth )
+ mnWidth = 0;
+ bChange = true;
+ }
+ break;
+ }
+ case Property_IsVisible:
+ {
+ sal_Bool bIsVisible = mbIsVisible;
+ bOk = aValue >>= bIsVisible;
+ if( bOk && (mbIsVisible != bIsVisible) )
+ {
+ mbIsVisible = bIsVisible;
+ bChange = true;
+ }
+ break;
+ }
+
+ case Property_IsStartOfNewPage:
+ {
+ sal_Bool bIsStartOfNewPage = mbIsStartOfNewPage;
+ bOk = aValue >>= bIsStartOfNewPage;
+ if( bOk && (mbIsStartOfNewPage != bIsStartOfNewPage) )
+ {
+ mbIsStartOfNewPage = bIsStartOfNewPage;
+ bChange = true;
+ }
+ break;
+ }
+ default:
+ throw UnknownPropertyException();
+ }
+ if( !bOk )
+ throw IllegalArgumentException();
+
+ if( bChange )
+ {
+ if( pUndo )
+ {
+ pModel->AddUndo( pUndo );
+ pUndo = 0;
+ }
+ mxTableModel->setModified(sal_True);
+ }
+
+ if( pUndo )
+ delete pUndo;
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL TableColumn::getFastPropertyValue( sal_Int32 nHandle ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ switch( nHandle )
+ {
+ case Property_Width: return Any( mnWidth );
+ case Property_OptimalWidth: return Any( mbOptimalWidth );
+ case Property_IsVisible: return Any( mbIsVisible );
+ case Property_IsStartOfNewPage: return Any( mbIsStartOfNewPage );
+ default: throw UnknownPropertyException();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+rtl::Reference< ::comphelper::FastPropertySetInfo > TableColumn::getStaticPropertySetInfo()
+{
+ static rtl::Reference< ::comphelper::FastPropertySetInfo > xInfo;
+ if( !xInfo.is() )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !xInfo.is() )
+ {
+ comphelper::PropertyVector aProperties(6);
+
+ aProperties[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ) );
+ aProperties[0].Handle = Property_Width;
+ aProperties[0].Type = ::getCppuType((const sal_Int32*)0);
+ aProperties[0].Attributes = 0;
+
+ aProperties[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OptimalWidth" ) );
+ aProperties[1].Handle = Property_OptimalWidth;
+ aProperties[1].Type = ::getBooleanCppuType();
+ aProperties[1].Attributes = 0;
+
+ aProperties[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVisible" ) );
+ aProperties[2].Handle = Property_IsVisible;
+ aProperties[2].Type = ::getBooleanCppuType();
+ aProperties[2].Attributes = 0;
+
+ aProperties[3].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsStartOfNewPage" ) );
+ aProperties[3].Handle = Property_IsStartOfNewPage;
+ aProperties[3].Type = ::getBooleanCppuType();
+ aProperties[3].Attributes = 0;
+
+ aProperties[4].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) );
+ aProperties[4].Handle = Property_Width;
+ aProperties[4].Type = ::getCppuType((const sal_Int32*)0);
+ aProperties[4].Attributes = 0;
+
+ aProperties[5].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OptimalSize" ) );
+ aProperties[5].Handle = Property_OptimalWidth;
+ aProperties[5].Type = ::getBooleanCppuType();
+ aProperties[5].Attributes = 0;
+
+ xInfo.set( new ::comphelper::FastPropertySetInfo(aProperties) );
+ }
+ }
+
+ return xInfo;
+}
+
+// -----------------------------------------------------------------------------
+
+} }
diff --git a/svx/source/table/tablecolumn.hxx b/svx/source/table/tablecolumn.hxx
new file mode 100644
index 000000000000..e020354fe1a7
--- /dev/null
+++ b/svx/source/table/tablecolumn.hxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_TABLECOLUMN_HXX_
+#define _SVX_TABLECOLUMN_HXX_
+
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <cppuhelper/implbase2.hxx>
+
+#include "propertyset.hxx"
+#include "tablemodel.hxx"
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+// -----------------------------------------------------------------------------
+// TableColumn
+// -----------------------------------------------------------------------------
+
+typedef ::cppu::ImplInheritanceHelper2< ::comphelper::FastPropertySet, ::com::sun::star::table::XCellRange, ::com::sun::star::container::XNamed > TableColumnBase;
+
+class TableColumn : public TableColumnBase
+{
+ friend class TableColumnUndo;
+ friend class TableModel;
+public:
+ TableColumn( const TableModelRef& xTableModel, sal_Int32 nColumn );
+ virtual ~TableColumn();
+
+ void dispose();
+ void throwIfDisposed() const throw (::com::sun::star::uno::RuntimeException);
+
+ TableColumn& operator=( const TableColumn& );
+
+ // XCellRange
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell > SAL_CALL getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > SAL_CALL getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > SAL_CALL getCellRangeByName( const ::rtl::OUString& aRange ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XNamed
+ virtual ::rtl::OUString SAL_CALL getName() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XFastPropertySet
+ virtual void SAL_CALL setFastPropertyValue( ::sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue( ::sal_Int32 nHandle ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+private:
+ static rtl::Reference< ::comphelper::FastPropertySetInfo > getStaticPropertySetInfo();
+
+ TableModelRef mxTableModel;
+ sal_Int32 mnColumn;
+ sal_Int32 mnWidth;
+ sal_Bool mbOptimalWidth;
+ sal_Bool mbIsVisible;
+ sal_Bool mbIsStartOfNewPage;
+ ::rtl::OUString maName;
+};
+
+} }
+
+#endif
diff --git a/svx/source/table/tablecolumns.cxx b/svx/source/table/tablecolumns.cxx
new file mode 100644
index 000000000000..7d0e89a252cd
--- /dev/null
+++ b/svx/source/table/tablecolumns.cxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <com/sun/star/lang/DisposedException.hpp>
+
+#include "tablecolumns.hxx"
+#include "tablecolumn.hxx"
+
+// -----------------------------------------------------------------------------
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::table;
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+// -----------------------------------------------------------------------------
+// TableColumns
+// -----------------------------------------------------------------------------
+
+TableColumns::TableColumns( const TableModelRef& xTableModel )
+: mxTableModel( xTableModel )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+TableColumns::~TableColumns()
+{
+ dispose();
+}
+
+// -----------------------------------------------------------------------------
+
+void TableColumns::dispose()
+{
+ mxTableModel.clear();
+}
+
+// -----------------------------------------------------------------------------
+
+void TableColumns::throwIfDisposed() const throw (::com::sun::star::uno::RuntimeException)
+{
+ if( !mxTableModel.is() )
+ throw DisposedException();
+}
+
+// -----------------------------------------------------------------------------
+// XTableRows
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableColumns::insertByIndex( sal_Int32 nIndex, sal_Int32 nCount ) throw (RuntimeException)
+{
+ throwIfDisposed();
+ mxTableModel->insertColumns( nIndex, nCount );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableColumns::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount ) throw (RuntimeException)
+{
+ throwIfDisposed();
+ mxTableModel->removeColumns( nIndex, nCount );
+}
+
+// -----------------------------------------------------------------------------
+// XIndexAccess
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL TableColumns::getCount() throw (RuntimeException)
+{
+ throwIfDisposed();
+ return mxTableModel->getColumnCount();
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL TableColumns::getByIndex( sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ throwIfDisposed();
+
+ if( ( Index < 0 ) || ( Index >= mxTableModel->getColumnCount() ) )
+ throw IndexOutOfBoundsException();
+
+ return Any( Reference< XCellRange >( mxTableModel->getColumn( Index ).get() ) );
+}
+
+// -----------------------------------------------------------------------------
+// XElementAccess
+// -----------------------------------------------------------------------------
+
+Type SAL_CALL TableColumns::getElementType() throw (RuntimeException)
+{
+ throwIfDisposed();
+
+ return XCellRange::static_type();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL TableColumns::hasElements() throw (RuntimeException)
+{
+ throwIfDisposed();
+
+ return mxTableModel->getColumnCount() != 0;
+}
+
+// -----------------------------------------------------------------------------
+
+} }
diff --git a/svx/source/table/tablecolumns.hxx b/svx/source/table/tablecolumns.hxx
new file mode 100644
index 000000000000..2a7be2851141
--- /dev/null
+++ b/svx/source/table/tablecolumns.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_TABLECOLUMNS_HXX_
+#define _SVX_TABLECOLUMNS_HXX_
+
+#include <com/sun/star/table/XTableColumns.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+#include "tablemodel.hxx"
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+// -----------------------------------------------------------------------------
+// TableColumns
+// -----------------------------------------------------------------------------
+
+class TableColumns : public ::cppu::WeakAggImplHelper1< ::com::sun::star::table::XTableColumns >
+{
+public:
+ TableColumns( const TableModelRef& xTableModel );
+ virtual ~TableColumns();
+
+ void dispose();
+ void throwIfDisposed() const throw (::com::sun::star::uno::RuntimeException);
+
+ // XTableColumns
+ virtual void SAL_CALL insertByIndex( sal_Int32 nIndex, sal_Int32 nCount ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeByIndex( sal_Int32 nIndex, sal_Int32 nCount ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( sal_Int32 Index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // Methods
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasElements() throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ TableModelRef mxTableModel;
+};
+
+} }
+
+#endif
diff --git a/svx/source/table/tablecontroller.cxx b/svx/source/table/tablecontroller.cxx
new file mode 100644
index 000000000000..4a0432c0c15f
--- /dev/null
+++ b/svx/source/table/tablecontroller.cxx
@@ -0,0 +1,2618 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "tablecontroller.hxx"
+
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/XMergeableCellRange.hpp>
+#include <com/sun/star/table/XMergeableCell.hpp>
+
+#include <sal/config.h>
+
+#include <vcl/svapp.hxx>
+#include <svl/whiter.hxx>
+
+#include <sfx2/request.hxx>
+
+#include <editeng/scripttypeitem.hxx>
+#include <svx/svdotable.hxx>
+#include <svx/sdr/overlay/overlayobjectcell.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <svx/svxids.hrc>
+#include <editeng/outlobj.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdetc.hxx>
+#include <editeng/editobj.hxx>
+#include "editeng/editstat.hxx"
+#include "editeng/unolingu.hxx"
+#include "svx/sdrpagewindow.hxx"
+#include <svx/selectioncontroller.hxx>
+#include <svx/svdmodel.hxx>
+#include "sdrpaintwindow.hxx"
+#include <svx/svxdlg.hxx>
+#include <editeng/boxitem.hxx>
+#include "cell.hxx"
+#include <editeng/borderline.hxx>
+#include <editeng/colritem.hxx>
+#include "editeng/bolnitem.hxx"
+#include "svdstr.hrc"
+#include "svdglob.hxx"
+#include "svx/svdpage.hxx"
+#include "tableundo.hxx"
+#include "tablelayouter.hxx"
+
+using ::rtl::OUString;
+using namespace ::sdr::table;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::style;
+
+namespace sdr { namespace table {
+
+// --------------------------------------------------------------------
+// class SvxTableControllerModifyListener
+// --------------------------------------------------------------------
+
+class SvxTableControllerModifyListener : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XModifyListener >
+{
+public:
+ SvxTableControllerModifyListener( SvxTableController* pController )
+ : mpController( pController ) {}
+
+ // 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);
+
+ SvxTableController* mpController;
+};
+
+// --------------------------------------------------------------------
+// XModifyListener
+// --------------------------------------------------------------------
+
+void SAL_CALL SvxTableControllerModifyListener::modified( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
+{
+ if( mpController )
+ mpController->onTableModified();
+}
+
+// --------------------------------------------------------------------
+// XEventListener
+// --------------------------------------------------------------------
+
+void SAL_CALL SvxTableControllerModifyListener::disposing( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
+{
+ mpController = 0;
+}
+
+// --------------------------------------------------------------------
+// class SvxTableController
+// --------------------------------------------------------------------
+
+rtl::Reference< sdr::SelectionController > CreateTableController( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController )
+{
+ return SvxTableController::create( pView, pObj, xRefController );
+}
+
+// --------------------------------------------------------------------
+
+rtl::Reference< sdr::SelectionController > SvxTableController::create( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController )
+{
+ if( xRefController.is() )
+ {
+ SvxTableController* pController = dynamic_cast< SvxTableController* >( xRefController.get() );
+ if( pController && (pController->mxTableObj.get() == pObj) && (pController->mpView == pView) )
+ return xRefController;
+ }
+ return new SvxTableController( pView, pObj );
+}
+
+// --------------------------------------------------------------------
+
+SvxTableController::SvxTableController( SdrObjEditView* pView, const SdrObject* pObj )
+: mbCellSelectionMode(false)
+, mbLeftButtonDown(false)
+, mpSelectionOverlay(0)
+, mpView( dynamic_cast< SdrView* >( pView ) )
+, mxTableObj( dynamic_cast< SdrTableObj* >( const_cast< SdrObject* >( pObj ) ) )
+, mpModel( 0 )
+, mnUpdateEvent( 0 )
+{
+ if( pObj )
+ mpModel = pObj->GetModel();
+
+ if( mxTableObj.is() )
+ {
+ static_cast< const SdrTableObj* >( pObj )->getActiveCellPos( maCursorFirstPos );
+ maCursorLastPos = maCursorFirstPos;
+
+ Reference< XTable > xTable( static_cast< const SdrTableObj* >( pObj )->getTable() );
+ if( xTable.is() )
+ {
+ mxModifyListener = new SvxTableControllerModifyListener( this );
+ xTable->addModifyListener( mxModifyListener );
+
+ mxTable.set( dynamic_cast< TableModel* >( xTable.get() ) );
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+SvxTableController::~SvxTableController()
+{
+ if( mnUpdateEvent )
+ {
+ Application::RemoveUserEvent( mnUpdateEvent );
+ }
+
+ if( mxModifyListener.is() && mxTableObj.get() )
+ {
+ Reference< XTable > xTable( static_cast< SdrTableObj* >( mxTableObj.get() )->getTable() );
+ if( xTable.is() )
+ {
+ xTable->removeModifyListener( mxModifyListener );
+ mxModifyListener.clear();
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+const sal_uInt16 ACTION_NONE = 0;
+const sal_uInt16 ACTION_GOTO_FIRST_CELL = 1;
+const sal_uInt16 ACTION_GOTO_FIRST_COLUMN = 2;
+const sal_uInt16 ACTION_GOTO_FIRST_ROW = 3;
+const sal_uInt16 ACTION_GOTO_LEFT_CELL = 4;
+const sal_uInt16 ACTION_GOTO_UP_CELL = 5;
+const sal_uInt16 ACTION_GOTO_RIGHT_CELL = 6;
+const sal_uInt16 ACTION_GOTO_DOWN_CELL = 7;
+const sal_uInt16 ACTION_GOTO_LAST_CELL = 8;
+const sal_uInt16 ACTION_GOTO_LAST_COLUMN = 9;
+const sal_uInt16 ACTION_GOTO_LAST_ROW = 10;
+const sal_uInt16 ACTION_EDIT_CELL = 11;
+const sal_uInt16 ACTION_STOP_TEXT_EDIT = 12;
+const sal_uInt16 ACTION_REMOVE_SELECTION = 13;
+const sal_uInt16 ACTION_START_SELECTION = 14;
+const sal_uInt16 ACTION_HANDLED_BY_VIEW = 15;
+const sal_uInt16 ACTION_TAB = 18;
+
+bool SvxTableController::onKeyInput(const KeyEvent& rKEvt, Window* pWindow )
+{
+ if( !checkTableObject() )
+ return false;
+
+ // check if we are read only
+ if( mpModel && mpModel->IsReadOnly())
+ {
+ switch( rKEvt.GetKeyCode().GetCode() )
+ {
+ case awt::Key::DOWN:
+ case awt::Key::UP:
+ case awt::Key::LEFT:
+ case awt::Key::RIGHT:
+ case awt::Key::TAB:
+ case awt::Key::HOME:
+ case awt::Key::END:
+ case awt::Key::NUM2:
+ case awt::Key::NUM4:
+ case awt::Key::NUM6:
+ case awt::Key::NUM8:
+ case awt::Key::ESCAPE:
+ case awt::Key::F2:
+ break;
+ default:
+ // tell the view we eat the event, no further processing needed
+ return true;
+ }
+ }
+
+ sal_uInt16 nAction = getKeyboardAction( rKEvt, pWindow );
+
+ return executeAction( nAction, ( rKEvt.GetKeyCode().IsShift() ) ? sal_True : sal_False, pWindow );
+}
+
+// --------------------------------------------------------------------
+// ::com::sun::star::awt::XMouseClickHandler:
+// --------------------------------------------------------------------
+
+bool SvxTableController::onMouseButtonDown(const MouseEvent& rMEvt, Window* pWindow )
+{
+ if( !pWindow || !checkTableObject() )
+ return false;
+
+ SdrViewEvent aVEvt;
+ if( !rMEvt.IsRight() && mpView->PickAnything(rMEvt,SDRMOUSEBUTTONDOWN, aVEvt) == SDRHIT_HANDLE )
+ return false;
+
+ TableHitKind eHit = static_cast< SdrTableObj* >(mxTableObj.get())->CheckTableHit( pWindow->PixelToLogic(rMEvt.GetPosPixel()), maMouseDownPos.mnCol, maMouseDownPos.mnRow, 0 );
+
+ mbLeftButtonDown = (rMEvt.GetClicks() == 1) && rMEvt.IsLeft();
+
+ if( eHit == SDRTABLEHIT_CELL )
+ {
+ StartSelection( maMouseDownPos );
+ return true;
+ }
+
+ if( rMEvt.IsRight() && eHit != SDRTABLEHIT_NONE )
+ return true; // right click will become context menu
+
+ // for cell selektion with the mouse remember our first hit
+ if( mbLeftButtonDown )
+ {
+ RemoveSelection();
+
+ Point aPnt(rMEvt.GetPosPixel());
+ if (pWindow!=NULL)
+ aPnt=pWindow->PixelToLogic(aPnt);
+
+ SdrHdl* pHdl = mpView->PickHandle(aPnt);
+
+ if( pHdl )
+ {
+ mbLeftButtonDown = false;
+ }
+ else
+ {
+ ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
+
+ if( !pWindow || !pTableObj || eHit == SDRTABLEHIT_NONE)
+ {
+ mbLeftButtonDown = false;
+ }
+ }
+ }
+
+ return false;
+}
+
+// --------------------------------------------------------------------
+
+bool SvxTableController::onMouseButtonUp(const MouseEvent& rMEvt, Window* /*pWin*/)
+{
+ if( !checkTableObject() )
+ return false;
+
+ mbLeftButtonDown = false;
+
+ if( rMEvt.GetClicks() == 2 )
+ return true;
+
+ return false;
+}
+
+// --------------------------------------------------------------------
+
+bool SvxTableController::onMouseMove(const MouseEvent& rMEvt, Window* pWindow )
+{
+ if( !checkTableObject() )
+ return false;
+
+ if( rMEvt.IsLeft() )
+ {
+ int i = 0;
+ i++;
+ }
+
+ SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
+ CellPos aPos;
+ if( mbLeftButtonDown && pTableObj && pTableObj->CheckTableHit( pWindow->PixelToLogic(rMEvt.GetPosPixel()), aPos.mnCol, aPos.mnRow, 0 ) != SDRTABLEHIT_NONE )
+ {
+ if(aPos != maMouseDownPos)
+ {
+ if( mbCellSelectionMode )
+ {
+ setSelectedCells( maMouseDownPos, aPos );
+ return true;
+ }
+ else
+ {
+ StartSelection( maMouseDownPos );
+ }
+ }
+ else if( mbCellSelectionMode )
+ {
+ UpdateSelection( aPos );
+ return true;
+ }
+ }
+ return false;
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::onSelectionHasChanged()
+{
+ bool bSelected = false;
+
+ SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
+ if( pTableObj && pTableObj->IsTextEditActive() )
+ {
+ pTableObj->getActiveCellPos( maCursorFirstPos );
+ maCursorLastPos = maCursorFirstPos;
+ mbCellSelectionMode = false;
+ }
+ else
+ {
+ const SdrMarkList& rMarkList= mpView->GetMarkedObjectList();
+ if( rMarkList.GetMarkCount() == 1 )
+ bSelected = mxTableObj.get() == rMarkList.GetMark(0)->GetMarkedSdrObj();
+ }
+
+ if( bSelected )
+ {
+ updateSelectionOverlay();
+ }
+ else
+ {
+ destroySelectionOverlay();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::GetState( SfxItemSet& rSet )
+{
+ if( !mxTable.is() || !mxTableObj.is() || !mxTableObj->GetModel() )
+ return;
+
+ SfxItemSet* pSet = 0;
+
+ bool bVertDone = false;
+
+ // Iterate over all requested items in the set.
+ SfxWhichIter aIter( rSet );
+ USHORT nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_TABLE_VERT_BOTTOM:
+ case SID_TABLE_VERT_CENTER:
+ case SID_TABLE_VERT_NONE:
+ {
+ if( !mxTable.is() || !mxTableObj->GetModel() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ else if(!bVertDone)
+ {
+ if( !pSet )
+ {
+ pSet = new SfxItemSet( mxTableObj->GetModel()->GetItemPool() );
+ MergeAttrFromSelectedCells(*pSet, FALSE);
+ }
+
+ SdrTextVertAdjust eAdj = SDRTEXTVERTADJUST_BLOCK;
+
+ if( pSet->GetItemState( SDRATTR_TEXT_VERTADJUST ) != SFX_ITEM_DONTCARE )
+ eAdj = ((SdrTextVertAdjustItem&)(pSet->Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
+
+ rSet.Put(SfxBoolItem(SID_TABLE_VERT_BOTTOM, eAdj == SDRTEXTVERTADJUST_BOTTOM));
+ rSet.Put(SfxBoolItem(SID_TABLE_VERT_CENTER, eAdj == SDRTEXTVERTADJUST_CENTER));
+ rSet.Put(SfxBoolItem(SID_TABLE_VERT_NONE, eAdj == SDRTEXTVERTADJUST_TOP));
+ bVertDone = true;
+ }
+ break;
+ }
+ case SID_TABLE_DELETE_ROW:
+ if( !mxTable.is() || !hasSelectedCells() || (mxTable->getRowCount() <= 1) )
+ rSet.DisableItem(SID_TABLE_DELETE_ROW);
+ break;
+ case SID_TABLE_DELETE_COL:
+ if( !mxTable.is() || !hasSelectedCells() || (mxTable->getColumnCount() <= 1) )
+ rSet.DisableItem(SID_TABLE_DELETE_COL);
+ break;
+ case SID_TABLE_MERGE_CELLS:
+ if( !mxTable.is() || !hasSelectedCells() )
+ rSet.DisableItem(SID_TABLE_MERGE_CELLS);
+ break;
+ case SID_TABLE_SPLIT_CELLS:
+ if( !hasSelectedCells() || !mxTable.is() )
+ rSet.DisableItem(SID_TABLE_SPLIT_CELLS);
+ break;
+
+ case SID_OPTIMIZE_TABLE:
+ case SID_TABLE_DISTRIBUTE_COLUMNS:
+ case SID_TABLE_DISTRIBUTE_ROWS:
+ {
+ bool bDistributeColumns = false;
+ bool bDistributeRows = false;
+ if( mxTable.is() )
+ {
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+
+ bDistributeColumns = aStart.mnCol != aEnd.mnCol;
+ bDistributeRows = aStart.mnRow != aEnd.mnRow;
+ }
+ if( !bDistributeColumns && !bDistributeRows )
+ rSet.DisableItem(SID_OPTIMIZE_TABLE);
+ if( !bDistributeColumns )
+ rSet.DisableItem(SID_TABLE_DISTRIBUTE_COLUMNS);
+ if( !bDistributeRows )
+ rSet.DisableItem(SID_TABLE_DISTRIBUTE_ROWS);
+ break;
+ }
+
+ case SID_AUTOFORMAT:
+ case SID_TABLE_SORT_DIALOG:
+ case SID_TABLE_AUTOSUM:
+// if( !mxTable.is() )
+// rSet.DisableItem( nWhich );
+ break;
+ default:
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+ if( pSet )
+ delete pSet;
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::onInsert( sal_uInt16 nSId, const SfxItemSet* pArgs )
+{
+ ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
+ if( !pTableObj )
+ return;
+
+ if( mxTable.is() ) try
+ {
+ //
+ bool bInsertAfter = true;
+ sal_uInt16 nCount = 0;
+ if( pArgs )
+ {
+ const SfxPoolItem* pItem = 0;
+ pArgs->GetItemState(nSId, FALSE, &pItem);
+ if (pItem)
+ {
+ nCount = ((const SfxInt16Item* )pItem)->GetValue();
+ if(SFX_ITEM_SET == pArgs->GetItemState(SID_TABLE_PARAM_INSERT_AFTER, TRUE, &pItem))
+ bInsertAfter = ((const SfxBoolItem* )pItem)->GetValue();
+ }
+ }
+
+ CellPos aStart, aEnd;
+ if( hasSelectedCells() )
+ {
+ getSelectedCells( aStart, aEnd );
+ }
+ else
+ {
+ if( bInsertAfter )
+ {
+ aStart.mnCol = mxTable->getColumnCount() - 1;
+ aStart.mnRow = mxTable->getRowCount() - 1;
+ aEnd = aStart;
+ }
+ }
+
+ if( pTableObj->IsTextEditActive() )
+ mpView->SdrEndTextEdit(sal_True);
+
+ RemoveSelection();
+
+ const OUString sSize( RTL_CONSTASCII_USTRINGPARAM( "Size" ) );
+
+ const bool bUndo = mpModel && mpModel->IsUndoEnabled();
+
+ switch( nSId )
+ {
+ case SID_TABLE_INSERT_COL:
+ {
+ TableModelNotifyGuard aGuard( mxTable.get() );
+
+ if( bUndo )
+ {
+ mpModel->BegUndo( ImpGetResStr(STR_TABLE_INSCOL) );
+ mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
+ }
+
+ Reference< XTableColumns > xCols( mxTable->getColumns() );
+ const sal_Int32 nNewColumns = (nCount == 0) ? (aEnd.mnCol - aStart.mnCol + 1) : nCount;
+ const sal_Int32 nNewStartColumn = aEnd.mnCol + (bInsertAfter ? 1 : 0);
+ xCols->insertByIndex( nNewStartColumn, nNewColumns );
+
+ for( sal_Int32 nOffset = 0; nOffset < nNewColumns; nOffset++ )
+ {
+ Reference< XPropertySet >( xCols->getByIndex( aEnd.mnCol + nOffset + 1 ), UNO_QUERY_THROW )->
+ setPropertyValue( sSize,
+ Reference< XPropertySet >( xCols->getByIndex( aStart.mnCol + nOffset ), UNO_QUERY_THROW )->
+ getPropertyValue( sSize ) );
+ }
+
+ if( bUndo )
+ mpModel->EndUndo();
+
+ aStart.mnCol = nNewStartColumn;
+ aStart.mnRow = 0;
+ aEnd.mnCol = aStart.mnCol + nNewColumns - 1;
+ aEnd.mnRow = mxTable->getRowCount() - 1;
+ break;
+ }
+
+ case SID_TABLE_INSERT_ROW:
+ {
+ TableModelNotifyGuard aGuard( mxTable.get() );
+
+ if( bUndo )
+ {
+ mpModel->BegUndo( ImpGetResStr(STR_TABLE_INSROW ) );
+ mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
+ }
+
+ Reference< XTableRows > xRows( mxTable->getRows() );
+ const sal_Int32 nNewRows = (nCount == 0) ? (aEnd.mnRow - aStart.mnRow + 1) : nCount;
+ const sal_Int32 nNewRowStart = aEnd.mnRow + (bInsertAfter ? 1 : 0);
+ xRows->insertByIndex( nNewRowStart, nNewRows );
+
+ for( sal_Int32 nOffset = 0; nOffset < nNewRows; nOffset++ )
+ {
+ Reference< XPropertySet >( xRows->getByIndex( aEnd.mnRow + nOffset + 1 ), UNO_QUERY_THROW )->
+ setPropertyValue( sSize,
+ Reference< XPropertySet >( xRows->getByIndex( aStart.mnRow + nOffset ), UNO_QUERY_THROW )->
+ getPropertyValue( sSize ) );
+ }
+
+ if( bUndo )
+ mpModel->EndUndo();
+
+ aStart.mnCol = 0;
+ aStart.mnRow = nNewRowStart;
+ aEnd.mnCol = mxTable->getColumnCount() - 1;
+ aEnd.mnRow = aStart.mnRow + nNewRows - 1;
+ break;
+ }
+ }
+
+ StartSelection( aStart );
+ UpdateSelection( aEnd );
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR("svx::SvxTableController::onInsert(), exception caught!");
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::onDelete( sal_uInt16 nSId )
+{
+ ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
+ if( !pTableObj )
+ return;
+
+ if( mxTable.is() && hasSelectedCells() )
+ {
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+
+ if( pTableObj->IsTextEditActive() )
+ mpView->SdrEndTextEdit(sal_True);
+
+ RemoveSelection();
+
+ bool bDeleteTable = false;
+ switch( nSId )
+ {
+ case SID_TABLE_DELETE_COL:
+ {
+ const sal_Int32 nRemovedColumns = aEnd.mnCol - aStart.mnCol + 1;
+ if( nRemovedColumns == mxTable->getColumnCount() )
+ {
+ bDeleteTable = true;
+ }
+ else
+ {
+ Reference< XTableColumns > xCols( mxTable->getColumns() );
+ xCols->removeByIndex( aStart.mnCol, nRemovedColumns );
+ }
+ break;
+ }
+
+ case SID_TABLE_DELETE_ROW:
+ {
+ const sal_Int32 nRemovedRows = aEnd.mnRow - aStart.mnRow + 1;
+ if( nRemovedRows == mxTable->getRowCount() )
+ {
+ bDeleteTable = true;
+ }
+ else
+ {
+ Reference< XTableRows > xRows( mxTable->getRows() );
+ xRows->removeByIndex( aStart.mnRow, nRemovedRows );
+ }
+ break;
+ }
+ }
+
+ if( bDeleteTable )
+ mpView->DeleteMarkedObj();
+ else
+ UpdateTableShape();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::onSelect( sal_uInt16 nSId )
+{
+ if( mxTable.is() )
+ {
+ const sal_Int32 nRowCount = mxTable->getRowCount();
+ const sal_Int32 nColCount = mxTable->getColumnCount();
+ if( nRowCount && nColCount )
+ {
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+
+ switch( nSId )
+ {
+ case SID_TABLE_SELECT_ALL:
+ aEnd.mnCol = 0; aEnd.mnRow = 0;
+ aStart.mnCol = nColCount - 1; aStart.mnRow = nRowCount - 1;
+ break;
+ case SID_TABLE_SELECT_COL:
+ aEnd.mnRow = nRowCount - 1;
+ aStart.mnRow = 0;
+ break;
+ case SID_TABLE_SELECT_ROW:
+ aEnd.mnCol = nColCount - 1;
+ aStart.mnCol = 0;
+ break;
+ }
+
+ StartSelection( aEnd );
+ gotoCell( aStart, true, 0 );
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+void SvxTableController::onFormatTable( SfxRequest& rReq )
+{
+ ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
+ if( !pTableObj )
+ return;
+
+ const SfxItemSet* pArgs = rReq.GetArgs();
+
+ if( !pArgs && pTableObj->GetModel() )
+ {
+ SfxItemSet aNewAttr( pTableObj->GetModel()->GetItemPool() );
+ MergeAttrFromSelectedCells(aNewAttr, FALSE);
+
+ // merge drawing layer text distance items into SvxBoxItem used by the dialog
+ SvxBoxItem aBoxItem( static_cast< const SvxBoxItem& >( aNewAttr.Get( SDRATTR_TABLE_BORDER ) ) );
+ aBoxItem.SetDistance( sal::static_int_cast< USHORT >( ((SdrTextLeftDistItem&)(aNewAttr.Get(SDRATTR_TEXT_LEFTDIST))).GetValue()), BOX_LINE_LEFT );
+ aBoxItem.SetDistance( sal::static_int_cast< USHORT >( ((SdrTextRightDistItem&)(aNewAttr.Get(SDRATTR_TEXT_RIGHTDIST))).GetValue()), BOX_LINE_RIGHT );
+ aBoxItem.SetDistance( sal::static_int_cast< USHORT >( ((SdrTextUpperDistItem&)(aNewAttr.Get(SDRATTR_TEXT_UPPERDIST))).GetValue()), BOX_LINE_TOP );
+ aBoxItem.SetDistance( sal::static_int_cast< USHORT >( ((SdrTextLowerDistItem&)(aNewAttr.Get(SDRATTR_TEXT_LOWERDIST))).GetValue()), BOX_LINE_BOTTOM );
+ aNewAttr.Put( aBoxItem );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ std::auto_ptr< SfxAbstractTabDialog > pDlg( pFact ? pFact->CreateSvxFormatCellsDialog( NULL, &aNewAttr, pTableObj->GetModel(), pTableObj) : 0 );
+ if( pDlg.get() && pDlg->Execute() )
+ {
+ SfxItemSet aNewSet( *(pDlg->GetOutputItemSet ()) );
+
+ SvxBoxItem aNewBoxItem( static_cast< const SvxBoxItem& >( aNewSet.Get( SDRATTR_TABLE_BORDER ) ) );
+
+ if( aNewBoxItem.GetDistance( BOX_LINE_LEFT ) != aBoxItem.GetDistance( BOX_LINE_LEFT ) )
+ aNewSet.Put(SdrTextLeftDistItem( aNewBoxItem.GetDistance( BOX_LINE_LEFT ) ) );
+
+ if( aNewBoxItem.GetDistance( BOX_LINE_RIGHT ) != aBoxItem.GetDistance( BOX_LINE_RIGHT ) )
+ aNewSet.Put(SdrTextRightDistItem( aNewBoxItem.GetDistance( BOX_LINE_RIGHT ) ) );
+
+ if( aNewBoxItem.GetDistance( BOX_LINE_TOP ) != aBoxItem.GetDistance( BOX_LINE_TOP ) )
+ aNewSet.Put(SdrTextUpperDistItem( aNewBoxItem.GetDistance( BOX_LINE_TOP ) ) );
+
+ if( aNewBoxItem.GetDistance( BOX_LINE_BOTTOM ) != aBoxItem.GetDistance( BOX_LINE_BOTTOM ) )
+ aNewSet.Put(SdrTextLowerDistItem( aNewBoxItem.GetDistance( BOX_LINE_BOTTOM ) ) );
+
+ SetAttrToSelectedCells(aNewSet, FALSE);
+ }
+ UpdateTableShape();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::Execute( SfxRequest& rReq )
+{
+ const sal_uInt16 nSId = rReq.GetSlot();
+ switch( nSId )
+ {
+ case SID_TABLE_INSERT_ROW:
+ case SID_TABLE_INSERT_COL:
+ onInsert( nSId, rReq.GetArgs() );
+ break;
+ case SID_TABLE_DELETE_ROW:
+ case SID_TABLE_DELETE_COL:
+ onDelete( nSId );
+ break;
+ case SID_TABLE_SELECT_ALL:
+ case SID_TABLE_SELECT_COL:
+ case SID_TABLE_SELECT_ROW:
+ onSelect( nSId );
+ break;
+ case SID_FORMAT_TABLE_DLG:
+ onFormatTable( rReq );
+ break;
+
+ case SID_FRAME_LINESTYLE:
+ case SID_FRAME_LINECOLOR:
+ case SID_ATTR_BORDER:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if( pArgs )
+ ApplyBorderAttr( *pArgs );
+ }
+ break;
+
+ case SID_ATTR_FILL_STYLE:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if( pArgs )
+ SetAttributes( *pArgs, false );
+ }
+ break;
+
+ case SID_TABLE_MERGE_CELLS:
+ MergeMarkedCells();
+ break;
+
+ case SID_TABLE_SPLIT_CELLS:
+ SplitMarkedCells();
+ break;
+
+ case SID_TABLE_DISTRIBUTE_COLUMNS:
+ DistributeColumns();
+ break;
+
+ case SID_TABLE_DISTRIBUTE_ROWS:
+ DistributeRows();
+ break;
+
+ case SID_TABLE_VERT_BOTTOM:
+ case SID_TABLE_VERT_CENTER:
+ case SID_TABLE_VERT_NONE:
+ SetVertical( nSId );
+ break;
+
+ case SID_AUTOFORMAT:
+ case SID_TABLE_SORT_DIALOG:
+ case SID_TABLE_AUTOSUM:
+ default:
+ break;
+
+ case SID_TABLE_STYLE:
+ SetTableStyle( rReq.GetArgs() );
+ break;
+
+ case SID_TABLE_STYLE_SETTINGS:
+ SetTableStyleSettings( rReq.GetArgs() );
+ break;
+ }
+}
+
+void SvxTableController::SetTableStyle( const SfxItemSet* pArgs )
+{
+ SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
+ SdrModel* pModel = pTableObj ? pTableObj->GetModel() : 0;
+
+ if( !pTableObj || !pModel || !pArgs || (SFX_ITEM_SET != pArgs->GetItemState(SID_TABLE_STYLE, FALSE)) )
+ return;
+
+ const SfxStringItem* pArg = dynamic_cast< const SfxStringItem* >( &pArgs->Get( SID_TABLE_STYLE ) );
+ if( pArg && mxTable.is() ) try
+ {
+ Reference< XStyleFamiliesSupplier > xSFS( pModel->getUnoModel(), UNO_QUERY_THROW );
+ Reference< XNameAccess > xFamilyNameAccess( xSFS->getStyleFamilies(), UNO_QUERY_THROW );
+ const OUString sFamilyName( RTL_CONSTASCII_USTRINGPARAM( "table" ) );
+ Reference< XNameAccess > xTableFamilyAccess( xFamilyNameAccess->getByName( sFamilyName ), UNO_QUERY_THROW );
+
+ if( xTableFamilyAccess->hasByName( pArg->GetValue() ) )
+ {
+ // found table style with the same name
+ Reference< XIndexAccess > xNewTableStyle( xTableFamilyAccess->getByName( pArg->GetValue() ), UNO_QUERY_THROW );
+
+ const bool bUndo = pModel->IsUndoEnabled();
+
+ if( bUndo )
+ {
+ pModel->BegUndo( ImpGetResStr(STR_TABLE_STYLE) );
+ pModel->AddUndo( new TableStyleUndo( *pTableObj ) );
+ }
+
+ pTableObj->setTableStyle( xNewTableStyle );
+
+ const sal_Int32 nRowCount = mxTable->getRowCount();
+ const sal_Int32 nColCount = mxTable->getColumnCount();
+ for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
+ {
+ for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ ) try
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( xCell.is() )
+ {
+ SfxItemSet aSet( xCell->GetItemSet() );
+ bool bChanges = false;
+ const SfxItemSet& rStyleAttribs = xCell->GetStyleSheet()->GetItemSet();
+
+ for ( USHORT nWhich = SDRATTR_START; nWhich <= SDRATTR_TABLE_LAST; nWhich++ )
+ {
+ if( (rStyleAttribs.GetItemState( nWhich ) == SFX_ITEM_ON) && (aSet.GetItemState( nWhich ) == SFX_ITEM_ON) )
+ {
+ aSet.ClearItem( nWhich );
+ bChanges = true;
+ }
+ }
+
+ if( bChanges )
+ {
+ if( bUndo )
+ xCell->AddUndo();
+
+ xCell->SetMergedItemSetAndBroadcast( aSet, sal_True );
+ }
+ }
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR( "svx::SvxTableController::SetTableStyle(), exception caught!" );
+ }
+ }
+
+ if( bUndo )
+ pModel->EndUndo();
+ }
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR( "svx::SvxTableController::SetTableStyle(), exception caught!" );
+ }
+}
+
+void SvxTableController::SetTableStyleSettings( const SfxItemSet* pArgs )
+{
+ SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
+ SdrModel* pModel = pTableObj ? pTableObj->GetModel() : 0;
+
+ if( !pTableObj || !pModel )
+ return;
+
+ TableStyleSettings aSettings( pTableObj->getTableStyleSettings() );
+
+ const SfxPoolItem *pPoolItem=NULL;
+
+ if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEFIRSTROWSTYLE, FALSE,&pPoolItem)) )
+ aSettings.mbUseFirstRow = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
+
+ if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USELASTROWSTYLE, FALSE,&pPoolItem)) )
+ aSettings.mbUseLastRow = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
+
+ if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEBANDINGROWSTYLE, FALSE,&pPoolItem)) )
+ aSettings.mbUseRowBanding = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
+
+ if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEFIRSTCOLUMNSTYLE, FALSE,&pPoolItem)) )
+ aSettings.mbUseFirstColumn = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
+
+ if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USELASTCOLUMNSTYLE, FALSE,&pPoolItem)) )
+ aSettings.mbUseLastColumn = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
+
+ if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEBANDINGCOLUMNSTYLE, FALSE,&pPoolItem)) )
+ aSettings.mbUseColumnBanding = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
+
+ if( aSettings == pTableObj->getTableStyleSettings() )
+ return;
+
+ const bool bUndo = pModel->IsUndoEnabled();
+
+ if( bUndo )
+ {
+ pModel->BegUndo( ImpGetResStr(STR_TABLE_STYLE_SETTINGS) );
+ pModel->AddUndo( new TableStyleUndo( *pTableObj ) );
+ }
+
+ pTableObj->setTableStyleSettings( aSettings );
+
+ if( bUndo )
+ pModel->EndUndo();
+}
+
+void SvxTableController::SetVertical( sal_uInt16 nSId )
+{
+ SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
+ if( mxTable.is() && pTableObj )
+ {
+ TableModelNotifyGuard aGuard( mxTable.get() );
+
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+
+ SdrTextVertAdjust eAdj = SDRTEXTVERTADJUST_TOP;
+
+ switch( nSId )
+ {
+ case SID_TABLE_VERT_BOTTOM:
+ eAdj = SDRTEXTVERTADJUST_BOTTOM;
+ break;
+ case SID_TABLE_VERT_CENTER:
+ eAdj = SDRTEXTVERTADJUST_CENTER;
+ break;
+ //case SID_TABLE_VERT_NONE:
+ default:
+ break;
+ }
+
+ SdrTextVertAdjustItem aItem( eAdj );
+
+ for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
+ {
+ for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( xCell.is() )
+ xCell->SetMergedItem(aItem);
+ }
+ }
+
+ UpdateTableShape();
+ }
+}
+
+void SvxTableController::MergeMarkedCells()
+{
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+ SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
+ if( pTableObj )
+ {
+ if( pTableObj->IsTextEditActive() )
+ mpView->SdrEndTextEdit(sal_True);
+
+ TableModelNotifyGuard aGuard( mxTable.get() );
+ MergeRange( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow );
+ }
+}
+
+void SvxTableController::SplitMarkedCells()
+{
+ if( mxTable.is() )
+ {
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ std::auto_ptr< SvxAbstractSplittTableDialog > xDlg( pFact ? pFact->CreateSvxSplittTableDialog( NULL, false, 99, 99 ) : 0 );
+ if( xDlg.get() && xDlg->Execute() )
+ {
+ const sal_Int32 nCount = xDlg->GetCount() - 1;
+ if( nCount < 1 )
+ return;
+
+ getSelectedCells( aStart, aEnd );
+
+ Reference< XMergeableCellRange > xRange( mxTable->createCursorByRange( mxTable->getCellRangeByPosition( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow ) ), UNO_QUERY_THROW );
+
+ const sal_Int32 nRowCount = mxTable->getRowCount();
+ const sal_Int32 nColCount = mxTable->getColumnCount();
+
+
+ SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
+ if( pTableObj )
+ {
+ if( pTableObj->IsTextEditActive() )
+ mpView->SdrEndTextEdit(sal_True);
+
+ TableModelNotifyGuard aGuard( mxTable.get() );
+
+ const bool bUndo = mpModel && mpModel->IsUndoEnabled();
+ if( bUndo )
+ {
+ mpModel->BegUndo( ImpGetResStr(STR_TABLE_SPLIT) );
+ mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
+ }
+
+ if( xDlg->IsHorizontal() )
+ {
+ xRange->split( 0, nCount );
+ }
+ else
+ {
+ xRange->split( nCount, 0 );
+ }
+
+ if( bUndo )
+ mpModel->EndUndo();
+ }
+ aEnd.mnRow += mxTable->getRowCount() - nRowCount;
+ aEnd.mnCol += mxTable->getColumnCount() - nColCount;
+
+ setSelectedCells( aStart, aEnd );
+ }
+ }
+}
+
+void SvxTableController::DistributeColumns()
+{
+ SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
+ if( pTableObj )
+ {
+ const bool bUndo = mpModel && mpModel->IsUndoEnabled();
+ if( bUndo )
+ {
+ mpModel->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_COLUMNS) );
+ mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
+ }
+
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+ pTableObj->DistributeColumns( aStart.mnCol, aEnd.mnCol );
+
+ if( bUndo )
+ mpModel->EndUndo();
+ }
+}
+
+void SvxTableController::DistributeRows()
+{
+ SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
+ if( pTableObj )
+ {
+ const bool bUndo = mpModel && mpModel->IsUndoEnabled();
+ if( bUndo )
+ {
+ mpModel->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_ROWS) );
+ mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
+ }
+
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+ pTableObj->DistributeRows( aStart.mnRow, aEnd.mnRow );
+
+ if( bUndo )
+ mpModel->EndUndo();
+ }
+}
+
+bool SvxTableController::DeleteMarked()
+{
+ if( mbCellSelectionMode )
+ {
+ if( mxTable.is() )
+ {
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+ for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
+ {
+ for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( xCell.is() )
+ xCell->SetOutlinerParaObject( 0 );
+ }
+ }
+
+ UpdateTableShape();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool SvxTableController::GetStyleSheet( SfxStyleSheet*& rpStyleSheet ) const
+{
+ if( hasSelectedCells() )
+ {
+ rpStyleSheet = 0;
+
+ if( mxTable.is() )
+ {
+ SfxStyleSheet* pRet=0;
+ bool b1st=true;
+
+ CellPos aStart, aEnd;
+ const_cast<SvxTableController&>(*this).getSelectedCells( aStart, aEnd );
+
+ for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
+ {
+ for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( xCell.is() )
+ {
+ SfxStyleSheet* pSS=xCell->GetStyleSheet();
+ if(b1st)
+ {
+ pRet=pSS;
+ }
+ else if(pRet != pSS)
+ {
+ return true;
+ }
+ b1st=false;
+ }
+ }
+ }
+ rpStyleSheet = pRet;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool SvxTableController::SetStyleSheet( SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr )
+{
+ if( hasSelectedCells() && (!pStyleSheet || pStyleSheet->GetFamily() == SFX_STYLE_FAMILY_FRAME) )
+ {
+ if( mxTable.is() )
+ {
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+
+ for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
+ {
+ for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( xCell.is() )
+ xCell->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
+ }
+ }
+
+ UpdateTableShape();
+ return true;
+ }
+ }
+ return false;
+}
+
+// --------------------------------------------------------------------
+// internals
+// --------------------------------------------------------------------
+
+bool SvxTableController::checkTableObject()
+{
+ return mxTableObj.is();
+}
+
+// --------------------------------------------------------------------
+
+sal_uInt16 SvxTableController::getKeyboardAction( const KeyEvent& rKEvt, Window* /*pWindow*/ )
+{
+ const bool bMod1 = rKEvt.GetKeyCode().IsMod1(); // ctrl
+ const bool bMod2 = rKEvt.GetKeyCode().IsMod2() != 0; // Alt
+
+ const bool bTextEdit = mpView->IsTextEdit();
+
+ sal_uInt16 nAction = ACTION_HANDLED_BY_VIEW;
+
+ ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
+ if( !pTableObj )
+ return nAction;
+
+ // handle special keys
+ const sal_Int16 nCode = rKEvt.GetKeyCode().GetCode();
+ switch( nCode )
+ {
+ case awt::Key::ESCAPE: // handle escape
+ {
+ if( bTextEdit )
+ {
+ // escape during text edit ends text edit
+ nAction = ACTION_STOP_TEXT_EDIT;
+ }
+ if( mbCellSelectionMode )
+ {
+ // escape with selected cells removes selection
+ nAction = ACTION_REMOVE_SELECTION;
+ }
+ break;
+ }
+ case awt::Key::RETURN: // handle return
+ {
+ if( !bMod1 && !bMod2 && !bTextEdit )
+ {
+ // when not already editing, return starts text edit
+ setSelectionStart( pTableObj->getFirstCell() );
+ nAction = ACTION_EDIT_CELL;
+ }
+ break;
+ }
+ case awt::Key::F2: // f2 toggles text edit
+ {
+ if( bMod1 || bMod2 ) // f2 with modifiers is handled by the view
+ {
+ }
+ else if( bTextEdit )
+ {
+ // f2 during text edit stops text edit
+ nAction = ACTION_STOP_TEXT_EDIT;
+ }
+ else if( mbCellSelectionMode )
+ {
+ // f2 with selected cells removes selection
+ nAction = ACTION_REMOVE_SELECTION;
+ }
+ else
+ {
+ // f2 with no selection and no text edit starts text edit
+ setSelectionStart( pTableObj->getFirstCell() );
+ nAction = ACTION_EDIT_CELL;
+ }
+ break;
+ }
+ case awt::Key::HOME:
+ case awt::Key::NUM7:
+ {
+ if( (bMod1 || bMod2) && (bTextEdit || mbCellSelectionMode) )
+ {
+ if( bMod1 && !bMod2 )
+ {
+ // strg + home jumps to first cell
+ nAction = ACTION_GOTO_FIRST_CELL;
+ }
+ else if( !bMod1 && bMod2 )
+ {
+ // alt + home jumps to first column
+ nAction = ACTION_GOTO_FIRST_COLUMN;
+ }
+ }
+ break;
+ }
+ case awt::Key::END:
+ case awt::Key::NUM1:
+ {
+ if( (bMod1 || bMod2) && (bTextEdit || mbCellSelectionMode) )
+ {
+ if( bMod1 && !bMod2 )
+ {
+ // strg + end jumps to last cell
+ nAction = ACTION_GOTO_LAST_CELL;
+ }
+ else if( !bMod1 && bMod2 )
+ {
+ // alt + home jumps to last column
+ nAction = ACTION_GOTO_LAST_COLUMN;
+ }
+ }
+ break;
+ }
+
+ case awt::Key::TAB:
+ {
+ if( bTextEdit || mbCellSelectionMode )
+ nAction = ACTION_TAB;
+ break;
+ }
+
+ case awt::Key::UP:
+ case awt::Key::NUM8:
+ case awt::Key::DOWN:
+ case awt::Key::NUM2:
+ case awt::Key::LEFT:
+ case awt::Key::NUM4:
+ case awt::Key::RIGHT:
+ case awt::Key::NUM6:
+ {
+ bool bTextMove = false;
+
+ if( !bMod1 && bMod2 )
+ {
+ if( (nCode == awt::Key::UP) || (nCode == awt::Key::NUM8) )
+ {
+ nAction = ACTION_GOTO_LEFT_CELL;
+ }
+ else if( (nCode == awt::Key::DOWN) || (nCode == awt::Key::NUM2) )
+ {
+ nAction = ACTION_GOTO_RIGHT_CELL;
+ }
+ break;
+ }
+
+ if( !bTextMove )
+ {
+ OutlinerView* pOLV = mpView->GetTextEditOutlinerView();
+ if( pOLV )
+ {
+ RemoveSelection();
+ // during text edit, check if we navigate out of the cell
+ ESelection aOldSelection = pOLV->GetSelection();
+ pOLV->PostKeyEvent(rKEvt);
+ bTextMove = pOLV && ( aOldSelection.IsEqual(pOLV->GetSelection()) );
+ if( !bTextMove )
+ {
+ nAction = ACTION_NONE;
+ }
+ }
+ }
+
+ if( mbCellSelectionMode || bTextMove )
+ {
+ // no text edit, navigate in cells if selection active
+ switch( nCode )
+ {
+ case awt::Key::LEFT:
+ case awt::Key::NUM4:
+ nAction = ACTION_GOTO_LEFT_CELL;
+ break;
+ case awt::Key::RIGHT:
+ case awt::Key::NUM6:
+ nAction = ACTION_GOTO_RIGHT_CELL;
+ break;
+ case awt::Key::DOWN:
+ case awt::Key::NUM2:
+ nAction = ACTION_GOTO_DOWN_CELL;
+ break;
+ case awt::Key::UP:
+ case awt::Key::NUM8:
+ nAction = ACTION_GOTO_UP_CELL;
+ break;
+ }
+ }
+ break;
+ }
+ case awt::Key::PAGEUP:
+ if( bMod2 )
+ nAction = ACTION_GOTO_FIRST_ROW;
+ break;
+
+ case awt::Key::PAGEDOWN:
+ if( bMod2 )
+ nAction = ACTION_GOTO_LAST_ROW;
+ break;
+ }
+ return nAction;
+}
+
+bool SvxTableController::executeAction( sal_uInt16 nAction, bool bSelect, Window* pWindow )
+{
+ ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
+ if( !pTableObj )
+ return false;
+
+ switch( nAction )
+ {
+ case ACTION_GOTO_FIRST_CELL:
+ {
+ gotoCell( pTableObj->getFirstCell(), bSelect, pWindow, nAction );
+ break;
+ }
+
+ case ACTION_GOTO_LEFT_CELL:
+ {
+ gotoCell( pTableObj->getLeftCell( getSelectionEnd(), !bSelect ), bSelect, pWindow, nAction );
+ break;
+ }
+
+ case ACTION_GOTO_RIGHT_CELL:
+ {
+ gotoCell( pTableObj->getRightCell( getSelectionEnd(), !bSelect ), bSelect, pWindow, nAction);
+ break;
+ }
+
+ case ACTION_GOTO_LAST_CELL:
+ {
+ gotoCell( pTableObj->getLastCell(), bSelect, pWindow, nAction );
+ break;
+ }
+
+ case ACTION_GOTO_FIRST_COLUMN:
+ {
+ CellPos aPos( pTableObj->getFirstCell().mnCol, getSelectionEnd().mnRow );
+ gotoCell( aPos, bSelect, pWindow, nAction );
+ break;
+ }
+
+ case ACTION_GOTO_LAST_COLUMN:
+ {
+ CellPos aPos( pTableObj->getLastCell().mnCol, getSelectionEnd().mnRow );
+ gotoCell( aPos, bSelect, pWindow, nAction );
+ break;
+ }
+
+ case ACTION_GOTO_FIRST_ROW:
+ {
+ CellPos aPos( getSelectionEnd().mnCol, pTableObj->getFirstCell().mnRow );
+ gotoCell( aPos, bSelect, pWindow, nAction );
+ break;
+ }
+
+ case ACTION_GOTO_UP_CELL:
+ {
+ gotoCell( pTableObj->getUpCell(getSelectionEnd(), !bSelect), bSelect, pWindow, nAction );
+ break;
+ }
+
+ case ACTION_GOTO_DOWN_CELL:
+ {
+ gotoCell( pTableObj->getDownCell(getSelectionEnd(), !bSelect), bSelect, pWindow, nAction );
+ break;
+ }
+
+ case ACTION_GOTO_LAST_ROW:
+ {
+ CellPos aPos( getSelectionEnd().mnCol, pTableObj->getLastCell().mnRow );
+ gotoCell( aPos, bSelect, pWindow, nAction );
+ break;
+ }
+
+ case ACTION_EDIT_CELL:
+ EditCell( getSelectionStart(), pWindow, 0, nAction );
+ break;
+
+ case ACTION_STOP_TEXT_EDIT:
+ StopTextEdit();
+ break;
+
+ case ACTION_REMOVE_SELECTION:
+ RemoveSelection();
+ break;
+
+ case ACTION_START_SELECTION:
+ StartSelection( getSelectionStart() );
+ break;
+
+ case ACTION_TAB:
+ {
+ if( bSelect )
+ gotoCell( pTableObj->getPreviousCell( getSelectionEnd(), true ), false, pWindow, nAction );
+ else
+ {
+ CellPos aSelectionEnd( getSelectionEnd() );
+ CellPos aNextCell( pTableObj->getNextCell( aSelectionEnd, true ) );
+ if( aSelectionEnd == aNextCell )
+ {
+ onInsert( SID_TABLE_INSERT_ROW, 0 );
+ aNextCell = pTableObj->getNextCell( aSelectionEnd, true );
+ }
+ gotoCell( aNextCell, false, pWindow, nAction );
+ }
+ break;
+ }
+ }
+
+ return nAction != ACTION_HANDLED_BY_VIEW;
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::gotoCell( const CellPos& rPos, bool bSelect, Window* pWindow, sal_uInt16 nAction )
+{
+ if( mxTableObj.is() && static_cast<SdrTableObj*>(mxTableObj.get())->IsTextEditActive() )
+ mpView->SdrEndTextEdit(sal_True);
+
+ if( bSelect )
+ {
+ maCursorLastPos = rPos;
+ if( mxTableObj.is() )
+ static_cast< SdrTableObj* >( mxTableObj.get() )->setActiveCell( rPos );
+
+ if( !mbCellSelectionMode )
+ {
+ setSelectedCells( maCursorFirstPos, rPos );
+ }
+ else
+ {
+ UpdateSelection( rPos );
+ }
+ }
+ else
+ {
+ RemoveSelection();
+ EditCell( rPos, pWindow, 0, nAction );
+ }
+}
+
+// --------------------------------------------------------------------
+
+const CellPos& SvxTableController::getSelectionStart()
+{
+ checkCell( maCursorFirstPos );
+ return maCursorFirstPos;
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::setSelectionStart( const CellPos& rPos )
+{
+ maCursorFirstPos = rPos;
+}
+
+// --------------------------------------------------------------------
+
+const CellPos& SvxTableController::getSelectionEnd()
+{
+ checkCell( maCursorLastPos );
+ return maCursorLastPos;
+}
+
+// --------------------------------------------------------------------
+
+Reference< XCellCursor > SvxTableController::getSelectionCursor()
+{
+ Reference< XCellCursor > xCursor;
+
+ if( mxTable.is() )
+ {
+ if( hasSelectedCells() )
+ {
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+ xCursor = mxTable->createCursorByRange( mxTable->getCellRangeByPosition( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow ) );
+ }
+ else
+ {
+ xCursor = mxTable->createCursor();
+ }
+ }
+
+ return xCursor;
+}
+
+void SvxTableController::MergeRange( sal_Int32 nFirstCol, sal_Int32 nFirstRow, sal_Int32 nLastCol, sal_Int32 nLastRow )
+{
+ if( mxTable.is() ) try
+ {
+ Reference< XMergeableCellRange > xRange( mxTable->createCursorByRange( mxTable->getCellRangeByPosition( nFirstCol, nFirstRow,nLastCol, nLastRow ) ), UNO_QUERY_THROW );
+ if( xRange->isMergeable() )
+ {
+ const bool bUndo = mpModel && mpModel->IsUndoEnabled();
+ if( bUndo )
+ {
+ mpModel->BegUndo( ImpGetResStr(STR_TABLE_MERGE) );
+ mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*mxTableObj.get()) );
+ }
+
+ xRange->merge();
+
+ if( bUndo )
+ mpModel->EndUndo();
+ }
+ }
+ catch( Exception& )
+ {
+ DBG_ASSERT( false, "sdr::table::SvxTableController::MergeRange(), exception caught!" );
+ }
+}
+
+
+
+// --------------------------------------------------------------------
+
+void SvxTableController::checkCell( CellPos& rPos )
+{
+ if( mxTable.is() ) try
+ {
+ if( rPos.mnCol >= mxTable->getColumnCount() )
+ rPos.mnCol = mxTable->getColumnCount()-1;
+
+ if( rPos.mnRow >= mxTable->getRowCount() )
+ rPos.mnRow = mxTable->getRowCount()-1;
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR("sdr::table::SvxTableController::checkCell(), exception caught!" );
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::findMergeOrigin( CellPos& rPos )
+{
+ if( mxTable.is() ) try
+ {
+ Reference< XMergeableCell > xCell( mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ), UNO_QUERY_THROW );
+ if( xCell.is() && xCell->isMerged() )
+ {
+ ::findMergeOrigin( mxTable, rPos.mnCol, rPos.mnRow, rPos.mnCol, rPos.mnRow );
+ }
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR("sdr::table::SvxTableController::findMergeOrigin(), exception caught!" );
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::EditCell( const CellPos& rPos, ::Window* pWindow, const awt::MouseEvent* pMouseEvent /*= 0*/, sal_uInt16 nAction /*= ACTION_NONE */ )
+{
+ SdrPageView* pPV = mpView->GetSdrPageView();
+
+ ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
+ if( pTableObj && pTableObj->GetPage() == pPV->GetPage() )
+ {
+ bool bEmptyOutliner = false;
+
+ if(!pTableObj->GetOutlinerParaObject() && mpView->GetTextEditOutliner())
+ {
+ ::Outliner* pOutl = mpView->GetTextEditOutliner();
+ ULONG nParaAnz = pOutl->GetParagraphCount();
+ Paragraph* p1stPara = pOutl->GetParagraph( 0 );
+
+ if(nParaAnz==1 && p1stPara)
+ {
+ // Bei nur einem Pararaph
+ if (pOutl->GetText(p1stPara).Len() == 0)
+ {
+ bEmptyOutliner = true;
+ }
+ }
+ }
+
+ CellPos aPos( rPos );
+ findMergeOrigin( aPos );
+
+ if( pTableObj != mpView->GetTextEditObject() || bEmptyOutliner || !pTableObj->IsTextEditActive( aPos ) )
+ {
+ if( pTableObj->IsTextEditActive() )
+ mpView->SdrEndTextEdit(sal_True);
+
+ pTableObj->setActiveCell( aPos );
+
+ // create new outliner, owner will be the SdrObjEditView
+ SdrOutliner* pOutl = SdrMakeOutliner( OUTLINERMODE_OUTLINEOBJECT, mpModel );
+ if( pTableObj->IsVerticalWriting() )
+ pOutl->SetVertical( TRUE );
+
+ if(mpView->SdrBeginTextEdit(pTableObj, pPV, pWindow, sal_True, pOutl))
+ {
+ maCursorLastPos = maCursorFirstPos = rPos;
+
+ OutlinerView* pOLV = mpView->GetTextEditOutlinerView();
+
+ bool bNoSel = true;
+
+ if( pMouseEvent )
+ {
+ ::MouseEvent aMEvt( *pMouseEvent );
+
+ SdrViewEvent aVEvt;
+ SdrHitKind eHit = mpView->PickAnything(aMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
+
+ if (eHit == SDRHIT_TEXTEDIT)
+ {
+ // Text getroffen
+ pOLV->MouseButtonDown(aMEvt);
+ pOLV->MouseMove(aMEvt);
+ pOLV->MouseButtonUp(aMEvt);
+// pOLV->MouseButtonDown(aMEvt);
+ bNoSel = false;
+ }
+ else
+ {
+ nAction = ACTION_GOTO_LEFT_CELL;
+ }
+ }
+
+ if( bNoSel )
+ {
+ // Move cursor to end of text
+ ESelection aNewSelection;
+
+ const WritingMode eMode = pTableObj->GetWritingMode();
+ if( ((nAction == ACTION_GOTO_LEFT_CELL) || (nAction == ACTION_GOTO_RIGHT_CELL)) && (eMode != WritingMode_TB_RL) )
+ {
+ const bool bLast = ((nAction == ACTION_GOTO_LEFT_CELL) && (eMode == WritingMode_LR_TB)) ||
+ ((nAction == ACTION_GOTO_RIGHT_CELL) && (eMode == WritingMode_RL_TB));
+
+ if( bLast )
+ aNewSelection = ESelection(EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND, EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND);
+ }
+ pOLV->SetSelection(aNewSelection);
+ }
+ }
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+bool SvxTableController::StopTextEdit()
+{
+ if(mpView->IsTextEdit())
+ {
+ mpView->SdrEndTextEdit();
+ mpView->SetCurrentObj(OBJ_TABLE);
+ mpView->SetEditMode(SDREDITMODE_EDIT);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::DeleteTable()
+{
+ //
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::getSelectedCells( CellPos& rFirst, CellPos& rLast )
+{
+ if( mbCellSelectionMode )
+ {
+ checkCell( maCursorFirstPos );
+ checkCell( maCursorLastPos );
+
+ rFirst.mnCol = std::min( maCursorFirstPos.mnCol, maCursorLastPos.mnCol );
+ rFirst.mnRow = std::min( maCursorFirstPos.mnRow, maCursorLastPos.mnRow );
+ rLast.mnCol = std::max( maCursorFirstPos.mnCol, maCursorLastPos.mnCol );
+ rLast.mnRow = std::max( maCursorFirstPos.mnRow, maCursorLastPos.mnRow );
+
+ bool bExt = false;
+ if( mxTable.is() ) do
+ {
+ bExt = false;
+ for( sal_Int32 nRow = rFirst.mnRow; nRow <= rLast.mnRow && !bExt; nRow++ )
+ {
+ for( sal_Int32 nCol = rFirst.mnCol; nCol <= rLast.mnCol && !bExt; nCol++ )
+ {
+ Reference< XMergeableCell > xCell( mxTable->getCellByPosition( nCol, nRow ), UNO_QUERY );
+ if( !xCell.is() )
+ continue;
+
+ if( xCell->isMerged() )
+ {
+ CellPos aPos( nCol, nRow );
+ findMergeOrigin( aPos );
+ if( (aPos.mnCol < rFirst.mnCol) || (aPos.mnRow < rFirst.mnRow) )
+ {
+ rFirst.mnCol = std::min( rFirst.mnCol, aPos.mnCol );
+ rFirst.mnRow = std::min( rFirst.mnRow, aPos.mnRow );
+ bExt = true;
+ }
+ }
+ else
+ {
+ if( ((nCol + xCell->getColumnSpan() - 1) > rLast.mnCol) || (nRow + xCell->getRowSpan() - 1 ) > rLast.mnRow )
+ {
+ rLast.mnCol = std::max( rLast.mnCol, nCol + xCell->getColumnSpan() - 1 );
+ rLast.mnRow = std::max( rLast.mnRow, nRow + xCell->getRowSpan() - 1 );
+ bExt = true;
+ }
+ }
+ }
+ }
+ }
+ while(bExt);
+ }
+ else if( mpView && mpView->IsTextEdit() )
+ {
+ rFirst = getSelectionStart();
+ findMergeOrigin( rFirst );
+ rLast = rFirst;
+
+ if( mxTable.is() )
+ {
+ Reference< XMergeableCell > xCell( mxTable->getCellByPosition( rLast.mnCol, rLast.mnRow ), UNO_QUERY );
+ if( xCell.is() )
+ {
+ rLast.mnCol += xCell->getColumnSpan() - 1;
+ rLast.mnRow += xCell->getRowSpan() - 1;
+ }
+ }
+ }
+ else
+ {
+ rFirst.mnCol = 0;
+ rFirst.mnRow = 0;
+ if( mxTable.is() )
+ {
+ rLast.mnRow = mxTable->getRowCount()-1;
+ rLast.mnCol = mxTable->getColumnCount()-1;
+ }
+ else
+ {
+ rLast.mnRow = 0;
+ rLast.mnCol = 0;
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::StartSelection( const CellPos& rPos )
+{
+ StopTextEdit();
+ mbCellSelectionMode = true;
+ maCursorLastPos = maCursorFirstPos = rPos;
+ mpView->MarkListHasChanged();
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::setSelectedCells( const CellPos& rStart, const CellPos& rEnd )
+{
+ StopTextEdit();
+ mbCellSelectionMode = true;
+ maCursorFirstPos = rStart;
+ UpdateSelection( rEnd );
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::UpdateSelection( const CellPos& rPos )
+{
+ maCursorLastPos = rPos;
+ mpView->MarkListHasChanged();
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::clearSelection()
+{
+ RemoveSelection();
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::selectAll()
+{
+ if( mxTable.is() )
+ {
+ CellPos aPos1, aPos2( mxTable->getColumnCount()-1, mxTable->getRowCount()-1 );
+ if( (aPos2.mnCol >= 0) && (aPos2.mnRow >= 0) )
+ {
+ setSelectedCells( aPos1, aPos2 );
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::RemoveSelection()
+{
+ if( mbCellSelectionMode )
+ {
+ mbCellSelectionMode = false;
+ mpView->MarkListHasChanged();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::onTableModified()
+{
+ if( mnUpdateEvent == 0 )
+ mnUpdateEvent = Application::PostUserEvent( LINK( this, SvxTableController, UpdateHdl ) );
+}
+// --------------------------------------------------------------------
+
+void SvxTableController::updateSelectionOverlay()
+{
+ destroySelectionOverlay();
+ if( mbCellSelectionMode )
+ {
+ ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
+ if( pTableObj )
+ {
+ sdr::overlay::OverlayObjectCell::RangeVector aRanges;
+
+ Rectangle aRect;
+ CellPos aStart,aEnd;
+ getSelectedCells( aStart, aEnd );
+ pTableObj->getCellBounds( aStart, aRect );
+
+ basegfx::B2DRange a2DRange( basegfx::B2DPoint(aRect.Left(), aRect.Top()) );
+ a2DRange.expand( basegfx::B2DPoint(aRect.Right(), aRect.Bottom()) );
+
+ findMergeOrigin( aEnd );
+ pTableObj->getCellBounds( aEnd, aRect );
+ a2DRange.expand( basegfx::B2DPoint(aRect.Left(), aRect.Top()) );
+ a2DRange.expand( basegfx::B2DPoint(aRect.Right(), aRect.Bottom()) );
+ aRanges.push_back( a2DRange );
+
+ ::Color aHighlight( COL_BLUE );
+ OutputDevice* pOutDev = mpView->GetFirstOutputDevice();
+ if( pOutDev )
+ aHighlight = pOutDev->GetSettings().GetStyleSettings().GetHighlightColor();
+
+ const sal_uInt32 nCount = mpView->PaintWindowCount();
+ for( sal_uInt32 nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow(nIndex);
+ if( pPaintWindow )
+ {
+ ::sdr::overlay::OverlayManager* pOverlayManager = pPaintWindow->GetOverlayManager();
+ if( pOverlayManager )
+ {
+ // sdr::overlay::CellOverlayType eType = sdr::overlay::CELL_OVERLAY_INVERT;
+ sdr::overlay::CellOverlayType eType = sdr::overlay::CELL_OVERLAY_TRANSPARENT;
+
+ sdr::overlay::OverlayObjectCell* pOverlay = new sdr::overlay::OverlayObjectCell( eType, aHighlight, aRanges );
+
+ pOverlayManager->add(*pOverlay);
+ mpSelectionOverlay = new ::sdr::overlay::OverlayObjectList;
+ mpSelectionOverlay->append(*pOverlay);
+ }
+ }
+ }
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::destroySelectionOverlay()
+{
+ if( mpSelectionOverlay )
+ {
+ delete mpSelectionOverlay;
+ mpSelectionOverlay = 0;
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::MergeAttrFromSelectedCells(SfxItemSet& rAttr, bool bOnlyHardAttr) const
+{
+ if( mxTable.is() )
+ {
+ CellPos aStart, aEnd;
+ const_cast<SvxTableController&>(*this).getSelectedCells( aStart, aEnd );
+
+ for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
+ {
+ for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( xCell.is() && !xCell->isMerged() )
+ {
+ const SfxItemSet& rSet = xCell->GetItemSet();
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich(aIter.FirstWhich());
+ while(nWhich)
+ {
+ if(!bOnlyHardAttr)
+ {
+ if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, FALSE))
+ rAttr.InvalidateItem(nWhich);
+ else
+ rAttr.MergeValue(rSet.Get(nWhich), TRUE);
+ }
+ else if(SFX_ITEM_SET == rSet.GetItemState(nWhich, FALSE))
+ {
+ const SfxPoolItem& rItem = rSet.Get(nWhich);
+ rAttr.MergeValue(rItem, TRUE);
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+ }
+ }
+ }
+ }
+
+ if( mpView->IsTextEdit() )
+ {
+ }
+}
+
+// --------------------------------------------------------------------
+
+const sal_uInt16 CELL_BEFORE = 0x0001;
+const sal_uInt16 CELL_LEFT = 0x0002;
+const sal_uInt16 CELL_RIGHT = 0x0004;
+const sal_uInt16 CELL_AFTER = 0x0008;
+
+const sal_uInt16 CELL_UPPER = 0x0010;
+const sal_uInt16 CELL_TOP = 0x0020;
+const sal_uInt16 CELL_BOTTOM = 0x0040;
+const sal_uInt16 CELL_LOWER = 0x0080;
+
+// --------------------------------------------------------------------
+
+static void ImplSetLinePreserveColor( SvxBoxItem& rNewFrame, const SvxBorderLine* pNew, USHORT nLine )
+{
+ if( pNew )
+ {
+ const SvxBorderLine* pOld = rNewFrame.GetLine(nLine);
+ if( pOld )
+ {
+ SvxBorderLine aNewLine( *pNew );
+ aNewLine.SetColor( pOld->GetColor() );
+ rNewFrame.SetLine( &aNewLine, nLine );
+ return;
+ }
+ }
+ rNewFrame.SetLine( pNew, nLine );
+}
+
+// --------------------------------------------------------------------
+
+static void ImplApplyBoxItem( sal_uInt16 nCellFlags, const SvxBoxItem* pBoxItem, const SvxBoxInfoItem* pBoxInfoItem, SvxBoxItem& rNewFrame )
+{
+ if( (nCellFlags & (CELL_BEFORE|CELL_AFTER|CELL_UPPER|CELL_LOWER)) != 0 )
+ {
+ // current cell is outside the selection
+
+ if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER)) == 0 ) // check if its not nw or ne corner
+ {
+ if( nCellFlags & CELL_UPPER )
+ {
+ if( pBoxInfoItem->IsValid(VALID_TOP) )
+ rNewFrame.SetLine(0, BOX_LINE_BOTTOM );
+ }
+ else if( nCellFlags & CELL_LOWER )
+ {
+ if( pBoxInfoItem->IsValid(VALID_BOTTOM) )
+ rNewFrame.SetLine( 0, BOX_LINE_TOP );
+ }
+ }
+ else if( (nCellFlags & ( CELL_UPPER|CELL_LOWER)) == 0 ) // check if its not sw or se corner
+ {
+ if( nCellFlags & CELL_BEFORE )
+ {
+ if( pBoxInfoItem->IsValid(VALID_LEFT) )
+ rNewFrame.SetLine( 0, BOX_LINE_RIGHT );
+ }
+ else if( nCellFlags & CELL_AFTER )
+ {
+ if( pBoxInfoItem->IsValid(VALID_RIGHT) )
+ rNewFrame.SetLine( 0, BOX_LINE_LEFT );
+ }
+ }
+ }
+ else
+ {
+ // current cell is inside the selection
+
+ if( (nCellFlags & CELL_LEFT) ? pBoxInfoItem->IsValid(VALID_LEFT) : pBoxInfoItem->IsValid(VALID_VERT) )
+ rNewFrame.SetLine( (nCellFlags & CELL_LEFT) ? pBoxItem->GetLeft() : pBoxInfoItem->GetVert(), BOX_LINE_LEFT );
+
+ if( (nCellFlags & CELL_RIGHT) ? pBoxInfoItem->IsValid(VALID_RIGHT) : pBoxInfoItem->IsValid(VALID_VERT) )
+ rNewFrame.SetLine( (nCellFlags & CELL_RIGHT) ? pBoxItem->GetRight() : pBoxInfoItem->GetVert(), BOX_LINE_RIGHT );
+
+ if( (nCellFlags & CELL_TOP) ? pBoxInfoItem->IsValid(VALID_TOP) : pBoxInfoItem->IsValid(VALID_HORI) )
+ rNewFrame.SetLine( (nCellFlags & CELL_TOP) ? pBoxItem->GetTop() : pBoxInfoItem->GetHori(), BOX_LINE_TOP );
+
+ if( (nCellFlags & CELL_BOTTOM) ? pBoxInfoItem->IsValid(VALID_BOTTOM) : pBoxInfoItem->IsValid(VALID_HORI) )
+ rNewFrame.SetLine( (nCellFlags & CELL_BOTTOM) ? pBoxItem->GetBottom() : pBoxInfoItem->GetHori(), BOX_LINE_BOTTOM );
+
+ // apply distance to borders
+ if( pBoxInfoItem->IsValid( VALID_DISTANCE ) )
+ for( USHORT nLine = 0; nLine < 4; ++nLine )
+ rNewFrame.SetDistance( pBoxItem->GetDistance( nLine ), nLine );
+ }
+}
+
+// --------------------------------------------------------------------
+
+static void ImplSetLineColor( SvxBoxItem& rNewFrame, USHORT nLine, const Color& rColor )
+{
+ const SvxBorderLine* pSourceLine = rNewFrame.GetLine( nLine );
+ if( pSourceLine )
+ {
+ SvxBorderLine aLine( *pSourceLine );
+ aLine.SetColor( rColor );
+ rNewFrame.SetLine( &aLine, nLine );
+ }
+}
+
+// --------------------------------------------------------------------
+
+static void ImplApplyLineColorItem( sal_uInt16 nCellFlags, const SvxColorItem* pLineColorItem, SvxBoxItem& rNewFrame )
+{
+ const Color aColor( pLineColorItem->GetValue() );
+
+ if( (nCellFlags & (CELL_LOWER|CELL_BEFORE|CELL_AFTER)) == 0 )
+ ImplSetLineColor( rNewFrame, BOX_LINE_BOTTOM, aColor );
+
+ if( (nCellFlags & (CELL_UPPER|CELL_BEFORE|CELL_AFTER)) == 0 )
+ ImplSetLineColor( rNewFrame, BOX_LINE_TOP, aColor );
+
+ if( (nCellFlags & (CELL_UPPER|CELL_LOWER|CELL_AFTER)) == 0 )
+ ImplSetLineColor( rNewFrame, BOX_LINE_RIGHT, aColor );
+
+ if( (nCellFlags & (CELL_UPPER|CELL_LOWER|CELL_BEFORE)) == 0 )
+ ImplSetLineColor( rNewFrame, BOX_LINE_LEFT, aColor );
+}
+
+// --------------------------------------------------------------------
+
+static void ImplApplyBorderLineItem( sal_uInt16 nCellFlags, const SvxBorderLine* pBorderLineItem, SvxBoxItem& rNewFrame )
+{
+ if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER|CELL_UPPER|CELL_LOWER)) != 0 )
+ {
+ if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER)) == 0 ) // check if its not nw or ne corner
+ {
+ if( nCellFlags & CELL_UPPER )
+ {
+ if( rNewFrame.GetBottom() )
+ ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_BOTTOM );
+ }
+ else if( nCellFlags & CELL_LOWER )
+ {
+ if( rNewFrame.GetTop() )
+ ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_TOP );
+ }
+ }
+ else if( (nCellFlags & ( CELL_UPPER|CELL_LOWER)) == 0 ) // check if its not sw or se corner
+ {
+ if( nCellFlags & CELL_BEFORE )
+ {
+ if( rNewFrame.GetRight() )
+ ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_RIGHT );
+ }
+ else if( nCellFlags & CELL_AFTER )
+ {
+ if( rNewFrame.GetLeft() )
+ ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_LEFT );
+ }
+ }
+ }
+ else
+ {
+ if( rNewFrame.GetBottom() )
+ ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_BOTTOM );
+ if( rNewFrame.GetTop() )
+ ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_TOP );
+ if( rNewFrame.GetRight() )
+ ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_RIGHT );
+ if( rNewFrame.GetLeft() )
+ ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_LEFT );
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::ApplyBorderAttr( const SfxItemSet& rAttr )
+{
+ if( mxTable.is() )
+ {
+ const sal_Int32 nRowCount = mxTable->getRowCount();
+ const sal_Int32 nColCount = mxTable->getColumnCount();
+ if( nRowCount && nColCount )
+ {
+ const SvxBoxItem* pBoxItem = 0;
+ if(SFX_ITEM_SET == rAttr.GetItemState(SDRATTR_TABLE_BORDER, FALSE) )
+ pBoxItem = dynamic_cast< const SvxBoxItem* >( &rAttr.Get( SDRATTR_TABLE_BORDER ) );
+
+ const SvxBoxInfoItem* pBoxInfoItem = 0;
+ if(SFX_ITEM_SET == rAttr.GetItemState(SDRATTR_TABLE_BORDER_INNER, FALSE) )
+ pBoxInfoItem = dynamic_cast< const SvxBoxInfoItem* >( &rAttr.Get( SDRATTR_TABLE_BORDER_INNER ) );
+
+ const SvxColorItem* pLineColorItem = 0;
+ if(SFX_ITEM_SET == rAttr.GetItemState(SID_FRAME_LINECOLOR, FALSE) )
+ pLineColorItem = dynamic_cast< const SvxColorItem* >( &rAttr.Get( SID_FRAME_LINECOLOR ) );
+
+ const SvxBorderLine* pBorderLineItem = 0;
+ if(SFX_ITEM_SET == rAttr.GetItemState(SID_FRAME_LINESTYLE, FALSE) )
+ pBorderLineItem = ((const SvxLineItem&)rAttr.Get( SID_FRAME_LINESTYLE )).GetLine();
+
+ if( pBoxInfoItem && !pBoxItem )
+ {
+ const static SvxBoxItem gaEmptyBoxItem( SDRATTR_TABLE_BORDER );
+ pBoxItem = &gaEmptyBoxItem;
+ }
+ else if( pBoxItem && !pBoxInfoItem )
+ {
+ const static SvxBoxInfoItem gaEmptyBoxInfoItem( SDRATTR_TABLE_BORDER_INNER );
+ pBoxInfoItem = &gaEmptyBoxInfoItem;
+ }
+
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+
+ const sal_Int32 nLastRow = std::min( aEnd.mnRow + 2, nRowCount );
+ const sal_Int32 nLastCol = std::min( aEnd.mnCol + 2, nColCount );
+
+ for( sal_Int32 nRow = std::max( aStart.mnRow - 1, (sal_Int32)0 ); nRow < nLastRow; nRow++ )
+ {
+ sal_uInt16 nRowFlags = 0;
+ nRowFlags |= (nRow == aStart.mnRow) ? CELL_TOP : 0;
+ nRowFlags |= (nRow == aEnd.mnRow) ? CELL_BOTTOM : 0;
+ nRowFlags |= (nRow < aStart.mnRow) ? CELL_UPPER : 0;
+ nRowFlags |= (nRow > aEnd.mnRow) ? CELL_LOWER : 0;
+
+ for( sal_Int32 nCol = std::max( aStart.mnCol - 1, (sal_Int32)0 ); nCol < nLastCol; nCol++ )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( !xCell.is() )
+ continue;
+
+ const SfxItemSet& rSet = xCell->GetItemSet();
+ const SvxBoxItem* pOldOuter = (const SvxBoxItem*) &rSet.Get( SDRATTR_TABLE_BORDER );
+
+ SvxBoxItem aNewFrame( *pOldOuter );
+
+ sal_uInt16 nCellFlags = nRowFlags;
+ nCellFlags |= (nCol == aStart.mnCol) ? CELL_LEFT : 0;
+ nCellFlags |= (nCol == aEnd.mnCol) ? CELL_RIGHT : 0;
+ nCellFlags |= (nCol < aStart.mnCol) ? CELL_BEFORE : 0;
+ nCellFlags |= (nCol > aEnd.mnCol) ? CELL_AFTER : 0;
+
+ if( pBoxItem && pBoxInfoItem )
+ ImplApplyBoxItem( nCellFlags, pBoxItem, pBoxInfoItem, aNewFrame );
+
+ if( pLineColorItem )
+ ImplApplyLineColorItem( nCellFlags, pLineColorItem, aNewFrame );
+
+ if( pBorderLineItem )
+ ImplApplyBorderLineItem( nCellFlags, pBorderLineItem, aNewFrame );
+
+ if (aNewFrame != *pOldOuter)
+ {
+ SfxItemSet aAttr(*rSet.GetPool(), rSet.GetRanges());
+ aAttr.Put(aNewFrame);
+ xCell->SetMergedItemSetAndBroadcast( aAttr, false );
+ }
+ }
+ }
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SvxTableController::UpdateTableShape()
+{
+ SdrObject* pTableObj = mxTableObj.get();
+ if( pTableObj )
+ {
+ pTableObj->ActionChanged();
+ pTableObj->BroadcastObjectChange();
+ }
+ updateSelectionOverlay();
+}
+
+
+// --------------------------------------------------------------------
+
+void SvxTableController::SetAttrToSelectedCells(const SfxItemSet& rAttr, bool bReplaceAll)
+{
+ if( mxTable.is() )
+ {
+ const bool bUndo = mpModel && mpModel->IsUndoEnabled();
+
+ if( bUndo )
+ mpModel->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT) );
+
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+
+ SfxItemSet aAttr(*rAttr.GetPool(), rAttr.GetRanges());
+ aAttr.Put(rAttr, TRUE);
+
+ const bool bFrame = (rAttr.GetItemState( SDRATTR_TABLE_BORDER ) == SFX_ITEM_SET) || (rAttr.GetItemState( SDRATTR_TABLE_BORDER_INNER ) == SFX_ITEM_SET);
+
+ if( bFrame )
+ {
+ aAttr.ClearItem( SDRATTR_TABLE_BORDER );
+ aAttr.ClearItem( SDRATTR_TABLE_BORDER_INNER );
+ }
+
+ for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
+ {
+ for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( xCell.is() )
+ {
+ if( bUndo )
+ xCell->AddUndo();
+ xCell->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll);
+ }
+ }
+ }
+
+ if( bFrame )
+ {
+ ApplyBorderAttr( rAttr );
+ }
+
+ UpdateTableShape();
+
+ if( bUndo )
+ mpModel->EndUndo();
+
+ }
+}
+
+// --------------------------------------------------------------------
+
+bool SvxTableController::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const
+{
+ if( mxTableObj.is() && hasSelectedCells() )
+ {
+ MergeAttrFromSelectedCells( rTargetSet, bOnlyHardAttr );
+
+ if( mpView->IsTextEdit() )
+ {
+ if( mxTableObj->GetOutlinerParaObject() )
+ rTargetSet.Put( SvxScriptTypeItem( mxTableObj->GetOutlinerParaObject()->GetTextObject().GetScriptType() ) );
+
+ OutlinerView* pTextEditOutlinerView = mpView->GetTextEditOutlinerView();
+ if(pTextEditOutlinerView)
+ {
+ // FALSE= InvalidItems nicht al Default, sondern als "Loecher" betrachten
+ rTargetSet.Put(pTextEditOutlinerView->GetAttribs(), FALSE);
+ rTargetSet.Put( SvxScriptTypeItem( pTextEditOutlinerView->GetSelectedScriptType() ), FALSE );
+ }
+ }
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+// --------------------------------------------------------------------
+
+bool SvxTableController::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll)
+{
+ if( mbCellSelectionMode || mpView->IsTextEdit() )
+ {
+ SetAttrToSelectedCells( rSet, bReplaceAll );
+ return true;
+ }
+ return false;
+}
+
+// --------------------------------------------------------------------
+
+bool SvxTableController::GetMarkedObjModel( SdrPage* pNewPage )
+{
+ if( mxTableObj.is() && mbCellSelectionMode && pNewPage ) try
+ {
+ ::sdr::table::SdrTableObj& rTableObj = *static_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
+
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+
+ SdrTableObj* pNewTableObj = rTableObj.CloneRange( aStart, aEnd );
+
+ pNewTableObj->SetPage( pNewPage );
+ pNewTableObj->SetModel( pNewPage->GetModel() );
+
+ SdrInsertReason aReason(SDRREASON_VIEWCALL);
+ pNewPage->InsertObject(pNewTableObj,CONTAINER_APPEND,&aReason);
+
+ return true;
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" );
+ }
+ return false;
+}
+
+// --------------------------------------------------------------------
+
+bool SvxTableController::PasteObjModel( const SdrModel& rModel )
+{
+ if( mxTableObj.is() && mpView && (rModel.GetPageCount() >= 1) )
+ {
+ const SdrPage* pPastePage = rModel.GetPage(0);
+ if( pPastePage && pPastePage->GetObjCount() == 1 )
+ {
+ SdrTableObj* pPasteTableObj = dynamic_cast< SdrTableObj* >( pPastePage->GetObj(0) );
+ if( pPasteTableObj )
+ {
+ return PasteObject( pPasteTableObj );
+ }
+ }
+ }
+
+ return false;
+}
+
+// --------------------------------------------------------------------
+
+bool SvxTableController::PasteObject( SdrTableObj* pPasteTableObj )
+{
+ if( !pPasteTableObj )
+ return false;
+
+ Reference< XTable > xPasteTable( pPasteTableObj->getTable() );
+ if( !xPasteTable.is() )
+ return false;
+
+ if( !mxTable.is() )
+ return false;
+
+ sal_Int32 nPasteColumns = xPasteTable->getColumnCount();
+ sal_Int32 nPasteRows = xPasteTable->getRowCount();
+
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+
+ if( mpView->IsTextEdit() )
+ mpView->SdrEndTextEdit(sal_True);
+
+ sal_Int32 nColumns = mxTable->getColumnCount();
+ sal_Int32 nRows = mxTable->getRowCount();
+
+ const sal_Int32 nMissing = nPasteRows - ( nRows - aStart.mnRow );
+ if( nMissing > 0 )
+ {
+ Reference< XTableRows > xRows( mxTable->getRows() );
+ xRows->insertByIndex( nRows, nMissing );
+ nRows = mxTable->getRowCount();
+ }
+
+ nPasteRows = std::min( nPasteRows, nRows - aStart.mnRow );
+ nPasteColumns = std::min( nPasteColumns, nColumns - aStart.mnCol );
+
+ // copy cell contents
+ for( sal_Int32 nRow = 0; nRow < nPasteRows; ++nRow )
+ {
+ for( sal_Int32 nCol = 0; nCol < nPasteColumns; ++nCol )
+ {
+ CellRef xTargetCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( aStart.mnCol + nCol, aStart.mnRow + nRow ).get() ) );
+ if( xTargetCell.is() && !xTargetCell->isMerged() )
+ {
+ xTargetCell->AddUndo();
+ xTargetCell->cloneFrom( dynamic_cast< Cell* >( xPasteTable->getCellByPosition( nCol, nRow ).get() ) );
+ nCol += xTargetCell->getColumnSpan() - 1;
+ }
+ }
+ }
+
+ UpdateTableShape();
+
+ return true;
+}
+
+bool SvxTableController::TakeFormatPaintBrush( boost::shared_ptr< SfxItemSet >& /*rFormatSet*/ )
+{
+ // SdrView::TakeFormatPaintBrush() is enough
+ return false;
+}
+
+bool SvxTableController::ApplyFormatPaintBrush( SfxItemSet& rFormatSet, bool bNoCharacterFormats, bool bNoParagraphFormats )
+{
+ if( mbCellSelectionMode )
+ {
+ SdrTextObj* pTableObj = dynamic_cast<SdrTextObj*>( mxTableObj.get() );
+ if( !pTableObj )
+ return false;
+
+ const bool bUndo = mpModel && mpModel->IsUndoEnabled();
+
+ if( bUndo )
+ mpModel->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT) );
+
+ CellPos aStart, aEnd;
+ getSelectedCells( aStart, aEnd );
+
+ SfxItemSet aAttr(*rFormatSet.GetPool(), rFormatSet.GetRanges());
+ aAttr.Put(rFormatSet, TRUE);
+
+ const bool bFrame = (rFormatSet.GetItemState( SDRATTR_TABLE_BORDER ) == SFX_ITEM_SET) || (rFormatSet.GetItemState( SDRATTR_TABLE_BORDER_INNER ) == SFX_ITEM_SET);
+
+ if( bFrame )
+ {
+ aAttr.ClearItem( SDRATTR_TABLE_BORDER );
+ aAttr.ClearItem( SDRATTR_TABLE_BORDER_INNER );
+ }
+
+ const USHORT* pRanges = rFormatSet.GetRanges();
+ bool bTextOnly = true;
+
+ while( *pRanges )
+ {
+ if( (*pRanges != EE_PARA_START) && (*pRanges != EE_CHAR_START) )
+ {
+ bTextOnly = true;
+ break;
+ }
+ pRanges += 2;
+ }
+
+ const bool bReplaceAll = false;
+ for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
+ {
+ for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( xCell.is() )
+ {
+ if( bUndo )
+ xCell->AddUndo();
+ if( !bTextOnly )
+ xCell->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll);
+
+ SdrText* pText = static_cast< SdrText* >( xCell.get() );
+ mpView->ApplyFormatPaintBrushToText( rFormatSet, *pTableObj, pText, bNoCharacterFormats, bNoParagraphFormats );
+ }
+ }
+ }
+
+ if( bFrame )
+ {
+ ApplyBorderAttr( rFormatSet );
+ }
+
+ UpdateTableShape();
+
+ if( bUndo )
+ mpModel->EndUndo();
+
+ return true;
+
+ }
+ return false;
+}
+
+
+// --------------------------------------------------------------------
+
+IMPL_LINK( SvxTableController, UpdateHdl, void *, EMPTYARG )
+{
+ mnUpdateEvent = 0;
+
+ if( mbCellSelectionMode )
+ {
+ CellPos aStart( maCursorFirstPos );
+ CellPos aEnd( maCursorLastPos );
+ checkCell(aStart);
+ checkCell(aEnd);
+ if( aStart != maCursorFirstPos || aEnd != maCursorLastPos )
+ {
+ setSelectedCells( aStart, aEnd );
+ }
+ }
+ updateSelectionOverlay();
+
+ return 0;
+}
+
+} }
diff --git a/svx/source/table/tablecontroller.hxx b/svx/source/table/tablecontroller.hxx
new file mode 100644
index 000000000000..8ced09bc587f
--- /dev/null
+++ b/svx/source/table/tablecontroller.hxx
@@ -0,0 +1,170 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_TABLECONTROLLER_HXX_
+#define _SVX_TABLECONTROLLER_HXX_
+
+#include <com/sun/star/util/XModifyListener.hpp>
+#include <com/sun/star/table/XTable.hpp>
+#include <rtl/ref.hxx>
+
+#include <svx/sdr/overlay/overlayobjectlist.hxx>
+#include <svx/selectioncontroller.hxx>
+#include <svx/svdotable.hxx>
+#include <svx/svdview.hxx>
+#include <tablemodel.hxx>
+
+class SdrObjEditView;
+class SdrObject;
+class SfxItemSet;
+
+namespace sdr { namespace table {
+
+const sal_Int16 SELTYPE_NONE = 0;
+const sal_Int16 SELTYPE_MOUSE = 1;
+const sal_Int16 SELTYPE_KEYS = 2;
+
+class SVX_DLLPUBLIC SvxTableController: public sdr::SelectionController
+{
+public:
+ SVX_DLLPRIVATE SvxTableController( SdrObjEditView* pView, const SdrObject* pObj );
+ SVX_DLLPRIVATE virtual ~SvxTableController();
+
+ // from sdr::SelectionController
+ SVX_DLLPRIVATE virtual bool onKeyInput(const KeyEvent& rKEvt, Window* pWin);
+ SVX_DLLPRIVATE virtual bool onMouseButtonDown(const MouseEvent& rMEvt, Window* pWin);
+ SVX_DLLPRIVATE virtual bool onMouseButtonUp(const MouseEvent& rMEvt, Window* pWin);
+ SVX_DLLPRIVATE virtual bool onMouseMove(const MouseEvent& rMEvt, Window* pWin);
+
+ SVX_DLLPRIVATE virtual bool DeleteMarked();
+
+ SVX_DLLPRIVATE virtual void onSelectionHasChanged();
+
+ SVX_DLLPRIVATE virtual void GetState( SfxItemSet& rSet );
+ SVX_DLLPRIVATE virtual void Execute( SfxRequest& rReq );
+
+ SVX_DLLPRIVATE virtual bool GetStyleSheet( SfxStyleSheet* &rpStyleSheet ) const;
+ SVX_DLLPRIVATE virtual bool SetStyleSheet( SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr );
+
+ SVX_DLLPRIVATE virtual bool TakeFormatPaintBrush( boost::shared_ptr< SfxItemSet >& rFormatSet );
+ SVX_DLLPRIVATE virtual bool ApplyFormatPaintBrush( SfxItemSet& rFormatSet, bool bNoCharacterFormats, bool bNoParagraphFormats );
+
+ // slots
+ SVX_DLLPRIVATE void onInsert( sal_uInt16 nSId, const SfxItemSet* pArgs = 0 );
+ SVX_DLLPRIVATE void onDelete( sal_uInt16 nSId );
+ SVX_DLLPRIVATE void onSelect( sal_uInt16 nSId );
+ SVX_DLLPRIVATE void onFormatTable( SfxRequest& rReq );
+ SVX_DLLPRIVATE void MergeMarkedCells();
+ SVX_DLLPRIVATE void SplitMarkedCells();
+ SVX_DLLPRIVATE void DistributeColumns();
+ SVX_DLLPRIVATE void DistributeRows();
+ SVX_DLLPRIVATE void SetVertical( sal_uInt16 nSId );
+
+ SVX_DLLPRIVATE static rtl::Reference< sdr::SelectionController > create( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController );
+
+ SVX_DLLPRIVATE void MergeAttrFromSelectedCells(SfxItemSet& rAttr, bool bOnlyHardAttr) const;
+ SVX_DLLPRIVATE void SetAttrToSelectedCells(const SfxItemSet& rAttr, bool bReplaceAll);
+
+ SVX_DLLPRIVATE virtual bool GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const;
+ SVX_DLLPRIVATE virtual bool SetAttributes(const SfxItemSet& rSet, bool bReplaceAll);
+
+ SVX_DLLPRIVATE virtual bool GetMarkedObjModel( SdrPage* pNewPage );
+ SVX_DLLPRIVATE virtual bool PasteObjModel( const SdrModel& rModel );
+
+ SVX_DLLPRIVATE bool hasSelectedCells() const { return mbCellSelectionMode || mpView->IsTextEdit(); }
+
+ void getSelectedCells( CellPos& rFirstPos, CellPos& rLastPos );
+ void setSelectedCells( const CellPos& rFirstPos, const CellPos& rLastPos );
+ void clearSelection();
+ void selectAll();
+
+ SVX_DLLPRIVATE void onTableModified();
+
+private:
+ SvxTableController(SvxTableController &); // not defined
+ void operator =(SvxTableController &); // not defined
+
+ // internals
+ SVX_DLLPRIVATE void ApplyBorderAttr( const SfxItemSet& rAttr );
+ SVX_DLLPRIVATE void UpdateTableShape();
+
+ SVX_DLLPRIVATE void SetTableStyle( const SfxItemSet* pArgs );
+ SVX_DLLPRIVATE void SetTableStyleSettings( const SfxItemSet* pArgs );
+
+ SVX_DLLPRIVATE bool PasteObject( SdrTableObj* pPasteTableObj );
+
+ SVX_DLLPRIVATE bool checkTableObject();
+ SVX_DLLPRIVATE bool updateTableObject();
+ SVX_DLLPRIVATE const CellPos& getSelectionStart();
+ SVX_DLLPRIVATE void setSelectionStart( const CellPos& rPos );
+ SVX_DLLPRIVATE const CellPos& getSelectionEnd();
+ SVX_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellCursor > getSelectionCursor();
+ SVX_DLLPRIVATE void checkCell( CellPos& rPos );
+
+ SVX_DLLPRIVATE void MergeRange( sal_Int32 nFirstCol, sal_Int32 nFirstRow, sal_Int32 nLastCol, sal_Int32 nLastRow );
+
+ SVX_DLLPRIVATE void EditCell( const CellPos& rPos, ::Window* pWindow, const ::com::sun::star::awt::MouseEvent* pMouseEvent = 0, sal_uInt16 nAction = 0 );
+ SVX_DLLPRIVATE bool StopTextEdit();
+
+ SVX_DLLPRIVATE void DeleteTable();
+
+ SVX_DLLPRIVATE sal_uInt16 getKeyboardAction( const KeyEvent& rKEvt, Window* pWindow );
+ SVX_DLLPRIVATE bool executeAction( sal_uInt16 nAction, bool bSelect, Window* pWindow );
+ SVX_DLLPRIVATE void gotoCell( const CellPos& rCell, bool bSelect, Window* pWindow, sal_uInt16 nAction = 0 );
+
+ SVX_DLLPRIVATE void StartSelection( const CellPos& rPos );
+ SVX_DLLPRIVATE void UpdateSelection( const CellPos& rPos );
+ SVX_DLLPRIVATE void RemoveSelection();
+ SVX_DLLPRIVATE void updateSelectionOverlay();
+ SVX_DLLPRIVATE void destroySelectionOverlay();
+
+ SVX_DLLPRIVATE void findMergeOrigin( CellPos& rPos );
+
+ DECL_LINK( UpdateHdl, void * );
+
+ TableModelRef mxTable;
+
+ CellPos maCursorFirstPos;
+ CellPos maCursorLastPos;
+ bool mbCellSelectionMode;
+ CellPos maMouseDownPos;
+ bool mbLeftButtonDown;
+ ::sdr::overlay::OverlayObjectList* mpSelectionOverlay;
+
+ SdrView* mpView;
+ SdrObjectWeakRef mxTableObj;
+ SdrModel* mpModel;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > mxModifyListener;
+
+ ULONG mnUpdateEvent;
+};
+
+} }
+
+#endif // _SVX_TABLECONTROLLER_HXX_
+
diff --git a/svx/source/table/tabledesign.cxx b/svx/source/table/tabledesign.cxx
new file mode 100644
index 000000000000..e952425e5c30
--- /dev/null
+++ b/svx/source/table/tabledesign.cxx
@@ -0,0 +1,808 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+#include <com/sun/star/util/XModifyListener.hpp>
+#include <comphelper/serviceinfohelper.hxx>
+
+#include <osl/mutex.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase6.hxx>
+#include <cppuhelper/implbase7.hxx>
+#include <cppuhelper/interfacecontainer.h>
+
+#include "svx/unoprov.hxx"
+#include "svx/sdr/table/tabledesign.hxx"
+#include "svx/dialmgr.hxx"
+#include "svx/dialogs.hrc"
+
+#include "celltypes.hxx"
+
+#include <vector>
+#include <map>
+
+#include <boost/bind.hpp>
+
+// -----------------------------------------------------------------------------
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::container;
+
+using ::rtl::OUString;
+using ::vos::OGuard;
+using ::osl::MutexGuard;
+using ::osl::ClearableMutexGuard;
+using ::cppu::OInterfaceContainerHelper;
+
+namespace sdr { namespace table {
+
+typedef std::map< OUString, sal_Int32 > CellStyleNameMap;
+
+typedef ::cppu::WeakComponentImplHelper6< XStyle, XNameReplace, XServiceInfo, XIndexAccess, XModifyBroadcaster, XModifyListener > TableDesignStyleBase;
+
+class TableDesignStyle : private ::cppu::BaseMutex, public TableDesignStyleBase
+{
+public:
+ TableDesignStyle();
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw(RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException);
+
+ // XStyle
+ virtual ::sal_Bool SAL_CALL isUserDefined() throw (RuntimeException);
+ virtual ::sal_Bool SAL_CALL isInUse() throw (RuntimeException);
+ virtual OUString SAL_CALL getParentStyle() throw (RuntimeException);
+ virtual void SAL_CALL setParentStyle( const OUString& aParentStyle ) throw (NoSuchElementException, RuntimeException);
+
+ // XNamed
+ virtual OUString SAL_CALL getName() throw (RuntimeException);
+ virtual void SAL_CALL setName( const OUString& aName ) throw (RuntimeException);
+
+ // XNameAccess
+ virtual Any SAL_CALL getByName( const OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getElementNames() throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) throw(RuntimeException);
+
+ // XElementAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType() throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements() throw(RuntimeException);
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount() throw(RuntimeException) ;
+ virtual Any SAL_CALL getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException);
+
+ // XNameReplace
+ virtual void SAL_CALL replaceByName( const OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
+
+ // XModifyBroadcaster
+ virtual void SAL_CALL addModifyListener( const Reference< XModifyListener >& aListener ) throw (RuntimeException);
+ virtual void SAL_CALL removeModifyListener( const Reference< XModifyListener >& aListener ) throw (RuntimeException);
+
+ // XModifyListener
+ virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+
+ void notifyModifyListener();
+
+ // this function is called upon disposing the component
+ virtual void SAL_CALL disposing();
+
+ static const CellStyleNameMap& getCellStyleNameMap();
+
+ OUString msName;
+ Reference< XStyle > maCellStyles[style_count];
+};
+
+typedef std::vector< Reference< XStyle > > TableDesignStyleVector;
+
+class TableDesignFamily : public ::cppu::WeakImplHelper7< XNameContainer, XNamed, XIndexAccess, XSingleServiceFactory, XServiceInfo, XComponent, XPropertySet >
+{
+public:
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw(RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException);
+
+ // XNamed
+ virtual OUString SAL_CALL getName( ) throw (RuntimeException);
+ virtual void SAL_CALL setName( const OUString& aName ) throw (RuntimeException);
+
+ // XNameAccess
+ virtual Any SAL_CALL getByName( const OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getElementNames() throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) throw(RuntimeException);
+
+ // XElementAccess
+ virtual Type SAL_CALL getElementType() throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements() throw(RuntimeException);
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount() throw(RuntimeException) ;
+ virtual Any SAL_CALL getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException);
+
+ // XNameContainer
+ virtual void SAL_CALL insertByName( const OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL removeByName( const OUString& Name ) throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+
+ // XNameReplace
+ virtual void SAL_CALL replaceByName( const OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
+
+ // XSingleServiceFactory
+ virtual Reference< XInterface > SAL_CALL createInstance( ) throw(Exception, RuntimeException);
+ virtual Reference< XInterface > SAL_CALL createInstanceWithArguments( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException);
+
+ // XComponent
+ virtual void SAL_CALL dispose( ) throw (RuntimeException);
+ virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException);
+ virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) throw (RuntimeException);
+
+ // XPropertySet
+ virtual Reference<XPropertySetInfo> SAL_CALL getPropertySetInfo() throw (RuntimeException);
+ virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException);
+ virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference<XPropertyChangeListener>& xListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener>& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName,const Reference<XVetoableChangeListener>&aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
+
+ TableDesignStyleVector maDesigns;
+};
+
+//------------------------------------------------------------------------
+// TableDesignStyle
+//------------------------------------------------------------------------
+
+TableDesignStyle::TableDesignStyle()
+: TableDesignStyleBase(m_aMutex)
+{
+}
+
+const CellStyleNameMap& TableDesignStyle::getCellStyleNameMap()
+{
+ static CellStyleNameMap aMap;
+ if( aMap.empty() )
+ {
+ CellStyleNameMap aNewMap;
+ aNewMap[ OUString( RTL_CONSTASCII_USTRINGPARAM( "first-row" ) ) ] = first_row_style;
+ aNewMap[ OUString( RTL_CONSTASCII_USTRINGPARAM( "last-row" ) ) ] = last_row_style;
+ aNewMap[ OUString( RTL_CONSTASCII_USTRINGPARAM( "first-column" ) ) ] = first_column_style;
+ aNewMap[ OUString( RTL_CONSTASCII_USTRINGPARAM( "last-column" ) ) ] = last_column_style;
+ aNewMap[ OUString( RTL_CONSTASCII_USTRINGPARAM( "body" ) ) ] = body_style;
+ aNewMap[ OUString( RTL_CONSTASCII_USTRINGPARAM( "even-rows" ) ) ] = even_rows_style;
+ aNewMap[ OUString( RTL_CONSTASCII_USTRINGPARAM( "odd-rows" ) ) ] = odd_rows_style;
+ aNewMap[ OUString( RTL_CONSTASCII_USTRINGPARAM( "even-columns" ) ) ] = even_columns_style;
+ aNewMap[ OUString( RTL_CONSTASCII_USTRINGPARAM( "odd-columns" ) ) ] = odd_columns_style;
+ aNewMap[ OUString( RTL_CONSTASCII_USTRINGPARAM( "background" ) ) ] = background_style;
+ aMap.swap( aNewMap );
+ }
+
+ return aMap;
+}
+
+// ----------------------------------------------------------
+// XServiceInfo
+// ----------------------------------------------------------
+
+OUString SAL_CALL TableDesignStyle::getImplementationName() throw(RuntimeException)
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM("TableDesignStyle") );
+}
+
+// ----------------------------------------------------------
+
+sal_Bool SAL_CALL TableDesignStyle::supportsService( const OUString& ServiceName ) throw(RuntimeException)
+{
+ return comphelper::ServiceInfoHelper::supportsService( ServiceName, getSupportedServiceNames() );
+}
+
+// ----------------------------------------------------------
+
+Sequence< OUString > SAL_CALL TableDesignStyle::getSupportedServiceNames() throw(RuntimeException)
+{
+ OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.style.Style") );
+ Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+// ----------------------------------------------------------
+// XStyle
+// ----------------------------------------------------------
+
+sal_Bool SAL_CALL TableDesignStyle::isUserDefined() throw (RuntimeException)
+{
+ return sal_False;
+}
+
+// ----------------------------------------------------------
+
+sal_Bool SAL_CALL TableDesignStyle::isInUse() throw (RuntimeException)
+{
+ ClearableMutexGuard aGuard( rBHelper.rMutex );
+ OInterfaceContainerHelper * pContainer = rBHelper.getContainer( XModifyListener::static_type() );
+ if( pContainer )
+ {
+ Sequence< Reference< XInterface > > aListener( pContainer->getElements() );
+ aGuard.clear();
+
+ sal_Int32 nIndex = aListener.getLength();
+ while( --nIndex >= 0 )
+ {
+ TableDesignUser* pUser = dynamic_cast< TableDesignUser* >( aListener[nIndex].get() );
+ if( pUser && pUser->isInUse() )
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+// ----------------------------------------------------------
+
+OUString SAL_CALL TableDesignStyle::getParentStyle() throw (RuntimeException)
+{
+ return OUString();
+}
+
+// ----------------------------------------------------------
+
+void SAL_CALL TableDesignStyle::setParentStyle( const OUString& ) throw (NoSuchElementException, RuntimeException)
+{
+}
+
+// ----------------------------------------------------------
+// XNamed
+// ----------------------------------------------------------
+
+OUString SAL_CALL TableDesignStyle::getName() throw (RuntimeException)
+{
+ return msName;
+}
+
+// ----------------------------------------------------------
+
+void SAL_CALL TableDesignStyle::setName( const OUString& rName ) throw (RuntimeException)
+{
+ msName = rName;
+}
+
+// ----------------------------------------------------------
+// XNameAccess
+// ----------------------------------------------------------
+
+Any SAL_CALL TableDesignStyle::getByName( const OUString& rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ const CellStyleNameMap& rMap = getCellStyleNameMap();
+
+ CellStyleNameMap::const_iterator iter = rMap.find( rName );
+ if( iter == rMap.end() )
+ throw NoSuchElementException();
+
+ return Any( maCellStyles[(*iter).second] );
+}
+
+// ----------------------------------------------------------
+
+Sequence< OUString > SAL_CALL TableDesignStyle::getElementNames() throw(RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ const CellStyleNameMap& rMap = getCellStyleNameMap();
+ Sequence< OUString > aRet( rMap.size() );
+ OUString* pName = aRet.getArray();
+
+ CellStyleNameMap::const_iterator iter = rMap.begin();
+ while( iter != rMap.end() )
+ *pName++ = (*iter++).first;
+
+ return aRet;
+}
+
+// ----------------------------------------------------------
+
+sal_Bool SAL_CALL TableDesignStyle::hasByName( const OUString& rName ) throw(RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ const CellStyleNameMap& rMap = getCellStyleNameMap();
+
+ CellStyleNameMap::const_iterator iter = rMap.find( rName );
+ return ( iter != rMap.end() ) ? sal_True : sal_False;
+}
+
+// ----------------------------------------------------------
+// XElementAccess
+// ----------------------------------------------------------
+
+Type SAL_CALL TableDesignStyle::getElementType() throw(RuntimeException)
+{
+ return XStyle::static_type();
+}
+
+// ----------------------------------------------------------
+
+sal_Bool SAL_CALL TableDesignStyle::hasElements() throw(RuntimeException)
+{
+ return sal_True;
+}
+
+// ----------------------------------------------------------
+// XIndexAccess
+// ----------------------------------------------------------
+
+sal_Int32 SAL_CALL TableDesignStyle::getCount() throw(RuntimeException)
+{
+ return style_count;
+}
+
+// ----------------------------------------------------------
+
+Any SAL_CALL TableDesignStyle::getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( (Index < 0) || (Index >= style_count) )
+ throw IndexOutOfBoundsException();
+
+ return Any( maCellStyles[Index] );
+}
+
+// ----------------------------------------------------------
+// XNameReplace
+// ----------------------------------------------------------
+
+void SAL_CALL TableDesignStyle::replaceByName( const OUString& rName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ const CellStyleNameMap& rMap = getCellStyleNameMap();
+ CellStyleNameMap::const_iterator iter = rMap.find( rName );
+ if( iter == rMap.end() )
+ throw NoSuchElementException();
+
+
+ Reference< XStyle > xNewStyle;
+ if( !(aElement >>= xNewStyle) )
+ throw IllegalArgumentException();
+
+ const sal_Int32 nIndex = (*iter).second;
+
+ Reference< XStyle > xOldStyle( maCellStyles[nIndex] );
+
+ if( xNewStyle != xOldStyle )
+ {
+ Reference< XModifyListener > xListener( this );
+
+ // end listening to old style, if possible
+ Reference< XModifyBroadcaster > xOldBroadcaster( xOldStyle, UNO_QUERY );
+ if( xOldBroadcaster.is() )
+ xOldBroadcaster->removeModifyListener( xListener );
+
+ // start listening to new style, if possible
+ Reference< XModifyBroadcaster > xNewBroadcaster( xNewStyle, UNO_QUERY );
+ if( xNewBroadcaster.is() )
+ xNewBroadcaster->addModifyListener( xListener );
+
+ maCellStyles[nIndex] = xNewStyle;
+ }
+}
+
+// ----------------------------------------------------------
+// XComponent
+// ----------------------------------------------------------
+
+void SAL_CALL TableDesignStyle::disposing()
+{
+ for( sal_Int32 nIndex = 0; nIndex < style_count; nIndex++ )
+ maCellStyles[nIndex].clear();
+}
+
+//------------------------------------------------------------------------
+// XModifyBroadcaster
+//------------------------------------------------------------------------
+
+void SAL_CALL TableDesignStyle::addModifyListener( const Reference< XModifyListener >& xListener ) throw (RuntimeException)
+{
+ ClearableMutexGuard aGuard( rBHelper.rMutex );
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ aGuard.clear();
+ EventObject aEvt( static_cast< OWeakObject * >( this ) );
+ xListener->disposing( aEvt );
+ }
+ else
+ {
+ rBHelper.addListener( XModifyListener::static_type(), xListener );
+ }
+}
+
+//------------------------------------------------------------------------
+
+void SAL_CALL TableDesignStyle::removeModifyListener( const Reference< XModifyListener >& xListener ) throw (RuntimeException)
+{
+ rBHelper.removeListener( XModifyListener::static_type(), xListener );
+}
+
+//------------------------------------------------------------------------
+
+void TableDesignStyle::notifyModifyListener()
+{
+ MutexGuard aGuard( rBHelper.rMutex );
+
+ OInterfaceContainerHelper * pContainer = rBHelper.getContainer( XModifyListener::static_type() );
+ if( pContainer )
+ {
+ EventObject aEvt( static_cast< OWeakObject * >( this ) );
+ pContainer->forEach<XModifyListener>( boost::bind( &XModifyListener::modified, _1, boost::cref( aEvt ) ) );
+ }
+}
+
+//------------------------------------------------------------------------
+// XModifyListener
+//------------------------------------------------------------------------
+
+// if we get a modify hint from a style, notify all registered XModifyListener
+void SAL_CALL TableDesignStyle::modified( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
+{
+ notifyModifyListener();
+}
+
+//------------------------------------------------------------------------
+
+void SAL_CALL TableDesignStyle::disposing( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+//------------------------------------------------------------------------
+// TableStyle
+//------------------------------------------------------------------------
+
+// ----------------------------------------------------------
+// XServiceInfo
+// ----------------------------------------------------------
+
+OUString SAL_CALL TableDesignFamily::getImplementationName() throw(RuntimeException)
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM("TableDesignFamily") );
+}
+
+// ----------------------------------------------------------
+
+sal_Bool SAL_CALL TableDesignFamily::supportsService( const OUString& ServiceName ) throw(RuntimeException)
+{
+ return comphelper::ServiceInfoHelper::supportsService( ServiceName, getSupportedServiceNames() );
+}
+
+// ----------------------------------------------------------
+
+Sequence< OUString > SAL_CALL TableDesignFamily::getSupportedServiceNames() throw(RuntimeException)
+{
+ OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.style.StyleFamily") );
+ Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+// ----------------------------------------------------------
+// XNamed
+// ----------------------------------------------------------
+
+OUString SAL_CALL TableDesignFamily::getName() throw (RuntimeException)
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "table" ) );
+}
+
+// ----------------------------------------------------------
+
+void SAL_CALL TableDesignFamily::setName( const OUString& ) throw (RuntimeException)
+{
+}
+
+// ----------------------------------------------------------
+// XNameAccess
+// ----------------------------------------------------------
+
+Any SAL_CALL TableDesignFamily::getByName( const OUString& rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ for( TableDesignStyleVector::iterator iter( maDesigns.begin() ); iter != maDesigns.end(); iter++ )
+ {
+ if( (*iter)->getName() == rName )
+ return Any( (*iter) );
+ }
+
+ throw NoSuchElementException();
+}
+
+// ----------------------------------------------------------
+
+Sequence< OUString > SAL_CALL TableDesignFamily::getElementNames() throw(RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ Sequence< OUString > aRet( maDesigns.size() );
+ OUString* pNames = aRet.getArray();
+
+ for( TableDesignStyleVector::iterator iter( maDesigns.begin() ); iter != maDesigns.end(); iter++ )
+ *pNames++ = (*iter)->getName();
+
+ return aRet;
+}
+
+// ----------------------------------------------------------
+
+sal_Bool SAL_CALL TableDesignFamily::hasByName( const OUString& aName ) throw(RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ for( TableDesignStyleVector::iterator iter( maDesigns.begin() ); iter != maDesigns.end(); iter++ )
+ if( (*iter)->getName() == aName )
+ return sal_True;
+
+ return sal_False;
+}
+
+// ----------------------------------------------------------
+// XElementAccess
+// ----------------------------------------------------------
+
+Type SAL_CALL TableDesignFamily::getElementType() throw(RuntimeException)
+{
+ return XStyle::static_type();
+}
+
+// ----------------------------------------------------------
+
+sal_Bool SAL_CALL TableDesignFamily::hasElements() throw(RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ return maDesigns.empty() ? sal_False : sal_True;
+}
+
+// ----------------------------------------------------------
+// XIndexAccess
+// ----------------------------------------------------------
+
+sal_Int32 SAL_CALL TableDesignFamily::getCount() throw(RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ return sal::static_int_cast< sal_Int32 >( maDesigns.size() );
+}
+
+// ----------------------------------------------------------
+
+Any SAL_CALL TableDesignFamily::getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( (Index >= 0) && (Index < sal::static_int_cast< sal_Int32 >( maDesigns.size() ) ) )
+ return Any( maDesigns[Index] );
+
+ throw IndexOutOfBoundsException();
+}
+
+// ----------------------------------------------------------
+// XNameContainer
+// ----------------------------------------------------------
+
+void SAL_CALL TableDesignFamily::insertByName( const OUString& rName, const Any& rElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ Reference< XStyle > xStyle( rElement, UNO_QUERY );
+ if( !xStyle.is() )
+ throw IllegalArgumentException();
+
+ xStyle->setName( rName );
+ for( TableDesignStyleVector::iterator iter( maDesigns.begin() ); iter != maDesigns.end(); iter++ )
+ if( (*iter)->getName() == rName )
+ throw ElementExistException();
+
+ maDesigns.push_back( xStyle );
+}
+
+// ----------------------------------------------------------
+
+void SAL_CALL TableDesignFamily::removeByName( const OUString& rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ for( TableDesignStyleVector::iterator iter( maDesigns.begin() ); iter != maDesigns.end(); iter++ )
+ {
+ if( (*iter)->getName() == rName )
+ {
+ maDesigns.erase( iter );
+ return;
+ }
+ }
+
+
+ throw NoSuchElementException();
+}
+
+// ----------------------------------------------------------
+// XNameReplace
+// ----------------------------------------------------------
+
+void SAL_CALL TableDesignFamily::replaceByName( const OUString& rName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ Reference< XStyle > xStyle( aElement, UNO_QUERY );
+ if( !xStyle.is() )
+ throw IllegalArgumentException();
+
+ for( TableDesignStyleVector::iterator iter( maDesigns.begin() ); iter != maDesigns.end(); iter++ )
+ {
+ if( (*iter)->getName() == rName )
+ {
+ (*iter) = xStyle;
+ xStyle->setName( rName );
+ return;
+ }
+ }
+
+ throw NoSuchElementException();
+}
+
+// ----------------------------------------------------------
+// XSingleServiceFactory
+// ----------------------------------------------------------
+
+Reference< XInterface > SAL_CALL TableDesignFamily::createInstance() throw(Exception, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ return Reference< XInterface >( static_cast< XStyle* >( new TableDesignStyle ) );
+}
+
+// ----------------------------------------------------------
+
+Reference< XInterface > SAL_CALL TableDesignFamily::createInstanceWithArguments( const Sequence< Any >& ) throw(Exception, RuntimeException)
+{
+ return createInstance();
+}
+
+// ----------------------------------------------------------
+// XComponent
+// ----------------------------------------------------------
+
+void SAL_CALL TableDesignFamily::dispose( ) throw (RuntimeException)
+{
+ TableDesignStyleVector aDesigns;
+ aDesigns.swap( maDesigns );
+
+ for( TableDesignStyleVector::iterator iter( aDesigns.begin() ); iter != aDesigns.end(); iter++ )
+ {
+ Reference< XComponent > xComp( (*iter), UNO_QUERY );
+ if( xComp.is() )
+ xComp->dispose();
+ }
+}
+
+// ----------------------------------------------------------
+
+void SAL_CALL TableDesignFamily::addEventListener( const Reference< XEventListener >& ) throw (RuntimeException)
+{
+}
+
+// ----------------------------------------------------------
+
+void SAL_CALL TableDesignFamily::removeEventListener( const Reference< XEventListener >& ) throw (RuntimeException)
+{
+}
+
+// ----------------------------------------------------------
+// XPropertySet
+// ----------------------------------------------------------
+
+Reference<XPropertySetInfo> TableDesignFamily::getPropertySetInfo() throw (RuntimeException)
+{
+ OSL_ENSURE( 0, "###unexpected!" );
+ return Reference<XPropertySetInfo>();
+}
+
+// ----------------------------------------------------------
+
+void TableDesignFamily::setPropertyValue( const OUString& , const Any& ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ OSL_ENSURE( 0, "###unexpected!" );
+}
+
+// ----------------------------------------------------------
+
+Any TableDesignFamily::getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DisplayName") ))
+ {
+ OUString sDisplayName( SVX_RESSTR( RID_SVXSTR_STYLEFAMILY_TABLEDESIGN ) );
+ return Any( sDisplayName );
+ }
+ else
+ {
+ throw UnknownPropertyException( OUString( RTL_CONSTASCII_USTRINGPARAM("unknown property: ") ) + PropertyName, static_cast<OWeakObject *>(this) );
+ }
+}
+
+// ----------------------------------------------------------
+
+void TableDesignFamily::addPropertyChangeListener( const OUString& , const Reference<XPropertyChangeListener>& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ OSL_ENSURE( 0, "###unexpected!" );
+}
+
+// ----------------------------------------------------------
+
+void TableDesignFamily::removePropertyChangeListener( const OUString& , const Reference<XPropertyChangeListener>& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ OSL_ENSURE( 0, "###unexpected!" );
+}
+
+// ----------------------------------------------------------
+
+void TableDesignFamily::addVetoableChangeListener( const OUString& , const Reference<XVetoableChangeListener>& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ OSL_ENSURE( 0, "###unexpected!" );
+}
+
+// ----------------------------------------------------------
+
+void TableDesignFamily::removeVetoableChangeListener( const OUString& , const Reference<XVetoableChangeListener>& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ OSL_ENSURE( 0, "###unexpected!" );
+}
+
+// --------------------------------------------------------------------
+
+
+SVX_DLLPUBLIC Reference< XNameAccess > CreateTableDesignFamily()
+{
+ return new TableDesignFamily();
+}
+
+} }
diff --git a/svx/source/table/tablehandles.cxx b/svx/source/table/tablehandles.cxx
new file mode 100644
index 000000000000..33833f8b81b1
--- /dev/null
+++ b/svx/source/table/tablehandles.cxx
@@ -0,0 +1,314 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "tablehandles.hxx"
+
+#include <vcl/svapp.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/salbtype.hxx>
+#include <vcl/canvastools.hxx>
+#include <vcl/hatch.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/range/b2drectangle.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <svx/sdr/overlay/overlayobject.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <svx/sdrpagewindow.hxx>
+#include <sdrpaintwindow.hxx>
+#include <svx/svdmrkv.hxx>
+#include <svx/svdpagv.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <svx/sdr/overlay/overlayhatchrect.hxx>
+#include <drawinglayer/primitive2d/hiddengeometryprimitive2d.hxx>
+
+namespace sdr { namespace table {
+
+// --------------------------------------------------------------------
+
+class OverlayTableEdge : public sdr::overlay::OverlayObject
+{
+protected:
+ basegfx::B2DPolyPolygon maPolyPolygon;
+ bool mbVisible;
+
+ // geometry creation for OverlayObject
+ virtual drawinglayer::primitive2d::Primitive2DSequence createOverlayObjectPrimitive2DSequence();
+
+public:
+ OverlayTableEdge( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bVisible );
+ virtual ~OverlayTableEdge();
+};
+
+// --------------------------------------------------------------------
+
+TableEdgeHdl::TableEdgeHdl( const Point& rPnt, bool bHorizontal, sal_Int32 nMin, sal_Int32 nMax, sal_Int32 nEdges )
+: SdrHdl( rPnt, HDL_USER )
+, mbHorizontal( bHorizontal )
+, mnMin( nMin )
+, mnMax( nMax )
+, maEdges(nEdges)
+{
+}
+
+void TableEdgeHdl::SetEdge( sal_Int32 nEdge, sal_Int32 nStart, sal_Int32 nEnd, TableEdgeState eState )
+{
+ if( (nEdge >= 0) && (nEdge <= sal::static_int_cast<sal_Int32>(maEdges.size())) )
+ {
+ maEdges[nEdge].mnStart = nStart;
+ maEdges[nEdge].mnEnd = nEnd;
+ maEdges[nEdge].meState = eState;
+ }
+ else
+ {
+ OSL_ENSURE( false, "sdr::table::TableEdgeHdl::SetEdge(), invalid edge!" );
+ }
+}
+
+Pointer TableEdgeHdl::GetPointer() const
+{
+ if( mbHorizontal )
+ return POINTER_VSPLIT;
+ else
+ return POINTER_HSPLIT;
+}
+
+sal_Int32 TableEdgeHdl::GetValidDragOffset( const SdrDragStat& rDrag ) const
+{
+ return std::min( std::max( static_cast<sal_Int32>(mbHorizontal ? rDrag.GetDY() : rDrag.GetDX()), mnMin ), mnMax );
+}
+
+basegfx::B2DPolyPolygon TableEdgeHdl::getSpecialDragPoly(const SdrDragStat& rDrag) const
+{
+ basegfx::B2DPolyPolygon aVisible;
+ basegfx::B2DPolyPolygon aInvisible;
+
+ // create and return visible and non-visible parts for drag
+ getPolyPolygon(aVisible, aInvisible, &rDrag);
+ aVisible.append(aInvisible);
+
+ return aVisible;
+}
+
+void TableEdgeHdl::getPolyPolygon(basegfx::B2DPolyPolygon& rVisible, basegfx::B2DPolyPolygon& rInvisible, const SdrDragStat* pDrag) const
+{
+ // changed method to create visible and invisible partial polygons in one run in
+ // separate PolyPolygons; both kinds are used
+ basegfx::B2DPoint aOffset(aPos.X(), aPos.Y());
+ rVisible.clear();
+ rInvisible.clear();
+
+ if( pDrag )
+ {
+ int n = mbHorizontal ? 1 : 0;
+ aOffset[n] = aOffset[n] + GetValidDragOffset( *pDrag );
+ }
+
+ basegfx::B2DPoint aStart(aOffset), aEnd(aOffset);
+ int nPos = mbHorizontal ? 0 : 1;
+ TableEdgeVector::const_iterator aIter( maEdges.begin() );
+
+ while( aIter != maEdges.end() )
+ {
+ TableEdge aEdge(*aIter++);
+
+ aStart[nPos] = aOffset[nPos] + aEdge.mnStart;
+ aEnd[nPos] = aOffset[nPos] + aEdge.mnEnd;
+
+ basegfx::B2DPolygon aPolygon;
+ aPolygon.append( aStart );
+ aPolygon.append( aEnd );
+
+ if(aEdge.meState == Visible)
+ {
+ rVisible.append(aPolygon);
+ }
+ else
+ {
+ rInvisible.append(aPolygon);
+ }
+ }
+}
+
+void TableEdgeHdl::CreateB2dIAObject()
+{
+ GetRidOfIAObject();
+
+ if(pHdlList && pHdlList->GetView() && !pHdlList->GetView()->areMarkHandlesHidden())
+ {
+ SdrMarkView* pView = pHdlList->GetView();
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ basegfx::B2DPolyPolygon aVisible;
+ basegfx::B2DPolyPolygon aInvisible;
+
+ // get visible and invisible parts
+ getPolyPolygon(aVisible, aInvisible, 0);
+
+ if(aVisible.count() || aInvisible.count())
+ {
+ for(sal_uInt32 nWindow = 0; nWindow < pPageView->PageWindowCount(); nWindow++)
+ {
+ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(nWindow);
+
+ if(rPageWindow.GetPaintWindow().OutputToWindow())
+ {
+ if(rPageWindow.GetOverlayManager())
+ {
+ if(aVisible.count())
+ {
+ // create overlay object for visible parts
+ sdr::overlay::OverlayObject* pOverlayObject = new OverlayTableEdge(aVisible, true);
+ rPageWindow.GetOverlayManager()->add(*pOverlayObject);
+ maOverlayGroup.append(*pOverlayObject);
+ }
+
+ if(aInvisible.count())
+ {
+ // also create overlay object vor invisible parts to allow
+ // a standard HitTest using the primitives from that overlay object
+ // (see OverlayTableEdge implementation)
+ sdr::overlay::OverlayObject* pOverlayObject = new OverlayTableEdge(aInvisible, false);
+ rPageWindow.GetOverlayManager()->add(*pOverlayObject);
+ maOverlayGroup.append(*pOverlayObject);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+OverlayTableEdge::OverlayTableEdge( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bVisible )
+: OverlayObject(Color(COL_GRAY))
+, maPolyPolygon( rPolyPolygon )
+, mbVisible(bVisible)
+{
+}
+
+OverlayTableEdge::~OverlayTableEdge()
+{
+}
+
+drawinglayer::primitive2d::Primitive2DSequence OverlayTableEdge::createOverlayObjectPrimitive2DSequence()
+{
+ drawinglayer::primitive2d::Primitive2DSequence aRetval;
+
+ if(maPolyPolygon.count())
+ {
+ // Discussed with CL. Currently i will leave the transparence out since this
+ // a little bit expensive. We may check the look with drag polygons later
+ const drawinglayer::primitive2d::Primitive2DReference aReference(
+ new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D(
+ maPolyPolygon,
+ getBaseColor().getBColor()));
+
+ if(mbVisible)
+ {
+ // visible, just return as sequence
+ aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1);
+ }
+ else
+ {
+ // embed in HiddenGeometryPrimitive2D to support HitTest of this invisible
+ // overlay object
+ const drawinglayer::primitive2d::Primitive2DSequence aSequence(&aReference, 1);
+ const drawinglayer::primitive2d::Primitive2DReference aNewReference(
+ new drawinglayer::primitive2d::HiddenGeometryPrimitive2D(aSequence));
+ aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aNewReference, 1);
+ }
+ }
+
+ return aRetval;
+}
+
+// ====================================================================
+
+TableBorderHdl::TableBorderHdl( const Rectangle& rRect )
+: SdrHdl( rRect.TopLeft(), HDL_MOVE )
+, maRectangle( rRect )
+{
+
+}
+
+Pointer TableBorderHdl::GetPointer() const
+{
+ return POINTER_MOVE;
+}
+
+// create marker for this kind
+void TableBorderHdl::CreateB2dIAObject()
+{
+ GetRidOfIAObject();
+
+ if(pHdlList && pHdlList->GetView() && !pHdlList->GetView()->areMarkHandlesHidden())
+ {
+ SdrMarkView* pView = pHdlList->GetView();
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ for(sal_uInt32 nWindow = 0; nWindow < pPageView->PageWindowCount(); nWindow++)
+ {
+ // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
+ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(nWindow);
+
+ if(rPageWindow.GetPaintWindow().OutputToWindow())
+ {
+ if(rPageWindow.GetOverlayManager())
+ {
+ const basegfx::B2DRange aRange(vcl::unotools::b2DRectangleFromRectangle(maRectangle));
+ sdr::overlay::OverlayObject* pOverlayObject = new sdr::overlay::OverlayHatchRect(
+ aRange.getMinimum(),
+ aRange.getMaximum(),
+ Color(0x80, 0x80, 0x80),
+ 6.0,
+ 0.0,
+ 45 * F_PI180,
+ 0.0);
+
+ rPageWindow.GetOverlayManager()->add(*pOverlayObject);
+ maOverlayGroup.append(*pOverlayObject);
+ }
+ }
+ }
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+} // end of namespace table
+} // end of namespace sdr
diff --git a/svx/source/table/tablehandles.hxx b/svx/source/table/tablehandles.hxx
new file mode 100644
index 000000000000..0704e94a84b7
--- /dev/null
+++ b/svx/source/table/tablehandles.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_TABLEHANDLES_HXX
+#define _SVX_TABLEHANDLES_HXX
+
+#include <svx/sdr/overlay/overlayobject.hxx>
+
+#include <svx/svdhdl.hxx>
+
+// --------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+enum TableEdgeState { Empty, Invisible, Visible };
+
+struct TableEdge
+{
+ sal_Int32 mnStart;
+ sal_Int32 mnEnd;
+ TableEdgeState meState;
+
+ TableEdge() : mnStart(0), mnEnd(0), meState(Empty) {}
+};
+
+typedef std::vector< TableEdge > TableEdgeVector;
+
+class TableEdgeHdl : public SdrHdl
+{
+public:
+ TableEdgeHdl( const Point& rPnt, bool bHorizontal, sal_Int32 nMin, sal_Int32 nMax, sal_Int32 nEdges );
+
+ sal_Int32 GetValidDragOffset( const SdrDragStat& rDrag ) const;
+
+ virtual Pointer GetPointer() const;
+
+ void SetEdge( sal_Int32 nEdge, sal_Int32 nStart, sal_Int32 nEnd, TableEdgeState nState );
+
+ bool IsHorizontalEdge() const { return mbHorizontal; }
+
+ basegfx::B2DPolyPolygon getSpecialDragPoly(const SdrDragStat& rDrag) const;
+ void getPolyPolygon(basegfx::B2DPolyPolygon& rVisible, basegfx::B2DPolyPolygon& rInvisible, const SdrDragStat* pDrag) const;
+
+protected:
+ // create marker for this kind
+ virtual void CreateB2dIAObject();
+
+private:
+ bool mbHorizontal;
+ sal_Int32 mnMin, mnMax;
+ TableEdgeVector maEdges;
+};
+
+class TableBorderHdl : public SdrHdl
+{
+public:
+ TableBorderHdl( const Rectangle& rRect );
+
+ virtual Pointer GetPointer() const;
+
+protected:
+ // create marker for this kind
+ virtual void CreateB2dIAObject();
+
+private:
+ Rectangle maRectangle;
+};
+
+} // end of namespace table
+} // end of namespace sdr
+
+#endif
diff --git a/svx/source/table/tablelayouter.cxx b/svx/source/table/tablelayouter.cxx
new file mode 100644
index 000000000000..5e13bce7101e
--- /dev/null
+++ b/svx/source/table/tablelayouter.cxx
@@ -0,0 +1,1300 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <com/sun/star/table/XMergeableCell.hpp>
+#include <com/sun/star/awt/XLayoutConstrains.hpp>
+#include <boost/bind.hpp>
+
+#include "cell.hxx"
+#include "cellrange.hxx"
+#include "tablemodel.hxx"
+#include "tablerow.hxx"
+#include "tablerows.hxx"
+#include "tablecolumn.hxx"
+#include "tablecolumns.hxx"
+#include "tablelayouter.hxx"
+#include "svx/svdotable.hxx"
+#include "editeng/borderline.hxx"
+#include "editeng/boxitem.hxx"
+#include "svx/svdmodel.hxx"
+#include "svdstr.hrc"
+#include "svdglob.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::awt::XLayoutConstrains;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::text;
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+// -----------------------------------------------------------------------------
+
+static SvxBorderLine gEmptyBorder;
+
+// -----------------------------------------------------------------------------
+
+TableLayouter::TableLayouter( const TableModelRef& xTableModel )
+: mxTable( xTableModel )
+, meWritingMode( WritingMode_LR_TB )
+, msSize( RTL_CONSTASCII_USTRINGPARAM( "Size" ) )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+TableLayouter::~TableLayouter()
+{
+ ClearBorderLayout();
+}
+
+// -----------------------------------------------------------------------------
+
+basegfx::B2ITuple TableLayouter::getCellSize( const CellPos& rPos ) const
+{
+ sal_Int32 width = 0;
+ sal_Int32 height = 0;
+
+ try
+ {
+ CellRef xCell( getCell( rPos ) );
+ if( xCell.is() && !xCell->isMerged() )
+ {
+ CellPos aPos( rPos );
+
+ sal_Int32 nRowCount = getRowCount();
+ sal_Int32 nRowSpan = std::max( xCell->getRowSpan(), (sal_Int32)1 );
+ while( nRowSpan && (aPos.mnRow < nRowCount) )
+ {
+ if( ((sal_Int32)maRows.size()) <= aPos.mnRow )
+ break;
+
+ height += maRows[aPos.mnRow++].mnSize;
+ nRowSpan--;
+ }
+
+ sal_Int32 nColCount = getColumnCount();
+ sal_Int32 nColSpan = std::max( xCell->getColumnSpan(), (sal_Int32)1 );
+ while( nColSpan && (aPos.mnCol < nColCount ) )
+ {
+ if( ((sal_Int32)maColumns.size()) <= aPos.mnCol )
+ break;
+
+ width += maColumns[aPos.mnCol++].mnSize;
+ nColSpan--;
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR( "TableLayouter::getCellSize(), exception caught!" );
+ }
+
+ return basegfx::B2ITuple( width, height );
+}
+
+// -----------------------------------------------------------------------------
+
+bool TableLayouter::getCellArea( const CellPos& rPos, basegfx::B2IRectangle& rArea ) const
+{
+ try
+ {
+ CellRef xCell( getCell( rPos ) );
+ if( xCell.is() && !xCell->isMerged() && isValid(rPos) )
+ {
+ const basegfx::B2ITuple aCellSize( getCellSize( rPos ) );
+
+ if( (rPos.mnCol < ((sal_Int32)maColumns.size()) && (rPos.mnRow < ((sal_Int32)maRows.size()) ) ) )
+ {
+ const sal_Int32 x = maColumns[rPos.mnCol].mnPos;
+ const sal_Int32 y = maRows[rPos.mnRow].mnPos;
+
+ rArea = basegfx::B2IRectangle( x, y, x + aCellSize.getX(), y + aCellSize.getY() );
+ return true;
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR( "TableLayouter::getCellSize(), exception caught!" );
+ }
+ return false;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableLayouter::getRowHeight( sal_Int32 nRow )
+{
+ if( isValidRow(nRow) )
+ return maRows[nRow].mnSize;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+void TableLayouter::setRowHeight( sal_Int32 nRow, sal_Int32 nHeight )
+{
+ if( isValidRow(nRow) )
+ {
+ maRows[nRow].mnSize = nHeight;
+ }
+ else
+ {
+ DBG_ERROR( "TableLayouter::setRowHeight(), row out of range!" );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableLayouter::getColumnWidth( sal_Int32 nColumn )
+{
+ if( isValidColumn(nColumn) )
+ return maColumns[nColumn].mnSize;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+void TableLayouter::setColumnWidth( sal_Int32 nColumn, sal_Int32 nWidth )
+{
+ if( isValidColumn(nColumn) )
+ maColumns[nColumn].mnSize = nWidth;
+ else
+ DBG_ERROR( "TableLayouter::setColumnWidth(), column out of range!" );
+}
+
+// -----------------------------------------------------------------------------
+
+bool TableLayouter::isEdgeVisible( sal_Int32 nEdgeX, sal_Int32 nEdgeY, bool bHorizontal ) const
+{
+ const BorderLineMap& rMap = bHorizontal ? maHorizontalBorders : maVerticalBorders;
+
+ if( (nEdgeX >= 0) && (nEdgeX < sal::static_int_cast<sal_Int32>(rMap.size())) &&
+ (nEdgeY >= 0) && (nEdgeY < sal::static_int_cast<sal_Int32>(rMap[nEdgeX].size())) )
+ {
+ return rMap[nEdgeX][nEdgeY] != 0;
+ }
+ else
+ {
+ OSL_ENSURE( false, "sdr::table::TableLayouter::getBorderLine(), invalid edge!" );
+ }
+
+ return false;
+}
+
+// -----------------------------------------------------------------------------
+
+/** returns the requested borderline in rpBorderLine or a null pointer if there is no border at this edge */
+SvxBorderLine* TableLayouter::getBorderLine( sal_Int32 nEdgeX, sal_Int32 nEdgeY, bool bHorizontal )const
+{
+ SvxBorderLine* pLine = 0;
+
+ const BorderLineMap& rMap = bHorizontal ? maHorizontalBorders : maVerticalBorders;
+
+ if( (nEdgeX >= 0) && (nEdgeX < sal::static_int_cast<sal_Int32>(rMap.size())) &&
+ (nEdgeY >= 0) && (nEdgeY < sal::static_int_cast<sal_Int32>(rMap[nEdgeX].size())) )
+ {
+ pLine = rMap[nEdgeX][nEdgeY];
+ if( pLine == &gEmptyBorder )
+ pLine = 0;
+ }
+ else
+ {
+ OSL_ENSURE( false, "sdr::table::TableLayouter::getBorderLine(), invalid edge!" );
+ }
+
+ return pLine;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableLayouter::getHorizontalEdge( int nEdgeY, sal_Int32* pnMin /*= 0*/, sal_Int32* pnMax /*= 0*/ )
+{
+ sal_Int32 nRet = 0;
+ if( (nEdgeY >= 0) && (nEdgeY <= getRowCount() ) )
+ nRet = maRows[std::min((sal_Int32)nEdgeY,getRowCount()-1)].mnPos;
+
+ if( nEdgeY == getRowCount() )
+ nRet += maRows[nEdgeY - 1].mnSize;
+
+ if( pnMin )
+ {
+ if( (nEdgeY > 0) && (nEdgeY <= getRowCount() ) )
+ {
+ *pnMin = maRows[nEdgeY-1].mnPos + 600; // todo
+ }
+ else
+ {
+ *pnMin = nRet;
+ }
+ }
+
+ if( pnMax )
+ {
+ *pnMax = 0x0fffffff;
+ }
+ return nRet;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableLayouter::getVerticalEdge( int nEdgeX, sal_Int32* pnMin /*= 0*/, sal_Int32* pnMax /*= 0*/ )
+{
+ sal_Int32 nRet = 0;
+
+ const sal_Int32 nColCount = getColumnCount();
+ if( (nEdgeX >= 0) && (nEdgeX <= nColCount ) )
+ nRet = maColumns[std::min((sal_Int32)nEdgeX,nColCount-1)].mnPos;
+
+ const bool bRTL = meWritingMode == WritingMode_RL_TB;
+ if( bRTL )
+ {
+ if( (nEdgeX >= 0) && (nEdgeX < nColCount) )
+ nRet += maColumns[nEdgeX].mnSize;
+ }
+ else
+ {
+ if( nEdgeX == getColumnCount() )
+ nRet += maColumns[nEdgeX - 1].mnSize;
+ }
+
+ if( pnMin )
+ {
+ *pnMin = nRet;
+ if( bRTL )
+ {
+ if( nEdgeX < nColCount )
+ *pnMin = nRet - maColumns[nEdgeX].mnSize + getMinimumColumnWidth(nEdgeX);
+ }
+ else
+ {
+ if( (nEdgeX > 0) && (nEdgeX <= nColCount ) )
+ *pnMin = maColumns[nEdgeX-1].mnPos + getMinimumColumnWidth( nEdgeX-1 );
+ }
+ }
+
+ if( pnMax )
+ {
+ *pnMax = 0x0fffffff; // todo
+ if( bRTL )
+ {
+ if( nEdgeX > 0 )
+ *pnMax = nRet + maColumns[nEdgeX-1].mnSize - getMinimumColumnWidth( nEdgeX-1 );
+ }
+ else
+ {
+ if( (nEdgeX >= 0) && (nEdgeX < nColCount ) )
+ *pnMax = maColumns[nEdgeX].mnPos + maColumns[nEdgeX].mnSize - getMinimumColumnWidth( nEdgeX );
+ }
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------------
+
+static bool checkMergeOrigin( const TableModelRef& xTable, sal_Int32 nMergedX, sal_Int32 nMergedY, sal_Int32 nCellX, sal_Int32 nCellY, bool& bRunning )
+{
+ Reference< XMergeableCell > xCell( xTable->getCellByPosition( nCellX, nCellY ), UNO_QUERY );
+ if( xCell.is() && !xCell->isMerged() )
+ {
+ const sal_Int32 nRight = xCell->getColumnSpan() + nCellX;
+ const sal_Int32 nBottom = xCell->getRowSpan() + nCellY;
+ if( (nMergedX < nRight) && (nMergedY < nBottom) )
+ return true;
+
+ bRunning = false;
+ }
+ return false;
+}
+
+/** returns true if the cell(nMergedX,nMergedY) is merged with other cells.
+ the returned cell( rOriginX, rOriginY ) is the origin( top left cell ) of the merge.
+*/
+bool findMergeOrigin( const TableModelRef& xTable, sal_Int32 nMergedX, sal_Int32 nMergedY, sal_Int32& rOriginX, sal_Int32& rOriginY )
+{
+ rOriginX = nMergedX;
+ rOriginY = nMergedY;
+
+ if( xTable.is() ) try
+ {
+ // check if this cell already the origin or not merged at all
+ Reference< XMergeableCell > xCell( xTable->getCellByPosition( nMergedX, nMergedY ), UNO_QUERY_THROW );
+ if( !xCell.is() || !xCell->isMerged() )
+ return true;
+
+ bool bCheckVert = true;
+ bool bCheckHorz = true;
+
+ sal_Int32 nMinCol = 0;
+ sal_Int32 nMinRow = 0;
+
+ sal_Int32 nStep = 1, i;
+
+ sal_Int32 nRow, nCol;
+ do
+ {
+ if( bCheckVert )
+ {
+ nRow = nMergedY - nStep;
+ if( nRow >= nMinRow )
+ {
+ nCol = nMergedX;
+ for( i = 0; (i <= nStep) && (nCol >= nMinCol); i++, nCol-- )
+ {
+ if( checkMergeOrigin( xTable, nMergedX, nMergedY, nCol, nRow, bCheckVert ) )
+ {
+ rOriginX = nCol; rOriginY = nRow;
+ return true;
+ }
+
+ if( !bCheckVert )
+ {
+ if( nCol == nMergedX )
+ {
+ nMinRow = nRow+1;
+ }
+ else
+ {
+ bCheckVert = true;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ bCheckVert = false;
+ }
+ }
+
+ if( bCheckHorz )
+ {
+ nCol = nMergedX - nStep;
+ if( nCol >= nMinCol )
+ {
+ nRow = nMergedY;
+ for( i = 0; (i < nStep) && (nRow >= nMinRow); i++, nRow-- )
+ {
+ if( checkMergeOrigin( xTable, nMergedX, nMergedY, nCol, nRow, bCheckHorz ) )
+ {
+ rOriginX = nCol; rOriginY = nRow;
+ return true;
+ }
+
+ if( !bCheckHorz )
+ {
+ if( nRow == nMergedY )
+ {
+ nMinCol = nCol+1;
+ }
+ else
+ {
+ bCheckHorz = true;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ bCheckHorz = false;
+ }
+ }
+ nStep++;
+ }
+ while( bCheckVert || bCheckHorz );
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("sdr::table::TableLayouter::findMergeOrigin(), exception caught!");
+ }
+ return false;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableLayouter::getMinimumColumnWidth( sal_Int32 nColumn )
+{
+ if( isValidColumn( nColumn ) )
+ {
+ return maColumns[nColumn].mnMinSize;
+ }
+ else
+ {
+ DBG_ERROR( "TableLayouter::getMinimumColumnWidth(), column out of range!" );
+ return 0;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableLayouter::distribute( LayoutVector& rLayouts, sal_Int32 nDistribute )
+{
+ // break loops after 100 runs to avoid freezing office due to developer error
+ sal_Int32 nSafe = 100;
+
+ const sal_Size nCount = rLayouts.size();
+ sal_Size nIndex;
+
+ bool bConstrainsBroken = false;
+
+ do
+ {
+ // first enforce minimum size constrains on all entities
+ for( nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ Layout& rLayout = rLayouts[nIndex];
+ if( rLayout.mnSize < rLayout.mnMinSize )
+ {
+ nDistribute -= rLayout.mnMinSize - rLayout.mnSize;
+ rLayout.mnSize = rLayout.mnMinSize;
+ }
+ }
+
+ // calculate current width
+ // if nDistribute is < 0 (shrinking), entities that are already
+ // at minimum width are not counted
+ sal_Int32 nCurrentWidth = 0;
+ for( nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ Layout& rLayout = rLayouts[nIndex];
+ if( (nDistribute > 0) || (rLayout.mnSize > rLayout.mnMinSize) )
+ nCurrentWidth += rLayout.mnSize;
+ }
+
+ bConstrainsBroken = false;
+
+ // now distribute over entities
+ if( (nCurrentWidth != 0) && (nDistribute != 0) )
+ {
+ sal_Int32 nDistributed = nDistribute;
+ for( nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ Layout& rLayout = rLayouts[nIndex];
+ if( (nDistribute > 0) || (rLayout.mnSize > rLayout.mnMinSize) )
+ {
+ sal_Int32 n;
+ if( nIndex == (nCount-1) )
+ n = nDistributed; // for last entitie, use up rest
+ else
+ n = (nDistribute * rLayout.mnSize) / nCurrentWidth; //
+
+ nDistributed -= n;
+ rLayout.mnSize += n;
+
+ if( rLayout.mnSize < rLayout.mnMinSize )
+ bConstrainsBroken = true;
+ }
+ }
+ }
+ } while( bConstrainsBroken && --nSafe );
+
+ sal_Int32 nSize = 0;
+ for( nIndex = 0; nIndex < nCount; ++nIndex )
+ nSize += rLayouts[nIndex].mnSize;
+
+ return nSize;
+}
+
+// -----------------------------------------------------------------------------
+
+typedef std::vector< CellRef > MergeableCellVector;
+typedef std::vector< MergeableCellVector > MergeVector;
+typedef std::vector< sal_Int32 > Int32Vector;
+
+// -----------------------------------------------------------------------------
+
+void TableLayouter::LayoutTableWidth( Rectangle& rArea, bool bFit )
+{
+ const sal_Int32 nColCount = getColumnCount();
+ const sal_Int32 nRowCount = getRowCount();
+ if( nColCount == 0 )
+ return;
+
+ MergeVector aMergedCells( nColCount );
+ Int32Vector aOptimalColumns;
+
+ const OUString sOptimalSize( RTL_CONSTASCII_USTRINGPARAM("OptimalSize") );
+
+ if( sal::static_int_cast< sal_Int32 >( maColumns.size() ) != nColCount )
+ maColumns.resize( nColCount );
+
+ Reference< XTableColumns > xCols( mxTable->getColumns(), UNO_QUERY_THROW );
+
+ // first calculate current width and initial minimum width per column,
+ // merged cells will be counted later
+ sal_Int32 nCurrentWidth = 0;
+ sal_Int32 nCol = 0, nRow = 0;
+ for( nCol = 0; nCol < nColCount; nCol++ )
+ {
+ sal_Int32 nMinWidth = 0;
+
+ bool bIsEmpty = true; // check if all cells in this column are merged
+
+ for( nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ CellRef xCell( getCell( CellPos( nCol, nRow ) ) );
+ if( xCell.is() && !xCell->isMerged() )
+ {
+ bIsEmpty = false;
+
+ sal_Int32 nColSpan = xCell->getColumnSpan();
+ if( nColSpan > 1 )
+ {
+ // merged cells will be evaluated later
+ aMergedCells[nCol+nColSpan-1].push_back( xCell );
+ }
+ else
+ {
+ nMinWidth = std::max( nMinWidth, xCell->getMinimumSize().Width );
+ }
+ }
+ }
+
+ maColumns[nCol].mnMinSize = nMinWidth;
+
+ if( bIsEmpty )
+ {
+ maColumns[nCol].mnSize = 0;
+ }
+ else
+ {
+ sal_Int32 nColWidth = 0;
+ Reference< XPropertySet > xColSet( xCols->getByIndex( nCol ), UNO_QUERY_THROW );
+ sal_Bool bOptimal = sal_False;
+ xColSet->getPropertyValue( sOptimalSize ) >>= bOptimal;
+ if( bOptimal )
+ {
+ aOptimalColumns.push_back(nCol);
+ }
+ else
+ {
+ xColSet->getPropertyValue( msSize ) >>= nColWidth;
+ }
+
+ maColumns[nCol].mnSize = nColWidth;
+
+ if( maColumns[nCol].mnSize < nMinWidth )
+ maColumns[nCol].mnSize = nMinWidth;
+
+ nCurrentWidth += maColumns[nCol].mnSize;
+ }
+ }
+
+ // if we have optimal sized rows, distribute what is given (left)
+ if( !bFit && !aOptimalColumns.empty() && (nCurrentWidth < rArea.getWidth()) )
+ {
+ sal_Int32 nLeft = rArea.getWidth() - nCurrentWidth;
+ sal_Int32 nDistribute = nLeft / aOptimalColumns.size();
+
+ Int32Vector::iterator iter( aOptimalColumns.begin() );
+ while( iter != aOptimalColumns.end() )
+ {
+ sal_Int32 nOptCol = (*iter++);
+ if( iter == aOptimalColumns.end() )
+ nDistribute = nLeft;
+
+ maColumns[nOptCol].mnSize += nDistribute;
+ nLeft -= nDistribute;
+ }
+
+ DBG_ASSERT( nLeft == 0, "svx::TableLayouter::LayoutTableWidtht(), layouting failed!" );
+ }
+
+ // now check if merged cells fit
+ for( nCol = 1; nCol < nColCount; ++nCol )
+ {
+ bool bChanges = false;
+ MergeableCellVector::iterator iter( aMergedCells[nCol].begin() );
+
+ const sal_Int32 nOldSize = maColumns[nCol].mnSize;
+
+ while( iter != aMergedCells[nCol].end() )
+ {
+ CellRef xCell( (*iter++) );
+ sal_Int32 nMinWidth = xCell->getMinimumSize().Width;
+
+ for( sal_Int32 nMCol = nCol - xCell->getColumnSpan() + 1; (nMCol > 0) && (nMCol < nCol); ++nMCol )
+ nMinWidth -= maColumns[nMCol].mnSize;
+
+ if( nMinWidth > maColumns[nCol].mnMinSize )
+ maColumns[nCol].mnMinSize = nMinWidth;
+
+ if( nMinWidth > maColumns[nCol].mnSize )
+ {
+ maColumns[nCol].mnSize = nMinWidth;
+ bChanges = true;
+ }
+ }
+
+ if( bChanges )
+ nCurrentWidth += maColumns[nCol].mnSize - nOldSize;
+ }
+
+ // now scale if wanted and needed
+ if( bFit && (nCurrentWidth != rArea.getWidth()) )
+ distribute( maColumns, rArea.getWidth() - nCurrentWidth );
+
+ // last step, update left edges
+ sal_Int32 nNewWidth = 0;
+
+ const bool bRTL = meWritingMode == WritingMode_RL_TB;
+ RangeIterator<sal_Int32> coliter( 0, nColCount, !bRTL );
+ while( coliter.next(nCol ) )
+ {
+ maColumns[nCol].mnPos = nNewWidth;
+ nNewWidth += maColumns[nCol].mnSize;
+ if( bFit )
+ {
+ Reference< XPropertySet > xColSet( xCols->getByIndex(nCol), UNO_QUERY_THROW );
+ xColSet->setPropertyValue( msSize, Any( maColumns[nCol].mnSize ) );
+ }
+ }
+
+ rArea.SetSize( Size( nNewWidth, rArea.GetHeight() ) );
+ updateCells( rArea );
+}
+
+// -----------------------------------------------------------------------------
+
+void TableLayouter::LayoutTableHeight( Rectangle& rArea, bool bFit )
+{
+ const sal_Int32 nColCount = getColumnCount();
+ const sal_Int32 nRowCount = getRowCount();
+ if( nRowCount == 0 )
+ return;
+
+ Reference< XTableRows > xRows( mxTable->getRows() );
+
+ MergeVector aMergedCells( nRowCount );
+ Int32Vector aOptimalRows;
+
+ const OUString sOptimalSize( RTL_CONSTASCII_USTRINGPARAM("OptimalSize") );
+
+ // first calculate current height and initial minimum size per column,
+ // merged cells will be counted later
+ sal_Int32 nCurrentHeight = 0;
+ sal_Int32 nCol, nRow;
+ for( nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ sal_Int32 nMinHeight = 0;
+
+ bool bIsEmpty = true; // check if all cells in this row are merged
+
+ for( nCol = 0; nCol < nColCount; ++nCol )
+ {
+ CellRef xCell( getCell( CellPos( nCol, nRow ) ) );
+ if( xCell.is() && !xCell->isMerged() )
+ {
+ bIsEmpty = false;
+
+ sal_Int32 nRowSpan = xCell->getRowSpan();
+ if( nRowSpan > 1 )
+ {
+ // merged cells will be evaluated later
+ aMergedCells[nRow+nRowSpan-1].push_back( xCell );
+ }
+ else
+ {
+ nMinHeight = std::max( nMinHeight, xCell->getMinimumSize().Height );
+ }
+ }
+ }
+
+ maRows[nRow].mnMinSize = nMinHeight;
+
+ if( bIsEmpty )
+ {
+ maRows[nRow].mnSize = 0;
+ }
+ else
+ {
+ sal_Int32 nRowHeight = 0;
+ Reference< XPropertySet > xRowSet( xRows->getByIndex(nRow), UNO_QUERY_THROW );
+
+ sal_Bool bOptimal = sal_False;
+ xRowSet->getPropertyValue( sOptimalSize ) >>= bOptimal;
+ if( bOptimal )
+ {
+ aOptimalRows.push_back( nRow );
+ }
+ else
+ {
+ xRowSet->getPropertyValue( msSize ) >>= nRowHeight;
+ }
+
+ maRows[nRow].mnSize = nRowHeight;
+
+ if( maRows[nRow].mnSize < nMinHeight )
+ maRows[nRow].mnSize = nMinHeight;
+
+ nCurrentHeight += maRows[nRow].mnSize;
+ }
+ }
+
+ // if we have optimal sized rows, distribute what is given (left)
+ if( !bFit && !aOptimalRows.empty() && (nCurrentHeight < rArea.getHeight()) )
+ {
+ sal_Int32 nLeft = rArea.getHeight() - nCurrentHeight;
+ sal_Int32 nDistribute = nLeft / aOptimalRows.size();
+
+ Int32Vector::iterator iter( aOptimalRows.begin() );
+ while( iter != aOptimalRows.end() )
+ {
+ sal_Int32 nOptRow = (*iter++);
+ if( iter == aOptimalRows.end() )
+ nDistribute = nLeft;
+
+ maRows[nOptRow].mnSize += nDistribute;
+ nLeft -= nDistribute;
+
+ }
+
+ DBG_ASSERT( nLeft == 0, "svx::TableLayouter::LayoutTableHeight(), layouting failed!" );
+ }
+
+ // now check if merged cells fit
+ for( nRow = 1; nRow < nRowCount; ++nRow )
+ {
+ bool bChanges = false;
+ sal_Int32 nOldSize = maRows[nRow].mnSize;
+
+ MergeableCellVector::iterator iter( aMergedCells[nRow].begin() );
+ while( iter != aMergedCells[nRow].end() )
+ {
+ CellRef xCell( (*iter++) );
+ sal_Int32 nMinHeight = xCell->getMinimumSize().Height;
+
+ for( sal_Int32 nMRow = nRow - xCell->getRowSpan() + 1; (nMRow > 0) && (nMRow < nRow); ++nMRow )
+ nMinHeight -= maRows[nMRow].mnSize;
+
+ if( nMinHeight > maRows[nRow].mnMinSize )
+ maRows[nRow].mnMinSize = nMinHeight;
+
+ if( nMinHeight > maRows[nRow].mnSize )
+ {
+ maRows[nRow].mnSize = nMinHeight;
+ bChanges = true;
+ }
+ }
+ if( bChanges )
+ nCurrentHeight += maRows[nRow].mnSize - nOldSize;
+ }
+
+ // now scale if wanted and needed
+ if( bFit && nCurrentHeight != rArea.getHeight() )
+ distribute( maRows, rArea.getHeight() - nCurrentHeight );
+
+ // last step, update left edges
+ sal_Int32 nNewHeight = 0;
+ for( nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ maRows[nRow].mnPos = nNewHeight;
+ nNewHeight += maRows[nRow].mnSize;
+
+ if( bFit )
+ {
+ Reference< XPropertySet > xRowSet( xRows->getByIndex(nRow), UNO_QUERY_THROW );
+ xRowSet->setPropertyValue( msSize, Any( maRows[nRow].mnSize ) );
+ }
+ }
+
+ rArea.SetSize( Size( rArea.GetWidth(), nNewHeight ) );
+ updateCells( rArea );
+}
+
+// -----------------------------------------------------------------------------
+
+/** try to fit the table into the given rectangle.
+ If the rectangle is to small, it will be grown to fit the table. */
+void TableLayouter::LayoutTable( Rectangle& rRectangle, bool bFitWidth, bool bFitHeight )
+{
+ if( !mxTable.is() )
+ return;
+
+ const sal_Int32 nRowCount = mxTable->getRowCount();
+ const sal_Int32 nColCount = mxTable->getColumnCount();
+
+ if( (nRowCount != getRowCount()) || (nColCount != getColumnCount()) )
+ {
+ if( static_cast< sal_Int32 >( maRows.size() ) != nRowCount )
+ maRows.resize( nRowCount );
+
+ Reference< XTableRows > xRows( mxTable->getRows() );
+ for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
+ maRows[nRow].clear();
+
+ if( static_cast< sal_Int32 >( maColumns.size() ) != nColCount )
+ maColumns.resize( nColCount );
+
+ for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ )
+ maColumns[nCol].clear();
+ }
+
+ LayoutTableWidth( rRectangle, bFitWidth );
+ LayoutTableHeight( rRectangle, bFitHeight );
+ UpdateBorderLayout();
+}
+
+// -----------------------------------------------------------------------------
+
+void TableLayouter::updateCells( Rectangle& rRectangle )
+{
+ const sal_Int32 nColCount = getColumnCount();
+ const sal_Int32 nRowCount = getRowCount();
+
+ CellPos aPos;
+ for( aPos.mnRow = 0; aPos.mnRow < nRowCount; aPos.mnRow++ )
+ {
+ for( aPos.mnCol = 0; aPos.mnCol < nColCount; aPos.mnCol++ )
+ {
+ CellRef xCell( getCell( aPos ) );
+ if( xCell.is() )
+ {
+ basegfx::B2IRectangle aCellArea;
+ getCellArea( aPos, aCellArea );
+
+ Rectangle aCellRect;
+ aCellRect.nLeft = aCellArea.getMinX();
+ aCellRect.nRight = aCellArea.getMaxX();
+ aCellRect.nTop = aCellArea.getMinY();
+ aCellRect.nBottom = aCellArea.getMaxY();
+ aCellRect.Move( rRectangle.nLeft, rRectangle.nTop );
+ xCell->setCellRect( aCellRect );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+CellRef TableLayouter::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( "sdr::table::TableLayouter::getCell(), exception caught!" );
+ }
+ return xCell;
+}
+
+// -----------------------------------------------------------------------------
+
+bool TableLayouter::HasPriority( const SvxBorderLine* pThis, const SvxBorderLine* pOther )
+{
+ if (!pThis || ((pThis == &gEmptyBorder) && (pOther != 0)))
+ return false;
+ if (!pOther || (pOther == &gEmptyBorder))
+ return true;
+
+ USHORT nThisSize = pThis->GetOutWidth() + pThis->GetDistance() + pThis->GetInWidth();
+ USHORT nOtherSize = pOther->GetOutWidth() + pOther->GetDistance() + pOther->GetInWidth();
+
+ if (nThisSize > nOtherSize)
+ return true;
+
+ else if (nThisSize < nOtherSize)
+ {
+ return false;
+ }
+ else
+ {
+ if ( pOther->GetInWidth() && !pThis->GetInWidth() )
+ {
+ return true;
+ }
+ else if ( pThis->GetInWidth() && !pOther->GetInWidth() )
+ {
+ return false;
+ }
+ else
+ {
+ return true; //! ???
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TableLayouter::SetBorder( sal_Int32 nCol, sal_Int32 nRow, bool bHorizontal, const SvxBorderLine* pLine )
+{
+ if( pLine == 0 )
+ pLine = &gEmptyBorder;
+
+ SvxBorderLine *pOld = bHorizontal ? maHorizontalBorders[nCol][nRow] : maVerticalBorders[nCol][nRow];
+
+ if( HasPriority( pLine, pOld ) )
+ {
+ if( (pOld != 0) && (pOld != &gEmptyBorder) )
+ delete pOld;
+
+ SvxBorderLine* pNew = ( pLine != &gEmptyBorder ) ? new SvxBorderLine(*pLine) : &gEmptyBorder;
+
+ if( bHorizontal )
+ maHorizontalBorders[nCol][nRow] = pNew;
+ else
+ maVerticalBorders[nCol][nRow] = pNew;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TableLayouter::ClearBorderLayout()
+{
+ ClearBorderLayout(maHorizontalBorders);
+ ClearBorderLayout(maVerticalBorders);
+}
+
+// -----------------------------------------------------------------------------
+
+void TableLayouter::ClearBorderLayout(BorderLineMap& rMap)
+{
+ const sal_Int32 nColCount = rMap.size();
+
+ for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ )
+ {
+ const sal_Int32 nRowCount = rMap[nCol].size();
+ for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
+ {
+ SvxBorderLine* pLine = rMap[nCol][nRow];
+ if( pLine )
+ {
+ if( pLine != &gEmptyBorder )
+ delete pLine;
+
+ rMap[nCol][nRow] = 0;
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TableLayouter::ResizeBorderLayout()
+{
+ ClearBorderLayout();
+ ResizeBorderLayout(maHorizontalBorders);
+ ResizeBorderLayout(maVerticalBorders);
+}
+
+// -----------------------------------------------------------------------------
+
+void TableLayouter::ResizeBorderLayout( BorderLineMap& rMap )
+{
+ const sal_Int32 nColCount = getColumnCount() + 1;
+ const sal_Int32 nRowCount = getRowCount() + 1;
+
+ if( sal::static_int_cast<sal_Int32>(rMap.size()) != nColCount )
+ rMap.resize( nColCount );
+
+ for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ )
+ {
+ if( sal::static_int_cast<sal_Int32>(rMap[nCol].size()) != nRowCount )
+ rMap[nCol].resize( nRowCount );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TableLayouter::UpdateBorderLayout()
+{
+ // make sure old border layout is cleared and border maps have correct size
+ ResizeBorderLayout();
+
+ const sal_Int32 nColCount = getColumnCount();
+ const sal_Int32 nRowCount = getRowCount();
+
+ CellPos aPos;
+ for( aPos.mnRow = 0; aPos.mnRow < nRowCount; aPos.mnRow++ )
+ {
+ for( aPos.mnCol = 0; aPos.mnCol < nColCount; aPos.mnCol++ )
+ {
+ CellRef xCell( getCell( aPos ) );
+ if( !xCell.is() || xCell->isMerged() )
+ continue;
+
+ const SvxBoxItem* pThisAttr = (const SvxBoxItem*)xCell->GetItemSet().GetItem( SDRATTR_TABLE_BORDER );
+ OSL_ENSURE(pThisAttr,"sdr::table::TableLayouter::UpdateBorderLayout(), no border attribute?");
+
+ if( !pThisAttr )
+ continue;
+
+ const sal_Int32 nLastRow = xCell->getRowSpan() + aPos.mnRow;
+ const sal_Int32 nLastCol = xCell->getColumnSpan() + aPos.mnCol;
+
+ for( sal_Int32 nRow = aPos.mnRow; nRow < nLastRow; nRow++ )
+ {
+ SetBorder( aPos.mnCol, nRow, false, pThisAttr->GetLeft() );
+ SetBorder( nLastCol, nRow, false, pThisAttr->GetRight() );
+ }
+
+ for( sal_Int32 nCol = aPos.mnCol; nCol < nLastCol; nCol++ )
+ {
+ SetBorder( nCol, aPos.mnRow, true, pThisAttr->GetTop() );
+ SetBorder( nCol, nLastRow, true, pThisAttr->GetBottom() );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+/*
+void TableLayouter::SetLayoutToModel()
+{
+ const sal_Int32 nRowCount = getRowCount();
+ const sal_Int32 nColCount = getColumnCount();
+
+ try
+ {
+ sal_Int32 nOldSize = 0;
+
+ Reference< XIndexAccess > xRows( mxTable->getRows(), UNO_QUERY_THROW );
+ for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
+ {
+ Reference< XPropertySet > xRowSet( xRows->getByIndex( nRow ), UNO_QUERY_THROW );
+ xRowSet->getPropertyValue( msSize ) >>= nOldSize;
+ if( maRows[nRow].mnSize != nOldSize )
+ xRowSet->setPropertyValue( msSize, Any( maRows[nRow].mnSize ) );
+ }
+
+ for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ )
+ {
+ Reference< XPropertySet > xColSet( getColumnByIndex( nCol ), UNO_QUERY_THROW );
+ xColSet->getPropertyValue( msSize ) >>= nOldSize;
+ if( maColumns[nCol].mnSize != nOldSize )
+ xColSet->setPropertyValue( msSize, Any( maColumns[nCol].mnSize ) );
+ }
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("sdr::table::TableLayouter::SetLayoutToModel(), exception caught!");
+ }
+}
+*/
+// -----------------------------------------------------------------------------
+
+void TableLayouter::DistributeColumns( ::Rectangle& rArea, sal_Int32 nFirstCol, sal_Int32 nLastCol )
+{
+ if( mxTable.is() ) try
+ {
+ const sal_Int32 nColCount = getColumnCount();
+
+ if( (nFirstCol < 0) || (nFirstCol>= nLastCol) || (nLastCol >= nColCount) )
+ return;
+
+ sal_Int32 nAllWidth = 0;
+ for( sal_Int32 nCol = nFirstCol; nCol <= nLastCol; ++nCol )
+ nAllWidth += getColumnWidth(nCol);
+
+ sal_Int32 nWidth = nAllWidth / (nLastCol-nFirstCol+1);
+
+ Reference< XTableColumns > xCols( mxTable->getColumns(), UNO_QUERY_THROW );
+
+ for( sal_Int32 nCol = nFirstCol; nCol <= nLastCol; ++nCol )
+ {
+ if( nCol == nLastCol )
+ nWidth = nAllWidth; // last column get round errors
+
+ Reference< XPropertySet > xColSet( xCols->getByIndex( nCol ), UNO_QUERY_THROW );
+ xColSet->setPropertyValue( msSize, Any( nWidth ) );
+
+ nAllWidth -= nWidth;
+ }
+
+ LayoutTable( rArea, true, false );
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR("sdr::table::TableLayouter::DistributeColumns(), exception caught!");
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TableLayouter::DistributeRows( ::Rectangle& rArea, sal_Int32 nFirstRow, sal_Int32 nLastRow )
+{
+ if( mxTable.is() ) try
+ {
+ const sal_Int32 nRowCount = mxTable->getRowCount();
+
+ if( (nFirstRow < 0) || (nFirstRow>= nLastRow) || (nLastRow >= nRowCount) )
+ return;
+
+ sal_Int32 nAllHeight = 0;
+ sal_Int32 nMinHeight = 0;
+
+ for( sal_Int32 nRow = nFirstRow; nRow <= nLastRow; ++nRow )
+ {
+ nMinHeight = std::max( maRows[nRow].mnMinSize, nMinHeight );
+ nAllHeight += maRows[nRow].mnSize;
+ }
+
+ const sal_Int32 nRows = (nLastRow-nFirstRow+1);
+ sal_Int32 nHeight = nAllHeight / nRows;
+
+ if( nHeight < nMinHeight )
+ {
+ sal_Int32 nNeededHeight = nRows * nMinHeight;
+ rArea.nBottom += nNeededHeight - nAllHeight;
+ nHeight = nMinHeight;
+ nAllHeight = nRows * nMinHeight;
+ }
+
+ Reference< XTableRows > xRows( mxTable->getRows(), UNO_QUERY_THROW );
+ for( sal_Int32 nRow = nFirstRow; nRow <= nLastRow; ++nRow )
+ {
+ if( nRow == nLastRow )
+ nHeight = nAllHeight; // last row get round errors
+
+ Reference< XPropertySet > xRowSet( xRows->getByIndex( nRow ), UNO_QUERY_THROW );
+ xRowSet->setPropertyValue( msSize, Any( nHeight ) );
+
+ nAllHeight -= nHeight;
+ }
+
+ LayoutTable( rArea, false, true );
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR("sdr::table::TableLayouter::DistributeRows(), exception caught!");
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TableLayouter::SetWritingMode( com::sun::star::text::WritingMode eWritingMode )
+{
+ meWritingMode = eWritingMode;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableLayouter::getColumnStart( sal_Int32 nColumn ) const
+{
+ if( isValidColumn(nColumn) )
+ return maColumns[nColumn].mnPos;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableLayouter::getRowStart( sal_Int32 nRow ) const
+{
+ if( isValidRow(nRow) )
+ return maRows[nRow].mnPos;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+/*
+sal_Int32 TableLayouter::detectInsertedOrRemovedRows()
+{
+ sal_Int32 nHeightChange = 0;
+
+ try
+ {
+ Reference< XIndexAccess > xRows( mxTable->getRows(), UNO_QUERY_THROW );
+ std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > >::iterator oldIter( mxRows.begin() );
+ sal_Int32 nCount = xRows->getCount();
+ for( sal_Int32 nRow = 0; nRow < nCount; nRow++ )
+ {
+ Reference< XInterface > xRow( xRows->getByIndex(nRow), UNO_QUERY );
+
+ std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > >::iterator searchIter = mxRows.end();
+ if( oldIter != mxRows.end() )
+ searchIter = std::find( oldIter,mxRows.end(), xRow );
+
+ if( searchIter == mxRows.end() )
+ {
+ // new row
+ Reference< XPropertySet > xSet( xRow, UNO_QUERY_THROW );
+ sal_Int32 nSize = 0;
+ xSet->getPropertyValue( msSize ) >>= nSize;
+ nHeightChange += nSize;
+ }
+ else if( searchIter == oldIter )
+ {
+ // no change
+ oldIter++;
+ }
+ else
+ {
+ // rows removed
+ do
+ {
+ Reference< XPropertySet > xSet( (*oldIter), UNO_QUERY_THROW );
+ sal_Int32 nSize = 0;
+ xSet->getPropertyValue( msSize ) >>= nSize;
+ nHeightChange -= nSize;
+ }
+ while( oldIter++ != searchIter );
+ }
+ }
+
+ while( oldIter != mxRows.end() )
+ {
+ // rows removed
+ Reference< XPropertySet > xSet( (*oldIter++), UNO_QUERY_THROW );
+ sal_Int32 nSize = 0;
+ xSet->getPropertyValue( msSize ) >>= nSize;
+ nHeightChange -= nSize;
+ }
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR("svx::TableLayouter::detectInsertedOrRemovedRows(), exception caught!");
+ }
+
+ return nHeightChange;
+}
+*/
+
+// -----------------------------------------------------------------------------
+
+} }
diff --git a/svx/source/table/tablelayouter.hxx b/svx/source/table/tablelayouter.hxx
new file mode 100644
index 000000000000..9c56aafb556f
--- /dev/null
+++ b/svx/source/table/tablelayouter.hxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_TABLE_TABLELAYOUTER_HXX_
+#define _SVX_TABLE_TABLELAYOUTER_HXX_
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/text/WritingMode.hpp>
+#include <com/sun/star/table/XTable.hpp>
+#include <basegfx/range/b2irectangle.hxx>
+#include <basegfx/tuple/b2ituple.hxx>
+#include <tools/gen.hxx>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <map>
+
+#include "svx/svdotable.hxx"
+
+// -----------------------------------------------------------------------------
+
+class SvxBorderLine;
+
+namespace sdr { namespace table {
+
+/** returns true if the cell(nMergedCol,nMergedRow) is merged with other cells.
+ the returned cell( rOriginCol, rOriginRow ) is the origin( top left cell ) of the merge.
+*/
+bool findMergeOrigin( const TableModelRef& xTable, sal_Int32 nMergedCol, sal_Int32 nMergedRow, sal_Int32& rOriginCol, sal_Int32& rOriginRow );
+
+typedef std::vector< SvxBorderLine* > BorderLineVector;
+typedef std::vector< BorderLineVector > BorderLineMap;
+
+// -----------------------------------------------------------------------------
+// TableModel
+// -----------------------------------------------------------------------------
+
+class TableLayouter
+{
+public:
+ TableLayouter( const TableModelRef& xTableModel );
+ virtual ~TableLayouter();
+
+ /** this checks if new rows are inserted or old rows where removed.
+ This can be used to grow or shrink the table shape in this case.
+ @returns
+ the height difference
+ sal_Int32 detectInsertedOrRemovedRows();
+ */
+
+ /** try to fit the table into the given rectangle.
+ If the rectangle is to small, it will be grown to fit the table.
+
+ if bFitWidth or bFitHeight is set, the layouter tries to scale
+ the rows and/or columns to the given area. The result my be bigger
+ to fullfill constrains.
+
+ if bFitWidth or bFitHeight is set, the model is changed.
+ */
+ void LayoutTable( ::Rectangle& rRectangle, bool bFitWidth, bool bFitHeight );
+
+ /** after a call to LayoutTable, this method can be used to set the new
+ column and row sizes back to the model. */
+// void SetLayoutToModel();
+
+ void UpdateBorderLayout();
+
+ basegfx::B2ITuple getCellSize( const CellPos& rPos ) const;
+ bool getCellArea( const CellRef& xCell, basegfx::B2IRectangle& rArea ) const;
+ bool getCellArea( const CellPos& rPos, basegfx::B2IRectangle& rArea ) const;
+
+ ::sal_Int32 getRowCount() const { return static_cast< ::sal_Int32 >( maRows.size() ); }
+ ::sal_Int32 getColumnCount() const { return static_cast< ::sal_Int32 >( maColumns.size() ); }
+
+ sal_Int32 getRowHeight( sal_Int32 nRow );
+
+ // sets the layout height of the given row hard, LayoutTable must be called directly after calling this method! */
+ void setRowHeight( sal_Int32 nRow, sal_Int32 nHeight );
+
+ sal_Int32 getColumnWidth( sal_Int32 nColumn );
+
+ // sets the layout width of the given column hard, LayoutTable must be called directly after calling this method! */
+ void setColumnWidth( sal_Int32 nColumn, sal_Int32 nWidth );
+
+ sal_Int32 getMinimumColumnWidth( sal_Int32 nColumn );
+
+ sal_Int32 getColumnStart( sal_Int32 nColumn ) const;
+ sal_Int32 getRowStart( sal_Int32 nRow ) const;
+
+ /** checks if the given edge is visible.
+ Edges between merged cells are not visible.
+ */
+ bool isEdgeVisible( sal_Int32 nEdgeX, sal_Int32 nEdgeY, bool bHorizontal ) const;
+
+ /** returns the requested borderline in rpBorderLine or a null pointer if there is no border at this edge */
+ SvxBorderLine* getBorderLine( sal_Int32 nEdgeX, sal_Int32 nEdgeY, bool bHorizontal )const;
+
+ void updateCells( ::Rectangle& rRectangle );
+
+ sal_Int32 getHorizontalEdge( int nEdgeY, sal_Int32* pnMin = 0, sal_Int32* pnMax = 0 );
+ sal_Int32 getVerticalEdge( int nEdgeX , sal_Int32* pnMin = 0, sal_Int32* pnMax = 0);
+
+ void DistributeColumns( ::Rectangle& rArea, sal_Int32 nFirstCol, sal_Int32 nLastCol );
+ void DistributeRows( ::Rectangle& rArea, sal_Int32 nFirstRow, sal_Int32 nLastRow );
+
+ com::sun::star::text::WritingMode GetWritingMode() const { return meWritingMode; }
+ void SetWritingMode( com::sun::star::text::WritingMode eWritingMode );
+
+private:
+ CellRef getCell( const CellPos& rPos ) const;
+
+ void LayoutTableWidth( ::Rectangle& rArea, bool bFit );
+ void LayoutTableHeight( ::Rectangle& rArea, bool bFit );
+
+ inline bool isValidColumn( sal_Int32 nColumn ) const { return (nColumn >= 0) && (nColumn < static_cast<sal_Int32>( maColumns.size())); }
+ inline bool isValidRow( sal_Int32 nRow ) const { return (nRow >= 0) && (nRow < static_cast<sal_Int32>( maRows.size())); }
+ inline bool isValid( const CellPos& rPos ) const { return isValidColumn( rPos.mnCol ) && isValidRow( rPos.mnRow ); }
+
+ void ClearBorderLayout();
+ void ClearBorderLayout(BorderLineMap& rMap);
+ void ResizeBorderLayout();
+ void ResizeBorderLayout( BorderLineMap& rMap );
+
+ void SetBorder( sal_Int32 nCol, sal_Int32 nRow, bool bHorizontal, const SvxBorderLine* pLine );
+
+ static bool HasPriority( const SvxBorderLine* pThis, const SvxBorderLine* pOther );
+
+ struct Layout
+ {
+ sal_Int32 mnPos;
+ sal_Int32 mnSize;
+ sal_Int32 mnMinSize;
+
+ Layout() : mnPos( 0 ), mnSize( 0 ), mnMinSize( 0 ) {}
+ void clear() { mnPos = 0; mnSize = 0; mnMinSize = 0; }
+ };
+ typedef std::vector< Layout > LayoutVector;
+
+ sal_Int32 distribute( LayoutVector& rLayouts, sal_Int32 nDistribute );
+
+ TableModelRef mxTable;
+ LayoutVector maRows;
+ LayoutVector maColumns;
+
+ BorderLineMap maHorizontalBorders;
+ BorderLineMap maVerticalBorders;
+
+ com::sun::star::text::WritingMode meWritingMode;
+
+ const rtl::OUString msSize;
+};
+
+} }
+
+#endif
diff --git a/svx/source/table/tablemodel.cxx b/svx/source/table/tablemodel.cxx
new file mode 100644
index 000000000000..1c8d0aa60dc8
--- /dev/null
+++ b/svx/source/table/tablemodel.cxx
@@ -0,0 +1,1258 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <com/sun/star/table/XMergeableCell.hpp>
+
+#include <algorithm>
+#include <boost/bind.hpp>
+
+#include <vcl/svapp.hxx>
+#include <vos/mutex.hxx>
+
+#include "cell.hxx"
+#include "cellcursor.hxx"
+#include "tablemodel.hxx"
+#include "tablerow.hxx"
+#include "tablerows.hxx"
+#include "tablecolumn.hxx"
+#include "tablecolumns.hxx"
+#include "tableundo.hxx"
+#include "svx/svdotable.hxx"
+#include "svx/svdmodel.hxx"
+#include "svdstr.hrc"
+#include "svdglob.hxx"
+
+//#define PLEASE_DEBUG_THE_TABLES 1
+
+using ::rtl::OUString;
+using namespace ::osl;
+using namespace ::vos;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+// -----------------------------------------------------------------------------
+
+// removes the given range from a vector
+template< class Vec, class Iter > void remove_range( Vec& rVector, sal_Int32 nIndex, sal_Int32 nCount )
+{
+ const sal_Int32 nSize = static_cast<sal_Int32>(rVector.size());
+ if( nCount && (nIndex >= 0) && (nIndex < nSize) )
+ {
+ if( (nIndex + nCount) >= nSize )
+ {
+ // remove at end
+ rVector.resize( nIndex );
+ }
+ else
+ {
+ Iter aBegin( rVector.begin() );
+ while( nIndex-- )
+ aBegin++;
+ if( nCount == 1 )
+ {
+ rVector.erase( aBegin );
+ }
+ else
+ {
+ Iter aEnd( aBegin );
+
+ while( nCount-- )
+ aEnd++;
+ rVector.erase( aBegin, aEnd );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+/** inserts a range into a vector */
+template< class Vec, class Iter, class Entry > sal_Int32 insert_range( Vec& rVector, sal_Int32 nIndex, sal_Int32 nCount )
+{
+ if( nCount )
+ {
+ if( nIndex >= static_cast< sal_Int32 >( rVector.size() ) )
+ {
+ // append at end
+ nIndex = static_cast< sal_Int32 >( rVector.size() ); // cap to end
+ rVector.resize( nIndex + nCount );
+ }
+ else
+ {
+ // insert
+ sal_Int32 nFind = nIndex;
+ Iter aIter( rVector.begin() );
+ while( nFind-- )
+ aIter++;
+
+ Entry aEmpty;
+ rVector.insert( aIter, nCount, aEmpty );
+ }
+ }
+ return nIndex;
+}
+
+// -----------------------------------------------------------------------------
+
+TableModel::TableModel( SdrTableObj* pTableObj )
+: TableModelBase( m_aMutex )
+, mpTableObj( pTableObj )
+, mbModified( sal_False )
+, mbNotifyPending( false )
+, mnNotifyLock( 0 )
+{
+}
+
+TableModel::TableModel( SdrTableObj* pTableObj, const TableModelRef& xSourceTable )
+: TableModelBase( m_aMutex )
+, mpTableObj( pTableObj )
+, mbModified( sal_False )
+, mbNotifyPending( false )
+, mnNotifyLock( 0 )
+{
+ if( xSourceTable.is() )
+ {
+ const sal_Int32 nColCount = xSourceTable->getColumnCountImpl();
+ const sal_Int32 nRowCount = xSourceTable->getRowCountImpl();
+
+ init( nColCount, nRowCount );
+
+ sal_Int32 nRows = nRowCount;
+ while( nRows-- )
+ (*maRows[nRows]) = (*xSourceTable->maRows[nRows]);
+
+ sal_Int32 nColumns = nColCount;
+ while( nColumns-- )
+ (*maColumns[nColumns]) = (*xSourceTable->maColumns[nColumns]);
+
+ // copy cells
+ for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol )
+ {
+ for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ CellRef xTargetCell( getCell( nCol, nRow ) );
+ if( xTargetCell.is() )
+ xTargetCell->cloneFrom( xSourceTable->getCell( nCol, nRow ) );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+TableModel::~TableModel()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void TableModel::init( sal_Int32 nColumns, sal_Int32 nRows )
+{
+ if( nRows < 20 )
+ maRows.reserve( 20 );
+
+ if( nColumns < 20 )
+ maColumns.reserve( 20 );
+
+ if( nRows && nColumns )
+ {
+ maColumns.resize( nColumns );
+ maRows.resize( nRows );
+
+ while( nRows-- )
+ maRows[nRows].set( new TableRow( this, nRows, nColumns ) );
+
+ while( nColumns-- )
+ maColumns[nColumns].set( new TableColumn( this, nColumns ) );
+ }
+}
+
+// -----------------------------------------------------------------------------
+// ICellRange
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableModel::getLeft()
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableModel::getTop()
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableModel::getRight()
+{
+ return getColumnCount();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableModel::getBottom()
+{
+ return getRowCount();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XTable > TableModel::getTable()
+{
+ return this;
+}
+
+// -----------------------------------------------------------------------------
+
+void TableModel::UndoInsertRows( sal_Int32 nIndex, sal_Int32 nCount )
+{
+ TableModelNotifyGuard aGuard( this );
+
+ // remove the rows
+ remove_range<RowVector,RowVector::iterator>( maRows, nIndex, nCount );
+ updateRows();
+ setModified(sal_True);
+}
+
+// -----------------------------------------------------------------------------
+
+void TableModel::UndoRemoveRows( sal_Int32 nIndex, RowVector& aRows )
+{
+ TableModelNotifyGuard aGuard( this );
+
+ const sal_Int32 nCount = sal::static_int_cast< sal_Int32 >( aRows.size() );
+
+ nIndex = insert_range<RowVector,RowVector::iterator,TableRowRef>( maRows, nIndex, nCount );
+
+ for( sal_Int32 nOffset = 0; nOffset < nCount; ++nOffset )
+ maRows[nIndex+nOffset] = aRows[nOffset];
+
+ updateRows();
+ setModified(sal_True);
+}
+
+// -----------------------------------------------------------------------------
+
+void TableModel::UndoInsertColumns( sal_Int32 nIndex, sal_Int32 nCount )
+{
+ TableModelNotifyGuard aGuard( this );
+
+ // now remove the columns
+ remove_range<ColumnVector,ColumnVector::iterator>( maColumns, nIndex, nCount );
+ sal_Int32 nRows = getRowCountImpl();
+ while( nRows-- )
+ maRows[nRows]->removeColumns( nIndex, nCount );
+
+ updateColumns();
+ setModified(sal_True);
+}
+
+// -----------------------------------------------------------------------------
+
+void TableModel::UndoRemoveColumns( sal_Int32 nIndex, ColumnVector& aCols, CellVector& aCells )
+{
+ TableModelNotifyGuard aGuard( this );
+
+ const sal_Int32 nCount = sal::static_int_cast< sal_Int32 >( aCols.size() );
+
+ // assert if there are not enough cells saved
+ DBG_ASSERT( (aCols.size() * maRows.size()) == aCells.size(), "sdr::table::TableModel::UndoRemoveColumns(), invalid undo data!" );
+
+ nIndex = insert_range<ColumnVector,ColumnVector::iterator,TableColumnRef>( maColumns, nIndex, nCount );
+ for( sal_Int32 nOffset = 0; nOffset < nCount; ++nOffset )
+ maColumns[nIndex+nOffset] = aCols[nOffset];
+
+ CellVector::iterator aIter( aCells.begin() );
+
+ sal_Int32 nRows = getRowCountImpl();
+ for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
+ maRows[nRow]->insertColumns( nIndex, nCount, &aIter );
+
+ updateColumns();
+ setModified(sal_True);
+}
+
+// -----------------------------------------------------------------------------
+// XTable
+// -----------------------------------------------------------------------------
+
+Reference< XCellCursor > SAL_CALL TableModel::createCursor() throw (RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ return createCursorByRange( Reference< XCellRange >( this ) );
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XCellCursor > SAL_CALL TableModel::createCursorByRange( const Reference< XCellRange >& Range ) throw (IllegalArgumentException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ ICellRange* pRange = dynamic_cast< ICellRange* >( Range.get() );
+ if( (pRange == 0) || (pRange->getTable().get() != this) )
+ throw IllegalArgumentException();
+
+ TableModelRef xModel( this );
+ return new CellCursor( xModel, pRange->getLeft(), pRange->getTop(), pRange->getRight(), pRange->getBottom() );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL TableModel::getRowCount() throw (RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ return getRowCountImpl();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL TableModel::getColumnCount() throw (RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ return getColumnCountImpl();
+}
+
+// -----------------------------------------------------------------------------
+// XComponent
+// -----------------------------------------------------------------------------
+
+void TableModel::dispose() throw (RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ TableModelBase::dispose();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableModel::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException)
+{
+ TableModelBase::addEventListener( xListener );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableModel::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException)
+{
+ TableModelBase::removeEventListener( xListener );
+}
+
+// -----------------------------------------------------------------------------
+// XModifiable
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL TableModel::isModified( ) throw (RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ return mbModified;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableModel::setModified( sal_Bool bModified ) throw (PropertyVetoException, RuntimeException)
+{
+ {
+ OGuard aGuard( Application::GetSolarMutex() );
+ mbModified = bModified;
+ }
+ if( bModified )
+ notifyModification();
+}
+
+// -----------------------------------------------------------------------------
+// XModifyBroadcaster
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableModel::addModifyListener( const Reference< XModifyListener >& xListener ) throw (RuntimeException)
+{
+ rBHelper.addListener( XModifyListener::static_type() , xListener );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableModel::removeModifyListener( const Reference< XModifyListener >& xListener ) throw (RuntimeException)
+{
+ rBHelper.removeListener( XModifyListener::static_type() , xListener );
+}
+
+// -----------------------------------------------------------------------------
+// XColumnRowRange
+// -----------------------------------------------------------------------------
+
+Reference< XTableColumns > SAL_CALL TableModel::getColumns() throw (RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( !mxTableColumns.is() )
+ mxTableColumns.set( new TableColumns( this ) );
+ return mxTableColumns.get();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XTableRows > SAL_CALL TableModel::getRows() throw (RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( !mxTableRows.is() )
+ mxTableRows.set( new TableRows( this ) );
+ return mxTableRows.get();
+}
+
+// -----------------------------------------------------------------------------
+// XCellRange
+// -----------------------------------------------------------------------------
+
+Reference< XCell > SAL_CALL TableModel::getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow ) throw ( IndexOutOfBoundsException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ CellRef xCell( getCell( nColumn, nRow ) );
+ if( xCell.is() )
+ return xCell.get();
+
+ throw IndexOutOfBoundsException();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XCellRange > SAL_CALL TableModel::getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+
+ if( (nLeft >= 0) && (nTop >= 0) && (nRight >= nLeft) && (nBottom >= nTop) && (nRight < getColumnCountImpl()) && (nBottom < getRowCountImpl() ) )
+ {
+ TableModelRef xModel( this );
+ return new CellRange( xModel, nLeft, nTop, nRight, nBottom );
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XCellRange > SAL_CALL TableModel::getCellRangeByName( const OUString& /*aRange*/ ) throw (RuntimeException)
+{
+ return Reference< XCellRange >();
+}
+
+// -----------------------------------------------------------------------------
+// XPropertySet
+// -----------------------------------------------------------------------------
+
+Reference< XPropertySetInfo > SAL_CALL TableModel::getPropertySetInfo( ) throw (RuntimeException)
+{
+ Reference< XPropertySetInfo > xInfo;
+ return xInfo;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableModel::setPropertyValue( const ::rtl::OUString& /*aPropertyName*/, const Any& /*aValue*/ ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL TableModel::getPropertyValue( const OUString& /*PropertyName*/ ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ return Any();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableModel::addPropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableModel::removePropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableModel::addVetoableChangeListener( const OUString& /*aPropertyName*/, const Reference< XVetoableChangeListener >& /*xListener*/ ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableModel::removeVetoableChangeListener( const OUString& /*aPropertyName*/, const Reference< XVetoableChangeListener >& /*xListener*/ ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+// XFastPropertySet
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableModel::setFastPropertyValue( ::sal_Int32 /*nHandle*/, const Any& /*aValue*/ ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL TableModel::getFastPropertyValue( ::sal_Int32 /*nHandle*/ ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ Any aAny;
+ return aAny;
+}
+
+// -----------------------------------------------------------------------------
+// internals
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableModel::getRowCountImpl() const
+{
+ return static_cast< sal_Int32 >( maRows.size() );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Int32 TableModel::getColumnCountImpl() const
+{
+ return static_cast< sal_Int32 >( maColumns.size() );
+}
+
+// -----------------------------------------------------------------------------
+
+void TableModel::disposing()
+{
+ if( !maRows.empty() )
+ {
+ RowVector::iterator aIter( maRows.begin() );
+ while( aIter != maRows.end() )
+ (*aIter++)->dispose();
+ RowVector().swap(maRows);
+ }
+
+ if( !maColumns.empty() )
+ {
+ ColumnVector::iterator aIter( maColumns.begin() );
+ while( aIter != maColumns.end() )
+ (*aIter++)->dispose();
+ ColumnVector().swap(maColumns);
+ }
+
+ if( mxTableColumns.is() )
+ {
+ mxTableColumns->dispose();
+ mxTableColumns.clear();
+ }
+
+ if( mxTableRows.is() )
+ {
+ mxTableRows->dispose();
+ mxTableRows.clear();
+ }
+
+ mpTableObj = 0;
+}
+
+// -----------------------------------------------------------------------------
+// XBroadcaster
+// -----------------------------------------------------------------------------
+
+void TableModel::lockBroadcasts() throw (RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ ++mnNotifyLock;
+}
+// -----------------------------------------------------------------------------
+
+void TableModel::unlockBroadcasts() throw (RuntimeException)
+{
+ OGuard aGuard( Application::GetSolarMutex() );
+ --mnNotifyLock;
+ if( mnNotifyLock <= 0 )
+ {
+ mnNotifyLock = 0;
+ if( mbNotifyPending )
+ notifyModification();
+ }
+}
+
+// -----------------------------------------------------------------------------
+#ifdef PLEASE_DEBUG_THE_TABLES
+#include <stdio.h>
+#endif
+
+void TableModel::notifyModification()
+{
+ ::osl::MutexGuard guard( m_aMutex );
+ if( (mnNotifyLock == 0) && mpTableObj && mpTableObj->GetModel() )
+ {
+ mbNotifyPending = false;
+
+ ::cppu::OInterfaceContainerHelper * pModifyListeners = rBHelper.getContainer( XModifyListener::static_type() );
+ if( pModifyListeners )
+ {
+ EventObject aSource;
+ aSource.Source = static_cast< ::cppu::OWeakObject* >(this);
+ pModifyListeners->notifyEach( &XModifyListener::modified, aSource);
+ }
+ }
+ else
+ {
+ mbNotifyPending = true;
+ }
+
+#ifdef PLEASE_DEBUG_THE_TABLES
+ FILE* file = fopen( "c:\\table.xml","w" );
+
+ const sal_Int32 nColCount = getColumnCountImpl();
+ const sal_Int32 nRowCount = getRowCountImpl();
+
+ fprintf( file, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\r" );
+ fprintf( file, "<table columns=\"%ld\" rows=\"%ld\" updated=\"%s\">\n\r", nColCount, nRowCount, mbNotifyPending ? "false" : "true");
+
+ for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol )
+ {
+ fprintf( file, "<column this=\"%lx\"/>\n\r", maColumns[nCol].get() );
+ }
+
+ // first check merged cells before and inside the removed rows
+ for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ fprintf( file, "<row this=\"%lx\">\n\r", maRows[nRow].get() );
+ for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol )
+ {
+ CellRef xCell( getCell( nCol, nRow ) );
+ fprintf( file, "<cell this=\"%lx\"", xCell.get() );
+
+ sal_Int32 nRowSpan = xCell->getRowSpan();
+ sal_Int32 nColSpan = xCell->getColumnSpan();
+ sal_Bool bMerged = xCell->isMerged();
+
+ if( nColSpan != 1 )
+ fprintf( file, " column-span=\"%ld\"", nColSpan );
+ if( nRowSpan != 1 )
+ fprintf( file, " row-span=\"%ld\"", nRowSpan );
+
+ if( bMerged )
+ fprintf( file, " merged=\"true\"" );
+
+ fprintf( file, "/>" );
+ }
+ fprintf( file, "\n\r</row>\n\r" );
+ }
+
+ fprintf( file, "</table>\n\r" );
+ fclose( file );
+#endif
+}
+
+// -----------------------------------------------------------------------------
+
+CellRef TableModel::getCell( sal_Int32 nCol, sal_Int32 nRow ) const
+{
+ if( ((nRow >= 0) && (nRow < getRowCountImpl())) && (nCol >= 0) && (nCol < getColumnCountImpl()) )
+ {
+ return maRows[nRow]->maCells[nCol];
+ }
+ else
+ {
+ CellRef xRet;
+ return xRet;
+ }
+}
+
+// -----------------------------------------------------------------------------
+/*
+bool TableModel::getCellPos( const CellRef& xCell, ::sal_Int32& rnCol, ::sal_Int32& rnRow ) const
+{
+ const sal_Int32 nRowCount = getRowCount();
+ const sal_Int32 nColCount = getColumnCount();
+ for( rnRow = 0; rnRow < nRowCount; rnRow++ )
+ {
+ for( rnCol = 0; rnCol < nColCount; rnCol++ )
+ {
+ if( maRows[rnRow]->maCells[rnCol] == xCell )
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+*/
+
+// -----------------------------------------------------------------------------
+
+CellRef TableModel::createCell()
+{
+ CellRef xCell;
+ if( mpTableObj )
+ mpTableObj->createCell( xCell );
+ return xCell;
+}
+
+// -----------------------------------------------------------------------------
+
+void TableModel::insertColumns( sal_Int32 nIndex, sal_Int32 nCount )
+{
+ if( nCount && mpTableObj )
+ {
+ try
+ {
+ SdrModel* pModel = mpTableObj->GetModel();
+
+ TableModelNotifyGuard aGuard( this );
+ nIndex = insert_range<ColumnVector,ColumnVector::iterator,TableColumnRef>( maColumns, nIndex, nCount );
+
+ sal_Int32 nRows = getRowCountImpl();
+ while( nRows-- )
+ maRows[nRows]->insertColumns( nIndex, nCount );
+
+ ColumnVector aNewColumns(nCount);
+ for( sal_Int32 nOffset = 0; nOffset < nCount; ++nOffset )
+ {
+ TableColumnRef xNewCol( new TableColumn( this, nIndex+nOffset ) );
+ maColumns[nIndex+nOffset] = xNewCol;
+ aNewColumns[nOffset] = xNewCol;
+ }
+
+ const bool bUndo = pModel && mpTableObj->IsInserted() && pModel->IsUndoEnabled();
+ if( bUndo )
+ {
+ pModel->BegUndo( ImpGetResStr(STR_TABLE_INSCOL) );
+ pModel->AddUndo( pModel->GetSdrUndoFactory().CreateUndoGeoObject(*mpTableObj) );
+
+ TableModelRef xThis( this );
+
+ nRows = getRowCountImpl();
+ CellVector aNewCells( nCount * nRows );
+ CellVector::iterator aCellIter( aNewCells.begin() );
+
+ nRows = getRowCountImpl();
+ for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
+ {
+ for( sal_Int32 nOffset = 0; nOffset < nCount; ++nOffset )
+ (*aCellIter++) = getCell( nIndex + nOffset, nRow );
+ }
+
+ pModel->AddUndo( new InsertColUndo( xThis, nIndex, aNewColumns, aNewCells ) );
+ }
+
+ const sal_Int32 nRowCount = getRowCountImpl();
+ // check if cells merge over new columns
+ for( sal_Int32 nCol = 0; nCol < nIndex; ++nCol )
+ {
+ for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ CellRef xCell( getCell( nCol, nRow ) );
+ sal_Int32 nColSpan = (xCell.is() && !xCell->isMerged()) ? xCell->getColumnSpan() : 1;
+ if( (nColSpan != 1) && ((nColSpan + nCol ) > nIndex) )
+ {
+ // cell merges over newly created columns, so add the new columns to the merged cell
+ const sal_Int32 nRowSpan = xCell->getRowSpan();
+ nColSpan += nCount;
+ merge( nCol, nRow, nColSpan, nRowSpan );
+ }
+ }
+ }
+
+ if( bUndo )
+ pModel->EndUndo();
+
+ if( pModel )
+ pModel->SetChanged();
+
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("sdr::table::TableModel::insertColumns(), exception caught!");
+ }
+ updateColumns();
+ setModified(sal_True);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TableModel::removeColumns( sal_Int32 nIndex, sal_Int32 nCount )
+{
+ sal_Int32 nColCount = getColumnCountImpl();
+
+ if( mpTableObj && nCount && (nIndex >= 0) && (nIndex < nColCount) )
+ {
+ try
+ {
+ TableModelNotifyGuard aGuard( this );
+
+ // clip removed columns to columns actually avalaible
+ if( (nIndex + nCount) > nColCount )
+ nCount = nColCount - nIndex;
+
+ sal_Int32 nRows = getRowCountImpl();
+
+ SdrModel* pModel = mpTableObj->GetModel();
+
+ const bool bUndo = pModel && mpTableObj->IsInserted() && pModel->IsUndoEnabled();
+ if( bUndo )
+ {
+ pModel->BegUndo( ImpGetResStr(STR_UNDO_COL_DELETE) );
+ pModel->AddUndo( pModel->GetSdrUndoFactory().CreateUndoGeoObject(*mpTableObj) );
+
+ TableModelRef xThis( this );
+ ColumnVector aRemovedCols( nCount );
+ sal_Int32 nOffset;
+ for( nOffset = 0; nOffset < nCount; ++nOffset )
+ {
+ aRemovedCols[nOffset] = maColumns[nIndex+nOffset];
+ }
+
+ CellVector aRemovedCells( nCount * nRows );
+ CellVector::iterator aCellIter( aRemovedCells.begin() );
+ for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
+ {
+ for( nOffset = 0; nOffset < nCount; ++nOffset )
+ (*aCellIter++) = getCell( nIndex + nOffset, nRow );
+ }
+
+ pModel->AddUndo( new RemoveColUndo( xThis, nIndex, aRemovedCols, aRemovedCells ) );
+ }
+
+ // only rows before and inside the removed rows are considered
+ nColCount = nIndex + nCount + 1;
+
+ const sal_Int32 nRowCount = getRowCountImpl();
+
+ // first check merged cells before and inside the removed rows
+ for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol )
+ {
+ for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ CellRef xCell( getCell( nCol, nRow ) );
+ sal_Int32 nColSpan = (xCell.is() && !xCell->isMerged()) ? xCell->getColumnSpan() : 1;
+ if( nColSpan <= 1 )
+ continue;
+
+ if( nCol >= nIndex )
+ {
+ // current cell is inside the removed columns
+ if( (nCol + nColSpan) > ( nIndex + nCount ) )
+ {
+ // current cells merges with columns after the removed columns
+ const sal_Int32 nRemove = nCount - nCol + nIndex;
+
+ CellRef xTargetCell( getCell( nIndex + nCount, nRow ) );
+ if( xTargetCell.is() )
+ {
+ if( bUndo )
+ xTargetCell->AddUndo();
+ xTargetCell->merge( nColSpan - nRemove, xCell->getRowSpan() );
+ xTargetCell->replaceContentAndFormating( xCell );
+ }
+ }
+ }
+ else if( nColSpan > (nIndex - nCol) )
+ {
+ // current cells spans inside the removed columns, so adjust
+ const sal_Int32 nRemove = ::std::min( nCount, nCol + nColSpan - nIndex );
+ if( bUndo )
+ xCell->AddUndo();
+ xCell->merge( nColSpan - nRemove, xCell->getRowSpan() );
+ }
+ }
+ }
+
+ // now remove the columns
+ remove_range<ColumnVector,ColumnVector::iterator>( maColumns, nIndex, nCount );
+ while( nRows-- )
+ maRows[nRows]->removeColumns( nIndex, nCount );
+
+ if( bUndo )
+ pModel->EndUndo();
+
+ if( pModel )
+ pModel->SetChanged();
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("sdr::table::TableModel::removeColumns(), exception caught!");
+ }
+
+ updateColumns();
+ setModified(sal_True);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TableModel::insertRows( sal_Int32 nIndex, sal_Int32 nCount )
+{
+ if( nCount && mpTableObj )
+ {
+ SdrModel* pModel = mpTableObj->GetModel();
+ const bool bUndo = pModel && mpTableObj->IsInserted() && pModel->IsUndoEnabled();
+ try
+ {
+ TableModelNotifyGuard aGuard( this );
+
+ nIndex = insert_range<RowVector,RowVector::iterator,TableRowRef>( maRows, nIndex, nCount );
+
+ RowVector aNewRows(nCount);
+ const sal_Int32 nColCount = getColumnCountImpl();
+ for( sal_Int32 nOffset = 0; nOffset < nCount; ++nOffset )
+ {
+ TableRowRef xNewRow( new TableRow( this, nIndex+nOffset, nColCount ) );
+ maRows[nIndex+nOffset] = xNewRow;
+ aNewRows[nOffset] = xNewRow;
+ }
+
+ if( bUndo )
+ {
+ pModel->BegUndo( ImpGetResStr(STR_TABLE_INSROW) );
+ pModel->AddUndo( pModel->GetSdrUndoFactory().CreateUndoGeoObject(*mpTableObj) );
+ TableModelRef xThis( this );
+ pModel->AddUndo( new InsertRowUndo( xThis, nIndex, aNewRows ) );
+ }
+
+ // check if cells merge over new columns
+ for( sal_Int32 nRow = 0; nRow < nIndex; ++nRow )
+ {
+ for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol )
+ {
+ CellRef xCell( getCell( nCol, nRow ) );
+ sal_Int32 nRowSpan = (xCell.is() && !xCell->isMerged()) ? xCell->getRowSpan() : 1;
+ if( (nRowSpan > 1) && ((nRowSpan + nRow) > nIndex) )
+ {
+ // cell merges over newly created columns, so add the new columns to the merged cell
+ const sal_Int32 nColSpan = xCell->getColumnSpan();
+ nRowSpan += nCount;
+ merge( nCol, nRow, nColSpan, nRowSpan );
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("sdr::table::TableModel::insertRows(), exception caught!");
+ }
+ if( bUndo )
+ pModel->EndUndo();
+
+ if( pModel )
+ pModel->SetChanged();
+
+ updateRows();
+ setModified(sal_True);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TableModel::removeRows( sal_Int32 nIndex, sal_Int32 nCount )
+{
+ sal_Int32 nRowCount = getRowCountImpl();
+
+ if( mpTableObj && nCount && (nIndex >= 0) && (nIndex < nRowCount) )
+ {
+ SdrModel* pModel = mpTableObj->GetModel();
+ const bool bUndo = pModel && mpTableObj->IsInserted()&& pModel->IsUndoEnabled();
+
+ try
+ {
+ TableModelNotifyGuard aGuard( this );
+
+ // clip removed rows to rows actually avalaible
+ if( (nIndex + nCount) > nRowCount )
+ nCount = nRowCount - nIndex;
+
+ if( bUndo )
+ {
+ pModel->BegUndo( ImpGetResStr(STR_UNDO_ROW_DELETE) );
+ pModel->AddUndo( pModel->GetSdrUndoFactory().CreateUndoGeoObject(*mpTableObj) );
+
+ TableModelRef xThis( this );
+
+ RowVector aRemovedRows( nCount );
+ for( sal_Int32 nOffset = 0; nOffset < nCount; ++nOffset )
+ aRemovedRows[nOffset] = maRows[nIndex+nOffset];
+
+ pModel->AddUndo( new RemoveRowUndo( xThis, nIndex, aRemovedRows ) );
+ }
+
+ // only rows before and inside the removed rows are considered
+ nRowCount = nIndex + nCount + 1;
+
+ const sal_Int32 nColCount = getColumnCountImpl();
+
+ // first check merged cells before and inside the removed rows
+ for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol )
+ {
+ CellRef xCell( getCell( nCol, nRow ) );
+ sal_Int32 nRowSpan = (xCell.is() && !xCell->isMerged()) ? xCell->getRowSpan() : 1;
+ if( nRowSpan <= 1 )
+ continue;
+
+ if( nRow >= nIndex )
+ {
+ // current cell is inside the removed rows
+ if( (nRow + nRowSpan) > (nIndex + nCount) )
+ {
+ // current cells merges with rows after the removed rows
+ const sal_Int32 nRemove = nCount - nRow + nIndex;
+
+ CellRef xTargetCell( getCell( nCol, nIndex + nCount ) );
+ if( xTargetCell.is() )
+ {
+ if( bUndo )
+ xTargetCell->AddUndo();
+ xTargetCell->merge( xCell->getColumnSpan(), nRowSpan - nRemove );
+ xTargetCell->replaceContentAndFormating( xCell );
+ }
+ }
+ }
+ else if( nRowSpan > (nIndex - nRow) )
+ {
+ // current cells spans inside the removed rows, so adjust
+ const sal_Int32 nRemove = ::std::min( nCount, nRow + nRowSpan - nIndex );
+ if( bUndo )
+ xCell->AddUndo();
+ xCell->merge( xCell->getColumnSpan(), nRowSpan - nRemove );
+ }
+ }
+ }
+
+ // now remove the rows
+ remove_range<RowVector,RowVector::iterator>( maRows, nIndex, nCount );
+
+ if( bUndo )
+ pModel->EndUndo();
+
+ if( pModel )
+ pModel->SetChanged();
+ }
+ catch( Exception& )
+ {
+ DBG_ERROR("sdr::table::TableModel::removeRows(), exception caught!");
+ }
+
+ updateRows();
+ setModified(sal_True);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+TableRowRef TableModel::getRow( sal_Int32 nRow ) const throw (IndexOutOfBoundsException)
+{
+ if( (nRow >= 0) && (nRow < getRowCountImpl()) )
+ return maRows[nRow];
+
+ throw IndexOutOfBoundsException();
+}
+
+// -----------------------------------------------------------------------------
+
+TableColumnRef TableModel::getColumn( sal_Int32 nColumn ) const throw (IndexOutOfBoundsException)
+{
+ if( (nColumn >= 0) && (nColumn < getColumnCountImpl()) )
+ return maColumns[nColumn];
+
+ throw IndexOutOfBoundsException();
+}
+
+// -----------------------------------------------------------------------------
+
+/** deletes rows and columns that are completly merged. Must be called between BegUndo/EndUndo! */
+void TableModel::optimize()
+{
+ TableModelNotifyGuard aGuard( this );
+
+ bool bWasModified = false;
+
+ if( !maRows.empty() && !maColumns.empty() )
+ {
+ sal_Int32 nCol = getColumnCountImpl() - 1;
+ while( nCol > 0 )
+ {
+ bool bEmpty = true;
+ for( sal_Int32 nRow = 0; (nRow < getRowCountImpl()) && bEmpty; nRow++ )
+ {
+ Reference< XMergeableCell > xCell( getCellByPosition( nCol, nRow ), UNO_QUERY );
+ if( xCell.is() && !xCell->isMerged() )
+ bEmpty = false;
+ }
+
+ if( bEmpty )
+ {
+ if( nCol > 0 ) try
+ {
+ const OUString sWidth( RTL_CONSTASCII_USTRINGPARAM("Width") );
+ sal_Int32 nWidth1 = 0, nWidth2 = 0;
+ Reference< XPropertySet > xSet1( static_cast< XCellRange* >( maColumns[nCol].get() ), UNO_QUERY_THROW );
+ Reference< XPropertySet > xSet2( static_cast< XCellRange* >( maColumns[nCol-1].get() ), UNO_QUERY_THROW );
+ xSet1->getPropertyValue( sWidth ) >>= nWidth1;
+ xSet2->getPropertyValue( sWidth ) >>= nWidth2;
+ nWidth1 += nWidth2;
+ xSet2->setPropertyValue( sWidth, Any( nWidth1 ) );
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR("svx::TableModel::optimize(), exception caught!");
+ }
+
+ removeColumns( nCol, 1 );
+ bWasModified = true;
+ }
+
+ nCol--;
+ }
+
+ sal_Int32 nRow = getRowCountImpl() - 1;
+ while( nRow > 0 )
+ {
+ bool bEmpty = true;
+ for( nCol = 0; (nCol < getColumnCountImpl()) && bEmpty; nCol++ )
+ {
+ Reference< XMergeableCell > xCell( getCellByPosition( nCol, nRow ), UNO_QUERY );
+ if( xCell.is() && !xCell->isMerged() )
+ bEmpty = false;
+ }
+
+ if( bEmpty )
+ {
+ if( nRow > 0 ) try
+ {
+ const OUString sHeight( RTL_CONSTASCII_USTRINGPARAM("Height") );
+ sal_Int32 nHeight1 = 0, nHeight2 = 0;
+ Reference< XPropertySet > xSet1( static_cast< XCellRange* >( maRows[nRow].get() ), UNO_QUERY_THROW );
+ Reference< XPropertySet > xSet2( static_cast< XCellRange* >( maRows[nRow-1].get() ), UNO_QUERY_THROW );
+ xSet1->getPropertyValue( sHeight ) >>= nHeight1;
+ xSet2->getPropertyValue( sHeight ) >>= nHeight2;
+ nHeight1 += nHeight2;
+ xSet2->setPropertyValue( sHeight, Any( nHeight1 ) );
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR("svx::TableModel::optimize(), exception caught!");
+ }
+
+ removeRows( nRow, 1 );
+ bWasModified = true;
+ }
+
+ nRow--;
+ }
+ }
+ if( bWasModified )
+ setModified(sal_True);
+}
+
+// -----------------------------------------------------------------------------
+
+void TableModel::merge( sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nColSpan, sal_Int32 nRowSpan )
+{
+ SdrModel* pModel = mpTableObj->GetModel();
+
+ const bool bUndo = pModel && mpTableObj->IsInserted() && pModel->IsUndoEnabled();
+
+ const sal_Int32 nLastRow = nRow + nRowSpan;
+ const sal_Int32 nLastCol = nCol + nColSpan;
+
+ if( (nLastRow > getRowCount()) || (nLastCol > getRowCount() ) )
+ {
+ DBG_ERROR("TableModel::merge(), merge beyound the table!");
+ }
+
+ // merge first cell
+ CellRef xOriginCell( dynamic_cast< Cell* >( getCellByPosition( nCol, nRow ).get() ) );
+ if( xOriginCell.is() )
+ {
+ if( bUndo )
+ xOriginCell->AddUndo();
+ xOriginCell->merge( nColSpan, nRowSpan );
+ }
+
+ sal_Int32 nTempCol = nCol + 1;
+
+ // merge remaining cells
+ for( ; nRow < nLastRow; nRow++ )
+ {
+ for( ; nTempCol < nLastCol; nTempCol++ )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( getCellByPosition( nTempCol, nRow ).get() ) );
+ if( xCell.is() && !xCell->isMerged() )
+ {
+ if( bUndo )
+ xCell->AddUndo();
+ xCell->setMerged();
+ xOriginCell->mergeContent( xCell );
+ }
+ }
+ nTempCol = nCol;
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+
+void TableModel::updateRows()
+{
+ sal_Int32 nRow = 0;
+ RowVector::iterator iter = maRows.begin();
+ while( iter != maRows.end() )
+ {
+ (*iter++)->mnRow = nRow++;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TableModel::updateColumns()
+{
+ sal_Int32 nColumn = 0;
+ ColumnVector::iterator iter = maColumns.begin();
+ while( iter != maColumns.end() )
+ {
+ (*iter++)->mnColumn = nColumn++;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+} }
diff --git a/svx/source/table/tablemodel.hxx b/svx/source/table/tablemodel.hxx
new file mode 100644
index 000000000000..a1498c0041a6
--- /dev/null
+++ b/svx/source/table/tablemodel.hxx
@@ -0,0 +1,225 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_TABLE_TABLEMODEL_HXX_
+#define _SVX_TABLE_TABLEMODEL_HXX_
+
+#include <com/sun/star/util/XBroadcaster.hpp>
+#include <com/sun/star/table/XTable.hpp>
+#include <basegfx/range/b2irectangle.hxx>
+#include <basegfx/tuple/b2ituple.hxx>
+#include <cppuhelper/compbase2.hxx>
+#include <comphelper/broadcasthelper.hxx>
+#include <comphelper/listenernotification.hxx>
+#include <tools/gen.hxx>
+#include "celltypes.hxx"
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+class SdrTableObj;
+
+// -----------------------------------------------------------------------------
+// ICellRange
+// -----------------------------------------------------------------------------
+
+/** base class for each object implementing an XCellRange */
+class ICellRange
+{
+public:
+ virtual sal_Int32 getLeft() = 0;
+ virtual sal_Int32 getTop() = 0;
+ virtual sal_Int32 getRight() = 0;
+ virtual sal_Int32 getBottom() = 0;
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XTable > getTable() = 0;
+};
+
+// -----------------------------------------------------------------------------
+// TableModel
+// -----------------------------------------------------------------------------
+
+typedef ::cppu::WeakComponentImplHelper2< ::com::sun::star::table::XTable, ::com::sun::star::util::XBroadcaster > TableModelBase;
+
+class TableModel : public TableModelBase,
+ public ::comphelper::OBaseMutex,
+ public ICellRange
+{
+ friend class InsertRowUndo;
+ friend class RemoveRowUndo;
+ friend class InsertColUndo;
+ friend class RemoveColUndo;
+ friend class TableColumnUndo;
+ friend class TableRowUndo;
+ friend class TableColumn;
+ friend class TableRow;
+ friend class TableRows;
+ friend class TableColumns;
+ friend class TableModelNotifyGuard;
+
+public:
+ TableModel( SdrTableObj* pTableObj );
+ TableModel( SdrTableObj* pTableObj, const TableModelRef& xSourceTable );
+ virtual ~TableModel();
+
+ void init( sal_Int32 nColumns, sal_Int32 nRows );
+
+ SdrTableObj* getSdrTableObj() const { return mpTableObj; }
+
+ /** deletes rows and columns that are completly merged. Must be called between BegUndo/EndUndo! */
+ void optimize();
+
+ /// merges the cell at the given position with the given span
+ void merge( sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nColSpan, sal_Int32 nRowSpan );
+
+ // ICellRange
+ virtual sal_Int32 getLeft();
+ virtual sal_Int32 getTop();
+ virtual sal_Int32 getRight();
+ virtual sal_Int32 getBottom();
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XTable > getTable();
+
+ // XTable
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellCursor > SAL_CALL createCursor( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellCursor > SAL_CALL createCursorByRange( const ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange >& Range ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getRowCount() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getColumnCount() throw (::com::sun::star::uno::RuntimeException);
+
+ // XComponent
+ virtual void SAL_CALL dispose( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XModifiable
+ virtual ::sal_Bool SAL_CALL isModified( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setModified( ::sal_Bool bModified ) throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException);
+
+ // XModifyBroadcaster
+ virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XColumnRowRange
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XTableColumns > SAL_CALL getColumns() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XTableRows > SAL_CALL getRows() throw (::com::sun::star::uno::RuntimeException);
+
+ // XCellRange
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell > SAL_CALL getCellByPosition( ::sal_Int32 nColumn, ::sal_Int32 nRow ) throw ( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > SAL_CALL getCellRangeByPosition( ::sal_Int32 nLeft, ::sal_Int32 nTop, ::sal_Int32 nRight, ::sal_Int32 nBottom ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > SAL_CALL getCellRangeByName( const ::rtl::OUString& aRange ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XFastPropertySet
+ virtual void SAL_CALL setFastPropertyValue( ::sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue( ::sal_Int32 nHandle ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XBroadcaster
+ virtual void SAL_CALL lockBroadcasts() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL unlockBroadcasts() throw (::com::sun::star::uno::RuntimeException);
+
+protected:
+ void notifyModification();
+
+ void insertColumns( sal_Int32 nIndex, sal_Int32 nCount );
+ void removeColumns( sal_Int32 nIndex, sal_Int32 nCount );
+ void insertRows( sal_Int32 nIndex, sal_Int32 nCount );
+ void removeRows( sal_Int32 nIndex, sal_Int32 nCount );
+
+ sal_Int32 getRowCountImpl() const;
+ sal_Int32 getColumnCountImpl() const;
+
+ CellRef createCell();
+ CellRef getCell( ::sal_Int32 nCol, ::sal_Int32 nRow ) const;
+
+ void UndoInsertRows( sal_Int32 nIndex, sal_Int32 nCount );
+ void UndoRemoveRows( sal_Int32 nIndex, RowVector& aNewRows );
+
+ void UndoInsertColumns( sal_Int32 nIndex, sal_Int32 nCount );
+ void UndoRemoveColumns( sal_Int32 nIndex, ColumnVector& aNewCols, CellVector& aCells );
+
+private:
+ /** this function is called upon disposing the component
+ */
+ virtual void SAL_CALL disposing();
+
+ TableRowRef getRow( sal_Int32 nRow ) const throw (::com::sun::star::lang::IndexOutOfBoundsException);
+ TableColumnRef getColumn( sal_Int32 nColumn ) const throw (::com::sun::star::lang::IndexOutOfBoundsException);
+
+ void updateRows();
+ void updateColumns();
+
+ RowVector maRows;
+ ColumnVector maColumns;
+
+ TableColumnsRef mxTableColumns;
+ TableRowsRef mxTableRows;
+
+ SdrTableObj* mpTableObj;
+
+ sal_Bool mbModified;
+ bool mbNotifyPending;
+
+ sal_Int32 mnNotifyLock;
+};
+
+class TableModelNotifyGuard
+{
+public:
+ TableModelNotifyGuard( TableModel* pModel )
+ : mxBroadcaster( static_cast< ::com::sun::star::util::XBroadcaster* >( pModel ) )
+ {
+ if( mxBroadcaster.is() )
+ mxBroadcaster->lockBroadcasts();
+ }
+
+ TableModelNotifyGuard( ::com::sun::star::uno::XInterface* pInterface )
+ : mxBroadcaster( pInterface, ::com::sun::star::uno::UNO_QUERY )
+ {
+ if( mxBroadcaster.is() )
+ mxBroadcaster->lockBroadcasts();
+ }
+
+ ~TableModelNotifyGuard()
+ {
+ if( mxBroadcaster.is() )
+ mxBroadcaster->unlockBroadcasts();
+ }
+
+private:
+ com::sun::star::uno::Reference< ::com::sun::star::util::XBroadcaster > mxBroadcaster;
+};
+
+} }
+
+#endif
diff --git a/svx/source/table/tablerow.cxx b/svx/source/table/tablerow.cxx
new file mode 100644
index 000000000000..379d4beb37df
--- /dev/null
+++ b/svx/source/table/tablerow.cxx
@@ -0,0 +1,381 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <com/sun/star/lang/DisposedException.hpp>
+
+#include "cell.hxx"
+#include "tablerow.hxx"
+#include "tableundo.hxx"
+#include "svx/svdmodel.hxx"
+#include "svx/svdotable.hxx"
+
+// -----------------------------------------------------------------------------
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::beans;
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+const sal_Int32 Property_Height = 0;
+const sal_Int32 Property_OptimalHeight = 1;
+const sal_Int32 Property_IsVisible = 2;
+const sal_Int32 Property_IsStartOfNewPage = 3;
+
+// -----------------------------------------------------------------------------
+// TableRow
+// -----------------------------------------------------------------------------
+
+TableRow::TableRow( const TableModelRef& xTableModel, sal_Int32 nRow, sal_Int32 nColumns )
+: TableRowBase( getStaticPropertySetInfo() )
+, mxTableModel( xTableModel )
+, mnRow( nRow )
+, mnHeight( 0 )
+, mbOptimalHeight( sal_True )
+, mbIsVisible( sal_True )
+, mbIsStartOfNewPage( sal_False )
+{
+ if( nColumns < 20 )
+ maCells.reserve( 20 );
+
+ if( nColumns )
+ {
+ maCells.resize( nColumns );
+ while( nColumns-- )
+ maCells[ nColumns ] = mxTableModel->createCell();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+TableRow::~TableRow()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void TableRow::dispose()
+{
+ mxTableModel.clear();
+ if( !maCells.empty() )
+ {
+ CellVector::iterator aIter( maCells.begin() );
+ while( aIter != maCells.end() )
+ (*aIter++)->dispose();
+ CellVector().swap(maCells);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TableRow::throwIfDisposed() const throw (::com::sun::star::uno::RuntimeException)
+{
+ if( !mxTableModel.is() )
+ throw DisposedException();
+}
+
+// -----------------------------------------------------------------------------
+
+TableRow& TableRow::operator=( const TableRow& r )
+{
+ mnHeight = r.mnHeight;
+ mbOptimalHeight = r.mbOptimalHeight;
+ mbIsVisible = r.mbIsVisible;
+ mbIsStartOfNewPage = r.mbIsStartOfNewPage;
+ maName = r.maName;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------------
+
+void TableRow::insertColumns( sal_Int32 nIndex, sal_Int32 nCount, CellVector::iterator* pIter /* = 0 */ )
+{
+ throwIfDisposed();
+ if( nCount )
+ {
+ if( nIndex >= static_cast< sal_Int32 >( maCells.size() ) )
+ nIndex = static_cast< sal_Int32 >( maCells.size() );
+ if ( pIter )
+ maCells.insert( maCells.begin() + nIndex, *pIter, (*pIter) + nCount );
+ else
+ {
+ maCells.reserve( maCells.size() + nCount );
+ for ( sal_Int32 i = 0; i < nCount; i++ )
+ maCells.insert( maCells.begin() + nIndex + i, mxTableModel->createCell() );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void TableRow::removeColumns( sal_Int32 nIndex, sal_Int32 nCount )
+{
+ throwIfDisposed();
+ if( (nCount >= 0) && ( nIndex >= 0) )
+ {
+ if( (nIndex + nCount) < static_cast< sal_Int32 >( maCells.size() ) )
+ {
+ CellVector::iterator aBegin( maCells.begin() );
+ while( nIndex-- && (aBegin != maCells.end()) )
+ aBegin++;
+
+ if( nCount > 1 )
+ {
+ CellVector::iterator aEnd( aBegin );
+ while( nCount-- && (aEnd != maCells.end()) )
+ aEnd++;
+ maCells.erase( aBegin, aEnd );
+ }
+ else
+ {
+ maCells.erase( aBegin );
+ }
+ }
+ else
+ {
+ maCells.resize( nIndex );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+// XCellRange
+// -----------------------------------------------------------------------------
+
+Reference< XCell > SAL_CALL TableRow::getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ throwIfDisposed();
+ if( nRow != 0 )
+ throw IndexOutOfBoundsException();
+
+ return mxTableModel->getCellByPosition( nColumn, mnRow );
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XCellRange > SAL_CALL TableRow::getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ throwIfDisposed();
+ if( (nLeft >= 0 ) && (nTop == 0) && (nRight >= nLeft) && (nBottom == 0) )
+ {
+ return mxTableModel->getCellRangeByPosition( nLeft, mnRow, nRight, mnRow );
+ }
+ throw IndexOutOfBoundsException();
+}
+
+// -----------------------------------------------------------------------------
+
+Reference< XCellRange > SAL_CALL TableRow::getCellRangeByName( const OUString& /*aRange*/ ) throw (RuntimeException)
+{
+ throwIfDisposed();
+ return Reference< XCellRange >();
+}
+
+// -----------------------------------------------------------------------------
+// XNamed
+// -----------------------------------------------------------------------------
+
+OUString SAL_CALL TableRow::getName() throw (RuntimeException)
+{
+ return maName;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableRow::setName( const OUString& aName ) throw (RuntimeException)
+{
+ maName = aName;
+}
+
+// -----------------------------------------------------------------------------
+// XFastPropertySet
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableRow::setFastPropertyValue( sal_Int32 nHandle, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, RuntimeException)
+{
+ bool bOk = false;
+ bool bChange = false;
+
+ TableRowUndo* pUndo = 0;
+
+ SdrModel* pModel = mxTableModel->getSdrTableObj()->GetModel();
+
+ const bool bUndo = mxTableModel.is() && mxTableModel->getSdrTableObj() && mxTableModel->getSdrTableObj()->IsInserted() && pModel && pModel->IsUndoEnabled();
+
+ if( bUndo )
+ {
+ TableRowRef xThis( this );
+ pUndo = new TableRowUndo( xThis );
+ }
+
+ switch( nHandle )
+ {
+ case Property_Height:
+ {
+ sal_Int32 nHeight = mnHeight;
+ bOk = aValue >>= nHeight;
+ if( bOk && (mnHeight != nHeight) )
+ {
+ mnHeight = nHeight;
+ mbOptimalHeight = mnHeight == 0;
+ bChange = true;
+ }
+ break;
+ }
+
+ case Property_OptimalHeight:
+ {
+ sal_Bool bOptimalHeight = mbOptimalHeight;
+ bOk = aValue >>= bOptimalHeight;
+ if( bOk && (mbOptimalHeight != bOptimalHeight) )
+ {
+ mbOptimalHeight = bOptimalHeight;
+ if( bOptimalHeight )
+ mnHeight = 0;
+ bChange = true;
+ }
+ break;
+ }
+ case Property_IsVisible:
+ {
+ sal_Bool bIsVisible = mbIsVisible;
+ bOk = aValue >>= bIsVisible;
+ if( bOk && (mbIsVisible != bIsVisible) )
+ {
+ mbIsVisible = bIsVisible;
+ bChange = true;
+ }
+ break;
+ }
+
+ case Property_IsStartOfNewPage:
+ {
+ sal_Bool bIsStartOfNewPage = mbIsStartOfNewPage;
+ bOk = aValue >>= bIsStartOfNewPage;
+ if( bOk && (mbIsStartOfNewPage != bIsStartOfNewPage) )
+ {
+ mbIsStartOfNewPage = bIsStartOfNewPage;
+ bChange = true;
+ }
+ break;
+ }
+ default:
+ throw UnknownPropertyException();
+ }
+ if( !bOk )
+ throw IllegalArgumentException();
+
+ if( bChange )
+ {
+ if( pUndo )
+ {
+ pModel->AddUndo( pUndo );
+ pUndo = 0;
+ }
+ mxTableModel->setModified(sal_True);
+ }
+
+ if( pUndo )
+ delete pUndo;
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL TableRow::getFastPropertyValue( sal_Int32 nHandle ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ switch( nHandle )
+ {
+ case Property_Height: return Any( mnHeight );
+ case Property_OptimalHeight: return Any( mbOptimalHeight );
+ case Property_IsVisible: return Any( mbIsVisible );
+ case Property_IsStartOfNewPage: return Any( mbIsStartOfNewPage );
+ default: throw UnknownPropertyException();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+rtl::Reference< ::comphelper::FastPropertySetInfo > TableRow::getStaticPropertySetInfo()
+{
+ static rtl::Reference< ::comphelper::FastPropertySetInfo > xInfo;
+ if( !xInfo.is() )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !xInfo.is() )
+ {
+ comphelper::PropertyVector aProperties(6);
+
+ aProperties[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Height" ) );
+ aProperties[0].Handle = Property_Height;
+ aProperties[0].Type = ::getCppuType((const sal_Int32*)0);
+ aProperties[0].Attributes = 0;
+
+ aProperties[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OptimalHeight" ) );
+ aProperties[1].Handle = Property_OptimalHeight;
+ aProperties[1].Type = ::getBooleanCppuType();
+ aProperties[1].Attributes = 0;
+
+ aProperties[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVisible" ) );
+ aProperties[2].Handle = Property_IsVisible;
+ aProperties[2].Type = ::getBooleanCppuType();
+ aProperties[2].Attributes = 0;
+
+ aProperties[3].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsStartOfNewPage" ) );
+ aProperties[3].Handle = Property_IsStartOfNewPage;
+ aProperties[3].Type = ::getBooleanCppuType();
+ aProperties[3].Attributes = 0;
+
+ aProperties[4].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) );
+ aProperties[4].Handle = Property_Height;
+ aProperties[4].Type = ::getCppuType((const sal_Int32*)0);
+ aProperties[4].Attributes = 0;
+
+ aProperties[5].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OptimalSize" ) );
+ aProperties[5].Handle = Property_OptimalHeight;
+ aProperties[5].Type = ::getBooleanCppuType();
+ aProperties[5].Attributes = 0;
+
+ xInfo.set( new ::comphelper::FastPropertySetInfo(aProperties) );
+ }
+ }
+
+ return xInfo;
+}
+
+// -----------------------------------------------------------------------------
+
+
+} }
diff --git a/svx/source/table/tablerow.hxx b/svx/source/table/tablerow.hxx
new file mode 100644
index 000000000000..4d1009c8f6b8
--- /dev/null
+++ b/svx/source/table/tablerow.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_TABLEROW_HXX_
+#define _SVX_TABLEROW_HXX_
+
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <cppuhelper/implbase2.hxx>
+
+#include "propertyset.hxx"
+#include "tablemodel.hxx"
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+// -----------------------------------------------------------------------------
+// TableRow
+// -----------------------------------------------------------------------------
+
+typedef ::cppu::ImplInheritanceHelper2< ::comphelper::FastPropertySet, ::com::sun::star::table::XCellRange, ::com::sun::star::container::XNamed > TableRowBase;
+
+class TableRow : public TableRowBase
+{
+ friend class TableModel;
+ friend class TableRowUndo;
+public:
+ TableRow( const TableModelRef& xTableModel, sal_Int32 nRow, sal_Int32 nColumns );
+ virtual ~TableRow();
+
+ void dispose();
+ void throwIfDisposed() const throw (::com::sun::star::uno::RuntimeException);
+
+ TableRow& operator=( const TableRow& );
+
+ void insertColumns( sal_Int32 nIndex, sal_Int32 nCount, CellVector::iterator* pIter = 0 );
+ void removeColumns( sal_Int32 nIndex, sal_Int32 nCount );
+
+ // XCellRange
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell > SAL_CALL getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > SAL_CALL getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > SAL_CALL getCellRangeByName( const ::rtl::OUString& aRange ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XNamed
+ virtual ::rtl::OUString SAL_CALL getName() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XFastPropertySet
+ virtual void SAL_CALL setFastPropertyValue( ::sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue( ::sal_Int32 nHandle ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+private:
+ static rtl::Reference< ::comphelper::FastPropertySetInfo > getStaticPropertySetInfo();
+
+ TableModelRef mxTableModel;
+ CellVector maCells;
+ sal_Int32 mnRow;
+ sal_Int32 mnHeight;
+ sal_Bool mbOptimalHeight;
+ sal_Bool mbIsVisible;
+ sal_Bool mbIsStartOfNewPage;
+ ::rtl::OUString maName;
+};
+
+} }
+
+#endif
diff --git a/svx/source/table/tablerows.cxx b/svx/source/table/tablerows.cxx
new file mode 100644
index 000000000000..2b995dfa896d
--- /dev/null
+++ b/svx/source/table/tablerows.cxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <com/sun/star/lang/DisposedException.hpp>
+
+#include "cell.hxx"
+#include "tablerow.hxx"
+#include "tablerows.hxx"
+
+// -----------------------------------------------------------------------------
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::table;
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+// -----------------------------------------------------------------------------
+// TableRows
+// -----------------------------------------------------------------------------
+
+TableRows::TableRows( const TableModelRef& xTableModel )
+: mxTableModel( xTableModel )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+TableRows::~TableRows()
+{
+ dispose();
+}
+
+// -----------------------------------------------------------------------------
+
+void TableRows::dispose()
+{
+ mxTableModel.clear();
+}
+
+// -----------------------------------------------------------------------------
+
+void TableRows::throwIfDisposed() const throw (::com::sun::star::uno::RuntimeException)
+{
+ if( !mxTableModel.is() )
+ throw DisposedException();
+}
+
+// -----------------------------------------------------------------------------
+// XTableRows
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableRows::insertByIndex( sal_Int32 nIndex, sal_Int32 nCount ) throw (RuntimeException)
+{
+ throwIfDisposed();
+ mxTableModel->insertRows( nIndex, nCount );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL TableRows::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount ) throw (RuntimeException)
+{
+ throwIfDisposed();
+ mxTableModel->removeRows( nIndex, nCount );
+}
+
+// -----------------------------------------------------------------------------
+// XIndexAccess
+// -----------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL TableRows::getCount() throw (RuntimeException)
+{
+ throwIfDisposed();
+ return mxTableModel->getRowCount();
+}
+
+// -----------------------------------------------------------------------------
+
+Any SAL_CALL TableRows::getByIndex( sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ throwIfDisposed();
+ return Any( Reference< XCellRange >( static_cast< XCellRange* >( mxTableModel->getRow( Index ).get() ) ) );
+}
+
+// -----------------------------------------------------------------------------
+// XElementAccess
+// -----------------------------------------------------------------------------
+
+Type SAL_CALL TableRows::getElementType() throw (RuntimeException)
+{
+ throwIfDisposed();
+ return XCellRange::static_type();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL TableRows::hasElements() throw (RuntimeException)
+{
+ throwIfDisposed();
+ return mxTableModel->getRowCount() != 0;
+}
+
+// -----------------------------------------------------------------------------
+
+} }
diff --git a/svx/source/table/tablerows.hxx b/svx/source/table/tablerows.hxx
new file mode 100644
index 000000000000..47d5b19832f0
--- /dev/null
+++ b/svx/source/table/tablerows.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_TABLEROWS_HXX_
+#define _SVX_TABLEROWS_HXX_
+
+#include <com/sun/star/table/XTableRows.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+#include "tablemodel.hxx"
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+// -----------------------------------------------------------------------------
+// TableRows
+// -----------------------------------------------------------------------------
+
+class TableRows : public ::cppu::WeakAggImplHelper1< ::com::sun::star::table::XTableRows >
+{
+public:
+ TableRows( const TableModelRef& xTableModel );
+ virtual ~TableRows();
+
+ void dispose();
+ void throwIfDisposed() const throw (::com::sun::star::uno::RuntimeException);
+
+ // XTableRows
+ virtual void SAL_CALL insertByIndex( sal_Int32 nIndex, sal_Int32 nCount ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeByIndex( sal_Int32 nIndex, sal_Int32 nCount ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( sal_Int32 Index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // Methods
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasElements() throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ TableModelRef mxTableModel;
+};
+
+} }
+
+#endif
diff --git a/svx/source/table/tablertfexporter.cxx b/svx/source/table/tablertfexporter.cxx
new file mode 100644
index 000000000000..d155e084fff8
--- /dev/null
+++ b/svx/source/table/tablertfexporter.cxx
@@ -0,0 +1,284 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <vector>
+
+#include <com/sun/star/table/XTable.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <tools/stream.hxx>
+#include <svtools/rtfkeywd.hxx>
+#include <svtools/rtfout.hxx>
+
+#include <editeng/eeitem.hxx>
+#include <svx/sdtaitm.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+
+#include "cell.hxx"
+#include "celltypes.hxx"
+#include "svx/svdotable.hxx"
+#include "svx/svdoutl.hxx"
+#include "editeng/editeng.hxx"
+#include "editeng/outlobj.hxx"
+
+//#include <tablertfexporter.hxx>
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+
+namespace sdr { namespace table {
+
+class SdrTableRtfExporter
+{
+public:
+ SdrTableRtfExporter( SvStream& rStrmP, SdrTableObj& rObj );
+ ULONG Write();
+ void WriteRow( const Reference< XPropertySet >& xRowSet, sal_Int32 nRow, const std::vector< sal_Int32 >& aColumnStart );
+ void WriteCell( sal_Int32 nCol, sal_Int32 nRow );
+
+private:
+ SvStream& mrStrm;
+ SdrTableObj& mrObj;
+ Reference< XTable > mxTable;
+ const OUString msSize;
+};
+
+void SdrTableObj::ExportAsRTF( SvStream& rStrm, SdrTableObj& rObj )
+{
+ SdrTableRtfExporter aEx( rStrm, rObj );
+ aEx.Write();
+}
+
+SdrTableRtfExporter::SdrTableRtfExporter( SvStream& rStrm, SdrTableObj& rObj )
+: mrStrm( rStrm )
+, mrObj( rObj )
+, mxTable( rObj.getTable() )
+, msSize( RTL_CONSTASCII_USTRINGPARAM("Size") )
+{
+}
+
+long HundMMToTwips( long nIn )
+{
+ long nRet = OutputDevice::LogicToLogic( nIn, MAP_100TH_MM, MAP_TWIP );
+ return nRet;
+}
+
+ULONG SdrTableRtfExporter::Write()
+{
+ mrStrm << '{' << OOO_STRING_SVTOOLS_RTF_RTF;
+ mrStrm << OOO_STRING_SVTOOLS_RTF_ANSI << RTFOutFuncs::sNewLine;
+
+ Reference< XTableColumns > xColumns( mxTable->getColumns() );
+ const sal_Int32 nColCount = xColumns->getCount();
+
+ std::vector< sal_Int32 > aColumnStart;
+ aColumnStart.reserve( nColCount );
+
+ // determine right offset of cells
+ sal_Int32 nPos = 0;
+ for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ ) try
+ {
+ Reference< XPropertySet > xSet( xColumns->getByIndex(nCol), UNO_QUERY_THROW );
+ sal_Int32 nWidth = 0;
+ xSet->getPropertyValue( msSize ) >>= nWidth;
+ nPos += HundMMToTwips( nWidth );
+ aColumnStart.push_back( nPos );
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR("SdrTableRtfExporter::Write(), exception caught!");
+ }
+
+ // export rows
+ Reference< XTableRows > xRows( mxTable->getRows() );
+ const sal_Int32 nRowCount = xRows->getCount();
+
+ for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ ) try
+ {
+ Reference< XPropertySet > xRowSet( xRows->getByIndex(nRow), UNO_QUERY_THROW );
+ WriteRow( xRowSet, nRow, aColumnStart );
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR("SdrTableRtfExporter::Write(), exception caught!");
+ }
+
+ mrStrm << '}' << RTFOutFuncs::sNewLine;
+ return mrStrm.GetError();
+}
+
+void SdrTableRtfExporter::WriteRow( const Reference< XPropertySet >& xRowSet, sal_Int32 nRow, const std::vector< sal_Int32 >& aColumnStart )
+{
+ sal_Int32 nRowHeight = 0;
+ xRowSet->getPropertyValue( msSize ) >>= nRowHeight;
+
+ mrStrm << OOO_STRING_SVTOOLS_RTF_TROWD << OOO_STRING_SVTOOLS_RTF_TRGAPH << "30" << OOO_STRING_SVTOOLS_RTF_TRLEFT << "-30";
+ mrStrm << OOO_STRING_SVTOOLS_RTF_TRRH << ByteString::CreateFromInt32( nRowHeight ).GetBuffer();
+
+ const sal_Int32 nColCount = mxTable->getColumnCount();
+ for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ )
+ {
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+
+ if( !xCell.is() )
+ continue;
+
+/*
+ const sal_Bool bIsMerged = xCell->isMerged();
+ const sal_Int32 nRowSpan = xCell->getRowSpan();
+ const sal_Int32 nColSpan = xCell->getColumnSpan();
+
+ const sal_Char* pChar;
+
+ if( !bIsMerged && ((nRowSpan > 1) || (nColSpan > 1)) )
+ mrStrm << OOO_STRING_SVTOOLS_RTF_CLMGF; // The first cell in a range of table cells to be merged.
+
+ SdrTextVertAdjust eVAdj = xCell->GetTextVerticalAdjust();
+ switch( eVAdj )
+ {
+ case SVX_VER_JUSTIFY_TOP: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALT; break;
+ case SVX_VER_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALC; break;
+ case SVX_VER_JUSTIFY_BOTTOM: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALB; break;
+ case SVX_VER_JUSTIFY_STANDARD: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALB; break; //! Bottom
+ default: pChar = NULL; break;
+ }
+ if ( pChar )
+ mrStrm << pChar;
+*/
+ mrStrm << OOO_STRING_SVTOOLS_RTF_CELLX << ByteString::CreateFromInt32( aColumnStart[nCol] ).GetBuffer();
+ if ( (nCol & 0x0F) == 0x0F )
+ mrStrm << RTFOutFuncs::sNewLine; // Zeilen nicht zu lang werden lassen
+ }
+ mrStrm << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_PLAIN << OOO_STRING_SVTOOLS_RTF_INTBL << RTFOutFuncs::sNewLine;
+
+ ULONG nStrmPos = mrStrm.Tell();
+ for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ )
+ {
+ WriteCell( nCol, nRow );
+ if ( mrStrm.Tell() - nStrmPos > 255 )
+ {
+ mrStrm << RTFOutFuncs::sNewLine;
+ nStrmPos = mrStrm.Tell();
+ }
+ }
+ mrStrm << OOO_STRING_SVTOOLS_RTF_ROW << RTFOutFuncs::sNewLine;
+}
+
+
+void SdrTableRtfExporter::WriteCell( sal_Int32 nCol, sal_Int32 nRow )
+{
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+
+ if( !xCell.is() || xCell->isMerged() )
+ {
+ mrStrm << OOO_STRING_SVTOOLS_RTF_CELL;
+ return ;
+ }
+
+ String aContent;
+
+ OutlinerParaObject* pParaObj = xCell->GetEditOutlinerParaObject();
+ bool bOwnParaObj = pParaObj != 0;
+
+ if( pParaObj == 0 )
+ pParaObj = xCell->GetOutlinerParaObject();
+
+ if(pParaObj)
+ {
+ // handle outliner attributes
+ SdrOutliner& rOutliner = mrObj.ImpGetDrawOutliner();
+ rOutliner.SetText(*pParaObj);
+
+ aContent = rOutliner.GetEditEngine().GetText( LINEEND_LF );
+
+ rOutliner.Clear();
+
+ if( bOwnParaObj )
+ delete pParaObj;
+ }
+
+ bool bResetPar, bResetAttr;
+ bResetPar = bResetAttr = FALSE;
+
+ SdrTextHorzAdjust eHAdj = xCell->GetTextHorizontalAdjust();
+
+ const SfxItemSet& rCellSet = xCell->GetItemSet();
+
+ const SvxWeightItem& rWeightItem = (const SvxWeightItem&) rCellSet.Get( EE_CHAR_WEIGHT );
+ const SvxPostureItem& rPostureItem = (const SvxPostureItem&) rCellSet.Get( EE_CHAR_ITALIC );
+ const SvxUnderlineItem& rUnderlineItem = (const SvxUnderlineItem&) rCellSet.Get( EE_CHAR_UNDERLINE );
+
+ const sal_Char* pChar;
+
+ switch( eHAdj )
+ {
+ case SDRTEXTHORZADJUST_CENTER: pChar = OOO_STRING_SVTOOLS_RTF_QC; break;
+ case SDRTEXTHORZADJUST_BLOCK: pChar = OOO_STRING_SVTOOLS_RTF_QJ; break;
+ case SDRTEXTHORZADJUST_RIGHT: pChar = OOO_STRING_SVTOOLS_RTF_QR; break;
+ case SDRTEXTHORZADJUST_LEFT:
+ default: pChar = OOO_STRING_SVTOOLS_RTF_QL; break;
+ }
+ mrStrm << pChar;
+
+ if ( rWeightItem.GetWeight() >= WEIGHT_BOLD )
+ { // bold
+ bResetAttr = true;
+ mrStrm << OOO_STRING_SVTOOLS_RTF_B;
+ }
+ if ( rPostureItem.GetPosture() != ITALIC_NONE )
+ { // italic
+ bResetAttr = true;
+ mrStrm << OOO_STRING_SVTOOLS_RTF_I;
+ }
+ if ( rUnderlineItem.GetLineStyle() != UNDERLINE_NONE )
+ { // underline
+ bResetAttr = true;
+ mrStrm << OOO_STRING_SVTOOLS_RTF_UL;
+ }
+
+ mrStrm << ' ';
+ RTFOutFuncs::Out_String( mrStrm, aContent );
+ mrStrm << OOO_STRING_SVTOOLS_RTF_CELL;
+
+ if ( bResetPar )
+ mrStrm << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_INTBL;
+ if ( bResetAttr )
+ mrStrm << OOO_STRING_SVTOOLS_RTF_PLAIN;
+}
+
+} }
+
diff --git a/svx/source/table/tablertfimporter.cxx b/svx/source/table/tablertfimporter.cxx
new file mode 100644
index 000000000000..359089444210
--- /dev/null
+++ b/svx/source/table/tablertfimporter.cxx
@@ -0,0 +1,447 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+#include <com/sun/star/table/XTable.hpp>
+
+#include <tools/stream.hxx>
+#include <svtools/rtftoken.h>
+
+#include <editeng/eeitem.hxx>
+#include <svx/svdetc.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/outlobj.hxx>
+
+#include "cell.hxx"
+#include "celltypes.hxx"
+#include "svx/svdotable.hxx"
+#include "svx/svdoutl.hxx"
+#include "editeng/editeng.hxx"
+#include "editeng/editdata.hxx"
+#include "svx/svdmodel.hxx"
+#include "editeng/svxrtf.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+
+namespace sdr { namespace table {
+
+struct RTFCellDefault
+{
+ SfxItemSet maItemSet;
+ sal_Int32 mnCol;
+ USHORT mnTwips; // right border of the cell
+ sal_Int32 mnColSpan; // MergeCell if >1, merged cells if 0
+
+ RTFCellDefault( SfxItemPool* pPool ) : maItemSet( *pPool ), mnCol(0), mnTwips(0 ), mnColSpan(1) {}
+};
+
+typedef std::vector< boost::shared_ptr< RTFCellDefault > > RTFCellDefaultVector;
+
+struct RTFCellInfo
+{
+ SfxItemSet maItemSet;
+ sal_Int32 mnStartPara;
+ sal_Int32 mnParaCount;
+ sal_Int32 mnColSpan;
+
+ RTFCellInfo( SfxItemPool& rPool ) : maItemSet( rPool ), mnStartPara(0), mnParaCount(0), mnColSpan(0) {}
+};
+
+typedef boost::shared_ptr< RTFCellInfo > RTFCellInfoPtr;
+typedef std::vector< RTFCellInfoPtr > RTFColumnVector;
+
+typedef boost::shared_ptr< RTFColumnVector > RTFColumnVectorPtr;
+
+typedef std::vector< RTFColumnVectorPtr > RTFRowVector;
+
+class SdrTableRTFParser
+{
+public:
+ SdrTableRTFParser( SdrTableObj& rTableObj );
+ ~SdrTableRTFParser();
+
+ void Read( SvStream& rStream );
+
+ void ProcToken( ImportInfo* pInfo );
+
+ void NextRow();
+ void NextColumn();
+ void NewCellRow();
+
+ void InsertCell( ImportInfo* pInfo );
+
+ void FillTable();
+
+ DECL_LINK( RTFImportHdl, ImportInfo* );
+
+private:
+ SdrTableObj& mrTableObj;
+ SdrOutliner* mpOutliner;
+ SfxItemPool& mrItemPool;
+
+ RTFCellDefaultVector maDefaultList;
+ RTFCellDefaultVector::iterator maDefaultIterator;
+
+ int mnLastToken;
+ sal_Int32 mnLastWidth;
+ bool mbNewDef;
+
+ USHORT mnStartPara;
+
+ sal_Int32 mnColCnt;
+ sal_Int32 mnRowCnt;
+ sal_Int32 mnColMax;
+
+ std::vector< sal_Int32 > maColumnEdges;
+
+ RTFRowVector maRows;
+
+ RTFCellDefault* mpInsDefault;
+ RTFCellDefault* mpActDefault;
+ RTFCellDefault* mpDefMerge;
+
+ Reference< XTable > mxTable;
+};
+
+SdrTableRTFParser::SdrTableRTFParser( SdrTableObj& rTableObj )
+: mrTableObj( rTableObj )
+, mpOutliner( SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, rTableObj.GetModel() ) )
+, mrItemPool( rTableObj.GetModel()->GetItemPool() )
+, mnLastToken( 0 )
+, mnLastWidth( 0 )
+, mbNewDef( false )
+, mnStartPara( 0 )
+, mnColCnt( 0 )
+, mnRowCnt( 0 )
+, mnColMax( 0 )
+, mpActDefault( 0 )
+, mpDefMerge( 0 )
+, mxTable( rTableObj.getTable() )
+{
+ mpOutliner->SetUpdateMode(TRUE);
+ mpOutliner->SetStyleSheet( 0, mrTableObj.GetStyleSheet() );
+ mpInsDefault = new RTFCellDefault( &mrItemPool );
+}
+
+SdrTableRTFParser::~SdrTableRTFParser()
+{
+ delete mpOutliner;
+ delete mpInsDefault;
+}
+
+void SdrTableRTFParser::Read( SvStream& rStream )
+{
+ EditEngine& rEdit = const_cast< EditEngine& >( mpOutliner->GetEditEngine() );
+
+ Link aOldLink( rEdit.GetImportHdl() );
+ rEdit.SetImportHdl( LINK( this, SdrTableRTFParser, RTFImportHdl ) );
+ mpOutliner->Read( rStream, String(), EE_FORMAT_RTF );
+ rEdit.SetImportHdl( aOldLink );
+
+ FillTable();
+}
+
+IMPL_LINK( SdrTableRTFParser, RTFImportHdl, ImportInfo*, pInfo )
+{
+ switch ( pInfo->eState )
+ {
+ case RTFIMP_NEXTTOKEN:
+ ProcToken( pInfo );
+ break;
+ case RTFIMP_UNKNOWNATTR:
+ ProcToken( pInfo );
+ break;
+ case RTFIMP_START:
+ {
+ SvxRTFParser* pParser = (SvxRTFParser*) pInfo->pParser;
+ pParser->SetAttrPool( &mrItemPool );
+ RTFPardAttrMapIds& rMap = pParser->GetPardMap();
+ rMap.nBox = SDRATTR_TABLE_BORDER;
+ }
+ break;
+ case RTFIMP_END:
+ if ( pInfo->aSelection.nEndPos )
+ {
+ mpActDefault = NULL;
+ pInfo->nToken = RTF_PAR;
+ pInfo->aSelection.nEndPara++;
+ ProcToken( pInfo );
+ }
+ break;
+ case RTFIMP_SETATTR:
+ break;
+ case RTFIMP_INSERTTEXT:
+ break;
+ case RTFIMP_INSERTPARA:
+ break;
+ default:
+ DBG_ERRORFILE("unknown ImportInfo.eState");
+ }
+ return 0;
+}
+
+void SdrTableRTFParser::NextRow()
+{
+ ++mnRowCnt;
+}
+
+void SdrTableRTFParser::InsertCell( ImportInfo* pInfo )
+{
+ sal_Int32 nCol = mpActDefault->mnCol;
+
+ RTFCellInfoPtr xCellInfo( new RTFCellInfo(mrItemPool) );
+
+ xCellInfo->mnStartPara = mnStartPara;
+ xCellInfo->mnParaCount = pInfo->aSelection.nEndPara - 1 - mnStartPara;
+
+ if( !maRows.empty() )
+ {
+ RTFColumnVectorPtr xColumn( maRows.back() );
+
+ if( xColumn->size() <= (size_t)nCol )
+ xColumn->resize( nCol+1 );
+
+ (*xColumn)[nCol] = xCellInfo;
+ }
+
+ mnStartPara = pInfo->aSelection.nEndPara - 1;
+}
+
+void SdrTableRTFParser::FillTable()
+{
+ try
+ {
+ sal_Int32 nColCount = mxTable->getColumnCount();
+ Reference< XTableColumns > xCols( mxTable->getColumns(), UNO_QUERY_THROW );
+
+ if( nColCount < mnColMax )
+ {
+ xCols->insertByIndex( nColCount, mnColMax - nColCount );
+ nColCount = mxTable->getColumnCount();
+ }
+
+ const OUString sWidth( RTL_CONSTASCII_USTRINGPARAM("Width") );
+ sal_Int32 nCol, nLastEdge = 0;
+ for( nCol = 0; nCol < nColCount; nCol++ )
+ {
+ Reference< XPropertySet > xSet( xCols->getByIndex( nCol ), UNO_QUERY_THROW );
+ sal_Int32 nWidth = maColumnEdges[nCol] - nLastEdge;
+
+ xSet->setPropertyValue( sWidth, Any( nWidth ) );
+ nLastEdge += nWidth;
+ }
+
+ const sal_Int32 nRowCount = mxTable->getRowCount();
+ if( nRowCount < mnRowCnt )
+ {
+ Reference< XTableRows > xRows( mxTable->getRows(), UNO_QUERY_THROW );
+ xRows->insertByIndex( nRowCount, mnRowCnt - nRowCount );
+ }
+
+ for( sal_Int32 nRow = 0; nRow < (sal_Int32)maRows.size(); nRow++ )
+ {
+ RTFColumnVectorPtr xColumn( maRows[nRow] );
+ for( nCol = 0; nCol < (sal_Int32)xColumn->size(); nCol++ )
+ {
+ RTFCellInfoPtr xCellInfo( (*xColumn)[nCol] );
+
+ CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
+ if( xCell.is() && xCellInfo.get() )
+ {
+ const SfxPoolItem *pPoolItem = 0;
+ if( xCellInfo->maItemSet.GetItemState(SDRATTR_TABLE_BORDER,FALSE,&pPoolItem)==SFX_ITEM_SET)
+ xCell->SetMergedItem( *pPoolItem );
+
+ String sDebug = mpOutliner->GetText( mpOutliner->GetParagraph( xCellInfo->mnStartPara ), xCellInfo->mnParaCount );
+
+ OutlinerParaObject* pTextObject = mpOutliner->CreateParaObject( (USHORT)xCellInfo->mnStartPara, (USHORT)xCellInfo->mnParaCount );
+ if( pTextObject )
+ {
+ SdrOutliner& rOutliner=mrTableObj.ImpGetDrawOutliner();
+ rOutliner.SetUpdateMode(TRUE);
+ rOutliner.SetText( *pTextObject );
+ mrTableObj.NbcSetOutlinerParaObjectForText( rOutliner.CreateParaObject(), xCell.get() );
+ delete pTextObject;
+ }
+ }
+ }
+ }
+
+ Rectangle aRect( mrTableObj.GetSnapRect() );
+ aRect.nRight = aRect.nLeft + nLastEdge;
+ mrTableObj.NbcSetSnapRect( aRect );
+
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ DBG_ERROR("sdr::table::SdrTableRTFParser::InsertCell(), exception caught!" );
+ }
+}
+
+void SdrTableRTFParser::NewCellRow()
+{
+ if( mbNewDef )
+ {
+ mbNewDef = FALSE;
+
+ maRows.push_back( RTFColumnVectorPtr( new RTFColumnVector() ) );
+ }
+ mpDefMerge = NULL;
+ maDefaultIterator = maDefaultList.begin();
+
+ NextColumn();
+
+ DBG_ASSERT( mpActDefault, "NewCellRow: pActDefault==0" );
+}
+
+void SdrTableRTFParser::NextColumn()
+{
+ if( maDefaultIterator != maDefaultList.end() )
+ mpActDefault = (*maDefaultIterator++).get();
+ else
+ mpActDefault = 0;
+}
+
+long TwipsToHundMM( long nIn )
+{
+ long nRet = OutputDevice::LogicToLogic( nIn, MAP_TWIP, MAP_100TH_MM );
+ return nRet;
+}
+
+void SdrTableRTFParser::ProcToken( ImportInfo* pInfo )
+{
+ switch ( pInfo->nToken )
+ {
+ case RTF_TROWD: // denotes table row defauls, before RTF_CELLX
+ {
+ mnColCnt = 0;
+ maDefaultList.clear();
+ mpDefMerge = NULL;
+ mnLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_CLMGF: // The first cell of cells to be merged
+ {
+ mpDefMerge = mpInsDefault;
+ mnLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_CLMRG: // A cell to be merged with the preceding cell
+ {
+ if ( !mpDefMerge )
+ mpDefMerge = maDefaultList.back().get();
+ DBG_ASSERT( mpDefMerge, "RTF_CLMRG: pDefMerge==0" );
+ if( mpDefMerge )
+ mpDefMerge->mnColSpan++;
+ mpInsDefault->mnColSpan = 0;
+ mnLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_CELLX: // closes cell default
+ {
+ mbNewDef = TRUE;
+ mpInsDefault->mnCol = mnColCnt;
+ maDefaultList.push_back( boost::shared_ptr< RTFCellDefault >( mpInsDefault ) );
+
+ if( (sal_Int32)maColumnEdges.size() <= mnColCnt )
+ maColumnEdges.resize( mnColCnt + 1 );
+
+ const sal_Int32 nSize = TwipsToHundMM( pInfo->nTokenValue );
+ maColumnEdges[mnColCnt] = std::max( maColumnEdges[mnColCnt], nSize );
+
+ mpInsDefault = new RTFCellDefault( &mrItemPool );
+ if ( ++mnColCnt > mnColMax )
+ mnColMax = mnColCnt;
+ mnLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_INTBL: // before the first RTF_CELL
+ {
+ if ( mnLastToken != RTF_INTBL && mnLastToken != RTF_CELL && mnLastToken != RTF_PAR )
+ {
+ NewCellRow();
+ mnLastToken = pInfo->nToken;
+ }
+ }
+ break;
+ case RTF_CELL: // denotes the end of a cell.
+ {
+ DBG_ASSERT( mpActDefault, "RTF_CELL: pActDefault==0" );
+ if ( mbNewDef || !mpActDefault )
+ NewCellRow();
+ if ( !mpActDefault )
+ mpActDefault = mpInsDefault;
+ if ( mpActDefault->mnColSpan > 0 )
+ {
+ InsertCell(pInfo);
+ }
+ NextColumn();
+ mnLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_ROW: // means the end of a row
+ {
+ NextRow();
+ mnLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_PAR: // Paragraph
+ mnLastToken = pInfo->nToken;
+ break;
+ default:
+ { // do not set nLastToken
+ switch ( pInfo->nToken & ~(0xff | RTF_TABLEDEF) )
+ {
+ case RTF_SHADINGDEF:
+// ((SvxRTFParser*)pInfo->pParser)->ReadBackgroundAttr(pInfo->nToken, mpInsDefault->maItemSet, TRUE );
+ break;
+ case RTF_BRDRDEF:
+ ((SvxRTFParser*)pInfo->pParser)->ReadBorderAttr(pInfo->nToken, mpInsDefault->maItemSet, TRUE );
+ break;
+ }
+ }
+ }
+}
+
+void SdrTableObj::ImportAsRTF( SvStream& rStream, SdrTableObj& rObj )
+{
+ SdrTableRTFParser aParser( rObj );
+ aParser.Read( rStream );
+}
+
+} }
+
diff --git a/svx/source/table/tableundo.cxx b/svx/source/table/tableundo.cxx
new file mode 100644
index 000000000000..d57be9f0994d
--- /dev/null
+++ b/svx/source/table/tableundo.cxx
@@ -0,0 +1,559 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "svx/sdr/properties/textproperties.hxx"
+#include "editeng/outlobj.hxx"
+
+#include "cell.hxx"
+#include "tableundo.hxx"
+#include "svx/svdotable.hxx"
+#include "tablerow.hxx"
+#include "tablecolumn.hxx"
+
+
+// -----------------------------------------------------------------------------
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::table;
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+CellUndo::CellUndo( const SdrObjectWeakRef& xObjRef, const CellRef& xCell )
+: SdrUndoAction( *xCell->GetModel() )
+, mxObjRef( xObjRef )
+, mxCell( xCell )
+, mbUndo( true )
+{
+ if( mxCell.is() && mxObjRef.is() )
+ {
+ getDataFromCell( maUndoData );
+ mxObjRef->AddObjectUser( *this );
+ }
+}
+
+CellUndo::~CellUndo()
+{
+ if( mxObjRef.is() )
+ mxObjRef->RemoveObjectUser( *this );
+ dispose();
+}
+
+void CellUndo::dispose()
+{
+ mxCell.clear();
+ delete maUndoData.mpProperties;
+ maUndoData.mpProperties = 0;
+ delete maRedoData.mpProperties;
+ maRedoData.mpProperties = 0;
+ delete maUndoData.mpOutlinerParaObject;
+ maUndoData.mpOutlinerParaObject = 0;
+ delete maRedoData.mpOutlinerParaObject;
+ maRedoData.mpOutlinerParaObject = 0;
+}
+
+void CellUndo::ObjectInDestruction(const SdrObject& )
+{
+ dispose();
+}
+
+void CellUndo::Undo()
+{
+ if( mxCell.is() && mbUndo )
+ {
+ if( maRedoData.mpProperties == 0 )
+ getDataFromCell( maRedoData );
+
+ setDataToCell( maUndoData );
+ mbUndo = false;
+ }
+}
+
+void CellUndo::Redo()
+{
+ if( mxCell.is() && !mbUndo )
+ {
+ setDataToCell( maRedoData );
+ mbUndo = true;
+ }
+}
+
+BOOL CellUndo::Merge( SfxUndoAction *pNextAction )
+{
+ CellUndo* pNext = dynamic_cast< CellUndo* >( pNextAction );
+ if( pNext && pNext->mxCell.get() == mxCell.get() )
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+void CellUndo::setDataToCell( const Data& rData )
+{
+ delete mxCell->mpProperties;
+ if( rData.mpProperties )
+ mxCell->mpProperties = Cell::CloneProperties( rData.mpProperties, *mxObjRef.get(), *mxCell.get() );
+ else
+ mxCell->mpProperties = 0;
+
+ if( rData.mpOutlinerParaObject )
+ mxCell->SetOutlinerParaObject( new OutlinerParaObject(*rData.mpOutlinerParaObject) );
+ else
+ mxCell->RemoveOutlinerParaObject();
+
+ mxCell->msFormula = rData.msFormula;
+ mxCell->mfValue = rData.mfValue;
+ mxCell->mnError = rData.mnError;
+ mxCell->mbMerged = rData.mbMerged;
+ mxCell->mnRowSpan = rData.mnRowSpan;
+ mxCell->mnColSpan = rData.mnColSpan;
+
+ if( mxObjRef.is() )
+ mxObjRef->ActionChanged();
+}
+
+void CellUndo::getDataFromCell( Data& rData )
+{
+ if( mxObjRef.is() && mxCell.is() )
+ {
+ if( mxCell->mpProperties )
+ rData.mpProperties = mxCell->CloneProperties( *mxObjRef.get(), *mxCell.get());
+
+ if( mxCell->GetOutlinerParaObject() )
+ rData.mpOutlinerParaObject = new OutlinerParaObject(*mxCell->GetOutlinerParaObject());
+ else
+ rData.mpOutlinerParaObject = 0;
+
+ rData.mnCellContentType = mxCell->mnCellContentType;
+
+ rData.msFormula = mxCell->msFormula;
+ rData.mfValue = mxCell->mfValue;
+ rData.mnError = mxCell->mnError;
+ rData.mbMerged = mxCell->mbMerged;
+ rData.mnRowSpan = mxCell->mnRowSpan;
+ rData.mnColSpan = mxCell->mnColSpan;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// class InsertRowUndo : public SdrUndoAction
+// -----------------------------------------------------------------------------
+
+static void Dispose( RowVector& rRows )
+{
+ RowVector::iterator aIter( rRows.begin() );
+ while( aIter != rRows.end() )
+ (*aIter++)->dispose();
+}
+
+// -----------------------------------------------------------------------------
+
+InsertRowUndo::InsertRowUndo( const TableModelRef& xTable, sal_Int32 nIndex, RowVector& aNewRows )
+: SdrUndoAction( *xTable->getSdrTableObj()->GetModel() )
+, mxTable( xTable )
+, mnIndex( nIndex )
+, mbUndo( true )
+{
+ maRows.swap( aNewRows );
+}
+
+// -----------------------------------------------------------------------------
+
+InsertRowUndo::~InsertRowUndo()
+{
+ if( !mbUndo )
+ Dispose( maRows );
+}
+
+// -----------------------------------------------------------------------------
+
+void InsertRowUndo::Undo()
+{
+ if( mxTable.is() )
+ {
+ mxTable->UndoInsertRows( mnIndex, sal::static_int_cast< sal_Int32 >( maRows.size() ) );
+ mbUndo = false;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void InsertRowUndo::Redo()
+{
+ if( mxTable.is() )
+ {
+ mxTable->UndoRemoveRows( mnIndex, maRows );
+ mbUndo = true;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// class RemoveRowUndo : public SdrUndoAction
+// -----------------------------------------------------------------------------
+
+RemoveRowUndo::RemoveRowUndo( const TableModelRef& xTable, sal_Int32 nIndex, RowVector& aRemovedRows )
+: SdrUndoAction( *xTable->getSdrTableObj()->GetModel() )
+, mxTable( xTable )
+, mnIndex( nIndex )
+, mbUndo( true )
+{
+ maRows.swap( aRemovedRows );
+}
+
+// -----------------------------------------------------------------------------
+
+RemoveRowUndo::~RemoveRowUndo()
+{
+ if( mbUndo )
+ Dispose( maRows );
+}
+
+// -----------------------------------------------------------------------------
+
+void RemoveRowUndo::Undo()
+{
+ if( mxTable.is() )
+ {
+ mxTable->UndoRemoveRows( mnIndex, maRows );
+ mbUndo = false;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void RemoveRowUndo::Redo()
+{
+ if( mxTable.is() )
+ {
+ mxTable->UndoInsertRows( mnIndex, sal::static_int_cast< sal_Int32 >( maRows.size() ) );
+ mbUndo = true;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// class InsertColUndo : public SdrUndoAction
+// -----------------------------------------------------------------------------
+
+static void Dispose( ColumnVector& rCols )
+{
+ ColumnVector::iterator aIter( rCols.begin() );
+ while( aIter != rCols.end() )
+ (*aIter++)->dispose();
+}
+
+// -----------------------------------------------------------------------------
+
+static void Dispose( CellVector& rCells )
+{
+ CellVector::iterator aIter( rCells.begin() );
+ while( aIter != rCells.end() )
+ (*aIter++)->dispose();
+}
+
+// -----------------------------------------------------------------------------
+
+InsertColUndo::InsertColUndo( const TableModelRef& xTable, sal_Int32 nIndex, ColumnVector& aNewCols, CellVector& aCells )
+: SdrUndoAction( *xTable->getSdrTableObj()->GetModel() )
+, mxTable( xTable )
+, mnIndex( nIndex )
+, mbUndo( true )
+{
+ maColumns.swap( aNewCols );
+ maCells.swap( aCells );
+}
+
+// -----------------------------------------------------------------------------
+
+InsertColUndo::~InsertColUndo()
+{
+ if( !mbUndo )
+ {
+ Dispose( maColumns );
+ Dispose( maCells );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void InsertColUndo::Undo()
+{
+ if( mxTable.is() )
+ {
+ mxTable->UndoInsertColumns( mnIndex, sal::static_int_cast< sal_Int32 >( maColumns.size() ) );
+ mbUndo = false;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void InsertColUndo::Redo()
+{
+ if( mxTable.is() )
+ {
+ mxTable->UndoRemoveColumns( mnIndex, maColumns, maCells );
+ mbUndo = true;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// class RemoveColUndo : public SdrUndoAction
+// -----------------------------------------------------------------------------
+
+RemoveColUndo::RemoveColUndo( const TableModelRef& xTable, sal_Int32 nIndex, ColumnVector& aNewCols, CellVector& aCells )
+: SdrUndoAction( *xTable->getSdrTableObj()->GetModel() )
+, mxTable( xTable )
+, mnIndex( nIndex )
+, mbUndo( true )
+{
+ maColumns.swap( aNewCols );
+ maCells.swap( aCells );
+}
+
+// -----------------------------------------------------------------------------
+
+RemoveColUndo::~RemoveColUndo()
+{
+ if( mbUndo )
+ {
+ Dispose( maColumns );
+ Dispose( maCells );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void RemoveColUndo::Undo()
+{
+ if( mxTable.is() )
+ {
+ mxTable->UndoRemoveColumns( mnIndex, maColumns, maCells );
+ mbUndo = false;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void RemoveColUndo::Redo()
+{
+ if( mxTable.is() )
+ {
+ mxTable->UndoInsertColumns( mnIndex, sal::static_int_cast< sal_Int32 >( maColumns.size() ) );
+ mbUndo = true;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// class TableColumnUndo : public SdrUndoAction
+// -----------------------------------------------------------------------------
+
+TableColumnUndo::TableColumnUndo( const TableColumnRef& xCol )
+: SdrUndoAction( *xCol->mxTableModel->getSdrTableObj()->GetModel() )
+, mxCol( xCol )
+, mbHasRedoData( false )
+{
+ getData( maUndoData );
+}
+
+// -----------------------------------------------------------------------------
+
+TableColumnUndo::~TableColumnUndo()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void TableColumnUndo::Undo()
+{
+ if( !mbHasRedoData )
+ {
+ getData( maRedoData );
+ mbHasRedoData = true;
+ }
+ setData( maUndoData );
+}
+
+// -----------------------------------------------------------------------------
+
+void TableColumnUndo::Redo()
+{
+ setData( maRedoData );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL TableColumnUndo::Merge( SfxUndoAction *pNextAction )
+{
+ TableColumnUndo* pNext = dynamic_cast< TableColumnUndo* >( pNextAction );
+ return pNext && pNext->mxCol == mxCol;
+}
+
+// -----------------------------------------------------------------------------
+
+void TableColumnUndo::setData( const Data& rData )
+{
+ mxCol->mnColumn = rData.mnColumn;
+ mxCol->mnWidth = rData.mnWidth;
+ mxCol->mbOptimalWidth = rData.mbOptimalWidth;
+ mxCol->mbIsVisible = rData.mbIsVisible;
+ mxCol->mbIsStartOfNewPage = rData.mbIsStartOfNewPage;
+ mxCol->maName = rData.maName;
+}
+
+// -----------------------------------------------------------------------------
+
+void TableColumnUndo::getData( Data& rData )
+{
+ rData.mnColumn = mxCol->mnColumn;
+ rData.mnWidth = mxCol->mnWidth;
+ rData.mbOptimalWidth = mxCol->mbOptimalWidth;
+ rData.mbIsVisible = mxCol->mbIsVisible;
+ rData.mbIsStartOfNewPage = mxCol->mbIsStartOfNewPage;
+ rData.maName = mxCol->maName;
+}
+
+// -----------------------------------------------------------------------------
+// class TableRowUndo : public SdrUndoAction
+// -----------------------------------------------------------------------------
+
+TableRowUndo::TableRowUndo( const TableRowRef& xRow )
+: SdrUndoAction( *xRow->mxTableModel->getSdrTableObj()->GetModel() )
+, mxRow( xRow )
+, mbHasRedoData( false )
+{
+ getData( maUndoData );
+}
+
+// -----------------------------------------------------------------------------
+
+TableRowUndo::~TableRowUndo()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void TableRowUndo::Undo()
+{
+ if( !mbHasRedoData )
+ {
+ getData( maRedoData );
+ mbHasRedoData = true;
+ }
+ setData( maUndoData );
+}
+
+// -----------------------------------------------------------------------------
+
+void TableRowUndo::Redo()
+{
+ setData( maRedoData );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL TableRowUndo::Merge( SfxUndoAction *pNextAction )
+{
+ TableRowUndo* pNext = dynamic_cast< TableRowUndo* >( pNextAction );
+ return pNext && pNext->mxRow == mxRow;
+}
+
+// -----------------------------------------------------------------------------
+
+void TableRowUndo::setData( const Data& rData )
+{
+ mxRow->mnRow = rData.mnRow;
+ mxRow->mnHeight = rData.mnHeight;
+ mxRow->mbOptimalHeight = rData.mbOptimalHeight;
+ mxRow->mbIsVisible = rData.mbIsVisible;
+ mxRow->mbIsStartOfNewPage = rData.mbIsStartOfNewPage;
+ mxRow->maName = rData.maName;
+ }
+
+// -----------------------------------------------------------------------------
+
+void TableRowUndo::getData( Data& rData )
+{
+ rData.mnRow = mxRow->mnRow;
+ rData.mnHeight = mxRow->mnHeight;
+ rData.mbOptimalHeight = mxRow->mbOptimalHeight;
+ rData.mbIsVisible = mxRow->mbIsVisible;
+ rData.mbIsStartOfNewPage = mxRow->mbIsStartOfNewPage;
+ rData.maName = mxRow->maName;
+}
+
+// -----------------------------------------------------------------------------
+
+TableStyleUndo::TableStyleUndo( const SdrTableObj& rTableObj )
+: SdrUndoAction( *rTableObj.GetModel() )
+, mxObjRef( const_cast< sdr::table::SdrTableObj*>( &rTableObj ) )
+{
+ getData( maUndoData );
+}
+
+void TableStyleUndo::Undo()
+{
+ if( !mbHasRedoData )
+ {
+ getData( maRedoData );
+ mbHasRedoData = true;
+ }
+ setData( maUndoData );
+}
+
+void TableStyleUndo::Redo()
+{
+ setData( maRedoData );
+}
+
+void TableStyleUndo::setData( const Data& rData )
+{
+ SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxObjRef.get() );
+ if( pTableObj )
+ {
+ pTableObj->setTableStyle( rData.mxTableStyle );
+ pTableObj->setTableStyleSettings( rData.maSettings );
+ }
+}
+
+void TableStyleUndo::getData( Data& rData )
+{
+ SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxObjRef.get() );
+ if( pTableObj )
+ {
+ rData.maSettings = pTableObj->getTableStyleSettings();
+ rData.mxTableStyle = pTableObj->getTableStyle();
+ }
+}
+
+} }
diff --git a/svx/source/table/tableundo.hxx b/svx/source/table/tableundo.hxx
new file mode 100644
index 000000000000..8bf00c4b0d98
--- /dev/null
+++ b/svx/source/table/tableundo.hxx
@@ -0,0 +1,259 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVX_TABLEUNDO_HXX_
+#define _SVX_TABLEUNDO_HXX_
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/table/CellContentType.hpp>
+
+#include "svx/svdotable.hxx"
+#include "svx/svdobj.hxx"
+#include "svx/svdundo.hxx"
+
+#include "celltypes.hxx"
+
+namespace sdr { namespace properties {
+ class TextProperties;
+} }
+
+class OutlinerParaObject;
+
+// -----------------------------------------------------------------------------
+
+namespace sdr { namespace table {
+
+class CellUndo : public SdrUndoAction, public sdr::ObjectUser
+{
+public:
+ CellUndo( const SdrObjectWeakRef& xObjRef, const CellRef& xCell );
+ virtual ~CellUndo();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual BOOL Merge( SfxUndoAction *pNextAction );
+
+ void dispose();
+ virtual void ObjectInDestruction(const SdrObject& rObject);
+
+private:
+ struct Data
+ {
+ sdr::properties::TextProperties* mpProperties;
+ OutlinerParaObject* mpOutlinerParaObject;
+
+ ::com::sun::star::table::CellContentType mnCellContentType;
+
+ ::rtl::OUString msFormula;
+ double mfValue;
+ ::sal_Int32 mnError;
+ ::sal_Bool mbMerged;
+ ::sal_Int32 mnRowSpan;
+ ::sal_Int32 mnColSpan;
+
+ Data() : mpProperties(0), mpOutlinerParaObject(0) {};
+ };
+
+ void setDataToCell( const Data& rData );
+ void getDataFromCell( Data& rData );
+
+ SdrObjectWeakRef mxObjRef;
+ CellRef mxCell;
+ Data maUndoData;
+ Data maRedoData;
+ bool mbUndo;
+};
+
+// -----------------------------------------------------------------------------
+
+class InsertRowUndo : public SdrUndoAction
+{
+public:
+ InsertRowUndo( const TableModelRef& xTable, sal_Int32 nIndex, RowVector& aNewRows );
+ virtual ~InsertRowUndo();
+
+ virtual void Undo();
+ virtual void Redo();
+
+private:
+ TableModelRef mxTable;
+ sal_Int32 mnIndex;
+ RowVector maRows;
+ bool mbUndo;
+};
+
+// -----------------------------------------------------------------------------
+
+class RemoveRowUndo : public SdrUndoAction
+{
+public:
+ RemoveRowUndo( const TableModelRef& xTable, sal_Int32 nIndex, RowVector& aRemovedRows );
+ virtual ~RemoveRowUndo();
+
+ virtual void Undo();
+ virtual void Redo();
+
+private:
+ TableModelRef mxTable;
+ sal_Int32 mnIndex;
+ RowVector maRows;
+ bool mbUndo;
+};
+
+// -----------------------------------------------------------------------------
+
+class InsertColUndo : public SdrUndoAction
+{
+public:
+ InsertColUndo( const TableModelRef& xTable, sal_Int32 nIndex, ColumnVector& aNewCols, CellVector& aCells );
+ virtual ~InsertColUndo();
+
+ virtual void Undo();
+ virtual void Redo();
+
+private:
+ TableModelRef mxTable;
+ sal_Int32 mnIndex;
+ ColumnVector maColumns;
+ CellVector maCells;
+ bool mbUndo;
+};
+
+// -----------------------------------------------------------------------------
+
+class RemoveColUndo : public SdrUndoAction
+{
+public:
+ RemoveColUndo( const TableModelRef& xTable, sal_Int32 nIndex, ColumnVector& aNewCols, CellVector& aCells );
+ virtual ~RemoveColUndo();
+
+ virtual void Undo();
+ virtual void Redo();
+
+private:
+ TableModelRef mxTable;
+ sal_Int32 mnIndex;
+ ColumnVector maColumns;
+ CellVector maCells;
+ bool mbUndo;
+};
+
+// -----------------------------------------------------------------------------
+
+class TableColumnUndo : public SdrUndoAction
+{
+public:
+ TableColumnUndo( const TableColumnRef& xCol );
+ virtual ~TableColumnUndo();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual BOOL Merge( SfxUndoAction *pNextAction );
+
+private:
+ struct Data
+ {
+ sal_Int32 mnColumn;
+ sal_Int32 mnWidth;
+ sal_Bool mbOptimalWidth;
+ sal_Bool mbIsVisible;
+ sal_Bool mbIsStartOfNewPage;
+ ::rtl::OUString maName;
+ };
+
+ void setData( const Data& rData );
+ void getData( Data& rData );
+
+ TableColumnRef mxCol;
+ Data maUndoData;
+ Data maRedoData;
+ bool mbHasRedoData;
+};
+
+// -----------------------------------------------------------------------------
+
+class TableRowUndo : public SdrUndoAction
+{
+public:
+ TableRowUndo( const TableRowRef& xRow );
+ virtual ~TableRowUndo();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual BOOL Merge( SfxUndoAction *pNextAction );
+
+private:
+ struct Data
+ {
+ CellVector maCells;
+ sal_Int32 mnRow;
+ sal_Int32 mnHeight;
+ sal_Bool mbOptimalHeight;
+ sal_Bool mbIsVisible;
+ sal_Bool mbIsStartOfNewPage;
+ ::rtl::OUString maName;
+ };
+
+ void setData( const Data& rData );
+ void getData( Data& rData );
+
+ TableRowRef mxRow;
+ Data maUndoData;
+ Data maRedoData;
+ bool mbHasRedoData;
+};
+
+// -----------------------------------------------------------------------------
+
+class TableStyleUndo : public SdrUndoAction
+{
+public:
+ TableStyleUndo( const SdrTableObj& rTableObj );
+
+ virtual void Undo();
+ virtual void Redo();
+
+private:
+ SdrObjectWeakRef mxObjRef;
+
+ struct Data
+ {
+ TableStyleSettings maSettings;
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > mxTableStyle;
+ };
+
+ void setData( const Data& rData );
+ void getData( Data& rData );
+
+ Data maUndoData;
+ Data maRedoData;
+ bool mbHasRedoData;
+};
+
+} }
+
+#endif
diff --git a/svx/source/table/viewcontactoftableobj.cxx b/svx/source/table/viewcontactoftableobj.cxx
new file mode 100644
index 000000000000..63d1066e7149
--- /dev/null
+++ b/svx/source/table/viewcontactoftableobj.cxx
@@ -0,0 +1,736 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "viewcontactoftableobj.hxx"
+#include <svx/svdotable.hxx>
+#include <com/sun/star/table/XTable.hpp>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <svx/sdr/primitive2d/sdrattributecreator.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
+#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx>
+#include <svx/sdr/primitive2d/sdrattributecreator.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <svx/sdr/attribute/sdrtextattribute.hxx>
+#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx>
+#include <editeng/borderline.hxx>
+#include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
+#include <svx/sdr/attribute/sdrfilltextattribute.hxx>
+#include <drawinglayer/attribute/sdrlineattribute.hxx>
+#include <drawinglayer/attribute/sdrshadowattribute.hxx>
+#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
+#include "cell.hxx"
+#include "tablelayouter.hxx"
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ class SdrCellPrimitive2D : public BufferedDecompositionPrimitive2D
+ {
+ private:
+ basegfx::B2DHomMatrix maTransform;
+ attribute::SdrFillTextAttribute maSdrFTAttribute;
+
+ protected:
+ // local decomposition.
+ virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const;
+
+ public:
+ SdrCellPrimitive2D(
+ const basegfx::B2DHomMatrix& rTransform,
+ const attribute::SdrFillTextAttribute& rSdrFTAttribute)
+ : BufferedDecompositionPrimitive2D(),
+ maTransform(rTransform),
+ maSdrFTAttribute(rSdrFTAttribute)
+ {
+ }
+
+ // data access
+ const basegfx::B2DHomMatrix& getTransform() const { return maTransform; }
+ const attribute::SdrFillTextAttribute& getSdrFTAttribute() const { return maSdrFTAttribute; }
+
+ // compare operator
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
+
+ // provide unique ID
+ DeclPrimitrive2DIDBlock()
+ };
+
+ Primitive2DSequence SdrCellPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const
+ {
+ // prepare unit polygon
+ Primitive2DSequence aRetval;
+ const basegfx::B2DPolyPolygon aUnitPolyPolygon(basegfx::tools::createUnitPolygon());
+
+ // add fill
+ if(!getSdrFTAttribute().getFill().isDefault())
+ {
+ appendPrimitive2DReferenceToPrimitive2DSequence(aRetval,
+ createPolyPolygonFillPrimitive(
+ aUnitPolyPolygon,
+ getTransform(),
+ getSdrFTAttribute().getFill(),
+ getSdrFTAttribute().getFillFloatTransGradient()));
+ }
+ else
+ {
+ // if no fill create one for HitTest and BoundRect fallback
+ appendPrimitive2DReferenceToPrimitive2DSequence(aRetval,
+ createHiddenGeometryPrimitives2D(
+ true,
+ aUnitPolyPolygon,
+ getTransform()));
+ }
+
+ // add text
+ if(!getSdrFTAttribute().getText().isDefault())
+ {
+ appendPrimitive2DReferenceToPrimitive2DSequence(aRetval,
+ createTextPrimitive(
+ aUnitPolyPolygon,
+ getTransform(),
+ getSdrFTAttribute().getText(),
+ attribute::SdrLineAttribute(),
+ true,
+ false,
+ false));
+ }
+
+ return aRetval;
+ }
+
+ bool SdrCellPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
+ {
+ const SdrCellPrimitive2D& rCompare = (SdrCellPrimitive2D&)rPrimitive;
+
+ return (getTransform() == rCompare.getTransform()
+ && getSdrFTAttribute() == rCompare.getSdrFTAttribute());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(SdrCellPrimitive2D, PRIMITIVE2D_ID_SDRCELLPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ class SdrBorderlinePrimitive2D : public BufferedDecompositionPrimitive2D
+ {
+ private:
+ basegfx::B2DHomMatrix maTransform;
+ SvxBorderLine maLeftLine;
+ SvxBorderLine maBottomLine;
+ SvxBorderLine maRightLine;
+ SvxBorderLine maTopLine;
+
+ // bitfield
+ unsigned mbLeftIsOutside : 1;
+ unsigned mbBottomIsOutside : 1;
+ unsigned mbRightIsOutside : 1;
+ unsigned mbTopIsOutside : 1;
+ unsigned mbInTwips : 1;
+
+ protected:
+ // local decomposition.
+ virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const;
+
+ public:
+ SdrBorderlinePrimitive2D(
+ const basegfx::B2DHomMatrix& rTransform,
+ const SvxBorderLine& rLeftLine,
+ const SvxBorderLine& rBottomLine,
+ const SvxBorderLine& rRightLine,
+ const SvxBorderLine& rTopLine,
+ bool bLeftIsOutside,
+ bool bBottomIsOutside,
+ bool bRightIsOutside,
+ bool bTopIsOutside,
+ bool bInTwips)
+ : BufferedDecompositionPrimitive2D(),
+ maTransform(rTransform),
+ maLeftLine(rLeftLine),
+ maBottomLine(rBottomLine),
+ maRightLine(rRightLine),
+ maTopLine(rTopLine),
+ mbLeftIsOutside(bLeftIsOutside),
+ mbBottomIsOutside(bBottomIsOutside),
+ mbRightIsOutside(bRightIsOutside),
+ mbTopIsOutside(bTopIsOutside),
+ mbInTwips(bInTwips)
+ {
+ }
+
+
+ // data access
+ const basegfx::B2DHomMatrix& getTransform() const { return maTransform; }
+ const SvxBorderLine& getLeftLine() const { return maLeftLine; }
+ const SvxBorderLine& getBottomLine() const { return maBottomLine; }
+ const SvxBorderLine& getRightLine() const { return maRightLine; }
+ const SvxBorderLine& getTopLine() const { return maTopLine; }
+ bool getLeftIsOutside() const { return mbLeftIsOutside; }
+ bool getBottomIsOutside() const { return mbBottomIsOutside; }
+ bool getRightIsOutside() const { return mbRightIsOutside; }
+ bool getTopIsOutside() const { return mbTopIsOutside; }
+ bool getInTwips() const { return mbInTwips; }
+
+ // compare operator
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
+
+ // provide unique ID
+ DeclPrimitrive2DIDBlock()
+ };
+
+ sal_uInt16 getBorderLineOutWidth(const SvxBorderLine& rLineA)
+ {
+ return (1 == rLineA.GetOutWidth() ? 0 : rLineA.GetOutWidth());
+ }
+
+ sal_uInt16 getBorderLineDistance(const SvxBorderLine& rLineA)
+ {
+ return (1 == rLineA.GetDistance() ? 0 : rLineA.GetDistance());
+ }
+
+ sal_uInt16 getBorderLineInWidth(const SvxBorderLine& rLineA)
+ {
+ return (1 == rLineA.GetInWidth() ? 0 : rLineA.GetInWidth());
+ }
+
+ sal_uInt16 getBorderLineWidth(const SvxBorderLine& rLineA)
+ {
+ return getBorderLineOutWidth(rLineA) + getBorderLineDistance(rLineA) + getBorderLineInWidth(rLineA);
+ }
+
+ double getInnerExtend(const SvxBorderLine& rLineA, bool bSideToUse)
+ {
+ if(!rLineA.isEmpty())
+ {
+ if(rLineA.isDouble())
+ {
+ // reduce to inner edge of associated matching line
+ return -((getBorderLineWidth(rLineA) / 2.0) - (bSideToUse ? getBorderLineOutWidth(rLineA) : getBorderLineInWidth(rLineA)));
+ }
+ else
+ {
+ // extend to overlap with single line
+ return getBorderLineWidth(rLineA) / 2.0;
+ }
+ }
+
+ return 0.0;
+ }
+
+ double getOuterExtend(const SvxBorderLine& rLineA)
+ {
+ if(!rLineA.isEmpty())
+ {
+ // extend to overlap with single line
+ return getBorderLineWidth(rLineA) / 2.0;
+ }
+
+ return 0.0;
+ }
+
+ double getChangedValue(sal_uInt16 nValue, bool bChangeToMM)
+ {
+ if(1 == nValue)
+ return 1.0;
+
+ if(bChangeToMM)
+ return nValue * (127.0 / 72.0);
+
+ return (double)nValue;
+ }
+
+ Primitive2DSequence SdrBorderlinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const
+ {
+ Primitive2DSequence xRetval(4);
+ sal_uInt32 nInsert(0);
+ const double fTwipsToMM(getInTwips() ? (127.0 / 72.0) : 1.0);
+
+ if(!getLeftLine().isEmpty())
+ {
+ // create left line from top to bottom
+ const basegfx::B2DPoint aStart(getTransform() * basegfx::B2DPoint(0.0, 0.0));
+ const basegfx::B2DPoint aEnd(getTransform() * basegfx::B2DPoint(0.0, 1.0));
+
+ if(!aStart.equal(aEnd))
+ {
+ const double fExtendIS(getInnerExtend(getTopLine(), false));
+ const double fExtendIE(getInnerExtend(getBottomLine(), true));
+ double fExtendOS(0.0);
+ double fExtendOE(0.0);
+
+ if(getLeftIsOutside())
+ {
+ if(getTopIsOutside())
+ {
+ fExtendOS = getOuterExtend(getTopLine());
+ }
+
+ if(getBottomIsOutside())
+ {
+ fExtendOE = getOuterExtend(getBottomLine());
+ }
+ }
+
+ xRetval[nInsert++] = Primitive2DReference(new BorderLinePrimitive2D(
+ aStart,
+ aEnd,
+ getChangedValue(getLeftLine().GetOutWidth(), getInTwips()),
+ getChangedValue(getLeftLine().GetDistance(), getInTwips()),
+ getChangedValue(getLeftLine().GetInWidth(), getInTwips()),
+ fExtendIS * fTwipsToMM,
+ fExtendIE * fTwipsToMM,
+ fExtendOS * fTwipsToMM,
+ fExtendOE * fTwipsToMM,
+ true,
+ getLeftIsOutside(),
+ getLeftLine().GetColor().getBColor()));
+ }
+ }
+
+ if(!getBottomLine().isEmpty())
+ {
+ // create bottom line from left to right
+ const basegfx::B2DPoint aStart(getTransform() * basegfx::B2DPoint(0.0, 1.0));
+ const basegfx::B2DPoint aEnd(getTransform() * basegfx::B2DPoint(1.0, 1.0));
+
+ if(!aStart.equal(aEnd))
+ {
+ const double fExtendIS(getInnerExtend(getLeftLine(), true));
+ const double fExtendIE(getInnerExtend(getRightLine(), false));
+ double fExtendOS(0.0);
+ double fExtendOE(0.0);
+
+ if(getBottomIsOutside())
+ {
+ if(getLeftIsOutside())
+ {
+ fExtendOS = getOuterExtend(getLeftLine());
+ }
+
+ if(getRightIsOutside())
+ {
+ fExtendOE = getOuterExtend(getRightLine());
+ }
+ }
+
+ xRetval[nInsert++] = Primitive2DReference(new BorderLinePrimitive2D(
+ aStart,
+ aEnd,
+ getChangedValue(getBottomLine().GetOutWidth(), getInTwips()),
+ getChangedValue(getBottomLine().GetDistance(), getInTwips()),
+ getChangedValue(getBottomLine().GetInWidth(), getInTwips()),
+ fExtendIS * fTwipsToMM,
+ fExtendIE * fTwipsToMM,
+ fExtendOS * fTwipsToMM,
+ fExtendOE * fTwipsToMM,
+ true,
+ getBottomIsOutside(),
+ getBottomLine().GetColor().getBColor()));
+ }
+ }
+
+ if(!getRightLine().isEmpty())
+ {
+ // create right line from top to bottom
+ const basegfx::B2DPoint aStart(getTransform() * basegfx::B2DPoint(1.0, 0.0));
+ const basegfx::B2DPoint aEnd(getTransform() * basegfx::B2DPoint(1.0, 1.0));
+
+ if(!aStart.equal(aEnd))
+ {
+ const double fExtendIS(getInnerExtend(getTopLine(), false));
+ const double fExtendIE(getInnerExtend(getBottomLine(), true));
+ double fExtendOS(0.0);
+ double fExtendOE(0.0);
+
+ if(getRightIsOutside())
+ {
+ if(getTopIsOutside())
+ {
+ fExtendOS = getOuterExtend(getTopLine());
+ }
+
+ if(getBottomIsOutside())
+ {
+ fExtendOE = getOuterExtend(getBottomLine());
+ }
+ }
+
+ xRetval[nInsert++] = Primitive2DReference(new BorderLinePrimitive2D(
+ aStart,
+ aEnd,
+ getChangedValue(getRightLine().GetOutWidth(), getInTwips()),
+ getChangedValue(getRightLine().GetDistance(), getInTwips()),
+ getChangedValue(getRightLine().GetInWidth(), getInTwips()),
+ fExtendOS * fTwipsToMM,
+ fExtendOE * fTwipsToMM,
+ fExtendIS * fTwipsToMM,
+ fExtendIE * fTwipsToMM,
+ getRightIsOutside(),
+ true,
+ getRightLine().GetColor().getBColor()));
+ }
+ }
+
+ if(!getTopLine().isEmpty())
+ {
+ // create top line from left to right
+ const basegfx::B2DPoint aStart(getTransform() * basegfx::B2DPoint(0.0, 0.0));
+ const basegfx::B2DPoint aEnd(getTransform() * basegfx::B2DPoint(1.0, 0.0));
+
+ if(!aStart.equal(aEnd))
+ {
+ const double fExtendIS(getInnerExtend(getLeftLine(), true));
+ const double fExtendIE(getInnerExtend(getRightLine(), false));
+ double fExtendOS(0.0);
+ double fExtendOE(0.0);
+
+ if(getTopIsOutside())
+ {
+ if(getLeftIsOutside())
+ {
+ fExtendOS = getOuterExtend(getLeftLine());
+ }
+
+ if(getRightIsOutside())
+ {
+ fExtendOE = getOuterExtend(getRightLine());
+ }
+ }
+
+ xRetval[nInsert++] = Primitive2DReference(new BorderLinePrimitive2D(
+ aStart,
+ aEnd,
+ getChangedValue(getTopLine().GetOutWidth(), getInTwips()),
+ getChangedValue(getTopLine().GetDistance(), getInTwips()),
+ getChangedValue(getTopLine().GetInWidth(), getInTwips()),
+ fExtendOS * fTwipsToMM,
+ fExtendOE * fTwipsToMM,
+ fExtendIS * fTwipsToMM,
+ fExtendIE * fTwipsToMM,
+ getTopIsOutside(),
+ true,
+ getTopLine().GetColor().getBColor()));
+ }
+ }
+
+ xRetval.realloc(nInsert);
+ return xRetval;
+ }
+
+ bool SdrBorderlinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
+ {
+ const SdrBorderlinePrimitive2D& rCompare = (SdrBorderlinePrimitive2D&)rPrimitive;
+
+ return (getTransform() == rCompare.getTransform()
+ && getLeftLine() == rCompare.getLeftLine()
+ && getBottomLine() == rCompare.getBottomLine()
+ && getRightLine() == rCompare.getRightLine()
+ && getTopLine() == rCompare.getTopLine()
+ && getLeftIsOutside() == rCompare.getLeftIsOutside()
+ && getBottomIsOutside() == rCompare.getBottomIsOutside()
+ && getRightIsOutside() == rCompare.getRightIsOutside()
+ && getTopIsOutside() == rCompare.getTopIsOutside()
+ && getInTwips() == rCompare.getInTwips());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(SdrBorderlinePrimitive2D, PRIMITIVE2D_ID_SDRBORDERLINEPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace sdr
+{
+ namespace contact
+ {
+ void impGetLine(SvxBorderLine& aLine, const sdr::table::TableLayouter& rLayouter, sal_Int32 nX, sal_Int32 nY, bool bHorizontal, sal_Int32 nColCount, sal_Int32 nRowCount, bool bIsRTL)
+ {
+ if(nX >= 0 && nX <= nColCount && nY >= 0 && nY <= nRowCount)
+ {
+ const SvxBorderLine* pLine = rLayouter.getBorderLine(nX, nY, bHorizontal);
+
+ if(pLine)
+ {
+ // copy line content
+ aLine = *pLine;
+
+ // check for mirroring. This shall always be done when it is
+ // not a top- or rightmost line
+ bool bMirror(aLine.isDouble());
+
+ if(bMirror)
+ {
+ if(bHorizontal)
+ {
+ // mirror all bottom lines
+ bMirror = (0 != nY);
+ }
+ else
+ {
+ // mirror all left lines
+ bMirror = (bIsRTL ? 0 != nX : nX != nColCount);
+ }
+ }
+
+ if(bMirror)
+ {
+ aLine.SetOutWidth(pLine->GetInWidth());
+ aLine.SetInWidth(pLine->GetOutWidth());
+ }
+
+ return;
+ }
+ }
+
+ // no success, copy empty line
+ const SvxBorderLine aEmptyLine;
+ aLine = aEmptyLine;
+ }
+
+ drawinglayer::primitive2d::Primitive2DSequence ViewContactOfTableObj::createViewIndependentPrimitive2DSequence() const
+ {
+ const sdr::table::SdrTableObj& rTableObj = GetTableObj();
+ const uno::Reference< com::sun::star::table::XTable > xTable = rTableObj.getTable();
+
+ if(xTable.is())
+ {
+ // create primitive representation for table
+ drawinglayer::primitive2d::Primitive2DSequence xRetval;
+ const sal_Int32 nRowCount(xTable->getRowCount());
+ const sal_Int32 nColCount(xTable->getColumnCount());
+ const sal_Int32 nAllCount(nRowCount * nColCount);
+
+ if(nAllCount)
+ {
+ const sdr::table::TableLayouter& rTableLayouter = rTableObj.getTableLayouter();
+ const bool bIsRTL(com::sun::star::text::WritingMode_RL_TB == rTableObj.GetWritingMode());
+ sdr::table::CellPos aCellPos;
+ sdr::table::CellRef xCurrentCell;
+ basegfx::B2IRectangle aCellArea;
+
+ // create range using the model data directly. This is in SdrTextObj::aRect which i will access using
+ // GetGeoRect() to not trigger any calculations. It's the unrotated geometry.
+ const Rectangle& rObjectRectangle(rTableObj.GetGeoRect());
+ const basegfx::B2DRange aObjectRange(rObjectRectangle.Left(), rObjectRectangle.Top(), rObjectRectangle.Right(), rObjectRectangle.Bottom());
+
+ // for each cell we need potentially a cell primitive and a border primitive
+ // (e.g. single cell). Prepare sequences and input counters
+ drawinglayer::primitive2d::Primitive2DSequence xCellSequence(nAllCount);
+ drawinglayer::primitive2d::Primitive2DSequence xBorderSequence(nAllCount);
+ sal_uInt32 nCellInsert(0);
+ sal_uInt32 nBorderInsert(0);
+
+ // variables for border lines
+ SvxBorderLine aLeftLine;
+ SvxBorderLine aBottomLine;
+ SvxBorderLine aRightLine;
+ SvxBorderLine aTopLine;
+
+ // create single primitives per cell
+ for(aCellPos.mnRow = 0; aCellPos.mnRow < nRowCount; aCellPos.mnRow++)
+ {
+ for(aCellPos.mnCol = 0; aCellPos.mnCol < nColCount; aCellPos.mnCol++)
+ {
+ xCurrentCell.set(dynamic_cast< sdr::table::Cell* >(xTable->getCellByPosition(aCellPos.mnCol, aCellPos.mnRow).get()));
+
+ if(xCurrentCell.is() && !xCurrentCell->isMerged())
+ {
+ if(rTableLayouter.getCellArea(aCellPos, aCellArea))
+ {
+ // create cell transformation matrix
+ basegfx::B2DHomMatrix aCellMatrix;
+ aCellMatrix.set(0, 0, (double)aCellArea.getWidth());
+ aCellMatrix.set(1, 1, (double)aCellArea.getHeight());
+ aCellMatrix.set(0, 2, (double)aCellArea.getMinX() + aObjectRange.getMinX());
+ aCellMatrix.set(1, 2, (double)aCellArea.getMinY() + aObjectRange.getMinY());
+
+ // handle cell fillings and text
+ const SfxItemSet& rCellItemSet = xCurrentCell->GetItemSet();
+ const sal_uInt32 nTextIndex(nColCount * aCellPos.mnRow + aCellPos.mnCol);
+ const SdrText* pSdrText = rTableObj.getText(nTextIndex);
+ drawinglayer::attribute::SdrFillTextAttribute aAttribute;
+
+ if(pSdrText)
+ {
+ // #i101508# take cell's local text frame distances into account
+ const sal_Int32 nLeft(xCurrentCell->GetTextLeftDistance());
+ const sal_Int32 nRight(xCurrentCell->GetTextRightDistance());
+ const sal_Int32 nUpper(xCurrentCell->GetTextUpperDistance());
+ const sal_Int32 nLower(xCurrentCell->GetTextLowerDistance());
+
+ aAttribute = drawinglayer::primitive2d::createNewSdrFillTextAttribute(
+ rCellItemSet,
+ pSdrText,
+ &nLeft,
+ &nUpper,
+ &nRight,
+ &nLower);
+ }
+ else
+ {
+ aAttribute = drawinglayer::primitive2d::createNewSdrFillTextAttribute(
+ rCellItemSet,
+ pSdrText);
+ }
+
+ // always create cell primitives for BoundRect and HitTest
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xCellReference(
+ new drawinglayer::primitive2d::SdrCellPrimitive2D(
+ aCellMatrix, aAttribute));
+ xCellSequence[nCellInsert++] = xCellReference;
+ }
+
+ // handle cell borders
+ const sal_Int32 nX(bIsRTL ? nColCount - aCellPos.mnCol : aCellPos.mnCol);
+ const sal_Int32 nY(aCellPos.mnRow);
+
+ // get access values for X,Y at the cell's end
+ const sal_Int32 nXSpan(xCurrentCell->getColumnSpan());
+ const sal_Int32 nYSpan(xCurrentCell->getRowSpan());
+ const sal_Int32 nXRight(bIsRTL ? nX - nXSpan : nX + nXSpan);
+ const sal_Int32 nYBottom(nY + nYSpan);
+
+ // get basic lines
+ impGetLine(aLeftLine, rTableLayouter, nX, nY, false, nColCount, nRowCount, bIsRTL);
+ impGetLine(aBottomLine, rTableLayouter, nX, nYBottom, true, nColCount, nRowCount, bIsRTL);
+ impGetLine(aRightLine, rTableLayouter, nXRight, nY, false, nColCount, nRowCount, bIsRTL);
+ impGetLine(aTopLine, rTableLayouter, nX, nY, true, nColCount, nRowCount, bIsRTL);
+
+ // create the primtive containing all data for one cell with borders
+ xBorderSequence[nBorderInsert++] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::SdrBorderlinePrimitive2D(
+ aCellMatrix,
+ aLeftLine,
+ aBottomLine,
+ aRightLine,
+ aTopLine,
+ bIsRTL ? nX == nColCount : 0 == nX,
+ nRowCount == nYBottom,
+ bIsRTL ? 0 == nXRight : nXRight == nColCount,
+ 0 == nY,
+ true));
+ }
+ }
+ }
+ }
+
+ // no empty references; reallocate sequences by used count
+ xCellSequence.realloc(nCellInsert);
+ xBorderSequence.realloc(nBorderInsert);
+
+ // append to target. We want fillings and text first
+ xRetval = xCellSequence;
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, xBorderSequence);
+ }
+
+ if(xRetval.hasElements())
+ {
+ // check and create evtl. shadow for created content
+ const SfxItemSet& rObjectItemSet = rTableObj.GetMergedItemSet();
+ const drawinglayer::attribute::SdrShadowAttribute aNewShadowAttribute(
+ drawinglayer::primitive2d::createNewSdrShadowAttribute(rObjectItemSet));
+
+ if(!aNewShadowAttribute.isDefault())
+ {
+ xRetval = drawinglayer::primitive2d::createEmbeddedShadowPrimitive(xRetval, aNewShadowAttribute);
+ }
+ }
+
+ return xRetval;
+ }
+ else
+ {
+ // take unrotated snap rect (direct model data) for position and size
+ const Rectangle& rRectangle = rTableObj.GetGeoRect();
+ const basegfx::B2DRange aObjectRange(
+ rRectangle.Left(), rRectangle.Top(),
+ rRectangle.Right(), rRectangle.Bottom());
+
+ // create object matrix
+ const GeoStat& rGeoStat(rTableObj.GetGeoStat());
+ const double fShearX(rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0);
+ const double fRotate(rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0);
+ const basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
+ aObjectRange.getWidth(), aObjectRange.getHeight(), fShearX, fRotate,
+ aObjectRange.getMinX(), aObjectRange.getMinY()));
+
+ // credate an invisible outline for the cases where no visible content exists
+ const drawinglayer::primitive2d::Primitive2DReference xReference(
+ drawinglayer::primitive2d::createHiddenGeometryPrimitives2D(
+ false,
+ aObjectMatrix));
+
+ return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
+ }
+ }
+
+ ViewContactOfTableObj::ViewContactOfTableObj(::sdr::table::SdrTableObj& rTableObj)
+ : ViewContactOfSdrObj(rTableObj)
+ {
+ }
+
+ ViewContactOfTableObj::~ViewContactOfTableObj()
+ {
+ }
+ } // end of namespace contact
+} // end of namespace sdr
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/table/viewcontactoftableobj.hxx b/svx/source/table/viewcontactoftableobj.hxx
new file mode 100644
index 000000000000..733f28be0d3e
--- /dev/null
+++ b/svx/source/table/viewcontactoftableobj.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SDR_CONTACT_VIEWCONTACTOFTABLEOBJ_HXX
+#define _SDR_CONTACT_VIEWCONTACTOFTABLEOBJ_HXX
+
+#include <svx/sdr/contact/viewcontactofsdrobj.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// predeclarations
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace sdr
+{
+ namespace table
+ {
+ class SdrTableObj;
+ }
+
+ namespace contact
+ {
+ class ViewContactOfTableObj : public ViewContactOfSdrObj
+ {
+ protected:
+ // internal access to SdrTextObj
+ ::sdr::table::SdrTableObj& GetTableObj() const
+ {
+ return (::sdr::table::SdrTableObj&)GetSdrObject();
+ }
+
+ // This method is responsible for creating the graphical visualisation data derived ONLY from
+ // the model data
+ virtual drawinglayer::primitive2d::Primitive2DSequence createViewIndependentPrimitive2DSequence() const;
+
+ public:
+ // basic constructor, used from SdrObject.
+ ViewContactOfTableObj(::sdr::table::SdrTableObj& rTextObj);
+ virtual ~ViewContactOfTableObj();
+ };
+ } // end of namespace contact
+} // end of namespace sdr
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif
+
+// eof