summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--[-rwxr-xr-x]comphelper/source/misc/anycompare.cxx130
-rw-r--r--svtools/inc/svtools/accessibletable.hxx29
-rw-r--r--svtools/inc/svtools/table/gridtablerenderer.hxx13
-rw-r--r--svtools/inc/svtools/table/tablecontrol.hxx16
-rw-r--r--[-rwxr-xr-x]svtools/inc/svtools/table/tablemodel.hxx24
-rw-r--r--svtools/inc/svtools/table/tablerenderer.hxx45
-rw-r--r--[-rwxr-xr-x]svtools/source/table/cellvalueconversion.cxx455
-rw-r--r--[-rwxr-xr-x]svtools/source/table/cellvalueconversion.hxx16
-rw-r--r--svtools/source/table/gridtablerenderer.cxx69
-rw-r--r--[-rwxr-xr-x]svtools/source/table/mousefunction.cxx19
-rw-r--r--svtools/source/table/tablecontrol.cxx169
-rw-r--r--[-rwxr-xr-x]svtools/source/table/tablecontrol_impl.cxx822
-rw-r--r--[-rwxr-xr-x]svtools/source/table/tablecontrol_impl.hxx65
-rw-r--r--svtools/source/table/tabledatawindow.cxx13
-rw-r--r--svtools/source/table/tabledatawindow.hxx6
-rw-r--r--svtools/source/toolpanel/drawerlayouter.cxx4
-rw-r--r--svtools/source/uno/svtxgridcontrol.cxx263
-rwxr-xr-xsvtools/source/uno/svtxgridcontrol.hxx43
-rw-r--r--svtools/source/uno/unocontroltablemodel.cxx98
-rw-r--r--svtools/source/uno/unocontroltablemodel.hxx8
-rw-r--r--toolkit/inc/toolkit/awt/vclxtabpagecontainer.hxx6
-rw-r--r--toolkit/inc/toolkit/awt/vclxtabpagemodel.hxx4
-rw-r--r--toolkit/inc/toolkit/controls/controlmodelcontainerbase.hxx4
-rw-r--r--toolkit/inc/toolkit/controls/tabpagecontainer.hxx21
-rw-r--r--toolkit/inc/toolkit/controls/tabpagemodel.hxx50
-rw-r--r--toolkit/inc/toolkit/helper/property.hxx4
-rw-r--r--[-rwxr-xr-x]toolkit/qa/complex/toolkit/GridControl.java184
-rw-r--r--[-rwxr-xr-x]toolkit/qa/complex/toolkit/awtgrid/TMutableGridDataModel.java153
-rw-r--r--toolkit/source/awt/vclxtabpagecontainer.cxx8
-rw-r--r--toolkit/source/awt/vclxtabpagemodel.cxx4
-rw-r--r--toolkit/source/controls/controlmodelcontainerbase.cxx28
-rw-r--r--toolkit/source/controls/grid/defaultgriddatamodel.cxx82
-rw-r--r--toolkit/source/controls/grid/defaultgriddatamodel.hxx7
-rw-r--r--toolkit/source/controls/grid/gridcontrol.cxx44
-rw-r--r--toolkit/source/controls/grid/gridcontrol.hxx19
-rw-r--r--[-rwxr-xr-x]toolkit/source/controls/grid/sortablegriddatamodel.cxx124
-rw-r--r--[-rwxr-xr-x]toolkit/source/controls/grid/sortablegriddatamodel.hxx17
-rw-r--r--toolkit/source/controls/tabpagecontainer.cxx95
-rw-r--r--toolkit/source/controls/tabpagemodel.cxx66
-rw-r--r--toolkit/source/helper/property.cxx4
-rw-r--r--toolkit/source/helper/registerservices.cxx16
-rw-r--r--vcl/inc/vcl/ctrl.hxx6
-rw-r--r--vcl/inc/vcl/help.hxx24
-rw-r--r--[-rwxr-xr-x]vcl/inc/vcl/window.hxx1
-rw-r--r--vcl/source/app/help.cxx10
-rw-r--r--vcl/source/control/ctrl.cxx10
46 files changed, 2356 insertions, 942 deletions
diff --git a/comphelper/source/misc/anycompare.cxx b/comphelper/source/misc/anycompare.cxx
index a86174daf08e..d01363e6656a 100755..100644
--- a/comphelper/source/misc/anycompare.cxx
+++ b/comphelper/source/misc/anycompare.cxx
@@ -29,6 +29,9 @@
#include "comphelper/anycompare.hxx"
/** === begin UNO includes === **/
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/Time.hpp>
+#include <com/sun/star/util/DateTime.hpp>
/** === end UNO includes === **/
//......................................................................................................................
@@ -63,9 +66,128 @@ namespace comphelper
using ::com::sun::star::uno::TypeClass_TYPE;
using ::com::sun::star::uno::TypeClass_ENUM;
using ::com::sun::star::uno::TypeClass_INTERFACE;
+ using ::com::sun::star::uno::TypeClass_STRUCT;
using ::com::sun::star::i18n::XCollator;
+ using ::com::sun::star::util::Date;
+ using ::com::sun::star::util::Time;
+ using ::com::sun::star::util::DateTime;
/** === end UNO using === **/
+ //==================================================================================================================
+ //= DatePredicateLess
+ //==================================================================================================================
+ class DatePredicateLess : public IKeyPredicateLess
+ {
+ public:
+ virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const
+ {
+ Date lhs, rhs;
+ if ( !( _lhs >>= lhs )
+ || !( _rhs >>= rhs )
+ )
+ throw ::com::sun::star::lang::IllegalArgumentException();
+
+ if ( lhs.Year < rhs.Year )
+ return true;
+ if ( lhs.Year > rhs.Year )
+ return false;
+
+ if ( lhs.Month < rhs.Month )
+ return true;
+ if ( lhs.Month > rhs.Month )
+ return false;
+
+ if ( lhs.Day < rhs.Day )
+ return true;
+ return false;
+ }
+ };
+
+ //==================================================================================================================
+ //= TimePredicateLess
+ //==================================================================================================================
+ class TimePredicateLess : public IKeyPredicateLess
+ {
+ public:
+ virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const
+ {
+ Time lhs, rhs;
+ if ( !( _lhs >>= lhs )
+ || !( _rhs >>= rhs )
+ )
+ throw ::com::sun::star::lang::IllegalArgumentException();
+
+ if ( lhs.Hours < rhs.Hours )
+ return true;
+ if ( lhs.Hours > rhs.Hours )
+ return false;
+
+ if ( lhs.Minutes < rhs.Minutes )
+ return true;
+ if ( lhs.Minutes > rhs.Minutes )
+ return false;
+
+ if ( lhs.Seconds < rhs.Seconds )
+ return true;
+ if ( lhs.Seconds > rhs.Seconds )
+ return false;
+
+ if ( lhs.HundredthSeconds < rhs.HundredthSeconds )
+ return true;
+ return false;
+ }
+ };
+
+ //==================================================================================================================
+ //= DateTimePredicateLess
+ //==================================================================================================================
+ class DateTimePredicateLess : public IKeyPredicateLess
+ {
+ public:
+ virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const
+ {
+ DateTime lhs, rhs;
+ if ( !( _lhs >>= lhs )
+ || !( _rhs >>= rhs )
+ )
+ throw ::com::sun::star::lang::IllegalArgumentException();
+
+ if ( lhs.Year < rhs.Year )
+ return true;
+ if ( lhs.Year > rhs.Year )
+ return false;
+
+ if ( lhs.Month < rhs.Month )
+ return true;
+ if ( lhs.Month > rhs.Month )
+ return false;
+
+ if ( lhs.Day < rhs.Day )
+ return true;
+ if ( lhs.Day > rhs.Day )
+ return false;
+
+ if ( lhs.Hours < rhs.Hours )
+ return true;
+ if ( lhs.Hours > rhs.Hours )
+ return false;
+
+ if ( lhs.Minutes < rhs.Minutes )
+ return true;
+ if ( lhs.Minutes > rhs.Minutes )
+ return false;
+
+ if ( lhs.Seconds < rhs.Seconds )
+ return true;
+ if ( lhs.Seconds > rhs.Seconds )
+ return false;
+
+ if ( lhs.HundredthSeconds < rhs.HundredthSeconds )
+ return true;
+ return false;
+ }
+ };
+
//------------------------------------------------------------------------------------------------------------------
::std::auto_ptr< IKeyPredicateLess > getStandardLessPredicate( Type const & i_type, Reference< XCollator > const & i_collator )
{
@@ -120,6 +242,14 @@ namespace comphelper
case TypeClass_INTERFACE:
pComparator.reset( new InterfacePredicateLess() );
break;
+ case TypeClass_STRUCT:
+ if ( i_type.equals( ::cppu::UnoType< Date >::get() ) )
+ pComparator.reset( new DatePredicateLess() );
+ else if ( i_type.equals( ::cppu::UnoType< Time >::get() ) )
+ pComparator.reset( new TimePredicateLess() );
+ else if ( i_type.equals( ::cppu::UnoType< DateTime >::get() ) )
+ pComparator.reset( new DateTimePredicateLess() );
+ break;
default:
break;
}
diff --git a/svtools/inc/svtools/accessibletable.hxx b/svtools/inc/svtools/accessibletable.hxx
index d7bd98481404..186c83d75be8 100644
--- a/svtools/inc/svtools/accessibletable.hxx
+++ b/svtools/inc/svtools/accessibletable.hxx
@@ -111,7 +111,9 @@ public:
virtual sal_Bool HasRowHeader() const= 0;
virtual sal_Bool ConvertPointToCellAddress( sal_Int32& _rnRow, sal_Int32& _rnColPos, const Point& _rPoint )= 0;
virtual Rectangle calcHeaderRect( sal_Bool _bIsColumnBar, sal_Bool _bOnScreen = sal_True ) = 0;
+ virtual Rectangle calcHeaderCellRect( sal_Bool _bColHeader, sal_Int32 _nPos ) = 0;
virtual Rectangle calcTableRect( sal_Bool _bOnScreen = sal_True ) = 0;
+ virtual Rectangle calcCellRect( sal_Int32 _nRowPos, sal_Int32 _nColPos ) = 0;
virtual Rectangle GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 nIndex)= 0;
virtual sal_Int32 GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint)= 0;
virtual void FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const= 0;
@@ -165,6 +167,33 @@ public:
virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
getTable() = 0;
+ /** commits the event at all listeners of the cell
+ @param nEventId
+ the event id
+ @param rNewValue
+ the new value
+ @param rOldValue
+ the old value
+ */
+ virtual void commitCellEvent(
+ sal_Int16 nEventId,
+ const ::com::sun::star::uno::Any& rNewValue,
+ const ::com::sun::star::uno::Any& rOldValue
+ ) = 0;
+ /** commits the event at all listeners of the table
+ @param nEventId
+ the event id
+ @param rNewValue
+ the new value
+ @param rOldValue
+ the old value
+ */
+ virtual void commitTableEvent(
+ sal_Int16 nEventId,
+ const ::com::sun::star::uno::Any& rNewValue,
+ const ::com::sun::star::uno::Any& rOldValue
+ ) = 0;
+
///** Commits an event to all listeners. */
virtual void commitEvent(
sal_Int16 nEventId,
diff --git a/svtools/inc/svtools/table/gridtablerenderer.hxx b/svtools/inc/svtools/table/gridtablerenderer.hxx
index c472fa408574..d7196419e2e5 100644
--- a/svtools/inc/svtools/table/gridtablerenderer.hxx
+++ b/svtools/inc/svtools/table/gridtablerenderer.hxx
@@ -90,15 +90,15 @@ namespace svt { namespace table
virtual void PaintColumnHeader( ColPos _nCol, bool _bActive, bool _bSelected,
OutputDevice& _rDevice, const Rectangle& _rArea,
const StyleSettings& _rStyle );
- virtual void PrepareRow( RowPos _nRow, bool _bActive, bool _bSelected,
+ virtual void PrepareRow( RowPos _nRow, bool i_hasControlFocus, bool _bSelected,
OutputDevice& _rDevice, const Rectangle& _rRowArea,
const StyleSettings& _rStyle );
virtual void PaintRowHeader(
- bool _bActive, bool _bSelected,
+ bool i_hasControlFocus, bool _bSelected,
OutputDevice& _rDevice, const Rectangle& _rArea,
const StyleSettings& _rStyle );
virtual void PaintCell( ColPos const i_col,
- bool _bActive, bool _bSelected,
+ bool i_hasControlFocus, bool _bSelected,
OutputDevice& _rDevice, const Rectangle& _rArea,
const StyleSettings& _rStyle );
virtual void ShowCellCursor( Window& _rView, const Rectangle& _rCursorRect);
@@ -108,7 +108,12 @@ namespace svt { namespace table
ColPos const i_colPos, RowPos const i_rowPos,
bool const i_active, bool const i_selected,
OutputDevice& i_targetDevice, Rectangle const & i_targetArea
- );
+ ) const;
+ virtual bool GetFormattedCellString(
+ ::com::sun::star::uno::Any const & i_cellValue,
+ ColPos const i_colPos, RowPos const i_rowPos,
+ ::rtl::OUString & o_cellString
+ ) const;
private:
struct CellRenderContext;
diff --git a/svtools/inc/svtools/table/tablecontrol.hxx b/svtools/inc/svtools/table/tablecontrol.hxx
index 8afc2209227c..6237e4fb9b6a 100644
--- a/svtools/inc/svtools/table/tablecontrol.hxx
+++ b/svtools/inc/svtools/table/tablecontrol.hxx
@@ -169,9 +169,14 @@ namespace svt { namespace table
SVT_DLLPRIVATE virtual ::rtl::OUString GetAccessibleObjectName(AccessibleTableControlObjType eObjType, sal_Int32 _nRow, sal_Int32 _nCol) const;
SVT_DLLPRIVATE virtual sal_Bool GoToCell( sal_Int32 _nColumnPos, sal_Int32 _nRow );
SVT_DLLPRIVATE virtual ::rtl::OUString GetAccessibleObjectDescription(AccessibleTableControlObjType eObjType, sal_Int32 _nPosition = -1) const;
- virtual void FillAccessibleStateSet(
- ::utl::AccessibleStateSetHelper& rStateSet,
- AccessibleTableControlObjType eObjType ) const;
+ SVT_DLLPRIVATE virtual void FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& rStateSet, AccessibleTableControlObjType eObjType ) const;
+
+ // temporary methods
+ // Those do not really belong into the public API - they're intended for firing A11Y-related events. However,
+ // firing those events should be an implementation internal to the TableControl resp. TableControl_Impl,
+ // instead of something triggered externally.
+ void commitCellEventIfAccessibleAlive( sal_Int16 const i_eventID, const ::com::sun::star::uno::Any& i_newValue, const ::com::sun::star::uno::Any& i_oldValue );
+ void commitTableEventIfAccessibleAlive( sal_Int16 const i_eventID, const ::com::sun::star::uno::Any& i_newValue, const ::com::sun::star::uno::Any& i_oldValue );
// .............................................................................................................
// IAccessibleTable
@@ -187,7 +192,9 @@ namespace svt { namespace table
virtual sal_Bool HasRowHeader() const;
virtual sal_Bool ConvertPointToCellAddress( sal_Int32& _rnRow, sal_Int32& _rnColPos, const Point& _rPoint );
virtual Rectangle calcHeaderRect( sal_Bool _bIsColumnBar, sal_Bool _bOnScreen = sal_True );
+ virtual Rectangle calcHeaderCellRect( sal_Bool _bIsColumnBar, sal_Int32 nPos);
virtual Rectangle calcTableRect( sal_Bool _bOnScreen = sal_True );
+ virtual Rectangle calcCellRect( sal_Int32 _nRowPos, sal_Int32 _nColPos );
virtual Rectangle GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 nIndex);
virtual sal_Int32 GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint);
virtual void FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const;
@@ -208,9 +215,6 @@ namespace svt { namespace table
// .............................................................................................................
private:
- DECL_DLLPRIVATE_LINK( ImplMouseButtonDownHdl, MouseEvent* );
- DECL_DLLPRIVATE_LINK( ImplMouseButtonUpHdl, MouseEvent* );
-
DECL_DLLPRIVATE_LINK( ImplSelectHdl, void* );
private:
diff --git a/svtools/inc/svtools/table/tablemodel.hxx b/svtools/inc/svtools/table/tablemodel.hxx
index 94f03b684e64..9cfc30c1a338 100755..100644
--- a/svtools/inc/svtools/table/tablemodel.hxx
+++ b/svtools/inc/svtools/table/tablemodel.hxx
@@ -472,6 +472,30 @@ namespace svt { namespace table
*/
virtual ::boost::optional< ::Color > getHeaderTextColor() const = 0;
+ /** returns the color to be used for the background of selected cells, when the control has the focus
+
+ If this value is not set, a default color from the style settings will be used.
+ */
+ virtual ::boost::optional< ::Color > getActiveSelectionBackColor() const = 0;
+
+ /** returns the color to be used for the background of selected cells, when the control does not have the focus
+
+ If this value is not set, a default color from the style settings will be used.
+ */
+ virtual ::boost::optional< ::Color > getInactiveSelectionBackColor() const = 0;
+
+ /** returns the color to be used for the text of selected cells, when the control has the focus
+
+ If this value is not set, a default color from the style settings will be used.
+ */
+ virtual ::boost::optional< ::Color > getActiveSelectionTextColor() const = 0;
+
+ /** returns the color to be used for the text of selected cells, when the control does not have the focus
+
+ If this value is not set, a default color from the style settings will be used.
+ */
+ virtual ::boost::optional< ::Color > getInactiveSelectionTextColor() const = 0;
+
/** returns the color to be used for rendering cell texts.
If this value is not set, a default color from the style settings will be used.
diff --git a/svtools/inc/svtools/table/tablerenderer.hxx b/svtools/inc/svtools/table/tablerenderer.hxx
index 3d50c9d70ee7..73d41028bf1f 100644
--- a/svtools/inc/svtools/table/tablerenderer.hxx
+++ b/svtools/inc/svtools/table/tablerenderer.hxx
@@ -133,9 +133,8 @@ namespace svt { namespace table
However, the renderer is also allowed to render any
cell-independent content of this row.
- @param _bActive
- <TRUE/> if and only if the row to be painted contains the
- currently active cell.
+ @param i_hasControlFocus
+ <TRUE/> if and only if the table control currently has the focus
@param _bSelected
<TRUE/> if and only if the row to be prepared is
selected currently.
@@ -147,7 +146,7 @@ namespace svt { namespace table
@param _rStyle
the style to be used for drawing
*/
- virtual void PrepareRow( RowPos _nRow, bool _bActive, bool _bSelected,
+ virtual void PrepareRow( RowPos _nRow, bool i_hasControlFocus, bool _bSelected,
OutputDevice& _rDevice, const Rectangle& _rRowArea,
const StyleSettings& _rStyle ) = 0;
@@ -156,9 +155,8 @@ namespace svt { namespace table
The row to be painted is denoted by the most recent call to
->PrepareRow.
- @param _bActive
- <TRUE/> if and only if the row to be painted contains the
- currently active cell.
+ @param i_hasControlFocus
+ <TRUE/> if and only if the table control currently has the focus
<br/>
Note that this flag is equal to the respective flag in the
previous ->PrepareRow call, it's passed here for convinience
@@ -177,9 +175,9 @@ namespace svt { namespace table
@param _rStyle
the style to be used for drawing
*/
- virtual void PaintRowHeader( bool _bActive, bool _bSelected,
- OutputDevice& _rDevice, const Rectangle& _rArea,
- const StyleSettings& _rStyle ) = 0;
+ virtual void PaintRowHeader( bool i_hasControlFocus, bool _bSelected,
+ OutputDevice& _rDevice, Rectangle const & _rArea,
+ StyleSettings const & _rStyle ) = 0;
/** paints a certain cell
@@ -194,8 +192,8 @@ namespace svt { namespace table
Note that this flag is equal to the respective flag in the
previous ->PrepareRow call, it's passed here for convinience
only.
- @param _bActive
- <TRUE/> if the cell is currently active.
+ @param i_hasControlFocus
+ <TRUE/> if and only if the table control currently has the focus
<br/>
Note that this flag is equal to the respective flag in the
previous ->PrepareRow call, it's passed here for convinience
@@ -208,7 +206,7 @@ namespace svt { namespace table
the style to be used for drawing
*/
virtual void PaintCell( ColPos const i_col,
- bool _bActive, bool _bSelected,
+ bool i_hasControlFocus, bool _bSelected,
OutputDevice& _rDevice, const Rectangle& _rArea,
const StyleSettings& _rStyle ) = 0;
@@ -259,7 +257,26 @@ namespace svt { namespace table
ColPos const i_colPos, RowPos const i_rowPos,
bool const i_active, bool const i_selected,
OutputDevice& i_targetDevice, Rectangle const & i_targetArea
- ) = 0;
+ ) const = 0;
+
+ /** attempts to format the content of the given cell as string
+
+ @param i_cellValue
+ the value for which an attempt for a string conversion should be made
+ @param i_colPos
+ the column position of the cell in question
+ @param i_rowPos
+ the row position of the cell in question
+ @param o_cellString
+ the cell content, formatted as string
+ @return
+ <TRUE/> if and only if the content could be formatted as string
+ */
+ virtual bool GetFormattedCellString(
+ ::com::sun::star::uno::Any const & i_cellValue,
+ ColPos const i_colPos, RowPos const i_rowPos,
+ ::rtl::OUString & o_cellString
+ ) const = 0;
/// deletes the renderer instance
virtual ~ITableRenderer() { }
diff --git a/svtools/source/table/cellvalueconversion.cxx b/svtools/source/table/cellvalueconversion.cxx
index 286ca505bb30..18e28c2cdc82 100755..100644
--- a/svtools/source/table/cellvalueconversion.cxx
+++ b/svtools/source/table/cellvalueconversion.cxx
@@ -29,8 +29,27 @@
#include "cellvalueconversion.hxx"
/** === begin UNO includes === **/
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/util/Time.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
/** === end UNO includes === **/
+#include <comphelper/componentcontext.hxx>
+#include <rtl/math.hxx>
+#include <rtl/strbuf.hxx>
+#include <tools/date.hxx>
+#include <tools/time.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/syslocale.hxx>
+
+#include <boost/shared_ptr.hpp>
+#include <hash_map>
+
//......................................................................................................................
namespace svt
{
@@ -38,36 +57,432 @@ namespace svt
/** === begin UNO using === **/
using ::com::sun::star::uno::Any;
+ using ::com::sun::star::util::XNumberFormatter;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::util::XNumberFormatsSupplier;
+ using ::com::sun::star::beans::XPropertySet;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::util::DateTime;
+ using ::com::sun::star::uno::TypeClass;
+ using ::com::sun::star::util::XNumberFormatTypes;
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::uno::TypeClass_BYTE;
+ using ::com::sun::star::uno::TypeClass_SHORT;
+ using ::com::sun::star::uno::TypeClass_UNSIGNED_SHORT;
+ using ::com::sun::star::uno::TypeClass_LONG;
+ using ::com::sun::star::uno::TypeClass_UNSIGNED_LONG;
+ using ::com::sun::star::uno::TypeClass_HYPER;
/** === end UNO using === **/
+ namespace NumberFormat = ::com::sun::star::util::NumberFormat;
+
+ typedef ::com::sun::star::util::Time UnoTime;
+ typedef ::com::sun::star::util::Date UnoDate;
//==================================================================================================================
- //= CellValueConversion
+ //= helper
//==================================================================================================================
- //------------------------------------------------------------------------------------------------------------------
- ::rtl::OUString CellValueConversion::convertToString( const Any& i_value )
+ namespace
{
- ::rtl::OUString sConvertString;
- if ( !i_value.hasValue() )
- return sConvertString;
+ //--------------------------------------------------------------------------------------------------------------
+ double lcl_convertDateToDays( long const i_day, long const i_month, long const i_year )
+ {
+ long const nNullDateDays = ::Date::DateToDays( 1, 1, 1900 );
+ long const nValueDateDays = ::Date::DateToDays( i_day, i_month, i_year );
+
+ return nValueDateDays - nNullDateDays;
+ }
+
+ //--------------------------------------------------------------------------------------------------------------
+ double lcl_convertTimeToDays( long const i_hours, long const i_minutes, long const i_seconds, long const i_100thSeconds )
+ {
+ return Time( i_hours, i_minutes, i_seconds, i_100thSeconds ).GetTimeInDays();
+ }
+ }
+
+ //==================================================================================================================
+ //= IValueNormalization
+ //==================================================================================================================
+ class SAL_NO_VTABLE IValueNormalization
+ {
+ public:
+ virtual ~IValueNormalization() { }
+
+ /** converts the given <code>Any</code> into a <code>double</code> value to be fed into a number formatter
+ */
+ virtual double convertToDouble( Any const & i_value ) const = 0;
+
+ /** returns the format key to be used for formatting values
+ */
+ virtual ::sal_Int32 getFormatKey() const = 0;
+ };
+
+ typedef ::boost::shared_ptr< IValueNormalization > PValueNormalization;
+ typedef ::std::hash_map< ::rtl::OUString, PValueNormalization, ::rtl::OUStringHash > NormalizerCache;
+
+ //==================================================================================================================
+ //= CellValueConversion_Data
+ //==================================================================================================================
+ struct CellValueConversion_Data
+ {
+ ::comphelper::ComponentContext const aContext;
+ Reference< XNumberFormatter > xNumberFormatter;
+ bool bAttemptedFormatterCreation;
+ NormalizerCache aNormalizers;
+
+ CellValueConversion_Data( ::comphelper::ComponentContext const & i_context )
+ :aContext( i_context )
+ ,xNumberFormatter()
+ ,bAttemptedFormatterCreation( false )
+ ,aNormalizers()
+ {
+ }
+ };
+
+ //==================================================================================================================
+ //= StandardFormatNormalizer
+ //==================================================================================================================
+ class StandardFormatNormalizer : public IValueNormalization
+ {
+ protected:
+ StandardFormatNormalizer( Reference< XNumberFormatter > const & i_formatter, ::sal_Int32 const i_numberFormatType )
+ :m_nFormatKey( 0 )
+ {
+ try
+ {
+ ENSURE_OR_THROW( i_formatter.is(), "StandardFormatNormalizer: no formatter!" );
+ Reference< XNumberFormatsSupplier > const xSupplier( i_formatter->getNumberFormatsSupplier(), UNO_SET_THROW );
+ Reference< XNumberFormatTypes > const xTypes( xSupplier->getNumberFormats(), UNO_QUERY_THROW );
+ m_nFormatKey = xTypes->getStandardFormat( i_numberFormatType, SvtSysLocale().GetLocale() );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ virtual ::sal_Int32 getFormatKey() const
+ {
+ return m_nFormatKey;
+ }
+
+ private:
+ ::sal_Int32 m_nFormatKey;
+ };
+
+ //==================================================================================================================
+ //= DoubleNormalization
+ //==================================================================================================================
+ class DoubleNormalization : public StandardFormatNormalizer
+ {
+ public:
+ DoubleNormalization( Reference< XNumberFormatter > const & i_formatter )
+ :StandardFormatNormalizer( i_formatter, NumberFormat::NUMBER )
+ {
+ }
+
+ virtual double convertToDouble( Any const & i_value ) const
+ {
+ double returnValue(0);
+ ::rtl::math::setNan( &returnValue );
+ OSL_VERIFY( i_value >>= returnValue );
+ return returnValue;
+ }
+
+ virtual ~DoubleNormalization() { }
+ };
+
+ //==================================================================================================================
+ //= IntegerNormalization
+ //==================================================================================================================
+ class IntegerNormalization : public StandardFormatNormalizer
+ {
+ public:
+ IntegerNormalization( Reference< XNumberFormatter > const & i_formatter )
+ :StandardFormatNormalizer( i_formatter, NumberFormat::NUMBER )
+ {
+ }
+
+ virtual ~IntegerNormalization() {}
+
+ virtual double convertToDouble( Any const & i_value ) const
+ {
+ sal_Int64 value( 0 );
+ OSL_VERIFY( i_value >>= value );
+ return value;
+ }
+ };
+
+ //==================================================================================================================
+ //= BooleanNormalization
+ //==================================================================================================================
+ class BooleanNormalization : public StandardFormatNormalizer
+ {
+ public:
+ BooleanNormalization( Reference< XNumberFormatter > const & i_formatter )
+ :StandardFormatNormalizer( i_formatter, NumberFormat::LOGICAL )
+ {
+ }
+
+ virtual ~BooleanNormalization() {}
+
+ virtual double convertToDouble( Any const & i_value ) const
+ {
+ bool value( false );
+ OSL_VERIFY( i_value >>= value );
+ return value ? 1 : 0;
+ }
+ };
+
+ //==================================================================================================================
+ //= DateTimeNormalization
+ //==================================================================================================================
+ class DateTimeNormalization : public StandardFormatNormalizer
+ {
+ public:
+ DateTimeNormalization( Reference< XNumberFormatter > const & i_formatter )
+ :StandardFormatNormalizer( i_formatter, NumberFormat::DATETIME )
+ {
+ }
+
+ virtual ~DateTimeNormalization() {}
+
+ virtual double convertToDouble( Any const & i_value ) const
+ {
+ double returnValue(0);
+ ::rtl::math::setNan( &returnValue );
+ // extract actual UNO value
+ DateTime aDateTimeValue;
+ ENSURE_OR_RETURN( i_value >>= aDateTimeValue, "allowed for DateTime values only", returnValue );
- // TODO: use css.script.XTypeConverter?
+ // date part
+ returnValue = lcl_convertDateToDays( aDateTimeValue.Day, aDateTimeValue.Month, aDateTimeValue.Year );
- sal_Int32 nInt = 0;
- sal_Bool bBool = false;
- double fDouble = 0;
+ // time part
+ returnValue += lcl_convertTimeToDays(
+ aDateTimeValue.Hours, aDateTimeValue.Minutes, aDateTimeValue.Seconds, aDateTimeValue.HundredthSeconds );
+ // done
+ return returnValue;
+ }
+ };
+
+ //==================================================================================================================
+ //= DateNormalization
+ //==================================================================================================================
+ class DateNormalization : public StandardFormatNormalizer
+ {
+ public:
+ DateNormalization( Reference< XNumberFormatter > const & i_formatter )
+ :StandardFormatNormalizer( i_formatter, NumberFormat::DATE )
+ {
+ }
+
+ virtual ~DateNormalization() {}
+
+ virtual double convertToDouble( Any const & i_value ) const
+ {
+ double returnValue(0);
+ ::rtl::math::setNan( &returnValue );
+
+ // extract
+ UnoDate aDateValue;
+ ENSURE_OR_RETURN( i_value >>= aDateValue, "allowed for Date values only", returnValue );
+
+ // convert
+ returnValue = lcl_convertDateToDays( aDateValue.Day, aDateValue.Month, aDateValue.Year );
+
+ // done
+ return returnValue;
+ }
+ };
+
+ //==================================================================================================================
+ //= TimeNormalization
+ //==================================================================================================================
+ class TimeNormalization : public StandardFormatNormalizer
+ {
+ public:
+ TimeNormalization( Reference< XNumberFormatter > const & i_formatter )
+ :StandardFormatNormalizer( i_formatter, NumberFormat::TIME )
+ {
+ }
+
+ virtual ~TimeNormalization() {}
+
+ virtual double convertToDouble( Any const & i_value ) const
+ {
+ double returnValue(0);
+ ::rtl::math::setNan( &returnValue );
+
+ // extract
+ UnoTime aTimeValue;
+ ENSURE_OR_RETURN( i_value >>= aTimeValue, "allowed for Time values only", returnValue );
+
+ // convert
+ returnValue += lcl_convertTimeToDays(
+ aTimeValue.Hours, aTimeValue.Minutes, aTimeValue.Seconds, aTimeValue.HundredthSeconds );
+
+ // done
+ return returnValue;
+ }
+ };
+
+ //==================================================================================================================
+ //= operations
+ //==================================================================================================================
+ namespace
+ {
+ //--------------------------------------------------------------------------------------------------------------
+ bool lcl_ensureNumberFormatter( CellValueConversion_Data & io_data )
+ {
+ if ( io_data.bAttemptedFormatterCreation )
+ return io_data.xNumberFormatter.is();
+ io_data.bAttemptedFormatterCreation = true;
+
+ try
+ {
+ // a number formatter
+ Reference< XNumberFormatter > const xFormatter(
+ io_data.aContext.createComponent( "com.sun.star.util.NumberFormatter" ), UNO_QUERY_THROW );
+
+ // a supplier of number formats
+ Sequence< Any > aInitArgs(1);
+ aInitArgs[0] <<= SvtSysLocale().GetLocale();
+
+ Reference< XNumberFormatsSupplier > const xSupplier(
+ io_data.aContext.createComponentWithArguments( "com.sun.star.util.NumberFormatsSupplier", aInitArgs ),
+ UNO_QUERY_THROW
+ );
+
+ // ensure a NullDate we will assume later on
+ UnoDate const aNullDate( 1, 1, 1900 );
+ Reference< XPropertySet > const xFormatSettings( xSupplier->getNumberFormatSettings(), UNO_SET_THROW );
+ xFormatSettings->setPropertyValue( ::rtl::OUString::createFromAscii( "NullDate" ), makeAny( aNullDate ) );
+
+ // knit
+ xFormatter->attachNumberFormatsSupplier( xSupplier );
+
+ // done
+ io_data.xNumberFormatter = xFormatter;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return io_data.xNumberFormatter.is();
+ }
+
+ //--------------------------------------------------------------------------------------------------------------
+ bool lcl_getValueNormalizer( CellValueConversion_Data & io_data, Type const & i_valueType,
+ PValueNormalization & o_formatter )
+ {
+ NormalizerCache::const_iterator pos = io_data.aNormalizers.find( i_valueType.getTypeName() );
+ if ( pos == io_data.aNormalizers.end() )
+ {
+ // never encountered this type before
+ o_formatter.reset();
+
+ ::rtl::OUString const sTypeName( i_valueType.getTypeName() );
+ TypeClass const eTypeClass = i_valueType.getTypeClass();
+
+ if ( sTypeName.equals( ::cppu::UnoType< DateTime >::get().getTypeName() ) )
+ {
+ o_formatter.reset( new DateTimeNormalization( io_data.xNumberFormatter ) );
+ }
+ else if ( sTypeName.equals( ::cppu::UnoType< UnoDate >::get().getTypeName() ) )
+ {
+ o_formatter.reset( new DateNormalization( io_data.xNumberFormatter ) );
+ }
+ else if ( sTypeName.equals( ::cppu::UnoType< UnoTime >::get().getTypeName() ) )
+ {
+ o_formatter.reset( new TimeNormalization( io_data.xNumberFormatter ) );
+ }
+ else if ( sTypeName.equals( ::cppu::UnoType< ::sal_Bool >::get().getTypeName() ) )
+ {
+ o_formatter.reset( new BooleanNormalization( io_data.xNumberFormatter ) );
+ }
+ else if ( sTypeName.equals( ::cppu::UnoType< double >::get().getTypeName() )
+ || sTypeName.equals( ::cppu::UnoType< float >::get().getTypeName() )
+ )
+ {
+ o_formatter.reset( new DoubleNormalization( io_data.xNumberFormatter ) );
+ }
+ else if ( ( eTypeClass == TypeClass_BYTE )
+ || ( eTypeClass == TypeClass_SHORT )
+ || ( eTypeClass == TypeClass_UNSIGNED_SHORT )
+ || ( eTypeClass == TypeClass_LONG )
+ || ( eTypeClass == TypeClass_UNSIGNED_LONG )
+ || ( eTypeClass == TypeClass_HYPER )
+ )
+ {
+ o_formatter.reset( new IntegerNormalization( io_data.xNumberFormatter ) );
+ }
+ else
+ {
+#if OSL_DEBUG_LEVEL > 0
+ ::rtl::OStringBuffer message( "lcl_getValueNormalizer: unsupported type '" );
+ message.append( ::rtl::OUStringToOString( sTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ message.append( "'!" );
+ OSL_ENSURE( false, message.makeStringAndClear() );
+#endif
+ }
+ io_data.aNormalizers[ sTypeName ] = o_formatter;
+ }
+ else
+ o_formatter = pos->second;
+
+ return !!o_formatter;
+ }
+ }
+
+ //==================================================================================================================
+ //= CellValueConversion
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ CellValueConversion::CellValueConversion( ::comphelper::ComponentContext const & i_context )
+ :m_pData( new CellValueConversion_Data( i_context ) )
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ CellValueConversion::~CellValueConversion()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::rtl::OUString CellValueConversion::convertToString( const Any& i_value )
+ {
::rtl::OUString sStringValue;
- if ( i_value >>= sConvertString )
- sStringValue = sConvertString;
- else if ( i_value >>= nInt )
- sStringValue = sConvertString.valueOf( nInt );
- else if ( i_value >>= bBool )
- sStringValue = sConvertString.valueOf( bBool );
- else if ( i_value >>= fDouble )
- sStringValue = sConvertString.valueOf( fDouble );
- else
- OSL_ENSURE( !i_value.hasValue(), "CellValueConversion::convertToString: cannot handle the given cell content type!" );
+ if ( !i_value.hasValue() )
+ return sStringValue;
+
+ if ( ! ( i_value >>= sStringValue ) )
+ {
+ if ( lcl_ensureNumberFormatter( *m_pData ) )
+ {
+ PValueNormalization pNormalizer;
+ if ( lcl_getValueNormalizer( *m_pData, i_value.getValueType(), pNormalizer ) )
+ {
+ try
+ {
+ double const formatterCompliantValue = pNormalizer->convertToDouble( i_value );
+ sal_Int32 const formatKey = pNormalizer->getFormatKey();
+ sStringValue = m_pData->xNumberFormatter->convertNumberToString(
+ formatKey, formatterCompliantValue );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ }
+ }
return sStringValue;
}
diff --git a/svtools/source/table/cellvalueconversion.hxx b/svtools/source/table/cellvalueconversion.hxx
index 4d6b8c8d6aac..c4d8baa98489 100755..100644
--- a/svtools/source/table/cellvalueconversion.hxx
+++ b/svtools/source/table/cellvalueconversion.hxx
@@ -31,6 +31,13 @@
#include <com/sun/star/uno/Any.hxx>
/** === end UNO includes === **/
+#include <boost/scoped_ptr.hpp>
+
+namespace comphelper
+{
+ class ComponentContext;
+}
+
//......................................................................................................................
namespace svt
{
@@ -39,10 +46,17 @@ namespace svt
//==================================================================================================================
//= CellValueConversion
//==================================================================================================================
+ struct CellValueConversion_Data;
class CellValueConversion
{
public:
- static ::rtl::OUString convertToString( const ::com::sun::star::uno::Any& i_cellValue );
+ CellValueConversion( ::comphelper::ComponentContext const & i_context );
+ ~CellValueConversion();
+
+ ::rtl::OUString convertToString( const ::com::sun::star::uno::Any& i_cellValue );
+
+ private:
+ ::boost::scoped_ptr< CellValueConversion_Data > m_pData;
};
//......................................................................................................................
diff --git a/svtools/source/table/gridtablerenderer.cxx b/svtools/source/table/gridtablerenderer.cxx
index 1e230d372c24..341c398b5bcd 100644
--- a/svtools/source/table/gridtablerenderer.cxx
+++ b/svtools/source/table/gridtablerenderer.cxx
@@ -35,6 +35,8 @@
#include <com/sun/star/graphic/XGraphic.hpp>
/** === end UNO includes === **/
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/processfactory.hxx>
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>
#include <vcl/window.hxx>
@@ -123,11 +125,14 @@ namespace svt { namespace table
RowPos nCurrentRow;
bool bUseGridLines;
CachedSortIndicator aSortIndicator;
+ CellValueConversion aStringConverter;
GridTableRenderer_Impl( ITableModel& _rModel )
:rModel( _rModel )
,nCurrentRow( ROW_INVALID )
,bUseGridLines( true )
+ ,aSortIndicator( )
+ ,aStringConverter( ::comphelper::ComponentContext( ::comphelper::getProcessServiceFactory() ) )
{
}
};
@@ -168,7 +173,9 @@ namespace svt { namespace table
}
sal_uLong nHorzFlag = TEXT_DRAW_LEFT;
- HorizontalAlignment const eHorzAlign = i_impl.rModel.getColumnModel( i_columnPos )->getHorizontalAlign();
+ HorizontalAlignment const eHorzAlign = i_impl.rModel.getColumnCount() > 0
+ ? i_impl.rModel.getColumnModel( i_columnPos )->getHorizontalAlign()
+ : HorizontalAlignment_CENTER;
switch ( eHorzAlign )
{
case HorizontalAlignment_CENTER: nHorzFlag = TEXT_DRAW_CENTER; break;
@@ -324,7 +331,7 @@ namespace svt { namespace table
}
//------------------------------------------------------------------------------------------------------------------
- void GridTableRenderer::PrepareRow( RowPos _nRow, bool _bActive, bool _bSelected,
+ void GridTableRenderer::PrepareRow( RowPos _nRow, bool i_hasControlFocus, bool _bSelected,
OutputDevice& _rDevice, const Rectangle& _rRowArea, const StyleSettings& _rStyle )
{
// remember the row for subsequent calls to the other ->ITableRenderer methods
@@ -334,13 +341,17 @@ namespace svt { namespace table
::Color backgroundColor = _rStyle.GetFieldColor();
- ::boost::optional< ::Color > aLineColor( m_pImpl->rModel.getLineColor() );
+ ::boost::optional< ::Color > const aLineColor( m_pImpl->rModel.getLineColor() );
::Color lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor;
+ ::Color const activeSelectionBackColor =
+ lcl_getEffectiveColor( m_pImpl->rModel.getActiveSelectionBackColor(), _rStyle, &StyleSettings::GetHighlightColor );
if ( _bSelected )
{
// selected rows use the background color from the style
- backgroundColor = _rStyle.GetHighlightColor();
+ backgroundColor = i_hasControlFocus
+ ? activeSelectionBackColor
+ : lcl_getEffectiveColor( m_pImpl->rModel.getInactiveSelectionBackColor(), _rStyle, &StyleSettings::GetDeactiveColor );
if ( !aLineColor )
lineColor = backgroundColor;
}
@@ -357,7 +368,7 @@ namespace svt { namespace table
}
else
{
- Color hilightColor = _rStyle.GetHighlightColor();
+ Color hilightColor = activeSelectionBackColor;
hilightColor.SetRed( 9 * ( fieldColor.GetRed() - hilightColor.GetRed() ) / 10 + hilightColor.GetRed() );
hilightColor.SetGreen( 9 * ( fieldColor.GetGreen() - hilightColor.GetGreen() ) / 10 + hilightColor.GetGreen() );
hilightColor.SetBlue( 9 * ( fieldColor.GetBlue() - hilightColor.GetBlue() ) / 10 + hilightColor.GetBlue() );
@@ -384,13 +395,10 @@ namespace svt { namespace table
_rDevice.DrawRect( _rRowArea );
_rDevice.Pop();
-
- (void)_bActive;
- // row containing the active cell not rendered any special at the moment
}
//------------------------------------------------------------------------------------------------------------------
- void GridTableRenderer::PaintRowHeader( bool _bActive, bool _bSelected, OutputDevice& _rDevice, const Rectangle& _rArea,
+ void GridTableRenderer::PaintRowHeader( bool i_hasControlFocus, bool _bSelected, OutputDevice& _rDevice, const Rectangle& _rArea,
const StyleSettings& _rStyle )
{
_rDevice.Push( PUSH_LINECOLOR | PUSH_TEXTCOLOR );
@@ -401,7 +409,7 @@ namespace svt { namespace table
_rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() );
Any const rowHeading( m_pImpl->rModel.getRowHeading( m_pImpl->nCurrentRow ) );
- ::rtl::OUString const rowTitle( CellValueConversion::convertToString( rowHeading ) );
+ ::rtl::OUString const rowTitle( m_pImpl->aStringConverter.convertToString( rowHeading ) );
if ( rowTitle.getLength() )
{
::Color const textColor = lcl_getEffectiveColor( m_pImpl->rModel.getHeaderTextColor(), _rStyle, &StyleSettings::GetFieldTextColor );
@@ -413,8 +421,7 @@ namespace svt { namespace table
_rDevice.DrawText( aTextRect, rowTitle, nDrawTextFlags );
}
- // TODO: active? selected?
- (void)_bActive;
+ (void)i_hasControlFocus;
(void)_bSelected;
_rDevice.Pop();
}
@@ -427,26 +434,28 @@ namespace svt { namespace table
StyleSettings const & rStyle;
ColPos const nColumn;
bool const bSelected;
+ bool const bHasControlFocus;
CellRenderContext( OutputDevice& i_device, Rectangle const & i_contentArea,
- StyleSettings const & i_style, ColPos const i_column, bool const i_selected )
+ StyleSettings const & i_style, ColPos const i_column, bool const i_selected, bool const i_hasControlFocus )
:rDevice( i_device )
,aContentArea( i_contentArea )
,rStyle( i_style )
,nColumn( i_column )
,bSelected( i_selected )
+ ,bHasControlFocus( i_hasControlFocus )
{
}
};
//------------------------------------------------------------------------------------------------------------------
- void GridTableRenderer::PaintCell( ColPos const i_column, bool _bSelected, bool _bActive,
+ void GridTableRenderer::PaintCell( ColPos const i_column, bool _bSelected, bool i_hasControlFocus,
OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle )
{
_rDevice.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
Rectangle const aContentArea( lcl_getContentArea( *m_pImpl, _rArea ) );
- CellRenderContext const aRenderContext( _rDevice, aContentArea, _rStyle, i_column, _bSelected );
+ CellRenderContext const aRenderContext( _rDevice, aContentArea, _rStyle, i_column, _bSelected, i_hasControlFocus );
impl_paintCellContent( aRenderContext );
if ( m_pImpl->bUseGridLines )
@@ -457,7 +466,9 @@ namespace svt { namespace table
if ( _bSelected && !aLineColor )
{
// if no line color is specified by the model, use the usual selection color for lines in selected cells
- lineColor = _rStyle.GetHighlightColor();
+ lineColor = i_hasControlFocus
+ ? lcl_getEffectiveColor( m_pImpl->rModel.getActiveSelectionBackColor(), _rStyle, &StyleSettings::GetHighlightColor )
+ : lcl_getEffectiveColor( m_pImpl->rModel.getInactiveSelectionBackColor(), _rStyle, &StyleSettings::GetDeactiveColor );
}
_rDevice.SetLineColor( lineColor );
@@ -466,9 +477,6 @@ namespace svt { namespace table
}
_rDevice.Pop();
-
- (void)_bActive;
- // no special painting for the active cell at the moment
}
//------------------------------------------------------------------------------------------------------------------
@@ -537,7 +545,7 @@ namespace svt { namespace table
return;
}
- const ::rtl::OUString sText( CellValueConversion::convertToString( aCellContent ) );
+ const ::rtl::OUString sText( m_pImpl->aStringConverter.convertToString( aCellContent ) );
impl_paintCellText( i_context, sText );
}
@@ -545,7 +553,12 @@ namespace svt { namespace table
void GridTableRenderer::impl_paintCellText( CellRenderContext const & i_context, ::rtl::OUString const & i_text )
{
if ( i_context.bSelected )
- i_context.rDevice.SetTextColor( i_context.rStyle.GetHighlightTextColor() );
+ {
+ ::Color const textColor = i_context.bHasControlFocus
+ ? lcl_getEffectiveColor( m_pImpl->rModel.getActiveSelectionTextColor(), i_context.rStyle, &StyleSettings::GetHighlightTextColor )
+ : lcl_getEffectiveColor( m_pImpl->rModel.getInactiveSelectionTextColor(), i_context.rStyle, &StyleSettings::GetDeactiveTextColor );
+ i_context.rDevice.SetTextColor( textColor );
+ }
else
{
::Color const textColor = lcl_getEffectiveColor( m_pImpl->rModel.getTextColor(), i_context.rStyle, &StyleSettings::GetFieldTextColor );
@@ -572,7 +585,7 @@ namespace svt { namespace table
//------------------------------------------------------------------------------------------------------------------
bool GridTableRenderer::FitsIntoCell( Any const & i_cellContent, ColPos const i_colPos, RowPos const i_rowPos,
- bool const i_active, bool const i_selected, OutputDevice& i_targetDevice, Rectangle const & i_targetArea )
+ bool const i_active, bool const i_selected, OutputDevice& i_targetDevice, Rectangle const & i_targetArea ) const
{
if ( !i_cellContent.hasValue() )
return true;
@@ -592,7 +605,7 @@ namespace svt { namespace table
return true;
}
- ::rtl::OUString const sText( CellValueConversion::convertToString( i_cellContent ) );
+ ::rtl::OUString const sText( m_pImpl->aStringConverter.convertToString( i_cellContent ) );
if ( sText.getLength() == 0 )
return true;
@@ -613,6 +626,16 @@ namespace svt { namespace table
return true;
}
+ //------------------------------------------------------------------------------------------------------------------
+ bool GridTableRenderer::GetFormattedCellString( Any const & i_cellValue, ColPos const i_colPos, RowPos const i_rowPos, ::rtl::OUString & o_cellString ) const
+ {
+ o_cellString = m_pImpl->aStringConverter.convertToString( i_cellValue );
+
+ OSL_UNUSED( i_colPos );
+ OSL_UNUSED( i_rowPos );
+ return true;
+ }
+
//......................................................................................................................
} } // namespace svt::table
//......................................................................................................................
diff --git a/svtools/source/table/mousefunction.cxx b/svtools/source/table/mousefunction.cxx
index 20d505e911e9..162abc7936c8 100755..100644
--- a/svtools/source/table/mousefunction.cxx
+++ b/svtools/source/table/mousefunction.cxx
@@ -207,27 +207,14 @@ namespace svt { namespace table
TableCell const tableCell( i_tableControl.hitTest( i_event.GetPosPixel() ) );
if ( tableCell.nRow >= 0 )
{
- bool bSetCursor = false;
if ( i_tableControl.getSelEngine()->GetSelectionMode() == NO_SELECTION )
{
- bSetCursor = true;
+ i_tableControl.activateCell( tableCell.nColumn, tableCell.nRow );
+ handled = true;
}
else
{
- if ( !i_tableControl.isRowSelected( tableCell.nRow ) )
- {
- handled = i_tableControl.getSelEngine()->SelMouseButtonDown( i_event );
- }
- else
- {
- bSetCursor = true;
- }
- }
-
- if ( bSetCursor )
- {
- i_tableControl.activateCell( tableCell.nColumn, tableCell.nRow );
- handled = true;
+ handled = i_tableControl.getSelEngine()->SelMouseButtonDown( i_event );
}
}
diff --git a/svtools/source/table/tablecontrol.cxx b/svtools/source/table/tablecontrol.cxx
index 01a9b667a8f7..d0e726fa5c53 100644
--- a/svtools/source/table/tablecontrol.cxx
+++ b/svtools/source/table/tablecontrol.cxx
@@ -35,6 +35,7 @@
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#include <tools/diagnose_ex.h>
@@ -49,6 +50,8 @@ namespace svt { namespace table
{
//......................................................................................................................
+ namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId;
+
//==================================================================================================================
//= TableControl
//==================================================================================================================
@@ -58,14 +61,14 @@ namespace svt { namespace table
,m_pImpl( new TableControl_Impl( *this ) )
{
TableDataWindow& rDataWindow = m_pImpl->getDataWindow();
- rDataWindow.SetMouseButtonDownHdl( LINK( this, TableControl, ImplMouseButtonDownHdl ) );
- rDataWindow.SetMouseButtonUpHdl( LINK( this, TableControl, ImplMouseButtonUpHdl ) );
rDataWindow.SetSelectHdl( LINK( this, TableControl, ImplSelectHdl ) );
// by default, use the background as determined by the style settings
const Color aWindowColor( GetSettings().GetStyleSettings().GetFieldColor() );
SetBackground( Wallpaper( aWindowColor ) );
SetFillColor( aWindowColor );
+
+ SetCompoundControl( true );
}
// -----------------------------------------------------------------------------------------------------------------
@@ -97,6 +100,27 @@ namespace svt { namespace table
{
if ( !m_pImpl->getInputHandler()->KeyInput( *m_pImpl, rKEvt ) )
Control::KeyInput( rKEvt );
+ else
+ {
+ if ( m_pImpl->isAccessibleAlive() )
+ {
+ m_pImpl->commitCellEvent( AccessibleEventId::STATE_CHANGED,
+ makeAny( AccessibleStateType::FOCUSED ),
+ Any()
+ );
+ // Huh? What the heck? Why do we unconditionally notify a STATE_CHANGE/FOCUSED after each and every
+ // (handled) key stroke?
+
+ m_pImpl->commitTableEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
+ Any(),
+ Any()
+ );
+ // ditto: Why do we notify this unconditionally? We should find the right place to notify the
+ // ACTIVE_DESCENDANT_CHANGED event.
+ // Also, we should check if STATE_CHANGED/FOCUSED is really necessary: finally, the children are
+ // transient, aren't they?
+ }
+ }
}
@@ -108,6 +132,10 @@ namespace svt { namespace table
// forward certain settings to the data window
switch ( i_nStateChange )
{
+ case STATE_CHANGE_CONTROL_FOCUS:
+ m_pImpl->invalidateSelectedRows();
+ break;
+
case STATE_CHANGE_CONTROLBACKGROUND:
if ( IsControlBackground() )
getDataWindow().SetControlBackground( GetControlBackground() );
@@ -209,7 +237,7 @@ namespace svt { namespace table
void TableControl::SelectRow( RowPos const i_rowIndex, bool const i_select )
{
ENSURE_OR_RETURN_VOID( ( i_rowIndex >= 0 ) && ( i_rowIndex < m_pImpl->getModel()->getRowCount() ),
- "TableControl::SelectRow: no control (anymore)!" );
+ "TableControl::SelectRow: invalid row index!" );
if ( i_select )
{
@@ -291,10 +319,10 @@ namespace svt { namespace table
switch( eObjType )
{
case TCTYPE_GRIDCONTROL:
- aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GridControl" ) );
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grid control" ) );
break;
case TCTYPE_TABLE:
- aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Table" ) );
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grid conrol" ) );
break;
case TCTYPE_ROWHEADERBAR:
aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowHeaderBar" ) );
@@ -303,7 +331,19 @@ namespace svt { namespace table
aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ColumnHeaderBar" ) );
break;
case TCTYPE_TABLECELL:
- aRetText = GetAccessibleCellText(_nRow, _nCol);
+ //the name of the cell constists of column name and row name if defined
+ //if the name is equal to cell content, it'll be read twice
+ if(GetModel()->hasColumnHeaders())
+ {
+ aRetText = GetColumnName(_nCol);
+ aRetText += rtl::OUString::createFromAscii(" , ");
+ }
+ if(GetModel()->hasRowHeaders())
+ {
+ aRetText += GetRowName(_nRow);
+ aRetText += rtl::OUString::createFromAscii(" , ");
+ }
+ //aRetText = GetAccessibleCellText(_nRow, _nCol);
break;
case TCTYPE_ROWHEADERCELL:
aRetText = GetRowName(_nRow);
@@ -324,7 +364,7 @@ namespace svt { namespace table
switch( eObjType )
{
case TCTYPE_GRIDCONTROL:
- aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GridControl description" ) );
+ aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grid control description" ) );
break;
case TCTYPE_TABLE:
aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TABLE description" ) );
@@ -336,7 +376,17 @@ namespace svt { namespace table
aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "COLUMNHEADERBAR description" ) );
break;
case TCTYPE_TABLECELL:
- aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TABLECELL description" ) );
+ // the description of the cell consists of column name and row name if defined
+ // if the name is equal to cell content, it'll be read twice
+ if ( GetModel()->hasColumnHeaders() )
+ {
+ aRetText = GetColumnName( GetCurrentColumn() );
+ aRetText += rtl::OUString::createFromAscii( " , " );
+ }
+ if ( GetModel()->hasRowHeaders() )
+ {
+ aRetText += GetRowName( GetCurrentRow() );
+ }
break;
case TCTYPE_ROWHEADERCELL:
aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ROWHEADERCELL description" ) );
@@ -401,38 +451,60 @@ namespace svt { namespace table
case TCTYPE_TABLE:
rStateSet.AddState( AccessibleStateType::FOCUSABLE );
- rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE);
- if ( HasFocus() )
+
+ if ( m_pImpl->getSelEngine()->GetSelectionMode() == MULTIPLE_SELECTION )
+ rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE);
+
+ if ( HasChildPathFocus() )
rStateSet.AddState( AccessibleStateType::FOCUSED );
+
if ( IsActive() )
rStateSet.AddState( AccessibleStateType::ACTIVE );
- if ( IsEnabled() )
+
+ if ( m_pImpl->getDataWindow().IsEnabled() )
+ {
rStateSet.AddState( AccessibleStateType::ENABLED );
+ rStateSet.AddState( AccessibleStateType::SENSITIVE );
+ }
+
if ( IsReallyVisible() )
rStateSet.AddState( AccessibleStateType::VISIBLE );
- rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
+ if ( eObjType == TCTYPE_TABLE )
+ rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
break;
+
case TCTYPE_ROWHEADERBAR:
rStateSet.AddState( AccessibleStateType::VISIBLE );
rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
break;
+
case TCTYPE_COLUMNHEADERBAR:
rStateSet.AddState( AccessibleStateType::VISIBLE );
rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
break;
+
case TCTYPE_TABLECELL:
{
+ rStateSet.AddState( AccessibleStateType::FOCUSABLE );
+ if ( HasChildPathFocus() )
+ rStateSet.AddState( AccessibleStateType::FOCUSED );
+ rStateSet.AddState( AccessibleStateType::ACTIVE );
rStateSet.AddState( AccessibleStateType::TRANSIENT );
rStateSet.AddState( AccessibleStateType::SELECTABLE);
- if( GetSelectedRowCount()>0)
- rStateSet.AddState( AccessibleStateType::SELECTED);
+ rStateSet.AddState( AccessibleStateType::VISIBLE );
+ rStateSet.AddState( AccessibleStateType::SHOWING );
+ if ( IsRowSelected( GetCurrentRow() ) )
+ // Hmm? Wouldn't we expect the affected row to be a parameter to this function?
+ rStateSet.AddState( AccessibleStateType::SELECTED );
}
break;
+
case TCTYPE_ROWHEADERCELL:
rStateSet.AddState( AccessibleStateType::VISIBLE );
rStateSet.AddState( AccessibleStateType::TRANSIENT );
break;
+
case TCTYPE_COLUMNHEADERCELL:
rStateSet.AddState( AccessibleStateType::VISIBLE );
break;
@@ -440,6 +512,20 @@ namespace svt { namespace table
}
//------------------------------------------------------------------------------------------------------------------
+ void TableControl::commitCellEventIfAccessibleAlive( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue )
+ {
+ if ( m_pImpl->isAccessibleAlive() )
+ m_pImpl->commitCellEvent( i_eventID, i_newValue, i_oldValue );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void TableControl::commitTableEventIfAccessibleAlive( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue )
+ {
+ if ( m_pImpl->isAccessibleAlive() )
+ m_pImpl->commitTableEvent( i_eventID, i_newValue, i_oldValue );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
Rectangle TableControl::GetWindowExtentsRelative( Window *pRelativeWindow ) const
{
return Control::GetWindowExtentsRelative( pRelativeWindow );
@@ -484,13 +570,12 @@ namespace svt { namespace table
//------------------------------------------------------------------------------------------------------------------
sal_Int32 TableControl::GetAccessibleControlCount() const
{
- sal_Int32 count = 0;
- if(GetRowCount()>0)
- count+=1;
- if(GetModel()->hasRowHeaders())
- count+=1;
- if(GetModel()->hasColumnHeaders())
- count+=1;
+ // TC_TABLE is always defined, no matter whether empty or not
+ sal_Int32 count = 1;
+ if ( GetModel()->hasRowHeaders() )
+ ++count;
+ if ( GetModel()->hasColumnHeaders() )
+ ++count;
return count;
}
@@ -532,10 +617,20 @@ namespace svt { namespace table
//------------------------------------------------------------------------------------------------------------------
void TableControl::FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const
{
- if ( GetCurrentRow() == _nRow && GetCurrentColumn() == _nColumnPos )
+ if ( IsRowSelected( _nRow ) )
+ _rStateSet.AddState( AccessibleStateType::SELECTED );
+ if ( HasChildPathFocus() )
_rStateSet.AddState( AccessibleStateType::FOCUSED );
else // only transient when column is not focused
_rStateSet.AddState( AccessibleStateType::TRANSIENT );
+
+ _rStateSet.AddState( AccessibleStateType::VISIBLE );
+ _rStateSet.AddState( AccessibleStateType::SHOWING );
+ _rStateSet.AddState( AccessibleStateType::ENABLED );
+ _rStateSet.AddState( AccessibleStateType::SENSITIVE );
+ _rStateSet.AddState( AccessibleStateType::ACTIVE );
+
+ (void)_nColumnPos;
}
//------------------------------------------------------------------------------------------------------------------
@@ -562,30 +657,27 @@ namespace svt { namespace table
}
//------------------------------------------------------------------------------------------------------------------
- Rectangle TableControl::calcTableRect(sal_Bool _bOnScreen)
+ Rectangle TableControl::calcHeaderCellRect( sal_Bool _bIsColumnBar, sal_Int32 nPos )
{
- (void)_bOnScreen;
- return m_pImpl->calcTableRect();
+ return m_pImpl->calcHeaderCellRect( _bIsColumnBar, nPos );
}
//------------------------------------------------------------------------------------------------------------------
- IMPL_LINK( TableControl, ImplSelectHdl, void*, EMPTYARG )
+ Rectangle TableControl::calcTableRect(sal_Bool _bOnScreen)
{
- Select();
- return 1;
+ (void)_bOnScreen;
+ return m_pImpl->calcTableRect();
}
//------------------------------------------------------------------------------------------------------------------
- IMPL_LINK( TableControl, ImplMouseButtonDownHdl, MouseEvent*, pData )
+ Rectangle TableControl::calcCellRect( sal_Int32 _nRowPos, sal_Int32 _nColPos )
{
- CallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, pData );
- return 1;
+ return m_pImpl->calcCellRect( _nRowPos, _nColPos );
}
-
//------------------------------------------------------------------------------------------------------------------
- IMPL_LINK( TableControl, ImplMouseButtonUpHdl, MouseEvent*, pData )
+ IMPL_LINK( TableControl, ImplSelectHdl, void*, EMPTYARG )
{
- CallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, pData );
+ Select();
return 1;
}
@@ -593,6 +685,15 @@ namespace svt { namespace table
void TableControl::Select()
{
ImplCallEventListenersAndHandler( VCLEVENT_TABLEROW_SELECT, m_pImpl->getSelectHandler(), this );
+
+ if ( m_pImpl->isAccessibleAlive() )
+ {
+ m_pImpl->commitAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
+
+ m_pImpl->commitTableEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), Any() );
+ // TODO: why do we notify this when the *selection* changed? Shouldn't we find a better place for this,
+ // actually, when the active descendant, i.e. the current cell, *really* changed?
+ }
}
//------------------------------------------------------------------------------------------------------------------
diff --git a/svtools/source/table/tablecontrol_impl.cxx b/svtools/source/table/tablecontrol_impl.cxx
index 8e481d27d993..4ecce7359a15 100755..100644
--- a/svtools/source/table/tablecontrol_impl.cxx
+++ b/svtools/source/table/tablecontrol_impl.cxx
@@ -34,7 +34,6 @@
#include "tabledatawindow.hxx"
#include "tablecontrol_impl.hxx"
#include "tablegeometry.hxx"
-#include "cellvalueconversion.hxx"
/** === begin UNO includes === **/
#include <com/sun/star/accessibility/XAccessible.hpp>
@@ -51,6 +50,7 @@
#include <tools/diagnose_ex.h>
#include <functional>
+#include <numeric>
#define MIN_COLUMN_WIDTH_PIXEL 4
@@ -186,6 +186,22 @@ namespace svt { namespace table
{
return ::boost::optional< ::Color >();
}
+ virtual ::boost::optional< ::Color > getActiveSelectionBackColor() const
+ {
+ return ::boost::optional< ::Color >();
+ }
+ virtual ::boost::optional< ::Color > getInactiveSelectionBackColor() const
+ {
+ return ::boost::optional< ::Color >();
+ }
+ virtual ::boost::optional< ::Color > getActiveSelectionTextColor() const
+ {
+ return ::boost::optional< ::Color >();
+ }
+ virtual ::boost::optional< ::Color > getInactiveSelectionTextColor() const
+ {
+ return ::boost::optional< ::Color >();
+ }
virtual ::boost::optional< ::Color > getTextColor() const
{
return ::boost::optional< ::Color >();
@@ -487,7 +503,7 @@ namespace svt { namespace table
// recalc some model-dependent cached info
impl_ni_updateCachedModelValues();
- impl_ni_updateScrollbars();
+ impl_ni_relayout();
// completely invalidate
m_rAntiImpl.Invalidate();
@@ -535,8 +551,8 @@ namespace svt { namespace table
if ( i_first <= m_nCurRow )
goTo( m_nCurColumn, m_nCurRow + insertedRows );
- // adjust scrollbars
- impl_ni_updateScrollbars();
+ // relayout, since the scrollbar need might have changed
+ impl_ni_relayout();
// notify A1YY events
if ( impl_isAccessibleAlive() )
@@ -545,20 +561,6 @@ namespace svt { namespace table
makeAny( AccessibleTableModelChange( AccessibleTableModelChangeType::INSERT, i_first, i_last, 0, m_pModel->getColumnCount() ) ),
Any()
);
- impl_commitAccessibleEvent( AccessibleEventId::CHILD,
- makeAny( m_pAccessibleTable->getTableHeader( TCTYPE_ROWHEADERBAR ) ),
- Any()
- );
-
-// for ( sal_Int32 i = 0 ; i <= m_pModel->getColumnCount(); ++i )
-// {
-// impl_commitAccessibleEvent(
-// CHILD,
-// makeAny( m_pAccessibleTable->getTable() ),
-// Any());
-// }
- // Huh? What's that? We're notifying |columnCount| CHILD events here, claiming the *table* itself
- // has been inserted. Doesn't make much sense, does it?
}
// schedule repaint
@@ -610,13 +612,13 @@ namespace svt { namespace table
m_nCurRow = ROW_INVALID;
}
- // adjust scrollbars
- impl_ni_updateScrollbars();
+ // relayout, since the scrollbar need might have changed
+ impl_ni_relayout();
// notify A11Y events
if ( impl_isAccessibleAlive() )
{
- impl_commitAccessibleEvent(
+ commitTableEvent(
AccessibleEventId::TABLE_MODEL_CHANGED,
makeAny( AccessibleTableModelChange(
AccessibleTableModelChangeType::DELETE,
@@ -641,8 +643,7 @@ namespace svt { namespace table
void TableControl_Impl::columnInserted( ColPos const i_colIndex )
{
m_nColumnCount = m_pModel->getColumnCount();
- impl_ni_updateColumnWidths();
- impl_ni_updateScrollbars();
+ impl_ni_relayout();
m_rAntiImpl.Invalidate();
@@ -653,8 +654,17 @@ namespace svt { namespace table
void TableControl_Impl::columnRemoved( ColPos const i_colIndex )
{
m_nColumnCount = m_pModel->getColumnCount();
- impl_ni_updateColumnWidths();
- impl_ni_updateScrollbars();
+
+ // adjust the current column, if it is larger than the column count now
+ if ( m_nCurColumn >= m_nColumnCount )
+ {
+ if ( m_nColumnCount > 0 )
+ goTo( m_nCurColumn - 1, m_nCurRow );
+ else
+ m_nCurColumn = COL_INVALID;
+ }
+
+ impl_ni_relayout();
m_rAntiImpl.Invalidate();
@@ -665,8 +675,7 @@ namespace svt { namespace table
void TableControl_Impl::allColumnsRemoved()
{
m_nColumnCount = m_pModel->getColumnCount();
- impl_ni_updateColumnWidths();
- impl_ni_updateScrollbars();
+ impl_ni_relayout();
m_rAntiImpl.Invalidate();
}
@@ -683,11 +692,8 @@ namespace svt { namespace table
//------------------------------------------------------------------------------------------------------------------
void TableControl_Impl::tableMetricsChanged()
{
- long const oldRowHeaderWidthPixel = m_nRowHeaderWidthPixel;
impl_ni_updateCachedTableMetrics();
- if ( oldRowHeaderWidthPixel != m_nRowHeaderWidthPixel )
- impl_ni_updateColumnWidths();
- impl_ni_updateScrollbars();
+ impl_ni_relayout();
m_rAntiImpl.Invalidate();
}
@@ -717,9 +723,8 @@ namespace svt { namespace table
{
if ( !m_bUpdatingColWidths )
{
- impl_ni_updateColumnWidths( i_column );
+ impl_ni_relayout( i_column );
invalidate( TableAreaAll );
- impl_ni_updateScrollbars();
}
nGroup &= ~COL_ATTRS_WIDTH;
@@ -795,67 +800,157 @@ namespace svt { namespace table
//------------------------------------------------------------------------------------------------------------------
void TableControl_Impl::impl_ni_updateCachedModelValues()
{
- m_pInputHandler.reset();
- m_nColumnCount = m_nRowCount = 0;
-
- impl_ni_updateCachedTableMetrics();
- impl_ni_updateColumnWidths();
-
m_pInputHandler = m_pModel->getInputHandler();
if ( !m_pInputHandler )
m_pInputHandler.reset( new DefaultInputHandler );
m_nColumnCount = m_pModel->getColumnCount();
+ if ( m_nLeftColumn >= m_nColumnCount )
+ m_nLeftColumn = ( m_nColumnCount > 0 ) ? m_nColumnCount - 1 : 0;
+
m_nRowCount = m_pModel->getRowCount();
+ if ( m_nTopRow >= m_nRowCount )
+ m_nTopRow = ( m_nRowCount > 0 ) ? m_nRowCount - 1 : 0;
+
+ impl_ni_updateCachedTableMetrics();
}
//------------------------------------------------------------------------------------------------------------------
- void TableControl_Impl::impl_ni_updateColumnWidths( ColPos const i_assumeInflexibleColumnsUpToIncluding )
+ namespace
{
- ENSURE_OR_RETURN_VOID( !m_bUpdatingColWidths, "TableControl_Impl::impl_ni_updateColumnWidths: recursive call detected!" );
+ //..............................................................................................................
+ /// determines whether a scrollbar is needed for the given values
+ bool lcl_determineScrollbarNeed( long const i_position, ScrollbarVisibility const i_visibility,
+ long const i_availableSpace, long const i_neededSpace )
+ {
+ if ( i_visibility == ScrollbarShowNever )
+ return false;
+ if ( i_visibility == ScrollbarShowAlways )
+ return true;
+ if ( i_position > 0 )
+ return true;
+ if ( i_availableSpace >= i_neededSpace )
+ return false;
+ return true;
+ }
- m_aColumnWidths.resize( 0 );
- if ( !m_pModel )
- return;
+ //..............................................................................................................
+ void lcl_setButtonRepeat( Window& _rWindow, sal_uLong _nDelay )
+ {
+ AllSettings aSettings = _rWindow.GetSettings();
+ MouseSettings aMouseSettings = aSettings.GetMouseSettings();
- const TableSize colCount = m_pModel->getColumnCount();
- if ( colCount == 0 )
- return;
+ aMouseSettings.SetButtonRepeat( _nDelay );
+ aSettings.SetMouseSettings( aMouseSettings );
- m_bUpdatingColWidths = true;
- const ::comphelper::FlagGuard aWidthUpdateFlag( m_bUpdatingColWidths );
+ _rWindow.SetSettings( aSettings, sal_True );
+ }
- m_aColumnWidths.reserve( colCount );
+ //..............................................................................................................
+ bool lcl_updateScrollbar( Window& _rParent, ScrollBar*& _rpBar,
+ bool const i_needBar, long _nVisibleUnits,
+ long _nPosition, long _nLineSize, long _nRange,
+ bool _bHorizontal, const Link& _rScrollHandler )
+ {
+ // do we currently have the scrollbar?
+ bool bHaveBar = _rpBar != NULL;
+
+ // do we need to correct the scrollbar visibility?
+ if ( bHaveBar && !i_needBar )
+ {
+ if ( _rpBar->IsTracking() )
+ _rpBar->EndTracking();
+ DELETEZ( _rpBar );
+ }
+ else if ( !bHaveBar && i_needBar )
+ {
+ _rpBar = new ScrollBar(
+ &_rParent,
+ WB_DRAG | ( _bHorizontal ? WB_HSCROLL : WB_VSCROLL )
+ );
+ _rpBar->SetScrollHdl( _rScrollHandler );
+ // get some speed into the scrolling ....
+ lcl_setButtonRepeat( *_rpBar, 0 );
+ }
+
+ if ( _rpBar )
+ {
+ _rpBar->SetRange( Range( 0, _nRange ) );
+ _rpBar->SetVisibleSize( _nVisibleUnits );
+ _rpBar->SetPageSize( _nVisibleUnits );
+ _rpBar->SetLineSize( _nLineSize );
+ _rpBar->SetThumbPos( _nPosition );
+ _rpBar->Show();
+ }
+
+ return ( bHaveBar != i_needBar );
+ }
+ //..............................................................................................................
+ /** returns the number of rows fitting into the given range,
+ for the given row height. Partially fitting rows are counted, too, if the
+ respective parameter says so.
+ */
+ TableSize lcl_getRowsFittingInto( long _nOverallHeight, long _nRowHeightPixel, bool _bAcceptPartialRow = false )
+ {
+ return _bAcceptPartialRow
+ ? ( _nOverallHeight + ( _nRowHeightPixel - 1 ) ) / _nRowHeightPixel
+ : _nOverallHeight / _nRowHeightPixel;
+ }
+
+ //..............................................................................................................
+ /** returns the number of columns fitting into the given area,
+ with the first visible column as given. Partially fitting columns are counted, too,
+ if the respective parameter says so.
+ */
+ TableSize lcl_getColumnsVisibleWithin( const Rectangle& _rArea, ColPos _nFirstVisibleColumn,
+ const TableControl_Impl& _rControl, bool _bAcceptPartialRow )
+ {
+ TableSize visibleColumns = 0;
+ TableColumnGeometry aColumn( _rControl, _rArea, _nFirstVisibleColumn );
+ while ( aColumn.isValid() )
+ {
+ if ( !_bAcceptPartialRow )
+ if ( aColumn.getRect().Right() > _rArea.Right() )
+ // this column is only partially visible, and this is not allowed
+ break;
+
+ aColumn.moveRight();
+ ++visibleColumns;
+ }
+ return visibleColumns;
+ }
+
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ long TableControl_Impl::impl_ni_calculateColumnWidths( ColPos const i_assumeInflexibleColumnsUpToIncluding,
+ bool const i_assumeVerticalScrollbar, ::std::vector< long >& o_newColWidthsPixel ) const
+ {
// the available horizontal space
long gridWidthPixel = m_rAntiImpl.GetOutputSizePixel().Width();
+ ENSURE_OR_RETURN( !!m_pModel, "TableControl_Impl::impl_ni_calculateColumnWidths: not allowed without a model!", gridWidthPixel );
if ( m_pModel->hasRowHeaders() && ( gridWidthPixel != 0 ) )
{
gridWidthPixel -= m_nRowHeaderWidthPixel;
}
- if ( m_pModel->getVerticalScrollbarVisibility() != ScrollbarShowNever )
+
+ if ( i_assumeVerticalScrollbar && ( m_pModel->getVerticalScrollbarVisibility() != ScrollbarShowNever ) )
{
long nScrollbarMetrics = m_rAntiImpl.GetSettings().GetStyleSettings().GetScrollBarSize();
gridWidthPixel -= nScrollbarMetrics;
}
- // TODO: shouldn't we take the visibility of the vertical scroll bar into account here, too?
- long const gridWidthAppFont = m_rAntiImpl.PixelToLogic( Size( gridWidthPixel, 0 ), MAP_APPFONT ).Width();
-
- // determine the accumulated current width of all columns
- for ( ColPos col = 0; col < colCount; ++col )
- {
- const PColumnModel pColumn = m_pModel->getColumnModel( col );
- ENSURE_OR_THROW( !!pColumn, "invalid column returned by the model!" );
-
- }
+ // no need to do anything without columns
+ TableSize const colCount = m_pModel->getColumnCount();
+ if ( colCount == 0 )
+ return gridWidthPixel;
// collect some meta data for our columns:
- // - their current (appt-font) metrics
+ // - their current (pixel) metrics
long accumulatedCurrentWidth = 0;
::std::vector< long > currentColWidths;
currentColWidths.reserve( colCount );
- // - their effective minimal and maximal width (app-font!)
typedef ::std::vector< ::std::pair< long, long > > ColumnLimits;
ColumnLimits effectiveColumnLimits;
effectiveColumnLimits.reserve( colCount );
@@ -865,13 +960,14 @@ namespace svt { namespace table
::std::vector< ::sal_Int32 > columnFlexibilities;
columnFlexibilities.reserve( colCount );
long flexibilityDenominator = 0;
+ size_t flexibleColumnCount = 0;
for ( ColPos col = 0; col < colCount; ++col )
{
PColumnModel const pColumn = m_pModel->getColumnModel( col );
ENSURE_OR_THROW( !!pColumn, "invalid column returned by the model!" );
// current width
- TableMetrics const currentWidth = pColumn->getWidth();
+ long const currentWidth = appFontWidthToPixel( pColumn->getWidth() );
currentColWidths.push_back( currentWidth );
// accumulated width
@@ -879,7 +975,7 @@ namespace svt { namespace table
// flexibility
::sal_Int32 flexibility = pColumn->getFlexibility();
- OSL_ENSURE( flexibility >= 0, "TableControl_Impl::impl_ni_updateColumnWidths: a column's flexibility should be non-negative." );
+ OSL_ENSURE( flexibility >= 0, "TableControl_Impl::impl_ni_calculateColumnWidths: a column's flexibility should be non-negative." );
if ( ( flexibility < 0 ) // normalization
|| ( !pColumn->isResizable() ) // column not resizeable => no auto-resize
|| ( col <= i_assumeInflexibleColumnsUpToIncluding ) // column shall be treated as inflexible => respec this
@@ -891,18 +987,18 @@ namespace svt { namespace table
// if the column is not flexible, it will not be asked for min/max, but we assume the current width as limit then
if ( flexibility > 0 )
{
- long const minWidth = pColumn->getMinWidth();
+ long const minWidth = appFontWidthToPixel( pColumn->getMinWidth() );
if ( minWidth > 0 )
effectiveMin = minWidth;
else
effectiveMin = MIN_COLUMN_WIDTH_PIXEL;
- long const maxWidth = pColumn->getMaxWidth();
- OSL_ENSURE( minWidth <= maxWidth, "TableControl_Impl::impl_ni_updateColumnWidths: pretty undecided 'bout its width limits, this column!" );
+ long const maxWidth = appFontWidthToPixel( pColumn->getMaxWidth() );
+ OSL_ENSURE( minWidth <= maxWidth, "TableControl_Impl::impl_ni_calculateColumnWidths: pretty undecided 'bout its width limits, this column!" );
if ( ( maxWidth > 0 ) && ( maxWidth >= minWidth ) )
effectiveMax = maxWidth;
else
- effectiveMax = gridWidthAppFont; // TODO: any better guess here?
+ effectiveMax = gridWidthPixel; // TODO: any better guess here?
if ( effectiveMin == effectiveMax )
// if the min and the max are identical, this implies no flexibility at all
@@ -911,27 +1007,29 @@ namespace svt { namespace table
columnFlexibilities.push_back( flexibility );
flexibilityDenominator += flexibility;
+ if ( flexibility > 0 )
+ ++flexibleColumnCount;
effectiveColumnLimits.push_back( ::std::pair< long, long >( effectiveMin, effectiveMax ) );
accumulatedMinWidth += effectiveMin;
accumulatedMaxWidth += effectiveMax;
}
- ::std::vector< long > newWidths( currentColWidths );
+ o_newColWidthsPixel = currentColWidths;
if ( flexibilityDenominator == 0 )
{
// no column is flexible => don't adjust anything
}
- else if ( gridWidthAppFont > accumulatedCurrentWidth )
+ else if ( gridWidthPixel > accumulatedCurrentWidth )
{ // we have space to give away ...
- long distributeAppFontUnits = gridWidthAppFont - accumulatedCurrentWidth;
- if ( gridWidthAppFont > accumulatedMaxWidth )
+ long distributePixel = gridWidthPixel - accumulatedCurrentWidth;
+ if ( gridWidthPixel > accumulatedMaxWidth )
{
// ... but the column's maximal widths are still less than we have
// => set them all to max
for ( size_t i = 0; i < size_t( colCount ); ++i )
{
- newWidths[i] = effectiveColumnLimits[i].second;
+ o_newColWidthsPixel[i] = effectiveColumnLimits[i].second;
}
}
else
@@ -941,13 +1039,13 @@ namespace svt { namespace table
{
startOver = false;
// distribute the remaining space amongst all columns with a positive flexibility
- for ( size_t i=0; i<newWidths.size() && !startOver; ++i )
+ for ( size_t i=0; i<o_newColWidthsPixel.size() && !startOver; ++i )
{
long const columnFlexibility = columnFlexibilities[i];
if ( columnFlexibility == 0 )
continue;
- long newColWidth = currentColWidths[i] + columnFlexibility * distributeAppFontUnits / flexibilityDenominator;
+ long newColWidth = currentColWidths[i] + columnFlexibility * distributePixel / flexibilityDenominator;
if ( newColWidth > effectiveColumnLimits[i].second )
{ // that was too much, we hit the col's maximum
@@ -956,9 +1054,10 @@ namespace svt { namespace table
// adjust the flexibility denominator ...
flexibilityDenominator -= columnFlexibility;
columnFlexibilities[i] = 0;
+ --flexibleColumnCount;
// ... and the remaining width ...
long const difference = newColWidth - currentColWidths[i];
- distributeAppFontUnits -= difference;
+ distributePixel -= difference;
// ... this way, we ensure that the width not taken up by this column is consumed by the other
// flexible ones (if there are some)
@@ -967,22 +1066,47 @@ namespace svt { namespace table
startOver = true;
}
- newWidths[i] = newColWidth;
+ o_newColWidthsPixel[i] = newColWidth;
}
}
while ( startOver );
+
+ // are there pixels left (might be caused by rounding errors)?
+ distributePixel = gridWidthPixel - ::std::accumulate( o_newColWidthsPixel.begin(), o_newColWidthsPixel.end(), 0 );
+ while ( ( distributePixel > 0 ) && ( flexibleColumnCount > 0 ) )
+ {
+ // yes => ignore relative flexibilities, and subsequently distribute single pixels to all flexible
+ // columns which did not yet reach their maximum.
+ for ( size_t i=0; ( i < o_newColWidthsPixel.size() ) && ( distributePixel > 0 ); ++i )
+ {
+ if ( columnFlexibilities[i] == 0 )
+ continue;
+
+ OSL_ENSURE( o_newColWidthsPixel[i] <= effectiveColumnLimits[i].second,
+ "TableControl_Impl::impl_ni_calculateColumnWidths: inconsitency!" );
+ if ( o_newColWidthsPixel[i] >= effectiveColumnLimits[i].first )
+ {
+ columnFlexibilities[i] = 0;
+ --flexibleColumnCount;
+ continue;
+ }
+
+ ++o_newColWidthsPixel[i];
+ --distributePixel;
+ }
+ }
}
}
- else if ( gridWidthAppFont < accumulatedCurrentWidth )
+ else if ( gridWidthPixel < accumulatedCurrentWidth )
{ // we need to take away some space from the columns which allow it ...
- long takeAwayAppFontUnits = accumulatedCurrentWidth - gridWidthAppFont;
- if ( gridWidthAppFont < accumulatedMinWidth )
+ long takeAwayPixel = accumulatedCurrentWidth - gridWidthPixel;
+ if ( gridWidthPixel < accumulatedMinWidth )
{
// ... but the column's minimal widths are still more than we have
// => set them all to min
for ( size_t i = 0; i < size_t( colCount ); ++i )
{
- newWidths[i] = effectiveColumnLimits[i].first;
+ o_newColWidthsPixel[i] = effectiveColumnLimits[i].first;
}
}
else
@@ -992,13 +1116,13 @@ namespace svt { namespace table
{
startOver = false;
// take away the space we need from the columns with a positive flexibility
- for ( size_t i=0; i<newWidths.size() && !startOver; ++i )
+ for ( size_t i=0; i<o_newColWidthsPixel.size() && !startOver; ++i )
{
long const columnFlexibility = columnFlexibilities[i];
if ( columnFlexibility == 0 )
continue;
- long newColWidth = currentColWidths[i] - columnFlexibility * takeAwayAppFontUnits / flexibilityDenominator;
+ long newColWidth = currentColWidths[i] - columnFlexibility * takeAwayPixel / flexibilityDenominator;
if ( newColWidth < effectiveColumnLimits[i].first )
{ // that was too much, we hit the col's minimum
@@ -1007,172 +1131,79 @@ namespace svt { namespace table
// adjust the flexibility denominator ...
flexibilityDenominator -= columnFlexibility;
columnFlexibilities[i] = 0;
+ --flexibleColumnCount;
// ... and the remaining width ...
long const difference = currentColWidths[i] - newColWidth;
- takeAwayAppFontUnits -= difference;
+ takeAwayPixel -= difference;
// and start over with the first column, since there might be earlier columns which need
// to be recalculated now
startOver = true;
}
- newWidths[i] = newColWidth;
+ o_newColWidthsPixel[i] = newColWidth;
}
}
while ( startOver );
- }
- }
- // now that we have calculated the app-font widths, get the actual pixels
- long accumulatedWidthPixel = m_nRowHeaderWidthPixel;
- for ( ColPos col = 0; col < colCount; ++col )
- {
- long const colWidth = m_rAntiImpl.LogicToPixel( Size( newWidths[col], 0 ), MAP_APPFONT ).Width();
- const long columnStart = accumulatedWidthPixel;
- const long columnEnd = columnStart + colWidth;
- m_aColumnWidths.push_back( MutableColumnMetrics( columnStart, columnEnd ) );
- accumulatedWidthPixel = columnEnd;
-
- // and don't forget to forward this to the column models
- PColumnModel const pColumn = m_pModel->getColumnModel( col );
- ENSURE_OR_THROW( !!pColumn, "invalid column returned by the model!" );
- pColumn->setWidth( newWidths[col] );
- }
+ // are there pixels left (might be caused by rounding errors)?
+ takeAwayPixel = ::std::accumulate( o_newColWidthsPixel.begin(), o_newColWidthsPixel.end(), 0 ) - gridWidthPixel;
+ while ( ( takeAwayPixel > 0 ) && ( flexibleColumnCount > 0 ) )
+ {
+ // yes => ignore relative flexibilities, and subsequently take away pixels from all flexible
+ // columns which did not yet reach their minimum.
+ for ( size_t i=0; ( i < o_newColWidthsPixel.size() ) && ( takeAwayPixel > 0 ); ++i )
+ {
+ if ( columnFlexibilities[i] == 0 )
+ continue;
- // if the column resizing happened to leave some space at the right, but there are columns
- // scrolled out to the left, scroll them in
- while ( ( m_nLeftColumn > 0 )
- && ( accumulatedWidthPixel - m_aColumnWidths[ m_nLeftColumn - 1 ].getStart() <= gridWidthPixel )
- )
- {
- --m_nLeftColumn;
- }
+ OSL_ENSURE( o_newColWidthsPixel[i] >= effectiveColumnLimits[i].first,
+ "TableControl_Impl::impl_ni_calculateColumnWidths: inconsitency!" );
+ if ( o_newColWidthsPixel[i] <= effectiveColumnLimits[i].first )
+ {
+ columnFlexibilities[i] = 0;
+ --flexibleColumnCount;
+ continue;
+ }
- // now adjust the column metrics, since they currently ignore the horizontal scroll position
- if ( m_nLeftColumn > 0 )
- {
- const long offsetPixel = m_aColumnWidths[ 0 ].getStart() - m_aColumnWidths[ m_nLeftColumn ].getStart();
- for ( ColumnPositions::iterator colPos = m_aColumnWidths.begin();
- colPos != m_aColumnWidths.end();
- ++colPos
- )
- {
- colPos->move( offsetPixel );
+ --o_newColWidthsPixel[i];
+ --takeAwayPixel;
+ }
+ }
}
}
+
+ return gridWidthPixel;
}
//------------------------------------------------------------------------------------------------------------------
- namespace
+ void TableControl_Impl::impl_ni_relayout( ColPos const i_assumeInflexibleColumnsUpToIncluding )
{
- //..............................................................................................................
- /// determines whether a scrollbar is needed for the given values
- bool lcl_determineScrollbarNeed( long const i_position, ScrollbarVisibility const i_visibility,
- long const i_availableSpace, long const i_neededSpace )
- {
- if ( i_visibility == ScrollbarShowNever )
- return false;
- if ( i_visibility == ScrollbarShowAlways )
- return true;
- if ( i_position > 0 )
- return true;
- if ( i_availableSpace >= i_neededSpace )
- return false;
- return true;
- }
-
- //..............................................................................................................
- void lcl_setButtonRepeat( Window& _rWindow, sal_uLong _nDelay )
- {
- AllSettings aSettings = _rWindow.GetSettings();
- MouseSettings aMouseSettings = aSettings.GetMouseSettings();
-
- aMouseSettings.SetButtonRepeat( _nDelay );
- aSettings.SetMouseSettings( aMouseSettings );
-
- _rWindow.SetSettings( aSettings, sal_True );
- }
-
- //..............................................................................................................
- void lcl_updateScrollbar( Window& _rParent, ScrollBar*& _rpBar,
- bool const i_needBar, long _nVisibleUnits,
- long _nPosition, long _nLineSize, long _nRange,
- bool _bHorizontal, const Link& _rScrollHandler )
- {
- // do we currently have the scrollbar?
- bool bHaveBar = _rpBar != NULL;
-
- // do we need to correct the scrollbar visibility?
- if ( bHaveBar && !i_needBar )
- {
- if ( _rpBar->IsTracking() )
- _rpBar->EndTracking();
- DELETEZ( _rpBar );
- }
- else if ( !bHaveBar && i_needBar )
- {
- _rpBar = new ScrollBar(
- &_rParent,
- WB_DRAG | ( _bHorizontal ? WB_HSCROLL : WB_VSCROLL )
- );
- _rpBar->SetScrollHdl( _rScrollHandler );
- // get some speed into the scrolling ....
- lcl_setButtonRepeat( *_rpBar, 0 );
- }
-
- if ( _rpBar )
- {
- _rpBar->SetRange( Range( 0, _nRange ) );
- _rpBar->SetVisibleSize( _nVisibleUnits );
- _rpBar->SetPageSize( _nVisibleUnits );
- _rpBar->SetLineSize( _nLineSize );
- _rpBar->SetThumbPos( _nPosition );
- _rpBar->Show();
- }
- }
-
- //..............................................................................................................
- /** returns the number of rows fitting into the given range,
- for the given row height. Partially fitting rows are counted, too, if the
- respective parameter says so.
- */
- TableSize lcl_getRowsFittingInto( long _nOverallHeight, long _nRowHeightPixel, bool _bAcceptPartialRow = false )
- {
- return _bAcceptPartialRow
- ? ( _nOverallHeight + ( _nRowHeightPixel - 1 ) ) / _nRowHeightPixel
- : _nOverallHeight / _nRowHeightPixel;
- }
-
- //..............................................................................................................
- /** returns the number of columns fitting into the given area,
- with the first visible column as given. Partially fitting columns are counted, too,
- if the respective parameter says so.
- */
- TableSize lcl_getColumnsVisibleWithin( const Rectangle& _rArea, ColPos _nFirstVisibleColumn,
- const TableControl_Impl& _rControl, bool _bAcceptPartialRow )
- {
- TableSize visibleColumns = 0;
- TableColumnGeometry aColumn( _rControl, _rArea, _nFirstVisibleColumn );
- while ( aColumn.isValid() )
- {
- if ( !_bAcceptPartialRow )
- if ( aColumn.getRect().Right() > _rArea.Right() )
- // this column is only partially visible, and this is not allowed
- break;
+ ENSURE_OR_RETURN_VOID( !m_bUpdatingColWidths, "TableControl_Impl::impl_ni_relayout: recursive call detected!" );
- aColumn.moveRight();
- ++visibleColumns;
- }
- return visibleColumns;
- }
-
- }
+ m_aColumnWidths.resize( 0 );
+ if ( !m_pModel )
+ return;
- //------------------------------------------------------------------------------------------------------------------
- void TableControl_Impl::impl_ni_updateScrollbars()
- {
+ ::comphelper::FlagRestorationGuard const aWidthUpdateFlag( m_bUpdatingColWidths, true );
SuppressCursor aHideCursor( *this );
+ // layouting steps:
+ //
+ // 1. adjust column widths, leaving space for a vertical scrollbar
+ // 2. determine need for a vertical scrollbar
+ // - V-YES: all fine, result from 1. is still valid
+ // - V-NO: result from 1. is still under consideration
+ //
+ // 3. determine need for a horizontal scrollbar
+ // - H-NO: all fine, result from 2. is still valid
+ // - H-YES: reconsider need for a vertical scrollbar, if result of 2. was V-NO
+ // - V-YES: all fine, result from 1. is still valid
+ // - V-NO: redistribute the remaining space (if any) amongst all columns which allow it
+
+ ::std::vector< long > newWidthsPixel;
+ long gridWidthPixel = impl_ni_calculateColumnWidths( i_assumeInflexibleColumnsUpToIncluding, true, newWidthsPixel );
+
// the width/height of a scrollbar, needed several times below
long const nScrollbarMetrics = m_rAntiImpl.GetSettings().GetStyleSettings().GetScrollBarSize();
@@ -1181,18 +1212,13 @@ namespace svt { namespace table
Rectangle aDataCellPlayground( Point( 0, 0 ), m_rAntiImpl.GetOutputSizePixel() );
aDataCellPlayground.Left() = m_nRowHeaderWidthPixel;
aDataCellPlayground.Top() = m_nColHeaderHeightPixel;
- m_nRowCount = m_pModel->getRowCount();
- m_nColumnCount = m_pModel->getColumnCount();
- if ( m_aColumnWidths.empty() )
- impl_ni_updateColumnWidths();
- OSL_ENSURE( m_aColumnWidths.size() == size_t( m_nColumnCount ), "TableControl_Impl::impl_ni_updateScrollbars: inconsistency!" );
- const long nAllColumnsWidth = m_aColumnWidths.empty()
- ? 0
- : m_aColumnWidths[ m_nColumnCount - 1 ].getEnd() - m_aColumnWidths[ 0 ].getStart();
+ OSL_ENSURE( ( m_nRowCount == m_pModel->getRowCount() ) && ( m_nColumnCount == m_pModel->getColumnCount() ),
+ "TableControl_Impl::impl_ni_relayout: how is this expected to work with invalid data?" );
+ long const nAllColumnsWidth = ::std::accumulate( newWidthsPixel.begin(), newWidthsPixel.end(), 0 );
- const ScrollbarVisibility eVertScrollbar = m_pModel->getVerticalScrollbarVisibility();
- const ScrollbarVisibility eHorzScrollbar = m_pModel->getHorizontalScrollbarVisibility();
+ ScrollbarVisibility const eVertScrollbar = m_pModel->getVerticalScrollbarVisibility();
+ ScrollbarVisibility const eHorzScrollbar = m_pModel->getHorizontalScrollbarVisibility();
// do we need a vertical scrollbar?
bool bNeedVerticalScrollbar = lcl_determineScrollbarNeed(
@@ -1203,8 +1229,10 @@ namespace svt { namespace table
aDataCellPlayground.Right() -= nScrollbarMetrics;
bFirstRoundVScrollNeed = true;
}
+
// do we need a horizontal scrollbar?
- const bool bNeedHorizontalScrollbar = lcl_determineScrollbarNeed( m_nLeftColumn, eHorzScrollbar, aDataCellPlayground.GetWidth(), nAllColumnsWidth );
+ bool const bNeedHorizontalScrollbar = lcl_determineScrollbarNeed(
+ m_nLeftColumn, eHorzScrollbar, aDataCellPlayground.GetWidth(), nAllColumnsWidth );
if ( bNeedHorizontalScrollbar )
{
aDataCellPlayground.Bottom() -= nScrollbarMetrics;
@@ -1223,12 +1251,77 @@ namespace svt { namespace table
}
}
}
+
+ // the initial call to impl_ni_calculateColumnWidths assumed that we need a vertical scrollbar. If, by now,
+ // we know that this is not the case, re-calculate the column widths.
+ if ( !bNeedVerticalScrollbar )
+ gridWidthPixel = impl_ni_calculateColumnWidths( i_assumeInflexibleColumnsUpToIncluding, false, newWidthsPixel );
+
+ // update the column objects with the new widths we finally calculated
+ TableSize const colCount = m_pModel->getColumnCount();
+ m_aColumnWidths.reserve( colCount );
+ long accumulatedWidthPixel = m_nRowHeaderWidthPixel;
+ bool anyColumnWidthChanged = false;
+ for ( ColPos col = 0; col < colCount; ++col )
+ {
+ const long columnStart = accumulatedWidthPixel;
+ const long columnEnd = columnStart + newWidthsPixel[col];
+ m_aColumnWidths.push_back( MutableColumnMetrics( columnStart, columnEnd ) );
+ accumulatedWidthPixel = columnEnd;
+
+ // and don't forget to forward this to the column models
+ PColumnModel const pColumn = m_pModel->getColumnModel( col );
+ ENSURE_OR_THROW( !!pColumn, "invalid column returned by the model!" );
+
+ long const oldColumnWidthAppFont = pColumn->getWidth();
+ long const newColumnWidthAppFont = pixelWidthToAppFont( newWidthsPixel[col] );
+ pColumn->setWidth( newColumnWidthAppFont );
+
+ anyColumnWidthChanged |= ( oldColumnWidthAppFont != newColumnWidthAppFont );
+ }
+
+ // if the column widths changed, ensure everything is repainted
+ if ( anyColumnWidthChanged )
+ invalidate( TableAreaAll );
+
+ // if the column resizing happened to leave some space at the right, but there are columns
+ // scrolled out to the left, scroll them in
+ while ( ( m_nLeftColumn > 0 )
+ && ( accumulatedWidthPixel - m_aColumnWidths[ m_nLeftColumn - 1 ].getStart() <= gridWidthPixel )
+ )
+ {
+ --m_nLeftColumn;
+ }
+
+ // now adjust the column metrics, since they currently ignore the horizontal scroll position
+ if ( m_nLeftColumn > 0 )
+ {
+ const long offsetPixel = m_aColumnWidths[ 0 ].getStart() - m_aColumnWidths[ m_nLeftColumn ].getStart();
+ for ( ColumnPositions::iterator colPos = m_aColumnWidths.begin();
+ colPos != m_aColumnWidths.end();
+ ++colPos
+ )
+ {
+ colPos->move( offsetPixel );
+ }
+ }
+
+ // show or hide the scrollbars as needed, and position the data window
+ impl_ni_positionChildWindows( aDataCellPlayground, bNeedVerticalScrollbar, bNeedHorizontalScrollbar );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void TableControl_Impl::impl_ni_positionChildWindows( Rectangle const & i_dataCellPlayground,
+ bool const i_verticalScrollbar, bool const i_horizontalScrollbar )
+ {
+ long const nScrollbarMetrics = m_rAntiImpl.GetSettings().GetStyleSettings().GetScrollBarSize();
+
// create or destroy the vertical scrollbar, as needed
lcl_updateScrollbar(
m_rAntiImpl,
m_pVScroll,
- bNeedVerticalScrollbar,
- lcl_getRowsFittingInto( aDataCellPlayground.GetHeight(), m_nRowHeightPixel ),
+ i_verticalScrollbar,
+ lcl_getRowsFittingInto( i_dataCellPlayground.GetHeight(), m_nRowHeightPixel ),
// visible units
m_nTopRow, // current position
1, // line size
@@ -1236,12 +1329,13 @@ namespace svt { namespace table
false, // vertical
LINK( this, TableControl_Impl, OnScroll ) // scroll handler
);
+
// position it
if ( m_pVScroll )
{
Rectangle aScrollbarArea(
- Point( aDataCellPlayground.Right() + 1, 0 ),
- Size( nScrollbarMetrics, aDataCellPlayground.Bottom() + 1 )
+ Point( i_dataCellPlayground.Right() + 1, 0 ),
+ Size( nScrollbarMetrics, i_dataCellPlayground.Bottom() + 1 )
);
m_pVScroll->SetPosSizePixel(
aScrollbarArea.TopLeft(), aScrollbarArea.GetSize() );
@@ -1251,8 +1345,8 @@ namespace svt { namespace table
lcl_updateScrollbar(
m_rAntiImpl,
m_pHScroll,
- bNeedHorizontalScrollbar,
- lcl_getColumnsVisibleWithin( aDataCellPlayground, m_nLeftColumn, *this, false ),
+ i_horizontalScrollbar,
+ lcl_getColumnsVisibleWithin( i_dataCellPlayground, m_nLeftColumn, *this, false ),
// visible units
m_nLeftColumn, // current position
1, // line size
@@ -1260,22 +1354,23 @@ namespace svt { namespace table
true, // horizontal
LINK( this, TableControl_Impl, OnScroll ) // scroll handler
);
+
// position it
if ( m_pHScroll )
{
- TableSize const nVisibleUnits = lcl_getColumnsVisibleWithin( aDataCellPlayground, m_nLeftColumn, *this, false );
+ TableSize const nVisibleUnits = lcl_getColumnsVisibleWithin( i_dataCellPlayground, m_nLeftColumn, *this, false );
TableMetrics const nRange = m_nColumnCount;
if( m_nLeftColumn + nVisibleUnits == nRange - 1 )
{
- if ( m_aColumnWidths[ nRange - 1 ].getStart() - m_aColumnWidths[ m_nLeftColumn ].getEnd() + m_aColumnWidths[ nRange-1 ].getWidth() > aDataCellPlayground.GetWidth() )
+ if ( m_aColumnWidths[ nRange - 1 ].getStart() - m_aColumnWidths[ m_nLeftColumn ].getEnd() + m_aColumnWidths[ nRange-1 ].getWidth() > i_dataCellPlayground.GetWidth() )
{
m_pHScroll->SetVisibleSize( nVisibleUnits -1 );
m_pHScroll->SetPageSize( nVisibleUnits - 1 );
}
}
Rectangle aScrollbarArea(
- Point( 0, aDataCellPlayground.Bottom() + 1 ),
- Size( aDataCellPlayground.Right() + 1, nScrollbarMetrics )
+ Point( 0, i_dataCellPlayground.Bottom() + 1 ),
+ Size( i_dataCellPlayground.Right() + 1, nScrollbarMetrics )
);
m_pHScroll->SetPosSizePixel(
aScrollbarArea.TopLeft(), aScrollbarArea.GetSize() );
@@ -1292,19 +1387,19 @@ namespace svt { namespace table
{
m_pScrollCorner = new ScrollBarBox( &m_rAntiImpl );
m_pScrollCorner->SetSizePixel( Size( nScrollbarMetrics, nScrollbarMetrics ) );
- m_pScrollCorner->SetPosPixel( Point( aDataCellPlayground.Right() + 1, aDataCellPlayground.Bottom() + 1 ) );
+ m_pScrollCorner->SetPosPixel( Point( i_dataCellPlayground.Right() + 1, i_dataCellPlayground.Bottom() + 1 ) );
m_pScrollCorner->Show();
}
else if(bHaveScrollCorner && bNeedScrollCorner)
{
- m_pScrollCorner->SetPosPixel( Point( aDataCellPlayground.Right() + 1, aDataCellPlayground.Bottom() + 1 ) );
+ m_pScrollCorner->SetPosPixel( Point( i_dataCellPlayground.Right() + 1, i_dataCellPlayground.Bottom() + 1 ) );
m_pScrollCorner->Show();
}
// resize the data window
m_pDataWindow->SetSizePixel( Size(
- aDataCellPlayground.GetWidth() + m_nRowHeaderWidthPixel,
- aDataCellPlayground.GetHeight() + m_nColHeaderHeightPixel
+ i_dataCellPlayground.GetWidth() + m_nRowHeaderWidthPixel,
+ i_dataCellPlayground.GetHeight() + m_nColHeaderHeightPixel
) );
}
@@ -1313,8 +1408,7 @@ namespace svt { namespace table
{
DBG_CHECK_ME();
- impl_ni_updateColumnWidths();
- impl_ni_updateScrollbars();
+ impl_ni_relayout();
checkCursorPosition();
}
@@ -1408,14 +1502,14 @@ namespace svt { namespace table
if ( _rUpdateRect.GetIntersection( aRowIterator.getRect() ).IsEmpty() )
continue;
- bool const isActiveRow = ( aRowIterator.getRow() == getCurrentRow() );
+ bool const isControlFocused = m_rAntiImpl.HasControlFocus();
bool const isSelectedRow = isRowSelected( aRowIterator.getRow() );
Rectangle const aRect = aRowIterator.getRect().GetIntersection( aAllDataCellsArea );
// give the redenderer a chance to prepare the row
pRenderer->PrepareRow(
- aRowIterator.getRow(), isActiveRow, isSelectedRow,
+ aRowIterator.getRow(), isControlFocused, isSelectedRow,
*m_pDataWindow, aRect, rStyle
);
@@ -1423,7 +1517,7 @@ namespace svt { namespace table
if ( m_pModel->hasRowHeaders() )
{
const Rectangle aCurrentRowHeader( aRowHeaderArea.GetIntersection( aRowIterator.getRect() ) );
- pRenderer->PaintRowHeader( isActiveRow, isSelectedRow, *m_pDataWindow, aCurrentRowHeader,
+ pRenderer->PaintRowHeader( isControlFocused, isSelectedRow, *m_pDataWindow, aCurrentRowHeader,
rStyle );
}
@@ -1437,7 +1531,7 @@ namespace svt { namespace table
)
{
bool isSelectedColumn = false;
- pRenderer->PaintCell( aCell.getColumn(), isSelectedRow || isSelectedColumn, isActiveRow,
+ pRenderer->PaintCell( aCell.getColumn(), isSelectedRow || isSelectedColumn, isControlFocused,
*m_pDataWindow, aCell.getRect(), rStyle );
}
}
@@ -1469,30 +1563,25 @@ namespace svt { namespace table
bool bSuccess = false;
bool selectionChanged = false;
- Rectangle rCells;
switch ( _eAction )
{
case cursorDown:
- if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION)
+ if ( m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION )
{
//if other rows already selected, deselect them
- if(m_aSelectedRows.size()>0)
+ if ( m_aSelectedRows.size()>0 )
{
- for(std::vector<RowPos>::iterator it=m_aSelectedRows.begin();
- it!=m_aSelectedRows.end();++it)
- {
- invalidateSelectedRegion(*it, *it, rCells);
- }
+ invalidateSelectedRows();
m_aSelectedRows.clear();
}
- if(m_nCurRow < m_nRowCount-1)
+ if ( m_nCurRow < m_nRowCount-1 )
{
++m_nCurRow;
m_aSelectedRows.push_back(m_nCurRow);
}
else
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ invalidateRow( m_nCurRow );
ensureVisible(m_nCurColumn,m_nCurRow,false);
selectionChanged = true;
bSuccess = true;
@@ -1509,23 +1598,19 @@ namespace svt { namespace table
{
if(m_aSelectedRows.size()>0)
{
- for(std::vector<RowPos>::iterator it=m_aSelectedRows.begin();
- it!=m_aSelectedRows.end();++it)
- {
- invalidateSelectedRegion(*it, *it, rCells);
- }
+ invalidateSelectedRows();
m_aSelectedRows.clear();
}
if(m_nCurRow>0)
{
--m_nCurRow;
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ invalidateRow( m_nCurRow );
}
else
{
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ invalidateRow( m_nCurRow );
}
ensureVisible(m_nCurColumn,m_nCurRow,false);
selectionChanged = true;
@@ -1607,7 +1692,7 @@ namespace svt { namespace table
//else select the row->put it in the vector
else
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ invalidateRow( m_nCurRow );
selectionChanged = true;
bSuccess = true;
}
@@ -1630,14 +1715,10 @@ namespace svt { namespace table
//and select the current row
if(m_nAnchor==-1)
{
- for(std::vector<RowPos>::iterator it=m_aSelectedRows.begin();
- it!=m_aSelectedRows.end();++it)
- {
- invalidateSelectedRegion(*it, *it, rCells);
- }
+ invalidateSelectedRows();
m_aSelectedRows.clear();
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ invalidateRow( m_nCurRow );
}
else
{
@@ -1655,12 +1736,12 @@ namespace svt { namespace table
if(nextRow>-1 && m_aSelectedRows[nextRow] == m_nCurRow)
{
m_aSelectedRows.erase(m_aSelectedRows.begin()+prevRow);
- invalidateSelectedRegion(m_nCurRow+1, m_nCurRow+1, rCells);
+ invalidateRow( m_nCurRow + 1 );
}
else
{
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ invalidateRow( m_nCurRow );
}
}
else
@@ -1670,7 +1751,7 @@ namespace svt { namespace table
m_aSelectedRows.push_back(m_nCurRow);
m_nCurRow--;
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow+1, m_nCurRow, rCells);
+ invalidateSelectedRegion( m_nCurRow+1, m_nCurRow );
}
}
}
@@ -1685,12 +1766,12 @@ namespace svt { namespace table
m_aSelectedRows.push_back(m_nCurRow);
m_nCurRow--;
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow+1, m_nCurRow, rCells);
+ invalidateSelectedRegion( m_nCurRow+1, m_nCurRow );
}
else
{
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ invalidateRow( m_nCurRow );
}
}
m_pSelEngine->SetAnchor(sal_True);
@@ -1717,14 +1798,10 @@ namespace svt { namespace table
//and select the current row
if(m_nAnchor==-1)
{
- for(std::vector<RowPos>::iterator it=m_aSelectedRows.begin();
- it!=m_aSelectedRows.end();++it)
- {
- invalidateSelectedRegion(*it, *it, rCells);
- }
+ invalidateSelectedRows();
m_aSelectedRows.clear();
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ invalidateRow( m_nCurRow );
}
else
{
@@ -1742,12 +1819,12 @@ namespace svt { namespace table
if(nextRow>-1 && m_aSelectedRows[nextRow] == m_nCurRow)
{
m_aSelectedRows.erase(m_aSelectedRows.begin()+prevRow);
- invalidateSelectedRegion(m_nCurRow-1, m_nCurRow-1, rCells);
+ invalidateRow( m_nCurRow - 1 );
}
else
{
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ invalidateRow( m_nCurRow );
}
}
else
@@ -1757,7 +1834,7 @@ namespace svt { namespace table
m_aSelectedRows.push_back(m_nCurRow);
m_nCurRow++;
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow-1, m_nCurRow, rCells);
+ invalidateSelectedRegion( m_nCurRow-1, m_nCurRow );
}
}
}
@@ -1770,12 +1847,12 @@ namespace svt { namespace table
m_aSelectedRows.push_back(m_nCurRow);
m_nCurRow++;
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow-1, m_nCurRow, rCells);
+ invalidateSelectedRegion( m_nCurRow-1, m_nCurRow );
}
else
{
m_aSelectedRows.push_back(m_nCurRow);
- invalidateSelectedRegion(m_nCurRow, m_nCurRow, rCells);
+ invalidateRow( m_nCurRow );
}
}
m_pSelEngine->SetAnchor(sal_True);
@@ -1797,7 +1874,7 @@ namespace svt { namespace table
{
//select the region between the current and the upper row
RowPos iter = m_nCurRow;
- invalidateSelectedRegion(m_nCurRow, 0, rCells);
+ invalidateSelectedRegion( m_nCurRow, 0 );
//put the rows in vector
while(iter>=0)
{
@@ -1823,7 +1900,7 @@ namespace svt { namespace table
return bSuccess = false;
//select the region between the current and the last row
RowPos iter = m_nCurRow;
- invalidateSelectedRegion(m_nCurRow, m_nRowCount-1, rCells);
+ invalidateSelectedRegion( m_nCurRow, m_nRowCount-1 );
//put the rows in the vector
while(iter<=m_nRowCount)
{
@@ -2001,6 +2078,12 @@ namespace svt { namespace table
}
//------------------------------------------------------------------------------------------------------------------
+ long TableControl_Impl::appFontWidthToPixel( long const i_appFontUnits ) const
+ {
+ return m_pDataWindow->LogicToPixel( Size( i_appFontUnits, 0 ), MAP_APPFONT ).Width();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
void TableControl_Impl::hideTracking()
{
m_pDataWindow->HideTracking();
@@ -2020,48 +2103,59 @@ namespace svt { namespace table
}
//------------------------------------------------------------------------------------------------------------------
- void TableControl_Impl::invalidateSelectedRegion(RowPos _nPrevRow, RowPos _nCurRow, Rectangle& _rCellRect)
+ void TableControl_Impl::invalidateSelectedRegion( RowPos _nPrevRow, RowPos _nCurRow )
{
DBG_CHECK_ME();
- //get the visible area of the table control and set the Left and right border of the region to be repainted
+ // get the visible area of the table control and set the Left and right border of the region to be repainted
Rectangle const aAllCells( impl_getAllVisibleCellsArea() );
- _rCellRect.Left() = aAllCells.Left();
- _rCellRect.Right() = aAllCells.Right();
- //if only one row is selected
- if(_nPrevRow == _nCurRow)
+
+ Rectangle aInvalidateRect;
+ aInvalidateRect.Left() = aAllCells.Left();
+ aInvalidateRect.Right() = aAllCells.Right();
+ // if only one row is selected
+ if ( _nPrevRow == _nCurRow )
{
Rectangle aCellRect;
impl_getCellRect( m_nCurColumn, _nCurRow, aCellRect );
- _rCellRect.Top() = aCellRect.Top();
- _rCellRect.Bottom() = aCellRect.Bottom();
+ aInvalidateRect.Top() = aCellRect.Top();
+ aInvalidateRect.Bottom() = aCellRect.Bottom();
}
//if the region is above the current row
else if(_nPrevRow < _nCurRow )
{
Rectangle aCellRect;
impl_getCellRect( m_nCurColumn, _nPrevRow, aCellRect );
- _rCellRect.Top() = aCellRect.Top();
+ aInvalidateRect.Top() = aCellRect.Top();
impl_getCellRect( m_nCurColumn, _nCurRow, aCellRect );
- _rCellRect.Bottom() = aCellRect.Bottom();
+ aInvalidateRect.Bottom() = aCellRect.Bottom();
}
//if the region is beneath the current row
else
{
Rectangle aCellRect;
impl_getCellRect( m_nCurColumn, _nCurRow, aCellRect );
- _rCellRect.Top() = aCellRect.Top();
+ aInvalidateRect.Top() = aCellRect.Top();
impl_getCellRect( m_nCurColumn, _nPrevRow, aCellRect );
- _rCellRect.Bottom() = aCellRect.Bottom();
+ aInvalidateRect.Bottom() = aCellRect.Bottom();
}
- m_pDataWindow->Invalidate(_rCellRect);
+ m_pDataWindow->Invalidate( aInvalidateRect );
}
+
//------------------------------------------------------------------------------------------------------------------
- void TableControl_Impl::invalidateRowRange( RowPos const i_firstRow, RowPos const i_lastRow )
+ void TableControl_Impl::invalidateSelectedRows()
{
- if ( m_nCursorHidden == 2 )
- // WTF? what kind of hack is this?
- --m_nCursorHidden;
+ for ( ::std::vector< RowPos >::iterator selRow = m_aSelectedRows.begin();
+ selRow != m_aSelectedRows.end();
+ ++selRow
+ )
+ {
+ invalidateRow( *selRow );
+ }
+ }
+ //------------------------------------------------------------------------------------------------------------------
+ void TableControl_Impl::invalidateRowRange( RowPos const i_firstRow, RowPos const i_lastRow )
+ {
RowPos const firstRow = i_firstRow < m_nTopRow ? m_nTopRow : i_firstRow;
RowPos const lastVisibleRow = m_nTopRow + impl_getVisibleRows( true ) - 1;
RowPos const lastRow = ( ( i_lastRow == ROW_INVALID ) || ( i_lastRow > lastVisibleRow ) ) ? lastVisibleRow : i_lastRow;
@@ -2203,9 +2297,13 @@ namespace svt { namespace table
//--------------------------------------------------------------------
::rtl::OUString TableControl_Impl::getCellContentAsString( RowPos const i_row, ColPos const i_col )
{
- ::com::sun::star::uno::Any content;
- m_pModel->getCellContent( i_col, i_row, content );
- return CellValueConversion::convertToString( content );
+ Any aCellValue;
+ m_pModel->getCellContent( i_col, i_row, aCellValue );
+
+ ::rtl::OUString sCellStringContent;
+ m_pModel->getRenderer()->GetFormattedCellString( aCellValue, i_col, i_row, sCellStringContent );
+
+ return sCellStringContent;
}
//--------------------------------------------------------------------
@@ -2245,12 +2343,19 @@ namespace svt { namespace table
m_pDataWindow->Invalidate( INVALIDATE_UPDATE );
// update the position at the vertical scrollbar
- m_pVScroll->SetThumbPos( m_nTopRow );
- }
-
- // The scroll bar availaility might change when we scrolled. This is because we do not hide
- // the scrollbar when it is, in theory, unnecessary, but currently at a position > 0. In this case, it will
- // be auto-hidden when it's scrolled back to pos 0.
+ if ( m_pVScroll != NULL )
+ m_pVScroll->SetThumbPos( m_nTopRow );
+ }
+
+ // The scroll bar availaility might change when we scrolled.
+ // For instance, imagine a view with 10 rows, if which 5 fit into the window, numbered 1 to 10.
+ // Now let
+ // - the user scroll to row number 6, so the last 5 rows are visible
+ // - somebody remove the last 4 rows
+ // - the user scroll to row number 5 being the top row, so the last two rows are visible
+ // - somebody remove row number 6
+ // - the user scroll to row number 1
+ // => in this case, the need for the scrollbar vanishes immediately.
if ( m_nTopRow == 0 )
m_rAntiImpl.PostUserEvent( LINK( this, TableControl_Impl, OnUpdateScrollbars ) );
@@ -2315,7 +2420,8 @@ namespace svt { namespace table
m_pDataWindow->Invalidate( INVALIDATE_UPDATE );
// update the position at the horizontal scrollbar
- m_pHScroll->SetThumbPos( m_nLeftColumn );
+ if ( m_pHScroll != NULL )
+ m_pHScroll->SetThumbPos( m_nLeftColumn );
}
// The scroll bar availaility might change when we scrolled. This is because we do not hide
@@ -2388,18 +2494,16 @@ namespace svt { namespace table
if ( i_ordinate < m_nRowHeaderWidthPixel )
return COL_ROW_HEADERS;
- long const ordinate = i_ordinate - m_nRowHeaderWidthPixel;
-
ColumnPositions::const_iterator lowerBound = ::std::lower_bound(
m_aColumnWidths.begin(),
m_aColumnWidths.end(),
- ordinate + 1,
+ i_ordinate + 1,
ColumnInfoPositionLess()
);
if ( lowerBound == m_aColumnWidths.end() )
{
// point is *behind* the start of the last column ...
- if ( ordinate < m_aColumnWidths.rbegin()->getEnd() )
+ if ( i_ordinate < m_aColumnWidths.rbegin()->getEnd() )
// ... but still before its end
return m_nColumnCount - 1;
return COL_INVALID;
@@ -2506,6 +2610,28 @@ namespace svt { namespace table
}
//--------------------------------------------------------------------
+ void TableControl_Impl::commitAccessibleEvent( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue )
+ {
+ impl_commitAccessibleEvent( i_eventID, i_newValue, i_oldValue );
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::commitCellEvent( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue )
+ {
+ DBG_CHECK_ME();
+ if ( impl_isAccessibleAlive() )
+ m_pAccessibleTable->commitCellEvent( i_eventID, i_newValue, i_oldValue );
+ }
+
+ //--------------------------------------------------------------------
+ void TableControl_Impl::commitTableEvent( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue )
+ {
+ DBG_CHECK_ME();
+ if ( impl_isAccessibleAlive() )
+ m_pAccessibleTable->commitTableEvent( i_eventID, i_newValue, i_oldValue );
+ }
+
+ //--------------------------------------------------------------------
Rectangle TableControl_Impl::calcHeaderRect(bool bColHeader)
{
Rectangle const aRectTableWithHeaders( impl_getAllVisibleCellsArea() );
@@ -2517,16 +2643,38 @@ namespace svt { namespace table
}
//--------------------------------------------------------------------
+ Rectangle TableControl_Impl::calcHeaderCellRect( bool bColHeader, sal_Int32 nPos )
+ {
+ Rectangle const aHeaderRect = calcHeaderRect( bColHeader );
+ TableCellGeometry const aGeometry(
+ *this, aHeaderRect,
+ bColHeader ? nPos : COL_ROW_HEADERS,
+ bColHeader ? ROW_COL_HEADERS : nPos
+ );
+ return aGeometry.getRect();
+ }
+
+ //--------------------------------------------------------------------
Rectangle TableControl_Impl::calcTableRect()
{
return impl_getAllVisibleDataCellArea();
}
//--------------------------------------------------------------------
+ Rectangle TableControl_Impl::calcCellRect( sal_Int32 nRow, sal_Int32 nCol )
+ {
+ Rectangle aCellRect;
+ impl_getCellRect( nRow, nCol, aCellRect );
+ return aCellRect;
+ }
+
+ //--------------------------------------------------------------------
IMPL_LINK( TableControl_Impl, OnUpdateScrollbars, void*, /**/ )
{
DBG_CHECK_ME();
- impl_ni_updateScrollbars();
+ // TODO: can't we simply use lcl_updateScrollbar here, so the scrollbars ranges are updated, instead of
+ // doing a complete re-layout?
+ impl_ni_relayout();
return 1L;
}
@@ -2666,8 +2814,7 @@ namespace svt { namespace table
}
m_pTableControl->setAnchor( m_pTableControl->getAnchor() - 1 );
}
- Rectangle aCellRect;
- m_pTableControl->invalidateSelectedRegion( m_pTableControl->getCurRow(), newRow, aCellRect );
+ m_pTableControl->invalidateSelectedRegion( m_pTableControl->getCurRow(), newRow );
bHandled = sal_True;
}
//no region selected
@@ -2690,8 +2837,7 @@ namespace svt { namespace table
if ( m_pTableControl->getSelectedRowCount() > 1 && m_pTableControl->getSelEngine()->GetSelectionMode() != SINGLE_SELECTION )
m_pTableControl->getSelEngine()->AddAlways(sal_True);
- Rectangle aCellRect;
- m_pTableControl->invalidateSelectedRegion( newRow, newRow, aCellRect );
+ m_pTableControl->invalidateRow( newRow );
bHandled = sal_True;
}
m_pTableControl->goTo( newCol, newRow );
@@ -2716,8 +2862,7 @@ namespace svt { namespace table
void TableFunctionSet::DeselectAtPoint( const Point& rPoint )
{
(void)rPoint;
- Rectangle aCellRange;
- m_pTableControl->invalidateSelectedRegion( m_nCurrentRow, m_nCurrentRow, aCellRange );
+ m_pTableControl->invalidateRow( m_nCurrentRow );
m_pTableControl->markRowAsDeselected( m_nCurrentRow );
}
@@ -2726,11 +2871,10 @@ namespace svt { namespace table
{
if ( m_pTableControl->hasRowSelection() )
{
- Rectangle aCellRange;
for ( size_t i=0; i<m_pTableControl->getSelectedRowCount(); ++i )
{
RowPos const rowIndex = m_pTableControl->getSelectedRowIndex(i);
- m_pTableControl->invalidateSelectedRegion( rowIndex, rowIndex, aCellRange );
+ m_pTableControl->invalidateRow( rowIndex );
}
m_pTableControl->markAllRowsAsDeselected();
diff --git a/svtools/source/table/tablecontrol_impl.hxx b/svtools/source/table/tablecontrol_impl.hxx
index bc1ac55fbe51..4f3d18aa84fd 100755..100644
--- a/svtools/source/table/tablecontrol_impl.hxx
+++ b/svtools/source/table/tablecontrol_impl.hxx
@@ -226,10 +226,10 @@ namespace svt { namespace table
/** returns the position of the current row in the selection vector */
int getRowSelectedNumber(const ::std::vector<RowPos>& selectedRows, RowPos current);
- /** _rCellRect contains the region, which should be invalidate after some action e.g. selecting row*/
- void invalidateSelectedRegion(RowPos _nPrevRow, RowPos _nCurRow, Rectangle& _rCellRect );
+ /** ??? */
+ void invalidateSelectedRegion( RowPos _nPrevRow, RowPos _nCurRow );
- /** invalidates the part of the data window which is covered by the given row
+ /** invalidates the part of the data window which is covered by the given rows
@param i_firstRow
the index of the first row to include in the invalidation
@param i_lastRow
@@ -238,6 +238,14 @@ namespace svt { namespace table
*/
void invalidateRowRange( RowPos const i_firstRow, RowPos const i_lastRow );
+ /** invalidates the part of the data window which is covered by the given row
+ */
+ void invalidateRow( RowPos const i_row ) { invalidateRowRange( i_row, i_row ); }
+
+ /** invalidates all selected rows
+ */
+ void invalidateSelectedRows();
+
void checkCursorPosition();
bool hasRowSelection() const { return !m_aSelectedRows.empty(); }
@@ -272,6 +280,10 @@ namespace svt { namespace table
void setSelectHandler( Link const & i_selectHandler ) { m_aSelectHdl = i_selectHandler; }
Link const& getSelectHandler() const { return m_aSelectHdl; }
+ void commitAccessibleEvent( sal_Int16 const i_eventID, const com::sun::star::uno::Any& i_newValue, const com::sun::star::uno::Any& i_oldValue );
+ void commitCellEvent( sal_Int16 const i_eventID, const com::sun::star::uno::Any& i_newValue, const com::sun::star::uno::Any& i_oldValue );
+ void commitTableEvent( sal_Int16 const i_eventID, const com::sun::star::uno::Any& i_newValue, const com::sun::star::uno::Any& i_oldValue );
+
// ITableControl
virtual void hideCursor();
virtual void showCursor();
@@ -296,19 +308,25 @@ namespace svt { namespace table
virtual bool isRowSelected( RowPos i_row ) const;
+ long appFontWidthToPixel( long const i_appFontUnits ) const;
+
TableDataWindow& getDataWindow() { return *m_pDataWindow; }
const TableDataWindow& getDataWindow() const { return *m_pDataWindow; }
ScrollBar* getHorzScrollbar();
ScrollBar* getVertScrollbar();
- Rectangle calcHeaderRect(bool bColHeader);
+ Rectangle calcHeaderRect( bool bColHeader );
+ Rectangle calcHeaderCellRect( bool bColHeader, sal_Int32 nPos );
Rectangle calcTableRect();
+ Rectangle calcCellRect( sal_Int32 nRow, sal_Int32 nCol );
// A11Y
::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
getAccessible( Window& i_parentWindow );
void disposeAccessible();
+ inline bool isAccessibleAlive() const { return impl_isAccessibleAlive(); }
+
// ITableModelListener
virtual void rowsInserted( RowPos first, RowPos last );
virtual void rowsRemoved( RowPos first, RowPos last );
@@ -371,26 +389,45 @@ namespace svt { namespace table
*/
void impl_ni_updateCachedTableMetrics();
- /** updates ->m_aColumnWidthsPixel with the current pixel widths of all model columns
+ /** does a relayout of the table control
- The method is not bound to the classes public invariants, as it's used in
- situations where the they must not necessarily be fullfilled.
+ Column widths, and consequently the availability of the vertical and horizontal scrollbar, are updated
+ with a call to this method.
@param i_assumeInflexibleColumnsUpToIncluding
the index of a column up to which all columns should be considered as inflexible, or
<code>COL_INVALID</code>.
*/
- void impl_ni_updateColumnWidths( ColPos const i_assumeInflexibleColumnsUpToIncluding = COL_INVALID );
+ void impl_ni_relayout( ColPos const i_assumeInflexibleColumnsUpToIncluding = COL_INVALID );
- /** updates the scrollbars of the control
+ /** calculates the new width of our columns, taking into account their min and max widths, and their relative
+ flexibility.
- The method is not bound to the classes public invariants, as it's used in
- situations where the they must not necessarily be fullfilled.
+ @param i_assumeInflexibleColumnsUpToIncluding
+ the index of a column up to which all columns should be considered as inflexible, or
+ <code>COL_INVALID</code>.
+
+ @param i_assumeVerticalScrollbar
+ controls whether or not we should assume the presence of a vertical scrollbar. If <true/>, and
+ if the model has a VerticalScrollbarVisibility != ScrollbarShowNever, the method will leave
+ space for a vertical scrollbar.
+
+ @return
+ the overall width of the grid, which is available for columns
+ */
+ long impl_ni_calculateColumnWidths(
+ ColPos const i_assumeInflexibleColumnsUpToIncluding,
+ bool const i_assumeVerticalScrollbar,
+ ::std::vector< long >& o_newColWidthsPixel
+ ) const;
- This includes both the existence of the scrollbars, and their
- state.
+ /** positions all child windows, e.g. the both scrollbars, the corner window, and the data window
*/
- void impl_ni_updateScrollbars();
+ void impl_ni_positionChildWindows(
+ Rectangle const & i_dataCellPlayground,
+ bool const i_verticalScrollbar,
+ bool const i_horizontalScrollbar
+ );
/** scrolls the view by the given number of rows
diff --git a/svtools/source/table/tabledatawindow.cxx b/svtools/source/table/tabledatawindow.cxx
index 11605e36c8b2..ccdd826686f6 100644
--- a/svtools/source/table/tabledatawindow.cxx
+++ b/svtools/source/table/tabledatawindow.cxx
@@ -32,7 +32,6 @@
#include "tabledatawindow.hxx"
#include "tablecontrol_impl.hxx"
#include "tablegeometry.hxx"
-#include "cellvalueconversion.hxx"
#include <vcl/help.hxx>
@@ -140,7 +139,7 @@ namespace svt { namespace table
aCellToolTip.clear();
}
- sHelpText = CellValueConversion::convertToString( aCellToolTip );
+ pTableModel->getRenderer()->GetFormattedCellString( aCellToolTip, hitCol, hitRow, sHelpText );
if ( sHelpText.indexOf( '\n' ) >= 0 )
nHelpStyle = QUICKHELP_TIP_STYLE_BALLOON;
@@ -149,18 +148,26 @@ namespace svt { namespace table
if ( sHelpText.getLength() )
{
+ // hide the standard (singleton) help window, so we do not have two help windows open at the same time
+ Help::HideBalloonAndQuickHelp();
+
Rectangle const aControlScreenRect(
OutputToScreenPixel( Point( 0, 0 ) ),
GetOutputSizePixel()
);
if ( m_nTipWindowHandle )
+ {
Help::UpdateTip( m_nTipWindowHandle, this, aControlScreenRect, sHelpText );
+ }
else
m_nTipWindowHandle = Help::ShowTip( this, aControlScreenRect, sHelpText, nHelpStyle );
}
else
+ {
impl_hideTipWindow();
+ Window::RequestHelp( rHEvt );
+ }
}
//------------------------------------------------------------------------------------------------------------------
@@ -204,7 +211,6 @@ namespace svt { namespace table
{
m_aSelectHdl.Call( NULL );
}
- m_aMouseButtonDownHdl.Call((MouseEvent*) &rMEvt);
}
//------------------------------------------------------------------------------------------------------------------
@@ -213,7 +219,6 @@ namespace svt { namespace table
if ( !m_rTableControl.getInputHandler()->MouseButtonUp( m_rTableControl, rMEvt ) )
Window::MouseButtonUp( rMEvt );
- m_aMouseButtonUpHdl.Call((MouseEvent*) &rMEvt);
m_rTableControl.getAntiImpl().GrabFocus();
}
diff --git a/svtools/source/table/tabledatawindow.hxx b/svtools/source/table/tabledatawindow.hxx
index 6f78ac49c44d..645c37641870 100644
--- a/svtools/source/table/tabledatawindow.hxx
+++ b/svtools/source/table/tabledatawindow.hxx
@@ -52,8 +52,6 @@ namespace svt { namespace table
friend class TableFunctionSet;
private:
TableControl_Impl& m_rTableControl;
- Link m_aMouseButtonDownHdl;
- Link m_aMouseButtonUpHdl;
Link m_aSelectHdl;
sal_uLong m_nTipWindowHandle;
@@ -61,10 +59,6 @@ namespace svt { namespace table
TableDataWindow( TableControl_Impl& _rTableControl );
~TableDataWindow();
- inline void SetMouseButtonDownHdl( const Link& rLink ) { m_aMouseButtonDownHdl = rLink; }
- inline const Link& GetMouseButtonDownHdl() const { return m_aMouseButtonDownHdl; }
- inline void SetMouseButtonUpHdl( const Link& rLink ) { m_aMouseButtonUpHdl = rLink; }
- inline const Link& GetMouseButtonUpHdl() const { return m_aMouseButtonUpHdl; }
inline void SetSelectHdl( const Link& rLink ) { m_aSelectHdl = rLink; }
inline const Link& GetSelectHdl() const { return m_aSelectHdl; }
diff --git a/svtools/source/toolpanel/drawerlayouter.cxx b/svtools/source/toolpanel/drawerlayouter.cxx
index 4de76107fd20..ecb808395c35 100644
--- a/svtools/source/toolpanel/drawerlayouter.cxx
+++ b/svtools/source/toolpanel/drawerlayouter.cxx
@@ -87,7 +87,7 @@ namespace svt
const size_t nUpperBound = !!aActivePanel ? *aActivePanel : nPanelCount - 1;
for ( size_t i=0; i<=nUpperBound; ++i )
{
- sal_uInt32 nDrawerHeight = m_aDrawers[i]->GetPreferredHeightPixel();
+ long const nDrawerHeight = m_aDrawers[i]->GetPreferredHeightPixel();
m_aDrawers[i]->SetPosSizePixel(
aUpperDrawerPos, Size( nWidth, nDrawerHeight ) );
aUpperDrawerPos.Move( 0, nDrawerHeight );
@@ -97,7 +97,7 @@ namespace svt
Point aLowerDrawerPos( i_rDeckPlayground.BottomLeft() );
for ( size_t j = nPanelCount - 1; j > nUpperBound; --j )
{
- sal_uInt32 nDrawerHeight = m_aDrawers[j]->GetPreferredHeightPixel();
+ long const nDrawerHeight = m_aDrawers[j]->GetPreferredHeightPixel();
m_aDrawers[j]->SetPosSizePixel(
Point( aLowerDrawerPos.X(), aLowerDrawerPos.Y() - nDrawerHeight + 1 ),
Size( nWidth, nDrawerHeight )
diff --git a/svtools/source/uno/svtxgridcontrol.cxx b/svtools/source/uno/svtxgridcontrol.cxx
index 0e826ef6bff3..64b8f9241ae0 100644
--- a/svtools/source/uno/svtxgridcontrol.cxx
+++ b/svtools/source/uno/svtxgridcontrol.cxx
@@ -43,24 +43,52 @@
#include <com/sun/star/awt/XControl.hpp>
#include <com/sun/star/awt/grid/GridInvalidDataException.hpp>
#include <com/sun/star/awt/grid/GridInvalidModelException.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/util/Color.hpp>
#include <com/sun/star/awt/FontDescriptor.hpp>
+/** === begin UNO using === **/
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::makeAny;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::awt::grid::XGridSelectionListener;
+using ::com::sun::star::style::VerticalAlignment;
+using ::com::sun::star::style::VerticalAlignment_TOP;
+using ::com::sun::star::view::SelectionType;
+using ::com::sun::star::view::SelectionType_NONE;
+using ::com::sun::star::view::SelectionType_RANGE;
+using ::com::sun::star::view::SelectionType_SINGLE;
+using ::com::sun::star::view::SelectionType_MULTI;
+using ::com::sun::star::awt::grid::XGridDataModel;
+using ::com::sun::star::awt::grid::GridInvalidDataException;
+using ::com::sun::star::lang::EventObject;
+using ::com::sun::star::lang::IndexOutOfBoundsException;
+using ::com::sun::star::awt::grid::XGridColumnModel;
+using ::com::sun::star::awt::grid::GridSelectionEvent;
+using ::com::sun::star::awt::grid::XGridColumn;
+using ::com::sun::star::container::ContainerEvent;
+using ::com::sun::star::awt::grid::GridDataEvent;
+using ::com::sun::star::awt::grid::GridInvalidModelException;
+using ::com::sun::star::util::VetoException;
+/** === end UNO using === **/
+
+namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId;
+namespace AccessibleStateType = ::com::sun::star::accessibility::AccessibleStateType;
+
using namespace ::svt::table;
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::awt::grid;
-using namespace ::com::sun::star::view;
-using namespace ::com::sun::star::style;
-using namespace ::com::sun::star::container;
-using namespace ::com::sun::star::accessibility;
+typedef ::com::sun::star::util::Color UnoColor;
+// ---------------------------------------------------------------------------------------------------------------------
SVTXGridControl::SVTXGridControl()
:m_pTableModel( new UnoControlTableModel() )
- ,m_bHasColumnHeaders( false )
- ,m_bHasRowHeaders( false )
,m_bTableModelInitCompleted( false )
- ,m_nSelectedRowCount( 0 )
,m_aSelectionListeners( *this )
{
}
@@ -78,7 +106,21 @@ void SVTXGridControl::SetWindow( Window* pWindow )
}
// ---------------------------------------------------------------------------------------------------------------------
-sal_Int32 SAL_CALL SVTXGridControl::getRowAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException)
+void SVTXGridControl::impl_checkColumnIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_columnIndex ) const
+{
+ if ( ( i_columnIndex < 0 ) || ( i_columnIndex >= i_table.GetColumnCount() ) )
+ throw IndexOutOfBoundsException( ::rtl::OUString(), *const_cast< SVTXGridControl* >( this ) );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void SVTXGridControl::impl_checkRowIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_rowIndex ) const
+{
+ if ( ( i_rowIndex < 0 ) || ( i_rowIndex >= i_table.GetRowCount() ) )
+ throw IndexOutOfBoundsException( ::rtl::OUString(), *const_cast< SVTXGridControl* >( this ) );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+sal_Int32 SAL_CALL SVTXGridControl::getRowAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (RuntimeException)
{
::vos::OGuard aGuard( GetMutex() );
@@ -90,7 +132,7 @@ sal_Int32 SAL_CALL SVTXGridControl::getRowAtPoint(::sal_Int32 x, ::sal_Int32 y)
}
// ---------------------------------------------------------------------------------------------------------------------
-sal_Int32 SAL_CALL SVTXGridControl::getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException)
+sal_Int32 SAL_CALL SVTXGridControl::getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (RuntimeException)
{
::vos::OGuard aGuard( GetMutex() );
@@ -125,14 +167,28 @@ sal_Int32 SAL_CALL SVTXGridControl::getCurrentRow( ) throw (RuntimeException)
return ( nRow >= 0 ) ? nRow : -1;
}
+//----------------------------------------------------------------------------------------------------------------------
+void SAL_CALL SVTXGridControl::goToCell( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException, VetoException)
+{
+ ::vos::OGuard aGuard( GetMutex() );
+
+ TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
+ ENSURE_OR_RETURN_VOID( pTable != NULL, "SVTXGridControl::getCurrentRow: no control (anymore)!" );
+
+ impl_checkColumnIndex_throw( *pTable, i_columnIndex );
+ impl_checkRowIndex_throw( *pTable, i_rowIndex );
+
+ pTable->GoTo( i_columnIndex, i_rowIndex );
+}
+
// ---------------------------------------------------------------------------------------------------------------------
-void SAL_CALL SVTXGridControl::addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException)
+void SAL_CALL SVTXGridControl::addSelectionListener(const Reference< XGridSelectionListener > & listener) throw (RuntimeException)
{
m_aSelectionListeners.addInterface(listener);
}
// ---------------------------------------------------------------------------------------------------------------------
-void SAL_CALL SVTXGridControl::removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException)
+void SAL_CALL SVTXGridControl::removeSelectionListener(const Reference< XGridSelectionListener > & listener) throw (RuntimeException)
{
m_aSelectionListeners.removeInterface(listener);
}
@@ -284,6 +340,27 @@ void SVTXGridControl::setProperty( const ::rtl::OUString& PropertyName, const An
pTable->Invalidate();
break;
+ case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR:
+ m_pTableModel->setActiveSelectionBackColor( aValue );
+ pTable->Invalidate();
+ break;
+
+ case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR:
+ m_pTableModel->setInactiveSelectionBackColor( aValue );
+ pTable->Invalidate();
+ break;
+
+ case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR:
+ m_pTableModel->setActiveSelectionTextColor( aValue );
+ pTable->Invalidate();
+ break;
+
+ case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR:
+ m_pTableModel->setInactiveSelectionTextColor( aValue );
+ pTable->Invalidate();
+ break;
+
+
case BASEPROPERTY_TEXTCOLOR:
m_pTableModel->setTextColor( aValue );
pTable->Invalidate();
@@ -455,7 +532,7 @@ Any SVTXGridControl::getProperty( const ::rtl::OUString& PropertyName ) throw(Ru
aPropertyValue.clear();
else
{
- Sequence< ::com::sun::star::util::Color > aAPIColors( aColors->size() );
+ Sequence< UnoColor > aAPIColors( aColors->size() );
for ( size_t i=0; i<aColors->size(); ++i )
{
aAPIColors[i] = aColors->at(i).GetColor();
@@ -477,6 +554,22 @@ Any SVTXGridControl::getProperty( const ::rtl::OUString& PropertyName ) throw(Ru
lcl_convertColor( m_pTableModel->getHeaderTextColor(), aPropertyValue );
break;
+ case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR:
+ lcl_convertColor( m_pTableModel->getActiveSelectionBackColor(), aPropertyValue );
+ break;
+
+ case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR:
+ lcl_convertColor( m_pTableModel->getInactiveSelectionBackColor(), aPropertyValue );
+ break;
+
+ case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR:
+ lcl_convertColor( m_pTableModel->getActiveSelectionTextColor(), aPropertyValue );
+ break;
+
+ case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR:
+ lcl_convertColor( m_pTableModel->getInactiveSelectionTextColor(), aPropertyValue );
+ break;
+
case BASEPROPERTY_TEXTCOLOR:
lcl_convertColor( m_pTableModel->getTextColor(), aPropertyValue );
break;
@@ -505,6 +598,10 @@ void SVTXGridControl::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
BASEPROPERTY_GRID_HEADER_TEXT_COLOR,
BASEPROPERTY_GRID_LINE_COLOR,
BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS,
+ BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR,
+ BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR,
+ BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR,
+ BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR,
0
);
VCLXWindow::ImplGetPropertyIds( rIds, true );
@@ -585,24 +682,26 @@ void SAL_CALL SVTXGridControl::elementReplaced( const ContainerEvent& i_event )
//----------------------------------------------------------------------------------------------------------------------
-void SAL_CALL SVTXGridControl::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException)
+void SAL_CALL SVTXGridControl::disposing( const EventObject& Source ) throw(RuntimeException)
{
VCLXWindow::disposing( Source );
}
//----------------------------------------------------------------------------------------------------------------------
-void SAL_CALL SVTXGridControl::selectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException)
+void SAL_CALL SVTXGridControl::selectRow( ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException )
{
::vos::OGuard aGuard( GetMutex() );
TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::selectRow: no control (anymore)!" );
+ impl_checkRowIndex_throw( *pTable, i_rowIndex );
+
pTable->SelectRow( i_rowIndex, true );
}
//----------------------------------------------------------------------------------------------------------------------
-void SAL_CALL SVTXGridControl::selectAllRows() throw (::com::sun::star::uno::RuntimeException)
+void SAL_CALL SVTXGridControl::selectAllRows() throw (RuntimeException)
{
::vos::OGuard aGuard( GetMutex() );
@@ -613,18 +712,20 @@ void SAL_CALL SVTXGridControl::selectAllRows() throw (::com::sun::star::uno::Run
}
//----------------------------------------------------------------------------------------------------------------------
-void SAL_CALL SVTXGridControl::deselectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException)
+void SAL_CALL SVTXGridControl::deselectRow( ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException )
{
::vos::OGuard aGuard( GetMutex() );
TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::deselectRow: no control (anymore)!" );
+ impl_checkRowIndex_throw( *pTable, i_rowIndex );
+
pTable->SelectRow( i_rowIndex, false );
}
//----------------------------------------------------------------------------------------------------------------------
-void SAL_CALL SVTXGridControl::deselectAllRows() throw (::com::sun::star::uno::RuntimeException)
+void SAL_CALL SVTXGridControl::deselectAllRows() throw (RuntimeException)
{
::vos::OGuard aGuard( GetMutex() );
@@ -635,12 +736,12 @@ void SAL_CALL SVTXGridControl::deselectAllRows() throw (::com::sun::star::uno::R
}
//----------------------------------------------------------------------------------------------------------------------
-::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL SVTXGridControl::getSelection() throw (::com::sun::star::uno::RuntimeException)
+Sequence< ::sal_Int32 > SAL_CALL SVTXGridControl::getSelectedRows() throw (RuntimeException)
{
::vos::OGuard aGuard( GetMutex() );
TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
- ENSURE_OR_RETURN( pTable, "SVTXGridControl::getSelection: no control (anymore)!", Sequence< sal_Int32 >() );
+ ENSURE_OR_RETURN( pTable, "SVTXGridControl::getSelectedRows: no control (anymore)!", Sequence< sal_Int32 >() );
sal_Int32 selectionCount = pTable->GetSelectedRowCount();
Sequence< sal_Int32 > selectedRows( selectionCount );
@@ -650,31 +751,31 @@ void SAL_CALL SVTXGridControl::deselectAllRows() throw (::com::sun::star::uno::R
}
//----------------------------------------------------------------------------------------------------------------------
-::sal_Bool SAL_CALL SVTXGridControl::isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException)
+::sal_Bool SAL_CALL SVTXGridControl::hasSelectedRows() throw (RuntimeException)
{
::vos::OGuard aGuard( GetMutex() );
TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
- ENSURE_OR_RETURN( pTable, "SVTXGridControl::getSelection: no control (anymore)!", sal_True );
+ ENSURE_OR_RETURN( pTable, "SVTXGridControl::hasSelectedRows: no control (anymore)!", sal_True );
return pTable->GetSelectedRowCount() > 0;
}
//----------------------------------------------------------------------------------------------------------------------
-::sal_Bool SAL_CALL SVTXGridControl::isSelectedIndex( ::sal_Int32 index ) throw (::com::sun::star::uno::RuntimeException)
+::sal_Bool SAL_CALL SVTXGridControl::isRowSelected( ::sal_Int32 index ) throw (RuntimeException)
{
::vos::OGuard aGuard( GetMutex() );
TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
- ENSURE_OR_RETURN( pTable, "SVTXGridControl::isSelectedIndex: no control (anymore)!", sal_False );
+ ENSURE_OR_RETURN( pTable, "SVTXGridControl::isRowSelected: no control (anymore)!", sal_False );
return pTable->IsRowSelected( index );
}
//----------------------------------------------------------------------------------------------------------------------
-void SVTXGridControl::dispose() throw(::com::sun::star::uno::RuntimeException)
+void SVTXGridControl::dispose() throw(RuntimeException)
{
- ::com::sun::star::lang::EventObject aObj;
+ EventObject aObj;
aObj.Source = (::cppu::OWeakObject*)this;
m_aSelectionListeners.disposeAndClear( aObj );
VCLXWindow::dispose();
@@ -685,22 +786,76 @@ void SVTXGridControl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent
{
::vos::OGuard aGuard( GetMutex() );
- ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > xKeepAlive( this );
+ Reference< XWindow > xKeepAlive( this );
+
+ TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
+ ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::ProcessWindowEvent: no control (anymore)!" );
+
+ bool handled = false;
switch ( rVclWindowEvent.GetId() )
{
case VCLEVENT_TABLEROW_SELECT:
{
- TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
- ENSURE_OR_BREAK( pTable, "SVTXGridControl::ProcessWindowEvent: no control (anymore)!" );
if ( m_aSelectionListeners.getLength() )
ImplCallItemListeners();
+ handled = true;
}
break;
- default:
- VCLXWindow::ProcessWindowEvent( rVclWindowEvent );
- break;
+ case VCLEVENT_CONTROL_GETFOCUS:
+ {
+ // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also
+ // works when the control is used outside the UNO context
+ if ( pTable->GetRowCount()>0 )
+ {
+ pTable->commitCellEventIfAccessibleAlive(
+ AccessibleEventId::STATE_CHANGED,
+ makeAny( AccessibleStateType::FOCUSED ),
+ Any()
+ );
+ pTable->commitTableEventIfAccessibleAlive(
+ AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
+ Any(),
+ Any()
+ );
+ }
+ else
+ {
+ pTable->commitTableEventIfAccessibleAlive(
+ AccessibleEventId::STATE_CHANGED,
+ makeAny( AccessibleStateType::FOCUSED ),
+ Any()
+ );
+ }
+ }
+ break;
+
+ case VCLEVENT_CONTROL_LOSEFOCUS:
+ {
+ // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also
+ // works when the control is used outside the UNO context
+ if ( pTable->GetRowCount()>0 )
+ {
+ pTable->commitCellEventIfAccessibleAlive(
+ AccessibleEventId::STATE_CHANGED,
+ Any(),
+ makeAny( AccessibleStateType::FOCUSED )
+ );
+ }
+ else
+ {
+ pTable->commitTableEventIfAccessibleAlive(
+ AccessibleEventId::STATE_CHANGED,
+ Any(),
+ makeAny( AccessibleStateType::FOCUSED )
+ );
+ }
+ }
+ break;
}
+
+ if ( !handled )
+ VCLXWindow::ProcessWindowEvent( rVclWindowEvent );
}
//----------------------------------------------------------------------------------------------------------------------
@@ -711,42 +866,13 @@ void SVTXGridControl::ImplCallItemListeners()
if ( m_aSelectionListeners.getLength() )
{
- sal_Int32 const actSelRowCount = pTable->GetSelectedRowCount();
- ::com::sun::star::awt::grid::GridSelectionEvent aEvent;
+ GridSelectionEvent aEvent;
aEvent.Source = (::cppu::OWeakObject*)this;
- aEvent.Column = 0;
- sal_Int32 diff = actSelRowCount - m_nSelectedRowCount;
- //row added to selection
- if(diff >= 1)
- {
- aEvent.Action = com::sun::star::awt::grid::SelectionEventType(0);
- aEvent.Row = pTable->GetSelectedRowIndex( actSelRowCount - 1 );
- aEvent.Range = diff;
- }
- //selected row changed
- else if(diff == 0 && actSelRowCount != 0)
- {
- aEvent.Row = pTable->GetSelectedRowIndex( actSelRowCount - 1 );
- aEvent.Action = com::sun::star::awt::grid::SelectionEventType(2);
- aEvent.Range = 0;
- }
- else
- {
- //selection changed: multiple row deselected, only 1 row is selected
- if(actSelRowCount == 1)
- {
- aEvent.Row = pTable->GetSelectedRowIndex( actSelRowCount - 1 );
- aEvent.Action = com::sun::star::awt::grid::SelectionEventType(2);
- }
- //row is deselected
- else
- {
- aEvent.Row = pTable->GetCurrentRow();
- aEvent.Action = com::sun::star::awt::grid::SelectionEventType(1);
- }
- aEvent.Range = 0;
- }
- m_nSelectedRowCount=actSelRowCount;
+
+ sal_Int32 const nSelectedRowCount( pTable->GetSelectedRowCount() );
+ aEvent.SelectedRowIndexes.realloc( nSelectedRowCount );
+ for ( sal_Int32 i=0; i<nSelectedRowCount; ++i )
+ aEvent.SelectedRowIndexes[i] = pTable->GetSelectedRowIndex( i );
m_aSelectionListeners.selectionChanged( aEvent );
}
}
@@ -777,4 +903,3 @@ void SVTXGridControl::impl_updateColumnsFromModel_nothrow()
DBG_UNHANDLED_EXCEPTION();
}
}
-
diff --git a/svtools/source/uno/svtxgridcontrol.hxx b/svtools/source/uno/svtxgridcontrol.hxx
index 525327b3c760..ebde9b76c078 100755
--- a/svtools/source/uno/svtxgridcontrol.hxx
+++ b/svtools/source/uno/svtxgridcontrol.hxx
@@ -31,6 +31,7 @@
#include <unocontroltablemodel.hxx>
#include <svtools/table/tablecontrol.hxx>
#include <com/sun/star/awt/grid/XGridControl.hpp>
+#include <com/sun/star/awt/grid/XGridRowSelection.hpp>
#include <com/sun/star/awt/grid/XGridDataListener.hpp>
#include <com/sun/star/awt/grid/GridDataEvent.hpp>
#include <com/sun/star/awt/grid/GridColumnEvent.hpp>
@@ -45,22 +46,22 @@
#include <toolkit/helper/listenermultiplexer.hxx>
-using namespace ::svt::table;
+namespace svt { namespace table {
+ class TableControl;
+} }
-typedef ::cppu::ImplInheritanceHelper3 < VCLXWindow
+typedef ::cppu::ImplInheritanceHelper4 < VCLXWindow
, ::com::sun::star::awt::grid::XGridControl
+ , ::com::sun::star::awt::grid::XGridRowSelection
, ::com::sun::star::awt::grid::XGridDataListener
, ::com::sun::star::container::XContainerListener
> SVTXGridControl_Base;
class SVTXGridControl : public SVTXGridControl_Base
{
private:
- ::boost::shared_ptr< UnoControlTableModel > m_pTableModel;
- bool m_bHasColumnHeaders;
- bool m_bHasRowHeaders;
- bool m_bTableModelInitCompleted;
- sal_Int32 m_nSelectedRowCount;
- SelectionListenerMultiplexer m_aSelectionListeners;
+ ::boost::shared_ptr< ::svt::table::UnoControlTableModel > m_pTableModel;
+ bool m_bTableModelInitCompleted;
+ SelectionListenerMultiplexer m_aSelectionListeners;
protected:
virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent );
@@ -84,22 +85,23 @@ public:
// XEventListener
virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
- // XGridSelection
- virtual void SAL_CALL selectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL selectAllRows() throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL deselectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL deselectAllRows() throw (::com::sun::star::uno::RuntimeException);
- virtual ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL getSelection() throw (::com::sun::star::uno::RuntimeException);
- virtual ::sal_Bool SAL_CALL isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException);
- virtual ::sal_Bool SAL_CALL isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException);
-
// XGridControl
virtual ::sal_Int32 SAL_CALL getRowAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Int32 SAL_CALL getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Int32 SAL_CALL getCurrentColumn( ) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Int32 SAL_CALL getCurrentRow( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL goToCell( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::util::VetoException);
+
+ // XGridRowSelection
+ virtual void SAL_CALL selectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException );
+ virtual void SAL_CALL selectAllRows() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL deselectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException );
+ virtual void SAL_CALL deselectAllRows() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL getSelectedRows() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasSelectedRows() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isRowSelected(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException);
void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException);
::com::sun::star::uno::Any SAL_CALL getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException);
@@ -115,5 +117,8 @@ protected:
private:
void impl_updateColumnsFromModel_nothrow();
void impl_checkTableModelInit();
+
+ void impl_checkColumnIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_columnIndex ) const;
+ void impl_checkRowIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_rowIndex ) const;
};
#endif // _SVT_GRIDCONTROL_HXX_
diff --git a/svtools/source/uno/unocontroltablemodel.cxx b/svtools/source/uno/unocontroltablemodel.cxx
index 933363115810..b4c1bed746fa 100644
--- a/svtools/source/uno/unocontroltablemodel.cxx
+++ b/svtools/source/uno/unocontroltablemodel.cxx
@@ -98,6 +98,10 @@ namespace svt { namespace table
::boost::optional< ::Color > m_aGridLineColor;
::boost::optional< ::Color > m_aHeaderBackgroundColor;
::boost::optional< ::Color > m_aHeaderTextColor;
+ ::boost::optional< ::Color > m_aActiveSelectionBackColor;
+ ::boost::optional< ::Color > m_aInactiveSelectionBackColor;
+ ::boost::optional< ::Color > m_aActiveSelectionTextColor;
+ ::boost::optional< ::Color > m_aInactiveSelectionTextColor;
::boost::optional< ::Color > m_aTextColor;
::boost::optional< ::Color > m_aTextLineColor;
::boost::optional< ::std::vector< ::Color > > m_aRowColors;
@@ -107,23 +111,27 @@ namespace svt { namespace table
WeakReference< XGridColumnModel > m_aColumnModel;
UnoControlTableModel_Impl()
- :aColumns ( )
- ,bHasColumnHeaders ( true )
- ,bHasRowHeaders ( false )
- ,eVScrollMode ( ScrollbarShowNever )
- ,eHScrollMode ( ScrollbarShowNever )
- ,pRenderer ( )
- ,pInputHandler ( )
- ,nRowHeight ( 10 )
- ,nColumnHeaderHeight ( 10 )
- ,nRowHeaderWidth ( 10 )
- ,m_aGridLineColor ( )
- ,m_aHeaderBackgroundColor ( )
- ,m_aHeaderTextColor ( )
- ,m_aTextColor ( )
- ,m_aTextLineColor ( )
- ,m_aRowColors ( )
- ,m_eVerticalAlign ( VerticalAlignment_TOP )
+ :aColumns ( )
+ ,bHasColumnHeaders ( true )
+ ,bHasRowHeaders ( false )
+ ,eVScrollMode ( ScrollbarShowNever )
+ ,eHScrollMode ( ScrollbarShowNever )
+ ,pRenderer ( )
+ ,pInputHandler ( )
+ ,nRowHeight ( 10 )
+ ,nColumnHeaderHeight ( 10 )
+ ,nRowHeaderWidth ( 10 )
+ ,m_aGridLineColor ( )
+ ,m_aHeaderBackgroundColor ( )
+ ,m_aHeaderTextColor ( )
+ ,m_aActiveSelectionBackColor ( )
+ ,m_aInactiveSelectionBackColor ( )
+ ,m_aActiveSelectionTextColor ( )
+ ,m_aInactiveSelectionTextColor ( )
+ ,m_aTextColor ( )
+ ,m_aTextLineColor ( )
+ ,m_aRowColors ( )
+ ,m_eVerticalAlign ( VerticalAlignment_TOP )
{
}
};
@@ -654,6 +662,34 @@ namespace svt { namespace table
}
//------------------------------------------------------------------------------------------------------------------
+ ::boost::optional< ::Color > UnoControlTableModel::getActiveSelectionBackColor() const
+ {
+ DBG_CHECK_ME();
+ return m_pImpl->m_aActiveSelectionBackColor;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::boost::optional< ::Color > UnoControlTableModel::getInactiveSelectionBackColor() const
+ {
+ DBG_CHECK_ME();
+ return m_pImpl->m_aInactiveSelectionBackColor;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::boost::optional< ::Color > UnoControlTableModel::getActiveSelectionTextColor() const
+ {
+ DBG_CHECK_ME();
+ return m_pImpl->m_aActiveSelectionTextColor;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::boost::optional< ::Color > UnoControlTableModel::getInactiveSelectionTextColor() const
+ {
+ DBG_CHECK_ME();
+ return m_pImpl->m_aInactiveSelectionTextColor;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
void UnoControlTableModel::setHeaderTextColor( Any const & i_color )
{
DBG_CHECK_ME();
@@ -661,6 +697,34 @@ namespace svt { namespace table
}
//------------------------------------------------------------------------------------------------------------------
+ void UnoControlTableModel::setActiveSelectionBackColor( Any const & i_color )
+ {
+ DBG_CHECK_ME();
+ lcl_setColor( i_color, m_pImpl->m_aActiveSelectionBackColor );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UnoControlTableModel::setInactiveSelectionBackColor( Any const & i_color )
+ {
+ DBG_CHECK_ME();
+ lcl_setColor( i_color, m_pImpl->m_aInactiveSelectionBackColor );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UnoControlTableModel::setActiveSelectionTextColor( Any const & i_color )
+ {
+ DBG_CHECK_ME();
+ lcl_setColor( i_color, m_pImpl->m_aActiveSelectionTextColor );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UnoControlTableModel::setInactiveSelectionTextColor( Any const & i_color )
+ {
+ DBG_CHECK_ME();
+ lcl_setColor( i_color, m_pImpl->m_aInactiveSelectionTextColor );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
::boost::optional< ::Color > UnoControlTableModel::getTextColor() const
{
DBG_CHECK_ME();
diff --git a/svtools/source/uno/unocontroltablemodel.hxx b/svtools/source/uno/unocontroltablemodel.hxx
index 537c3d9a5249..3c5f52748eee 100644
--- a/svtools/source/uno/unocontroltablemodel.hxx
+++ b/svtools/source/uno/unocontroltablemodel.hxx
@@ -89,6 +89,10 @@ namespace svt { namespace table
virtual ::boost::optional< ::Color > getLineColor() const;
virtual ::boost::optional< ::Color > getHeaderBackgroundColor() const;
virtual ::boost::optional< ::Color > getHeaderTextColor() const;
+ virtual ::boost::optional< ::Color > getActiveSelectionBackColor() const;
+ virtual ::boost::optional< ::Color > getInactiveSelectionBackColor() const;
+ virtual ::boost::optional< ::Color > getActiveSelectionTextColor() const;
+ virtual ::boost::optional< ::Color > getInactiveSelectionTextColor() const;
virtual ::boost::optional< ::Color > getTextColor() const;
virtual ::boost::optional< ::Color > getTextLineColor() const;
virtual ::boost::optional< ::std::vector< ::Color > >
@@ -130,6 +134,10 @@ namespace svt { namespace table
void setLineColor( ::com::sun::star::uno::Any const & i_color );
void setHeaderBackgroundColor( ::com::sun::star::uno::Any const & i_color );
void setHeaderTextColor( ::com::sun::star::uno::Any const & i_color );
+ void setActiveSelectionBackColor( ::com::sun::star::uno::Any const & i_color );
+ void setInactiveSelectionBackColor( ::com::sun::star::uno::Any const & i_color );
+ void setActiveSelectionTextColor( ::com::sun::star::uno::Any const & i_color );
+ void setInactiveSelectionTextColor( ::com::sun::star::uno::Any const & i_color );
void setTextColor( ::com::sun::star::uno::Any const & i_color );
void setTextLineColor( ::com::sun::star::uno::Any const & i_color );
void setRowBackgroundColors( ::com::sun::star::uno::Any const & i_APIValue );
diff --git a/toolkit/inc/toolkit/awt/vclxtabpagecontainer.hxx b/toolkit/inc/toolkit/awt/vclxtabpagecontainer.hxx
index d4fe2a727b43..f9c7b01da551 100644
--- a/toolkit/inc/toolkit/awt/vclxtabpagecontainer.hxx
+++ b/toolkit/inc/toolkit/awt/vclxtabpagecontainer.hxx
@@ -63,12 +63,12 @@ public:
// ::com::sun::star::awt::grid::XTabPageContainer
virtual ::sal_Int16 SAL_CALL getActiveTabPageID() throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setActiveTabPageID( ::sal_Int16 _activetabpageid ) throw (::com::sun::star::uno::RuntimeException);
- virtual ::sal_Int32 SAL_CALL getTabPageCount( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int16 SAL_CALL getTabPageCount( ) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Bool SAL_CALL isTabPageActive( ::sal_Int16 tabPageIndex ) throw (::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPage > SAL_CALL getTabPage( ::sal_Int16 tabPageIndex ) throw (::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPage > SAL_CALL getTabPageByID( ::sal_Int16 tabPageID ) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL addTabPageListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL removeTabPageListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addTabPageContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeTabPageContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (::com::sun::star::uno::RuntimeException);
static void ImplGetPropertyIds( std::list< sal_uInt16 > &aIds );
virtual void GetPropertyIds( std::list< sal_uInt16 > &aIds ) { return ImplGetPropertyIds( aIds ); }
diff --git a/toolkit/inc/toolkit/awt/vclxtabpagemodel.hxx b/toolkit/inc/toolkit/awt/vclxtabpagemodel.hxx
index 670ed25c0f2d..5d8237f2cacc 100644
--- a/toolkit/inc/toolkit/awt/vclxtabpagemodel.hxx
+++ b/toolkit/inc/toolkit/awt/vclxtabpagemodel.hxx
@@ -74,8 +74,8 @@ public:
virtual void SAL_CALL setTitle( const ::rtl::OUString& _title ) throw (::com::sun::star::uno::RuntimeException);
virtual ::rtl::OUString SAL_CALL getImageURL() throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setImageURL( const ::rtl::OUString& _imageurl ) throw (::com::sun::star::uno::RuntimeException);
- virtual ::rtl::OUString SAL_CALL getTooltip() throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL setTooltip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getToolTip() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setToolTip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException);
protected:
::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
};
diff --git a/toolkit/inc/toolkit/controls/controlmodelcontainerbase.hxx b/toolkit/inc/toolkit/controls/controlmodelcontainerbase.hxx
index 3090eba68749..c607a48f66cd 100644
--- a/toolkit/inc/toolkit/controls/controlmodelcontainerbase.hxx
+++ b/toolkit/inc/toolkit/controls/controlmodelcontainerbase.hxx
@@ -173,8 +173,8 @@ public:
virtual void SAL_CALL setTitle( const ::rtl::OUString& _title ) throw (::com::sun::star::uno::RuntimeException);
virtual ::rtl::OUString SAL_CALL getImageURL() throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setImageURL( const ::rtl::OUString& _imageurl ) throw (::com::sun::star::uno::RuntimeException);
- virtual ::rtl::OUString SAL_CALL getTooltip() throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL setTooltip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getToolTip() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setToolTip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException);
protected:
void startControlListening( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& _rxChildModel );
diff --git a/toolkit/inc/toolkit/controls/tabpagecontainer.hxx b/toolkit/inc/toolkit/controls/tabpagecontainer.hxx
index c7a2e3b8ef90..c660edf2e3e9 100644
--- a/toolkit/inc/toolkit/controls/tabpagecontainer.hxx
+++ b/toolkit/inc/toolkit/controls/tabpagecontainer.hxx
@@ -76,28 +76,29 @@ public:
// ::com::sun::star::lang::XServiceInfo
DECLIMPL_SERVICEINFO_DERIVED( UnoControlTabPageContainerModel, UnoControlModel, szServiceName_UnoControlTabPageContainerModel )
+
+ // XTabPageContainerModel
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPageModel > SAL_CALL createTabPage( ::sal_Int16 TabPageID ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPageModel > SAL_CALL loadTabPage( ::sal_Int16 TabPageID, const ::rtl::OUString& ResourceURL ) throw (::com::sun::star::uno::RuntimeException);
+
// XIndexContainer
virtual void SAL_CALL insertByIndex( sal_Int32 Index, const ::com::sun::star::uno::Any& Element )
throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL removeByIndex( sal_Int32 Index )
throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
- // XIndexReplace
+ // XIndexReplace
virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const ::com::sun::star::uno::Any& Element )
throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
- // XIndexAccess
+ // 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);
- // XElementAccess
+ // XElementAccess
virtual ::com::sun::star::uno::Type SAL_CALL getElementType() throw (::com::sun::star::uno::RuntimeException);
- //{
- //return ::getCppuType((com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >*)0);
- //}
-
virtual sal_Bool SAL_CALL hasElements() throw (::com::sun::star::uno::RuntimeException);
// ::com::sun::star::container::XContainer
@@ -125,12 +126,12 @@ public:
// ::com::sun::star::awt::tab::XTabPageContainer
virtual ::sal_Int16 SAL_CALL getActiveTabPageID() throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setActiveTabPageID( ::sal_Int16 _activetabpageid ) throw (::com::sun::star::uno::RuntimeException);
- virtual ::sal_Int32 SAL_CALL getTabPageCount( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int16 SAL_CALL getTabPageCount( ) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Bool SAL_CALL isTabPageActive( ::sal_Int16 tabPageIndex ) throw (::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPage > SAL_CALL getTabPage( ::sal_Int16 tabPageIndex ) throw (::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPage > SAL_CALL getTabPageByID( ::sal_Int16 tabPageID ) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL addTabPageListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL removeTabPageListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addTabPageContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeTabPageContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL addControl( const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& Control ) throw (::com::sun::star::uno::RuntimeException);
// ::com::sun::star::lang::XServiceInfo
diff --git a/toolkit/inc/toolkit/controls/tabpagemodel.hxx b/toolkit/inc/toolkit/controls/tabpagemodel.hxx
index 08938669fa58..68924b831af4 100644
--- a/toolkit/inc/toolkit/controls/tabpagemodel.hxx
+++ b/toolkit/inc/toolkit/controls/tabpagemodel.hxx
@@ -33,7 +33,6 @@
#include <com/sun/star/awt/tab/XTabPage.hpp>
#include <com/sun/star/resource/XStringResourceResolver.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
-#include <com/sun/star/uno/XComponentContext.hpp>
#include "toolkit/helper/servicenames.hxx"
#include "toolkit/helper/macros.hxx"
#include <toolkit/controls/unocontrolcontainer.hxx>
@@ -41,55 +40,6 @@
#include <list>
#include <cppuhelper/implbase2.hxx>
-// ----------------------------------------------------
-// class TabPageModel
-// ----------------------------------------------------
-//typedef ::cppu::ImplHelper2< ::com::sun::star::awt::tab::XTabPageModel,
-// ::com::sun::star::lang::XInitialization
-// > TabPageAccess_BASE;
-//
-//class TabPageModel : public TabPageAccess_BASE
-//{
-//
-//private:
-// bool m_bEnabled;
-// ::rtl::OUString m_sTitle;
-// ::rtl::OUString m_sImageURL;
-// ::rtl::OUString m_sTooltip;
-// sal_Int16 m_nTabPageId;
-//
-//public:
-// TabPageModel();
-// explicit TabPageModel( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & xCompContext);
-// ~TabPageModel();
-//
-// // XInitialization
-// virtual void SAL_CALL initialize (const com::sun::star::uno::Sequence<com::sun::star::uno::Any>& rArguments)
-// throw (com::sun::star::uno::Exception, com::sun::star::uno::RuntimeException);
-//
-// ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
-// void SAL_CALL acquire() throw() { OWeakAggObject::acquire(); }
-// void SAL_CALL release() throw() { OWeakAggObject::release(); }
-//
-// // ::com::sun::star::lang::XTypeProvider
-// //::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
-// //::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
-//
-// // ::com::sun::star::awt::tab::XTabPageModel
-// virtual ::sal_Int16 SAL_CALL getTabPageID() throw (::com::sun::star::uno::RuntimeException);
-// virtual ::sal_Bool SAL_CALL getEnabled() throw (::com::sun::star::uno::RuntimeException);
-// virtual void SAL_CALL setEnabled( ::sal_Bool _enabled ) throw (::com::sun::star::uno::RuntimeException);
-// virtual ::rtl::OUString SAL_CALL getTitle() throw (::com::sun::star::uno::RuntimeException);
-// virtual void SAL_CALL setTitle( const ::rtl::OUString& _title ) throw (::com::sun::star::uno::RuntimeException);
-// virtual ::rtl::OUString SAL_CALL getImageURL() throw (::com::sun::star::uno::RuntimeException);
-// virtual void SAL_CALL setImageURL( const ::rtl::OUString& _imageurl ) throw (::com::sun::star::uno::RuntimeException);
-// virtual ::rtl::OUString SAL_CALL getTooltip() throw (::com::sun::star::uno::RuntimeException);
-// virtual void SAL_CALL setTooltip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException);
-//};
-// ----------------------------------------------------
-// class UnoControlTabPageModel
-// ----------------------------------------------------
-
class UnoControlTabPageModel : public ControlModelContainerBase
//public TabPageModel
{
diff --git a/toolkit/inc/toolkit/helper/property.hxx b/toolkit/inc/toolkit/helper/property.hxx
index c2d6380dcb65..03cd972940a7 100644
--- a/toolkit/inc/toolkit/helper/property.hxx
+++ b/toolkit/inc/toolkit/helper/property.hxx
@@ -206,6 +206,10 @@ namespace rtl {
#define BASEPROPERTY_ROW_HEADER_WIDTH 155
#define BASEPROPERTY_COLUMN_HEADER_HEIGHT 156
#define BASEPROPERTY_USE_GRID_LINES 157
+#define BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR 158
+#define BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR 159
+#define BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR 160
+#define BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR 161
// Keine gebundenen Properties, werden immer aus der Property BASEPROPERTY_FONTDESCRIPTOR entnommen.
diff --git a/toolkit/qa/complex/toolkit/GridControl.java b/toolkit/qa/complex/toolkit/GridControl.java
index a06a52342417..22d6e10c7b60 100755..100644
--- a/toolkit/qa/complex/toolkit/GridControl.java
+++ b/toolkit/qa/complex/toolkit/GridControl.java
@@ -33,6 +33,7 @@ import com.sun.star.awt.XToolkit;
import com.sun.star.awt.grid.DefaultGridDataModel;
import com.sun.star.awt.grid.XGridColumn;
import com.sun.star.awt.grid.XGridColumnModel;
+import com.sun.star.awt.grid.XGridControl;
import com.sun.star.awt.grid.XGridDataModel;
import com.sun.star.awt.grid.XMutableGridDataModel;
import com.sun.star.awt.grid.XSortableMutableGridDataModel;
@@ -59,6 +60,8 @@ import java.util.List;
import java.util.Random;
import org.junit.AfterClass;
import org.junit.BeforeClass;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import org.openoffice.test.OfficeConnection;
@@ -205,6 +208,8 @@ public class GridControl
TMutableGridDataModel test = new TMutableGridDataModel( m_dataModel );
test.testAddRow();
test.testAddRows();
+ test.testInsertRow();
+ test.testInsertRows();
test.testRemoveRow();
test.testRemoveAllRows();
test.testUpdateCellData();
@@ -326,6 +331,33 @@ public class GridControl
// -----------------------------------------------------------------------------------------------------------------
@Test
+ public void testDataModel() throws Exception
+ {
+ impl_recreateGridModel();
+
+ // ensure that getCellData and getRowData have the same opinion on the data they deliver
+ final Object[][] data = new Object[][] {
+ new Object[] { 15, 17, 0 },
+ new Object[] { 9, 8, 14 },
+ new Object[] { 17, 2, 16 },
+ new Object[] { 0, 7, 14 },
+ new Object[] { 10, 16, 16 },
+ };
+ m_dataModel.addRows( new Object[ data.length ], data );
+
+ for ( int row = 0; row < data.length; ++row )
+ {
+ assertArrayEquals( "getRowData delivers wrong data in row " + row, data[row], m_dataModel.getRowData( row ) );
+ for ( int col = 0; col < data[row].length; ++col )
+ {
+ assertEquals( "getCellData delivers wrong data at position (" + col + ", " + row + ")",
+ data[row][col], m_dataModel.getCellData( col, row ) );
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------------------------
+ @Test
public void testSortableDataModel() throws Exception
{
impl_recreateGridModel();
@@ -403,63 +435,88 @@ public class GridControl
// -----------------------------------------------------------------------------------------------------------------
@Test
- public void testModelViewInteraction() throws Exception
+ public void testView() throws Exception
{
- final List< Object > disposables = new ArrayList< Object >();
- try
- {
- // create a siple dialog model/control/peer trinity
- final XControlModel dialogModel = createInstance( XControlModel.class, "com.sun.star.awt.UnoControlDialogModel" );
- disposables.add( dialogModel );
- final XPropertySet dialogProps = UnoRuntime.queryInterface( XPropertySet.class, dialogModel );
- dialogProps.setPropertyValue( "Width", 200 );
- dialogProps.setPropertyValue( "Height", 100 );
- dialogProps.setPropertyValue( "Title", "Grid Control Unit Test" );
- final XControl dialogControl = createInstance( XControl.class, "com.sun.star.awt.UnoControlDialog" );
- disposables.add( dialogControl );
- dialogControl.setModel( dialogModel );
- dialogControl.createPeer( createInstance( XToolkit.class, "com.sun.star.awt.Toolkit" ), null );
-
- // insert a grid control model
- final XMultiServiceFactory controlModelFactory = UnoRuntime.queryInterface( XMultiServiceFactory.class,
- dialogModel );
- XPropertySet gridModelProps = UnoRuntime.queryInterface( XPropertySet.class,
- controlModelFactory.createInstance( "com.sun.star.awt.grid.UnoControlGridModel" ) );
- disposables.add( gridModelProps );
- gridModelProps.setPropertyValue( "PositionX", 6 );
- gridModelProps.setPropertyValue( "PositionY", 6 );
- gridModelProps.setPropertyValue( "Width", 188 );
- gridModelProps.setPropertyValue( "Height", 88 );
- final XNameContainer modelContainer = UnoRuntime.queryInterface( XNameContainer.class, dialogModel );
- modelContainer.insertByName( "grid", gridModelProps );
-
- // check the respective control has been created
- final XControlContainer controlContainer = UnoRuntime.queryInterface( XControlContainer.class, dialogControl );
- final XControl gridControl = controlContainer.getControl( "grid" );
- assertNotNull( "no grid control created in the dialog", gridControl );
-
- // in the current implementation (not sure this is a good idea at all), the control (more precise: the peer)
- // ensures that if there are no columns in the column model, but in the data model, then the column model
- // will implicitly have the needed columns added.
- // To ensure that clients which rely on this do not break in the future, check this here.
- final XMutableGridDataModel dataModel = UnoRuntime.queryInterface( XMutableGridDataModel.class,
- gridModelProps.getPropertyValue( "GridDataModel" ) );
- assertNotNull( dataModel );
- assertEquals( 0, dataModel.getColumnCount() );
-
- final XGridColumnModel columnModel = UnoRuntime.queryInterface( XGridColumnModel.class,
- gridModelProps.getPropertyValue( "ColumnModel" ) );
- assertNotNull( columnModel );
- assertEquals( 0, columnModel.getColumnCount() );
-
- dataModel.addRow( null, new Object[] { 1, 2, 3 } );
- assertEquals( 3, dataModel.getColumnCount() );
- assertEquals( 3, columnModel.getColumnCount() );
- }
- finally
- {
- impl_dispose( disposables.toArray());
- }
+ final XControl control = impl_createDialogWithGridControl();
+ final XPropertySet gridModelProps =
+ UnoRuntime.queryInterface( XPropertySet.class, control.getModel() );
+
+ // in the current implementation (not sure this is a good idea at all), the control (more precise: the peer)
+ // ensures that if there are no columns in the column model, but in the data model, then the column model
+ // will implicitly have the needed columns added.
+ // To ensure that clients which rely on this do not break in the future, check this here.
+ final XMutableGridDataModel dataModel = UnoRuntime.queryInterface( XMutableGridDataModel.class,
+ gridModelProps.getPropertyValue( "GridDataModel" ) );
+ assertNotNull( dataModel );
+ assertEquals( 0, dataModel.getColumnCount() );
+
+ final XGridColumnModel columnModel = UnoRuntime.queryInterface( XGridColumnModel.class,
+ gridModelProps.getPropertyValue( "ColumnModel" ) );
+ assertNotNull( columnModel );
+ assertEquals( 0, columnModel.getColumnCount() );
+
+ final int columnCount = 3;
+ final int rowCount = 2;
+ dataModel.addRow( null, new Object[] { 1, 2, 3 } );
+ dataModel.addRow( null, new Object[] { 6, 5, 4 } );
+
+ assertEquals( columnCount, dataModel.getColumnCount() );
+ assertEquals( columnCount, columnModel.getColumnCount() );
+
+ // some cursor traveling
+ final XGridControl gridControl = UnoRuntime.queryInterface( XGridControl.class, control );
+ gridControl.goToCell( 0, 0 );
+ assertEquals( "wrong 'current column' (1)", 0, gridControl.getCurrentColumn() );
+ assertEquals( "wrong 'current row' (1)", 0, gridControl.getCurrentRow() );
+ gridControl.goToCell( columnCount - 1, rowCount - 1 );
+ assertEquals( "wrong 'current column' (2)", dataModel.getColumnCount() - 1, gridControl.getCurrentColumn() );
+ assertEquals( "wrong 'current row' (2)", dataModel.getRowCount() - 1, gridControl.getCurrentRow() );
+
+ // removing the last column, while the active cell is in this very last column, is expected to adjust
+ // the active cell
+ columnModel.removeColumn( columnCount - 1 );
+ assertEquals( "removed the last and active column, active column was not adjusted!",
+ columnCount - 2, gridControl.getCurrentColumn() );
+ // same holds for rows
+ dataModel.removeRow( rowCount - 1 );
+ assertEquals( "removed the last and active row, active row was not adjusted!",
+ rowCount - 2, gridControl.getCurrentRow() );
+ }
+
+ // -----------------------------------------------------------------------------------------------------------------
+ private XControl impl_createDialogWithGridControl() throws Exception
+ {
+ // create a simple dialog model/control/peer trinity
+ final XControlModel dialogModel = createInstance( XControlModel.class, "com.sun.star.awt.UnoControlDialogModel" );
+ m_disposables.add( dialogModel );
+ final XPropertySet dialogProps = UnoRuntime.queryInterface( XPropertySet.class, dialogModel );
+ dialogProps.setPropertyValue( "Width", 200 );
+ dialogProps.setPropertyValue( "Height", 100 );
+ dialogProps.setPropertyValue( "Title", "Grid Control Unit Test" );
+ final XControl dialogControl = createInstance( XControl.class, "com.sun.star.awt.UnoControlDialog" );
+ m_disposables.add( dialogControl );
+ dialogControl.setModel( dialogModel );
+ dialogControl.createPeer( createInstance( XToolkit.class, "com.sun.star.awt.Toolkit" ), null );
+
+ // insert a grid control model
+ final XMultiServiceFactory controlModelFactory = UnoRuntime.queryInterface( XMultiServiceFactory.class,
+ dialogModel );
+ final XPropertySet gridModelProps = UnoRuntime.queryInterface( XPropertySet.class,
+ controlModelFactory.createInstance( "com.sun.star.awt.grid.UnoControlGridModel" ) );
+ m_disposables.add( gridModelProps );
+ gridModelProps.setPropertyValue( "PositionX", 6 );
+ gridModelProps.setPropertyValue( "PositionY", 6 );
+ gridModelProps.setPropertyValue( "Width", 188 );
+ gridModelProps.setPropertyValue( "Height", 88 );
+ final XNameContainer modelContainer = UnoRuntime.queryInterface( XNameContainer.class, dialogModel );
+ modelContainer.insertByName( "grid", gridModelProps );
+
+ // check the respective control has been created
+ final XControlContainer controlContainer = UnoRuntime.queryInterface( XControlContainer.class, dialogControl );
+ final XControl gridControl = controlContainer.getControl( "grid" );
+ assertNotNull( "no grid control created in the dialog", gridControl );
+
+ return gridControl;
}
// -----------------------------------------------------------------------------------------------------------------
@@ -554,6 +611,20 @@ public class GridControl
}
// -----------------------------------------------------------------------------------------------------------------
+ @Before
+ public void initTestCase()
+ {
+ m_disposables.clear();
+ }
+
+ // -----------------------------------------------------------------------------------------------------------------
+ @After
+ public void cleanupTestCase()
+ {
+ impl_dispose( m_disposables.toArray() );
+ }
+
+ // -----------------------------------------------------------------------------------------------------------------
@BeforeClass
public static void setUpConnection() throws java.lang.Exception
{
@@ -684,4 +755,5 @@ public class GridControl
private XPropertySet m_gridControlModel;
private XGridColumnModel m_columnModel;
private XSortableMutableGridDataModel m_dataModel;
+ private final List< Object > m_disposables = new ArrayList< Object >();
}
diff --git a/toolkit/qa/complex/toolkit/awtgrid/TMutableGridDataModel.java b/toolkit/qa/complex/toolkit/awtgrid/TMutableGridDataModel.java
index c550dd9a047d..7f3c8fb55541 100755..100644
--- a/toolkit/qa/complex/toolkit/awtgrid/TMutableGridDataModel.java
+++ b/toolkit/qa/complex/toolkit/awtgrid/TMutableGridDataModel.java
@@ -53,14 +53,14 @@ public class TMutableGridDataModel
*/
public void testAddRow() throws IndexOutOfBoundsException
{
- m_dataModel.addRow( 1, m_rowValues[0] );
+ m_dataModel.addRow( m_rowHeadings[0], m_rowValues[0] );
GridDataEvent event = m_listener.assertSingleRowInsertionEvent();
m_listener.reset();
assertEquals( "row insertion: wrong FirstRow (1)", 0, event.FirstRow );
assertEquals( "row insertion: wrong LastRow (1)", 0, event.LastRow );
impl_assertRowData( 0 );
- m_dataModel.addRow( 2, m_rowValues[1] );
+ m_dataModel.addRow( m_rowHeadings[1], m_rowValues[1] );
event = m_listener.assertSingleRowInsertionEvent();
m_listener.reset();
assertEquals( "row insertion: wrong FirstRow (2)", 1, event.FirstRow );
@@ -75,7 +75,9 @@ public class TMutableGridDataModel
{
assertEquals( "precondition not met: call this directly after testAddRow, please!", 2, m_dataModel.getRowCount() );
- m_dataModel.addRows( new Object[] { "3", 4.0, "5" }, new Object[][] { m_rowValues[2], m_rowValues[3], m_rowValues[4] } );
+ m_dataModel.addRows(
+ new Object[] { m_rowHeadings[2], m_rowHeadings[3], m_rowHeadings[4] },
+ new Object[][] { m_rowValues[2], m_rowValues[3], m_rowValues[4] } );
GridDataEvent event = m_listener.assertSingleRowInsertionEvent();
assertEquals( "row insertion: wrong FirstRow (1)", 2, event.FirstRow );
assertEquals( "row insertion: wrong LastRow (1)", 4, event.LastRow );
@@ -97,6 +99,145 @@ public class TMutableGridDataModel
}
/**
+ * tests the XMutableGridDataModel.insertRow method
+ */
+ public void testInsertRow() throws IndexOutOfBoundsException
+ {
+ int expectedRowCount = m_rowValues.length;
+ assertEquals( "precondition not met: call this directly after testAddRows, please!", expectedRowCount, m_dataModel.getRowCount() );
+
+ // inserting some row somewhere between the other rows
+ final Object heading = "inbetweenRow";
+ final Object[] inbetweenRow = new Object[] { "foo", "bar", 3, 4, 5 };
+ final int insertionPos = 2;
+ m_dataModel.insertRow( insertionPos, heading, inbetweenRow );
+ ++expectedRowCount;
+ assertEquals( "inserting a row is expected to increment the row count",
+ expectedRowCount, m_dataModel.getRowCount() );
+
+ final GridDataEvent event = m_listener.assertSingleRowInsertionEvent();
+ assertEquals( "inserting a row results in wrong FirstRow being notified", insertionPos, event.FirstRow );
+ assertEquals( "inserting a row results in wrong LastRow being notified", insertionPos, event.LastRow );
+ m_listener.reset();
+
+ for ( int row=0; row<expectedRowCount; ++row )
+ {
+ final Object[] actualRowData = m_dataModel.getRowData( row );
+ final Object[] expectedRowData =
+ ( row < insertionPos )
+ ? m_rowValues[ row ]
+ : ( row == insertionPos )
+ ? inbetweenRow
+ : m_rowValues[ row - 1 ];
+ assertArrayEquals( "row number " + row + " has wrong content content after inserting a row",
+ expectedRowData, actualRowData );
+
+ final Object actualHeading = m_dataModel.getRowHeading(row);
+ final Object expectedHeading =
+ ( row < insertionPos )
+ ? m_rowHeadings[ row ]
+ : ( row == insertionPos )
+ ? heading
+ : m_rowHeadings[ row - 1 ];
+ assertEquals( "row " + row + " has a wrong heading after invoking insertRow",
+ expectedHeading, actualHeading );
+ }
+
+ // exceptions
+ assertException( "inserting a row at a position > rowCount is expected to throw",
+ m_dataModel, "insertRow",
+ new Class[] { Integer.class, Object.class, Object[].class },
+ new Object[] { expectedRowCount + 1, "", new Object[] { "1", 2, 3 } },
+ IndexOutOfBoundsException.class );
+ assertException( "inserting a row at a position < 0 is expected to throw",
+ m_dataModel, "insertRow",
+ new Class[] { Integer.class, Object.class, Object[].class },
+ new Object[] { -1, "", new Object[] { "1", 2, 3 } },
+ IndexOutOfBoundsException.class );
+
+ // remove the row, to create the situation expected by the next test
+ m_dataModel.removeRow( insertionPos );
+ m_listener.reset();
+ }
+
+ /**
+ * tests the XMutableGridDataModel.insertRows method
+ */
+ public void testInsertRows() throws IndexOutOfBoundsException, IllegalArgumentException
+ {
+ int expectedRowCount = m_rowValues.length;
+ assertEquals( "precondition not met: call this directly after testInsertRow, please!", expectedRowCount, m_dataModel.getRowCount() );
+
+ // inserting some rows somewhere between the other rows
+ final int insertionPos = 3;
+ final Object[] rowHeadings = new Object[] { "A", "B", "C" };
+ final Object[][] rowData = new Object[][] {
+ new Object[] { "A", "B", "C", "D", "E" },
+ new Object[] { "J", "I", "H", "G", "F" },
+ new Object[] { "K", "L", "M", "N", "O" }
+ };
+ final int insertedRowCount = rowData.length;
+ assertEquals( "invalid test data", rowHeadings.length, insertedRowCount );
+
+ m_dataModel.insertRows( insertionPos, rowHeadings, rowData );
+ expectedRowCount += insertedRowCount;
+
+ final GridDataEvent event = m_listener.assertSingleRowInsertionEvent();
+ assertEquals( "inserting multiple rows results in wrong FirstRow being notified",
+ insertionPos, event.FirstRow );
+ assertEquals( "inserting multiple rows results in wrong LastRow being notified",
+ insertionPos + insertedRowCount - 1, event.LastRow );
+ m_listener.reset();
+
+ for ( int row=0; row<expectedRowCount; ++row )
+ {
+ final Object[] actualRowData = m_dataModel.getRowData( row );
+ final Object[] expectedRowData =
+ ( row < insertionPos )
+ ? m_rowValues[ row ]
+ : ( row >= insertionPos ) && ( row < insertionPos + insertedRowCount )
+ ? rowData[ row - insertionPos ]
+ : m_rowValues[ row - insertedRowCount ];
+ assertArrayEquals( "row number " + row + " has wrong content content after inserting multiple rows",
+ expectedRowData, actualRowData );
+
+ final Object actualHeading = m_dataModel.getRowHeading(row);
+ final Object expectedHeading =
+ ( row < insertionPos )
+ ? m_rowHeadings[ row ]
+ : ( row >= insertionPos ) && ( row < insertionPos + insertedRowCount )
+ ? rowHeadings[ row - insertionPos ]
+ : m_rowHeadings[ row - insertedRowCount ];
+ assertEquals( "row " + row + " has a wrong heading after invoking insertRows",
+ expectedHeading, actualHeading );
+ }
+
+ // exceptions
+ assertException( "inserting multiple rows at a position > rowCount is expected to throw an IndexOutOfBoundsException",
+ m_dataModel, "insertRows",
+ new Class[] { Integer.class, Object[].class, Object[][].class },
+ new Object[] { expectedRowCount + 1, new Object[0], new Object[][] { } },
+ IndexOutOfBoundsException.class );
+ assertException( "inserting multiple rows at a position < 0 is expected to throw an IndexOutOfBoundsException",
+ m_dataModel, "insertRows",
+ new Class[] { Integer.class, Object[].class, Object[][].class },
+ new Object[] { -1, new Object[0], new Object[][] { } },
+ IndexOutOfBoundsException.class );
+ assertException( "inserting multiple rows with inconsistent array lengths is expected to throw an IllegalArgumentException",
+ m_dataModel, "insertRows",
+ new Class[] { Integer.class, Object[].class, Object[][].class },
+ new Object[] { 0, new Object[0], new Object[][] { new Object[0] } },
+ IllegalArgumentException.class );
+
+ // remove the row, to create the situation expected by the next test
+ for ( int i=0; i<insertedRowCount; ++i )
+ {
+ m_dataModel.removeRow( insertionPos );
+ m_listener.reset();
+ }
+ }
+
+ /**
* tests the XMutableGridDataModel.removeRow method
*/
public void testRemoveRow() throws IndexOutOfBoundsException
@@ -150,7 +291,7 @@ public class TMutableGridDataModel
{
assertEquals( "precondition not met: call this directly after testRemoveAllRows, please!", 0, m_dataModel.getRowCount() );
- m_dataModel.addRows( new Object[] { 1, 2, 3, 4, 5 }, m_rowValues );
+ m_dataModel.addRows( m_rowHeadings, m_rowValues );
m_listener.assertSingleRowInsertionEvent();
m_listener.reset();
@@ -311,4 +452,8 @@ public class TMutableGridDataModel
new Object[] { 4, 5, 6, 7, "8" },
new Object[] { 5, "6", 7, 8, 9 },
};
+
+ private final static Object[] m_rowHeadings = new Object[] {
+ "1", 2, 3.0, "4", (float)5.0
+ };
}
diff --git a/toolkit/source/awt/vclxtabpagecontainer.cxx b/toolkit/source/awt/vclxtabpagecontainer.cxx
index d4f7a5048701..64337153dac1 100644
--- a/toolkit/source/awt/vclxtabpagecontainer.cxx
+++ b/toolkit/source/awt/vclxtabpagecontainer.cxx
@@ -126,7 +126,7 @@ void SAL_CALL VCLXTabPageContainer::setActiveTabPageID( ::sal_Int16 _activetabpa
if ( pTabCtrl )
pTabCtrl->SelectTabPage(_activetabpageid);
}
-::sal_Int32 SAL_CALL VCLXTabPageContainer::getTabPageCount( ) throw (RuntimeException)
+::sal_Int16 SAL_CALL VCLXTabPageContainer::getTabPageCount( ) throw (RuntimeException)
{
TabControl* pTabCtrl = (TabControl*)GetWindow();
return pTabCtrl != NULL ? pTabCtrl->GetPageCount() : 0;
@@ -157,11 +157,11 @@ Reference< ::com::sun::star::awt::tab::XTabPage > SAL_CALL VCLXTabPageContainer:
}
return xTabPage;
}
-void SAL_CALL VCLXTabPageContainer::addTabPageListener( const Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (RuntimeException)
+void SAL_CALL VCLXTabPageContainer::addTabPageContainerListener( const Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (RuntimeException)
{
m_aTabPageListeners.addInterface( listener );
}
-void SAL_CALL VCLXTabPageContainer::removeTabPageListener( const Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (RuntimeException)
+void SAL_CALL VCLXTabPageContainer::removeTabPageContainerListener( const Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (RuntimeException)
{
m_aTabPageListeners.removeInterface( listener );
}
@@ -209,7 +209,7 @@ void SAL_CALL VCLXTabPageContainer::elementInserted( const ::com::sun::star::con
pPage->Hide();
pTabCtrl->SetTabPage(nPageID,pPage);
- pTabCtrl->SetHelpText(nPageID,xP->getTooltip());
+ pTabCtrl->SetHelpText(nPageID,xP->getToolTip());
pTabCtrl->SetPageImage(nPageID,TkResMgr::getImageFromURL(xP->getImageURL()));
pTabCtrl->SelectTabPage(nPageID);
m_aTabPages.push_back(xTabPage);
diff --git a/toolkit/source/awt/vclxtabpagemodel.cxx b/toolkit/source/awt/vclxtabpagemodel.cxx
index c7145992bd7f..936a2301dcb4 100644
--- a/toolkit/source/awt/vclxtabpagemodel.cxx
+++ b/toolkit/source/awt/vclxtabpagemodel.cxx
@@ -124,12 +124,12 @@ void SAL_CALL VCLXTabPageModel::setImageURL( const ::rtl::OUString& /*_imageurl*
{
//m_sImageURL = _imageurl;
}
-::rtl::OUString SAL_CALL VCLXTabPageModel::getTooltip() throw (::com::sun::star::uno::RuntimeException)
+::rtl::OUString SAL_CALL VCLXTabPageModel::getToolTip() throw (::com::sun::star::uno::RuntimeException)
{
//return m_sTooltip;
return ::rtl::OUString::createFromAscii("");
}
-void SAL_CALL VCLXTabPageModel::setTooltip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException)
+void SAL_CALL VCLXTabPageModel::setToolTip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException)
{
(void)_tooltip;
}
diff --git a/toolkit/source/controls/controlmodelcontainerbase.cxx b/toolkit/source/controls/controlmodelcontainerbase.cxx
index 25f30cb88d34..aa7452113652 100644
--- a/toolkit/source/controls/controlmodelcontainerbase.cxx
+++ b/toolkit/source/controls/controlmodelcontainerbase.cxx
@@ -39,14 +39,14 @@
#include <toolkit/controls/unocontrols.hxx>
#include "toolkit/controls/formattedcontrol.hxx"
#include "toolkit/controls/roadmapcontrol.hxx"
-#ifndef TOOLKIT_INC_TOOLKIT_CONTROLS_TKSCROLLBAR_HXX
#include "toolkit/controls/tkscrollbar.hxx"
-#endif
+#include "toolkit/controls/tabpagemodel.hxx"
#include <toolkit/controls/stdtabcontroller.hxx>
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/awt/WindowAttribute.hpp>
#include <com/sun/star/resource/XStringResourceResolver.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
#include <tools/list.hxx>
#include <cppuhelper/typeprovider.hxx>
#include <tools/debug.hxx>
@@ -389,6 +389,8 @@ Reference< XInterface > ControlModelContainerBase::createInstance( const ::rtl::
pNewModel = new OGeometryControlModel< UnoGridModel >( xFactory );
else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageContainerModel ) == 0 )
pNewModel = new OGeometryControlModel< UnoControlTabPageContainerModel >( xFactory );
+ else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageModel ) == 0 )
+ pNewModel = new OGeometryControlModel< UnoControlTabPageModel >( xFactory );
if ( !pNewModel )
{
@@ -417,9 +419,13 @@ Reference< XInterface > ControlModelContainerBase::createInstance( const ::rtl::
return xNewModel;
}
-Reference< XInterface > ControlModelContainerBase::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& /* Arguments */ ) throw(Exception, RuntimeException)
+Reference< XInterface > ControlModelContainerBase::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& i_arguments ) throw(Exception, RuntimeException)
{
- return createInstance( ServiceSpecifier );
+ const Reference< XInterface > xInstance( createInstance( ServiceSpecifier ) );
+ const Reference< XInitialization > xInstanceInit( xInstance, UNO_QUERY );
+ ENSURE_OR_RETURN( xInstanceInit.is(), "ControlModelContainerBase::createInstanceWithArguments: can't pass the arguments!", xInstance );
+ xInstanceInit->initialize( i_arguments );
+ return xInstance;
}
Sequence< ::rtl::OUString > ControlModelContainerBase::getAvailableServiceNames() throw(RuntimeException)
@@ -779,11 +785,11 @@ void SAL_CALL ControlModelContainerBase::setImageURL( const ::rtl::OUString& _im
{
m_sImageURL = _imageurl;
}
-::rtl::OUString SAL_CALL ControlModelContainerBase::getTooltip() throw (::com::sun::star::uno::RuntimeException)
+::rtl::OUString SAL_CALL ControlModelContainerBase::getToolTip() throw (::com::sun::star::uno::RuntimeException)
{
return m_sTooltip;
}
-void SAL_CALL ControlModelContainerBase::setTooltip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException)
+void SAL_CALL ControlModelContainerBase::setToolTip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException)
{
m_sTooltip = _tooltip;
}
@@ -1344,7 +1350,7 @@ void ControlContainerBase::ImplInsertControl( Reference< XControlModel >& rxMode
Reference < XControl > xCtrl;
maContext.createComponent( aDefCtrl, xCtrl );
- DBG_ASSERT( xCtrl.is(), "UnoDialogControl::ImplInsertControl: could not create the control!" );
+ DBG_ASSERT( xCtrl.is(), "ControlContainerBase::ImplInsertControl: could not create the control!" );
if ( xCtrl.is() )
{
xCtrl->setModel( rxModel );
@@ -1562,7 +1568,7 @@ void ControlContainerBase::elementInserted( const ContainerEvent& Event ) throw(
Event.Accessor >>= aName;
Event.Element >>= xModel;
- ENSURE_OR_RETURN_VOID( xModel.is(), "UnoDialogControl::elementInserted: illegal element!" );
+ ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementInserted: illegal element!" );
try
{
ImplInsertControl( xModel, aName );
@@ -1580,7 +1586,7 @@ void ControlContainerBase::elementRemoved( const ContainerEvent& Event ) throw(R
Reference< XControlModel > xModel;
Event.Element >>= xModel;
- ENSURE_OR_RETURN_VOID( xModel.is(), "UnoDialogControl::elementRemoved: illegal element!" );
+ ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementRemoved: illegal element!" );
try
{
ImplRemoveControl( xModel );
@@ -1600,7 +1606,7 @@ void ControlContainerBase::elementReplaced( const ContainerEvent& Event ) throw(
Event.ReplacedElement >>= xModel;
try
{
- OSL_ENSURE( xModel.is(), "UnoDialogControl::elementReplaced: invalid ReplacedElement!" );
+ OSL_ENSURE( xModel.is(), "ControlContainerBase::elementReplaced: invalid ReplacedElement!" );
if ( xModel.is() )
ImplRemoveControl( xModel );
}
@@ -1613,7 +1619,7 @@ void ControlContainerBase::elementReplaced( const ContainerEvent& Event ) throw(
::rtl::OUString aName;
Event.Accessor >>= aName;
Event.Element >>= xModel;
- ENSURE_OR_RETURN_VOID( xModel.is(), "UnoDialogControl::elementReplaced: invalid new element!" );
+ ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementReplaced: invalid new element!" );
try
{
ImplInsertControl( xModel, aName );
diff --git a/toolkit/source/controls/grid/defaultgriddatamodel.cxx b/toolkit/source/controls/grid/defaultgriddatamodel.cxx
index 4ef99d749ba1..acb71a33be4c 100644
--- a/toolkit/source/controls/grid/defaultgriddatamodel.cxx
+++ b/toolkit/source/controls/grid/defaultgriddatamodel.cxx
@@ -37,6 +37,7 @@
#include <rtl/ref.hxx>
#include <algorithm>
+#include <functional>
//......................................................................................................................
namespace toolkit
@@ -100,7 +101,7 @@ namespace toolkit
::sal_Int32 SAL_CALL DefaultGridDataModel::getRowCount() throw (::com::sun::star::uno::RuntimeException)
{
::comphelper::ComponentGuard aGuard( *this, rBHelper );
- return m_aData.size();
+ return impl_getRowCount_nolck();
}
//------------------------------------------------------------------------------------------------------------------
@@ -175,52 +176,82 @@ namespace toolkit
}
//------------------------------------------------------------------------------------------------------------------
- void SAL_CALL DefaultGridDataModel::addRow( const Any& i_heading, const Sequence< Any >& i_data ) throw (RuntimeException)
+ Sequence< Any > SAL_CALL DefaultGridDataModel::getRowData( ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
::comphelper::ComponentGuard aGuard( *this, rBHelper );
- sal_Int32 const columnCount = i_data.getLength();
-
- // store header name
- m_aRowHeaders.push_back( i_heading );
-
- // store row m_aData
- impl_addRow( i_data );
-
- // update column count
- if ( columnCount > m_nColumnCount )
- m_nColumnCount = columnCount;
+ Sequence< Any > resultData( m_nColumnCount );
+ RowData& rRowData = impl_getRowDataAccess_throw( i_rowIndex, m_nColumnCount );
- sal_Int32 const rowIndex = sal_Int32( m_aData.size() - 1 );
- broadcast(
- GridDataEvent( *this, -1, -1, rowIndex, rowIndex ),
- &XGridDataListener::rowsInserted,
- aGuard
- );
+ ::std::transform( rRowData.begin(), rRowData.end(), resultData.getArray(), ::std::select1st< CellData >() );
+ return resultData;
}
//------------------------------------------------------------------------------------------------------------------
- void DefaultGridDataModel::impl_addRow( Sequence< Any > const & i_rowData, sal_Int32 const i_assumedColCount )
+ void DefaultGridDataModel::impl_insertRow( sal_Int32 const i_position, Any const & i_heading, Sequence< Any > const & i_rowData, sal_Int32 const i_assumedColCount )
{
OSL_PRECOND( ( i_assumedColCount <= 0 ) || ( i_assumedColCount >= i_rowData.getLength() ),
- "DefaultGridDataModel::impl_addRow: invalid column count!" );
+ "DefaultGridDataModel::impl_insertRow: invalid column count!" );
+
+ // insert heading
+ m_aRowHeaders.insert( m_aRowHeaders.begin() + i_position, i_heading );
+ // create new data row
RowData newRow( i_assumedColCount > 0 ? i_assumedColCount : i_rowData.getLength() );
RowData::iterator cellData = newRow.begin();
for ( const Any* pData = stl_begin( i_rowData ); pData != stl_end( i_rowData ); ++pData, ++cellData )
cellData->first = *pData;
- m_aData.push_back( newRow );
+ // insert data row
+ m_aData.insert( m_aData.begin() + i_position, newRow );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::addRow( const Any& i_heading, const Sequence< Any >& i_data ) throw (RuntimeException)
+ {
+ insertRow( getRowCount(), i_heading, i_data );
}
//------------------------------------------------------------------------------------------------------------------
void SAL_CALL DefaultGridDataModel::addRows( const Sequence< Any >& i_headings, const Sequence< Sequence< Any > >& i_data ) throw (IllegalArgumentException, RuntimeException)
{
+ insertRows( getRowCount(), i_headings, i_data );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::insertRow( ::sal_Int32 i_index, const Any& i_heading, const Sequence< Any >& i_data ) throw (RuntimeException, IndexOutOfBoundsException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+
+ if ( ( i_index < 0 ) || ( i_index > impl_getRowCount_nolck() ) )
+ throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
+
+ // actually insert the row
+ impl_insertRow( i_index, i_heading, i_data );
+
+ // update column count
+ sal_Int32 const columnCount = i_data.getLength();
+ if ( columnCount > m_nColumnCount )
+ m_nColumnCount = columnCount;
+
+ broadcast(
+ GridDataEvent( *this, -1, -1, i_index, i_index ),
+ &XGridDataListener::rowsInserted,
+ aGuard
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::insertRows( ::sal_Int32 i_index, const Sequence< Any>& i_headings, const Sequence< Sequence< Any > >& i_data ) throw (IllegalArgumentException, IndexOutOfBoundsException, RuntimeException)
+ {
if ( i_headings.getLength() != i_data.getLength() )
throw IllegalArgumentException( ::rtl::OUString(), *this, -1 );
::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ if ( ( i_index < 0 ) || ( i_index > impl_getRowCount_nolck() ) )
+ throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
+
sal_Int32 const rowCount = i_headings.getLength();
if ( rowCount == 0 )
return;
@@ -236,17 +267,14 @@ namespace toolkit
for ( sal_Int32 row=0; row<rowCount; ++row )
{
- m_aRowHeaders.push_back( i_headings[row] );
- impl_addRow( i_data[row], maxColCount );
+ impl_insertRow( i_index + row, i_headings[row], i_data[row], maxColCount );
}
if ( maxColCount > m_nColumnCount )
m_nColumnCount = maxColCount;
- sal_Int32 const firstRow = sal_Int32( m_aData.size() - rowCount );
- sal_Int32 const lastRow = sal_Int32( m_aData.size() - 1 );
broadcast(
- GridDataEvent( *this, -1, -1, firstRow, lastRow ),
+ GridDataEvent( *this, -1, -1, i_index, i_index + rowCount - 1 ),
&XGridDataListener::rowsInserted,
aGuard
);
diff --git a/toolkit/source/controls/grid/defaultgriddatamodel.hxx b/toolkit/source/controls/grid/defaultgriddatamodel.hxx
index bf4b6cc3355e..e679160dc9db 100644
--- a/toolkit/source/controls/grid/defaultgriddatamodel.hxx
+++ b/toolkit/source/controls/grid/defaultgriddatamodel.hxx
@@ -65,6 +65,8 @@ public:
// XMutableGridDataModel
virtual void SAL_CALL addRow( const Any& i_heading, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Data ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL addRows( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& Headings, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& Data ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL insertRow( ::sal_Int32 i_index, const ::com::sun::star::uno::Any& i_heading, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Data ) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException);
+ virtual void SAL_CALL insertRows( ::sal_Int32 i_index, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& Headings, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& Data ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL removeRow( ::sal_Int32 RowIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL removeAllRows( ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL updateCellData( ::sal_Int32 ColumnIndex, ::sal_Int32 RowIndex, const ::com::sun::star::uno::Any& Value ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
@@ -81,6 +83,7 @@ public:
virtual ::com::sun::star::uno::Any SAL_CALL getCellData( ::sal_Int32 Column, ::sal_Int32 Row ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::uno::Any SAL_CALL getCellToolTip( ::sal_Int32 Column, ::sal_Int32 Row ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::uno::Any SAL_CALL getRowHeading( ::sal_Int32 RowIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL getRowData( ::sal_Int32 RowIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
// OComponentHelper
virtual void SAL_CALL disposing();
@@ -104,7 +107,9 @@ private:
::comphelper::ComponentGuard & i_instanceLock
);
- void impl_addRow( Sequence< Any > const & i_rowData, sal_Int32 const i_assumedColCount = -1 );
+ void impl_insertRow( sal_Int32 const i_position, Any const & i_heading, Sequence< Any > const & i_rowData, sal_Int32 const i_assumedColCount = -1 );
+
+ ::sal_Int32 impl_getRowCount_nolck() const { return sal_Int32( m_aData.size() ); }
CellData const & impl_getCellData_throw( sal_Int32 const i_columnIndex, sal_Int32 const i_rowIndex ) const;
CellData& impl_getCellDataAccess_throw( sal_Int32 const i_columnIndex, sal_Int32 const i_rowIndex );
diff --git a/toolkit/source/controls/grid/gridcontrol.cxx b/toolkit/source/controls/grid/gridcontrol.cxx
index acda52753a60..82619d01c7f5 100644
--- a/toolkit/source/controls/grid/gridcontrol.cxx
+++ b/toolkit/source/controls/grid/gridcontrol.cxx
@@ -54,6 +54,7 @@ using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::view;
+using namespace ::com::sun::star::util;
namespace toolkit
{
@@ -111,6 +112,10 @@ UnoGridModel::UnoGridModel( const ::com::sun::star::uno::Reference< ::com::sun::
ImplRegisterProperty( BASEPROPERTY_GRID_HEADER_BACKGROUND );
ImplRegisterProperty( BASEPROPERTY_GRID_HEADER_TEXT_COLOR );
ImplRegisterProperty( BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS );
+ ImplRegisterProperty( BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR );
+ ImplRegisterProperty( BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR );
+ ImplRegisterProperty( BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR );
+ ImplRegisterProperty( BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR );
ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN );
}
@@ -240,6 +245,10 @@ Any UnoGridModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
case BASEPROPERTY_GRID_HEADER_TEXT_COLOR:
case BASEPROPERTY_GRID_LINE_COLOR:
case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS:
+ case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR:
+ case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR:
+ case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR:
+ case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR:
return Any();
default:
return UnoControlModel::ImplGetDefaultValue( nPropId );
@@ -304,8 +313,8 @@ void SAL_CALL UnoGridControl::createPeer( const uno::Reference< awt::XToolkit >
{
UnoControlBase::createPeer( rxToolkit, rParentPeer );
- const Reference< XGridControl > xGrid( getPeer(), UNO_QUERY_THROW );
- xGrid->addSelectionListener(&m_aSelectionListeners);
+ const Reference< XGridRowSelection > xGrid( getPeer(), UNO_QUERY_THROW );
+ xGrid->addSelectionListener( &m_aSelectionListeners );
}
//----------------------------------------------------------------------------------------------------------------------
@@ -387,45 +396,52 @@ sal_Bool SAL_CALL UnoGridControl::setModel( const Reference< XControlModel >& i_
}
//----------------------------------------------------------------------------------------------------------------------
-void SAL_CALL UnoGridControl::selectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException)
+void SAL_CALL UnoGridControl::goToCell( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException, VetoException)
{
- Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->selectRow( i_rowIndex );
+ Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW );
+ xGrid->goToCell( i_columnIndex, i_rowIndex );
+}
+
+//----------------------------------------------------------------------------------------------------------------------
+void SAL_CALL UnoGridControl::selectRow( ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException )
+{
+ Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->selectRow( i_rowIndex );
}
//----------------------------------------------------------------------------------------------------------------------
void SAL_CALL UnoGridControl::selectAllRows() throw (::com::sun::star::uno::RuntimeException)
{
- Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->selectAllRows();
+ Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->selectAllRows();
}
//----------------------------------------------------------------------------------------------------------------------
-void SAL_CALL UnoGridControl::deselectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException)
+void SAL_CALL UnoGridControl::deselectRow( ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException )
{
- Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->deselectRow( i_rowIndex );
+ Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->deselectRow( i_rowIndex );
}
//----------------------------------------------------------------------------------------------------------------------
void SAL_CALL UnoGridControl::deselectAllRows() throw (::com::sun::star::uno::RuntimeException)
{
- Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->deselectAllRows();
+ Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->deselectAllRows();
}
//----------------------------------------------------------------------------------------------------------------------
-::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL UnoGridControl::getSelection() throw (::com::sun::star::uno::RuntimeException)
+::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL UnoGridControl::getSelectedRows() throw (::com::sun::star::uno::RuntimeException)
{
- return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->getSelection();
+ return Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->getSelectedRows();
}
//----------------------------------------------------------------------------------------------------------------------
-::sal_Bool SAL_CALL UnoGridControl::isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException)
+::sal_Bool SAL_CALL UnoGridControl::hasSelectedRows() throw (::com::sun::star::uno::RuntimeException)
{
- return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->isSelectionEmpty();
+ return Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->hasSelectedRows();
}
//----------------------------------------------------------------------------------------------------------------------
-::sal_Bool SAL_CALL UnoGridControl::isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException)
+::sal_Bool SAL_CALL UnoGridControl::isRowSelected(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException)
{
- return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->isSelectedIndex( index );
+ return Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->isRowSelected( index );
}
//----------------------------------------------------------------------------------------------------------------------
diff --git a/toolkit/source/controls/grid/gridcontrol.hxx b/toolkit/source/controls/grid/gridcontrol.hxx
index 61d9f8fc0232..de1ac8d657c3 100644
--- a/toolkit/source/controls/grid/gridcontrol.hxx
+++ b/toolkit/source/controls/grid/gridcontrol.hxx
@@ -29,12 +29,13 @@
#define TOOLKIT_GRID_CONTROL_HXX
#include <com/sun/star/awt/grid/XGridControl.hpp>
+#include <com/sun/star/awt/grid/XGridRowSelection.hpp>
#include <com/sun/star/view/SelectionType.hpp>
#include <toolkit/controls/unocontrolbase.hxx>
#include <toolkit/controls/unocontrolmodel.hxx>
#include <toolkit/helper/servicenames.hxx>
-#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
#include <comphelper/sequence.hxx>
#include <toolkit/helper/listenermultiplexer.hxx>
@@ -80,8 +81,9 @@ public:
// ===================================================================
// = UnoGridControl
// ===================================================================
-typedef ::cppu::ImplInheritanceHelper1 < UnoControlBase
+typedef ::cppu::ImplInheritanceHelper2 < UnoControlBase
, ::com::sun::star::awt::grid::XGridControl
+ , ::com::sun::star::awt::grid::XGridRowSelection
> UnoGridControl_Base;
class UnoGridControl : public UnoGridControl_Base
{
@@ -101,15 +103,16 @@ public:
virtual ::sal_Int32 SAL_CALL getRowAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Int32 SAL_CALL getCurrentColumn( ) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Int32 SAL_CALL getCurrentRow( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL goToCell( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::util::VetoException);
- // ::com::sun::star::awt::grid::XGridSelection
- virtual void SAL_CALL selectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException);
+ // ::com::sun::star::awt::grid::XGridRowSelection
+ virtual void SAL_CALL selectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException );
virtual void SAL_CALL selectAllRows() throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL deselectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL deselectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException );
virtual void SAL_CALL deselectAllRows() throw (::com::sun::star::uno::RuntimeException);
- virtual ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL getSelection() throw (::com::sun::star::uno::RuntimeException);
- virtual ::sal_Bool SAL_CALL isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException);
- virtual ::sal_Bool SAL_CALL isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL getSelectedRows() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasSelectedRows() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isRowSelected(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException);
diff --git a/toolkit/source/controls/grid/sortablegriddatamodel.cxx b/toolkit/source/controls/grid/sortablegriddatamodel.cxx
index 77a2ffa1637b..abfa123df0de 100755..100644
--- a/toolkit/source/controls/grid/sortablegriddatamodel.cxx
+++ b/toolkit/source/controls/grid/sortablegriddatamodel.cxx
@@ -295,45 +295,15 @@ namespace toolkit
MethodGuard aGuard( *this, rBHelper );
DBG_CHECK_ME();
- // if the data is not sorted, broadcast the event unchanged
- if ( !impl_isSorted_nothrow() )
- {
- GridDataEvent const aEvent( impl_createPublicEvent( i_event ) );
- impl_broadcast( &XGridDataListener::rowsInserted, aEvent, aGuard );
- return;
- }
-
- bool needReIndex = false;
- if ( i_event.FirstRow > i_event.LastRow )
- {
- OSL_ENSURE( false, "SortableGridDataModel::rowsInserted: invalid event - invalid row indexes!" );
- needReIndex = true;
- }
- else if ( size_t( i_event.FirstRow ) > m_privateToPublicRowIndex.size() )
- {
- OSL_ENSURE( false, "SortableGridDataModel::rowsInserted: invalid event - too large row index!" );
- needReIndex = true;
- }
-
- if ( needReIndex )
- {
- impl_rebuildIndexesAndNotify( aGuard );
- return;
- }
-
- // we do not insert the new rows into the sort order - if somebody adds rows while we're sorted, s/he has
- // to resort. Instead, we simply append the rows, no matter where they were inserted in the delegator data
- // model.
- sal_Int32 const nPublicFirstRow = sal_Int32( m_privateToPublicRowIndex.size() );
- sal_Int32 nPublicLastRow = nPublicFirstRow;
- for ( sal_Int32 newRow = i_event.FirstRow; newRow <= i_event.LastRow; ++newRow, ++nPublicLastRow )
+ if ( impl_isSorted_nothrow() )
{
- m_privateToPublicRowIndex.push_back( nPublicLastRow );
- m_publicToPrivateRowIndex.push_back( nPublicLastRow );
+ // no infrastructure is in place currently to sort the new row to its proper location,
+ // so we remove the sorting here.
+ impl_removeColumnSort( aGuard );
+ aGuard.reset();
}
- // broadcast the event
- GridDataEvent const aEvent( *this, -1, -1, nPublicFirstRow, nPublicLastRow );
+ GridDataEvent const aEvent( impl_createPublicEvent( i_event ) );
impl_broadcast( &XGridDataListener::rowsInserted, aEvent, aGuard );
}
@@ -362,14 +332,18 @@ namespace toolkit
lcl_clear( m_publicToPrivateRowIndex );
lcl_clear( m_privateToPublicRowIndex );
+ // rebuild the index
+ if ( !impl_reIndex_nothrow( m_currentSortColumn, m_sortAscending ) )
+ {
+ impl_removeColumnSort( i_instanceLock );
+ return;
+ }
+
// broadcast an artificial event, saying that all rows have been removed
GridDataEvent const aRemovalEvent( *this, -1, -1, -1, -1 );
impl_broadcast( &XGridDataListener::rowsRemoved, aRemovalEvent, i_instanceLock );
i_instanceLock.reset();
- // rebuild the index
- impl_reIndex_nothrow( m_currentSortColumn, m_sortAscending );
-
// broadcast an artificial event, saying that n rows have been added
GridDataEvent const aAdditionEvent( *this, -1, -1, 0, m_delegator->getRowCount() - 1 );
impl_broadcast( &XGridDataListener::rowsInserted, aAdditionEvent, i_instanceLock );
@@ -505,7 +479,7 @@ namespace toolkit
}
//------------------------------------------------------------------------------------------------------------------
- void SortableGridDataModel::impl_reIndex_nothrow( ::sal_Int32 const i_columnIndex, sal_Bool const i_sortAscending )
+ bool SortableGridDataModel::impl_reIndex_nothrow( ::sal_Int32 const i_columnIndex, sal_Bool const i_sortAscending )
{
::sal_Int32 const rowCount( getRowCount() );
::std::vector< ::sal_Int32 > aPublicToPrivate( rowCount );
@@ -527,7 +501,7 @@ namespace toolkit
// get predicate object
::std::auto_ptr< ::comphelper::IKeyPredicateLess > const pPredicate( ::comphelper::getStandardLessPredicate( dataType, m_collator ) );
- ENSURE_OR_RETURN_VOID( pPredicate.get(), "SortableGridDataModel::impl_reIndex_nothrow: no sortable data found!" );
+ ENSURE_OR_RETURN_FALSE( pPredicate.get(), "SortableGridDataModel::impl_reIndex_nothrow: no sortable data found!" );
// then sort
CellDataLessComparison const aComparator( aColumnData, *pPredicate, i_sortAscending );
@@ -536,7 +510,7 @@ namespace toolkit
catch( const Exception& )
{
DBG_UNHANDLED_EXCEPTION();
- return;
+ return false;
}
// also build the "private to public" mapping
@@ -546,6 +520,8 @@ namespace toolkit
m_publicToPrivateRowIndex.swap( aPublicToPrivate );
m_privateToPublicRowIndex.swap( aPrivateToPublic );
+
+ return true;
}
//------------------------------------------------------------------------------------------------------------------
@@ -557,7 +533,8 @@ namespace toolkit
if ( ( i_columnIndex < 0 ) || ( i_columnIndex >= getColumnCount() ) )
throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
- impl_reIndex_nothrow( i_columnIndex, i_sortAscending );
+ if ( !impl_reIndex_nothrow( i_columnIndex, i_sortAscending ) )
+ return;
m_currentSortColumn = i_columnIndex;
m_sortAscending = i_sortAscending;
@@ -570,25 +547,35 @@ namespace toolkit
}
//------------------------------------------------------------------------------------------------------------------
- void SAL_CALL SortableGridDataModel::removeColumnSort( ) throw (RuntimeException)
+ void SortableGridDataModel::impl_removeColumnSort_noBroadcast()
{
- MethodGuard aGuard( *this, rBHelper );
- DBG_CHECK_ME();
-
lcl_clear( m_publicToPrivateRowIndex );
lcl_clear( m_privateToPublicRowIndex );
m_currentSortColumn = -1;
m_sortAscending = sal_True;
+ }
+ //------------------------------------------------------------------------------------------------------------------
+ void SortableGridDataModel::impl_removeColumnSort( MethodGuard& i_instanceLock )
+ {
+ impl_removeColumnSort_noBroadcast();
impl_broadcast(
&XGridDataListener::dataChanged,
GridDataEvent( *this, -1, -1, -1, -1 ),
- aGuard
+ i_instanceLock
);
}
//------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::removeColumnSort( ) throw (RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+ impl_removeColumnSort( aGuard );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
Pair< ::sal_Int32, ::sal_Bool > SAL_CALL SortableGridDataModel::getCurrentSortOrder( ) throw (RuntimeException)
{
MethodGuard aGuard( *this, rBHelper );
@@ -620,6 +607,34 @@ namespace toolkit
}
//------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::insertRow( ::sal_Int32 i_index, const Any& i_heading, const Sequence< Any >& i_data ) throw (RuntimeException, IndexOutOfBoundsException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ ::sal_Int32 const rowIndex = i_index == getRowCount() ? i_index : impl_getPrivateRowIndex_throw( i_index );
+ // note that |RowCount| is a valid index in this method, but not for impl_getPrivateRowIndex_throw
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ delegator->insertRow( rowIndex, i_heading, i_data );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::insertRows( ::sal_Int32 i_index, const Sequence< Any>& i_headings, const Sequence< Sequence< Any > >& i_data ) throw (IllegalArgumentException, IndexOutOfBoundsException, RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ ::sal_Int32 const rowIndex = i_index == getRowCount() ? i_index : impl_getPrivateRowIndex_throw( i_index );
+ // note that |RowCount| is a valid index in this method, but not for impl_getPrivateRowIndex_throw
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ delegator->insertRows( rowIndex, i_headings, i_data );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
void SAL_CALL SortableGridDataModel::removeRow( ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
MethodGuard aGuard( *this, rBHelper );
@@ -782,6 +797,19 @@ namespace toolkit
}
//------------------------------------------------------------------------------------------------------------------
+ Sequence< Any > SAL_CALL SortableGridDataModel::getRowData( ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ return delegator->getRowData( rowIndex );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
void SAL_CALL SortableGridDataModel::disposing()
{
m_currentSortColumn = -1;
diff --git a/toolkit/source/controls/grid/sortablegriddatamodel.hxx b/toolkit/source/controls/grid/sortablegriddatamodel.hxx
index 50f08d3a7113..8f90801ee50c 100755..100644
--- a/toolkit/source/controls/grid/sortablegriddatamodel.hxx
+++ b/toolkit/source/controls/grid/sortablegriddatamodel.hxx
@@ -85,6 +85,8 @@ namespace toolkit
// XMutableGridDataModel
virtual void SAL_CALL addRow( const ::com::sun::star::uno::Any& Heading, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Data ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL addRows( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Headings, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& Data ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL insertRow( ::sal_Int32 i_index, const ::com::sun::star::uno::Any& i_heading, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Data ) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException);
+ virtual void SAL_CALL insertRows( ::sal_Int32 i_index, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& Headings, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& Data ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL removeRow( ::sal_Int32 RowIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL removeAllRows( ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL updateCellData( ::sal_Int32 ColumnIndex, ::sal_Int32 RowIndex, const ::com::sun::star::uno::Any& Value ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
@@ -98,9 +100,10 @@ namespace toolkit
// XGridDataModel
virtual ::sal_Int32 SAL_CALL getRowCount() throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Int32 SAL_CALL getColumnCount() throw (::com::sun::star::uno::RuntimeException);
- virtual ::com::sun::star::uno::Any SAL_CALL getCellData( ::sal_Int32 Column, ::sal_Int32 Row ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
- virtual ::com::sun::star::uno::Any SAL_CALL getCellToolTip( ::sal_Int32 Column, ::sal_Int32 Row ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getCellData( ::sal_Int32 Column, ::sal_Int32 RowIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getCellToolTip( ::sal_Int32 Column, ::sal_Int32 RowIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::uno::Any SAL_CALL getRowHeading( ::sal_Int32 RowIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL getRowData( ::sal_Int32 RowIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
// OComponentHelper
virtual void SAL_CALL disposing();
@@ -155,7 +158,7 @@ namespace toolkit
Neither <member>m_currentSortColumn</member> nor <member>m_sortAscending</member> are touched by this method.
Also, the given column index is not checked, this is the responsibility of the caller.
*/
- void impl_reIndex_nothrow( ::sal_Int32 const i_columnIndex, sal_Bool const i_sortAscending );
+ bool impl_reIndex_nothrow( ::sal_Int32 const i_columnIndex, sal_Bool const i_sortAscending );
/** translates the given event, obtained from our delegator, to a version which can be broadcasted to our own
clients.
@@ -180,6 +183,14 @@ namespace toolkit
*/
void impl_rebuildIndexesAndNotify( MethodGuard& i_instanceLock );
+ /** removes the current sorting, and notifies a change of all data
+ */
+ void impl_removeColumnSort( MethodGuard& i_instanceLock );
+
+ /** removes the current sorting, without any broadcast
+ */
+ void impl_removeColumnSort_noBroadcast();
+
private:
::comphelper::ComponentContext m_context;
bool m_isInitialized;
diff --git a/toolkit/source/controls/tabpagecontainer.cxx b/toolkit/source/controls/tabpagecontainer.cxx
index 808feca02e8a..84ecef367e56 100644
--- a/toolkit/source/controls/tabpagecontainer.cxx
+++ b/toolkit/source/controls/tabpagecontainer.cxx
@@ -28,19 +28,21 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"
+#include <toolkit/controls/geometrycontrolmodel.hxx>
#include <toolkit/controls/tabpagecontainer.hxx>
-
-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-#include <toolkit/helper/unopropertyarrayhelper.hxx>
+#include <toolkit/controls/tabpagemodel.hxx>
#include <toolkit/helper/property.hxx>
-#include <toolkit/controls/geometrycontrolmodel.hxx>
+#include <toolkit/helper/unopropertyarrayhelper.hxx>
+
+#include <com/sun/star/awt/XControlModel.hpp>
#include <com/sun/star/awt/XVclWindowPeer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
#include <comphelper/processfactory.hxx>
#include <osl/diagnose.h>
+#include <tools/diagnose_ex.h>
#include <vcl/svapp.hxx>
#include <vos/mutex.hxx>
-#include <com/sun/star/awt/XControlModel.hpp>
-#include <tools/diagnose_ex.h>
using ::rtl::OUString;
using namespace ::com::sun::star;
@@ -49,6 +51,7 @@ using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::view;
+using ::com::sun::star::awt::tab::XTabPageModel;
#define WRONG_TYPE_EXCEPTION "Type must be ::com::sun::star::awt::tab::XTabPageModel!"
// ----------------------------------------------------
@@ -89,13 +92,13 @@ uno::Any UnoControlTabPageContainerModel::ImplGetDefaultValue( sal_uInt16 nPropI
::cppu::IPropertyArrayHelper& UnoControlTabPageContainerModel::getInfoHelper()
{
- static UnoPropertyArrayHelper* pHelper = NULL;
- if ( !pHelper )
- {
+ static UnoPropertyArrayHelper* pHelper = NULL;
+ if ( !pHelper )
+ {
com::sun::star::uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds();
- pHelper = new UnoPropertyArrayHelper( aIDs );
+ pHelper = new UnoPropertyArrayHelper( aIDs );
}
- return *pHelper;
+ return *pHelper;
}
Reference< ::com::sun::star::beans::XPropertySetInfo > UnoControlTabPageContainerModel::getPropertySetInfo( ) throw(RuntimeException)
{
@@ -103,17 +106,67 @@ Reference< ::com::sun::star::beans::XPropertySetInfo > UnoControlTabPageContaine
return xInfo;
}
+namespace
+{
+ Reference< XTabPageModel > lcl_createTabPageModel( ::comphelper::ComponentContext const & i_context,
+ Sequence< Any > const & i_initArguments, Reference< XPropertySet > const & i_parentModel )
+ {
+ try
+ {
+ Reference< XPropertySet > const xParentDelegator( i_parentModel, UNO_QUERY_THROW );
+ Reference< XPropertySetInfo > const xPSI( xParentDelegator->getPropertySetInfo() );
+ bool const isGeometryControlModel = xPSI.is() && xPSI->hasPropertyByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) ) );
+
+ Reference< XInterface > xInstance;
+ if ( isGeometryControlModel )
+ xInstance = *( new OGeometryControlModel< UnoControlTabPageModel >( i_context.getLegacyServiceFactory() ) );
+ else
+ xInstance = *( new UnoControlTabPageModel( i_context.getLegacyServiceFactory() ) );
+
+ Reference< XTabPageModel > const xTabPageModel( xInstance, UNO_QUERY_THROW );
+ Reference< XInitialization > const xInit( xTabPageModel, UNO_QUERY_THROW );
+ xInit->initialize( i_initArguments );
+
+ return xTabPageModel;
+ }
+ catch( const RuntimeException& )
+ {
+ throw;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return NULL;
+ }
+}
+
+Reference< XTabPageModel > SAL_CALL UnoControlTabPageContainerModel::createTabPage( ::sal_Int16 i_tabPageID ) throw (RuntimeException)
+{
+ Sequence< Any > aInitArgs(1);
+ aInitArgs[0] <<= i_tabPageID;
+ return lcl_createTabPageModel( maContext, aInitArgs, this );
+}
+
+Reference< XTabPageModel > SAL_CALL UnoControlTabPageContainerModel::loadTabPage( ::sal_Int16 i_tabPageID, const ::rtl::OUString& i_resourceURL ) throw (RuntimeException)
+{
+ Sequence< Any > aInitArgs(2);
+ aInitArgs[0] <<= i_tabPageID;
+ aInitArgs[1] <<= i_resourceURL;
+ return lcl_createTabPageModel( maContext, aInitArgs, this );
+}
+
void SAL_CALL UnoControlTabPageContainerModel::insertByIndex( ::sal_Int32 nIndex, const com::sun::star::uno::Any& aElement) throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, uno::RuntimeException)
{
vos::OGuard aSolarGuard( Application::GetSolarMutex() );
- uno::Reference < ::awt::tab::XTabPageModel > xTabPageModel;
+ uno::Reference < XTabPageModel > xTabPageModel;
if(aElement >>= xTabPageModel)
{
if ( sal_Int32( m_aTabPageVector.size()) ==nIndex )
m_aTabPageVector.push_back( xTabPageModel );
else if ( sal_Int32( m_aTabPageVector.size()) > nIndex )
{
- std::vector< uno::Reference< ::awt::tab::XTabPageModel > >::iterator aIter = m_aTabPageVector.begin();
+ std::vector< uno::Reference< XTabPageModel > >::iterator aIter = m_aTabPageVector.begin();
aIter += nIndex;
m_aTabPageVector.insert( aIter, xTabPageModel );
}
@@ -167,12 +220,12 @@ uno::Type SAL_CALL UnoControlTabPageContainerModel::getElementType( ) throw (un
// XContainer
void UnoControlTabPageContainerModel::addContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException)
{
- maContainerListeners.addInterface( l );
+ maContainerListeners.addInterface( l );
}
void UnoControlTabPageContainerModel::removeContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException)
{
- maContainerListeners.removeInterface( l );
+ maContainerListeners.removeInterface( l );
}
// ----------------------------------------------------
@@ -203,7 +256,7 @@ void UnoControlTabPageContainer::createPeer( const uno::Reference< awt::XToolkit
Reference< XTabPageContainer > xTPContainer( getPeer(), UNO_QUERY_THROW );
if ( m_aTabPageListeners.getLength() )
- xTPContainer->addTabPageListener(&m_aTabPageListeners);
+ xTPContainer->addTabPageContainerListener(&m_aTabPageListeners);
}
// -------------------------------------------------------------------
@@ -221,7 +274,7 @@ void SAL_CALL UnoControlTabPageContainer::setActiveTabPageID( ::sal_Int16 _activ
Reference< XTabPageContainer > xTPContainer( getPeer(), UNO_QUERY_THROW );
xTPContainer->setActiveTabPageID(_activetabpageid);
}
-::sal_Int32 SAL_CALL UnoControlTabPageContainer::getTabPageCount( ) throw (RuntimeException)
+::sal_Int16 SAL_CALL UnoControlTabPageContainer::getTabPageCount( ) throw (RuntimeException)
{
vos::OGuard aSolarGuard( Application::GetSolarMutex() );
Reference< XTabPageContainer > xTPContainer( getPeer(), UNO_QUERY_THROW );
@@ -245,21 +298,21 @@ Reference< ::com::sun::star::awt::tab::XTabPage > SAL_CALL UnoControlTabPageCont
Reference< XTabPageContainer > xTPContainer( getPeer(), UNO_QUERY_THROW );
return xTPContainer->getTabPageByID(tabPageID);
}
-void SAL_CALL UnoControlTabPageContainer::addTabPageListener( const Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (RuntimeException)
+void SAL_CALL UnoControlTabPageContainer::addTabPageContainerListener( const Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (RuntimeException)
{
m_aTabPageListeners.addInterface( listener );
if( getPeer().is() && m_aTabPageListeners.getLength() == 1 )
{
uno::Reference < awt::tab::XTabPageContainer > xTabPageContainer( getPeer(), uno::UNO_QUERY );
- xTabPageContainer->addTabPageListener( &m_aTabPageListeners );
+ xTabPageContainer->addTabPageContainerListener( &m_aTabPageListeners );
}
}
-void SAL_CALL UnoControlTabPageContainer::removeTabPageListener( const Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (RuntimeException)
+void SAL_CALL UnoControlTabPageContainer::removeTabPageContainerListener( const Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (RuntimeException)
{
if( getPeer().is() && m_aTabPageListeners.getLength() == 1 )
{
uno::Reference < awt::tab::XTabPageContainer > xTabPageContainer( getPeer(), uno::UNO_QUERY );
- xTabPageContainer->addTabPageListener( &m_aTabPageListeners );
+ xTabPageContainer->addTabPageContainerListener( &m_aTabPageListeners );
}
m_aTabPageListeners.removeInterface( listener );
}
diff --git a/toolkit/source/controls/tabpagemodel.cxx b/toolkit/source/controls/tabpagemodel.cxx
index f498fefd761b..834b7f92e013 100644
--- a/toolkit/source/controls/tabpagemodel.cxx
+++ b/toolkit/source/controls/tabpagemodel.cxx
@@ -75,72 +75,6 @@ using namespace ::com::sun::star::util;
::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl );
// ----------------------------------------------------
-// class TabPageModel
-// ----------------------------------------------------
-
-//TabPageModel::TabPageModel()
-//{
-//}
-//TabPageModel::TabPageModel( uno::Reference< uno::XComponentContext > const & xCompContext)
-//{
-// (void) xCompContext;
-//}
-//
-//TabPageModel::~TabPageModel()
-//{
-//}
-//
-//////----- XInitialization -------------------------------------------------------------------
-//void SAL_CALL TabPageModel::initialize (const Sequence<Any>& rArguments)
-//{
-// sal_Int16 nPageId;
-// if ( rArguments.getLength() == 1 )
-// {
-// if ( !( rArguments[ 0 ] >>= nPageId ))
-// throw lang::IllegalArgumentException();
-// m_nTabPageId = nPageId;
-// }
-// else
-// m_nTabPageId = -1;
-//}
-//::sal_Int16 SAL_CALL TabPageModel::getTabPageID() throw (::com::sun::star::uno::RuntimeException)
-//{
-// return m_nTabPageId;
-//}
-//::sal_Bool SAL_CALL TabPageModel::getEnabled() throw (::com::sun::star::uno::RuntimeException)
-//{
-// return m_bEnabled;
-//}
-//void SAL_CALL TabPageModel::setEnabled( ::sal_Bool _enabled ) throw (::com::sun::star::uno::RuntimeException)
-//{
-// m_bEnabled = _enabled;
-//}
-//::rtl::OUString SAL_CALL TabPageModel::getTitle() throw (::com::sun::star::uno::RuntimeException)
-//{
-// return m_sTitle;
-//}
-//void SAL_CALL TabPageModel::setTitle( const ::rtl::OUString& _title ) throw (::com::sun::star::uno::RuntimeException)
-//{
-// m_sTitle = _title;
-//}
-//::rtl::OUString SAL_CALL TabPageModel::getImageURL() throw (::com::sun::star::uno::RuntimeException)
-//{
-// return m_sImageURL;
-//}
-//void SAL_CALL TabPageModel::setImageURL( const ::rtl::OUString& _imageurl ) throw (::com::sun::star::uno::RuntimeException)
-//{
-// m_sImageURL = _imageurl;
-//}
-//::rtl::OUString SAL_CALL TabPageModel::getTooltip() throw (::com::sun::star::uno::RuntimeException)
-//{
-// return m_sTooltip;
-//}
-//void SAL_CALL TabPageModel::setTooltip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException)
-//{
-// m_sTooltip = _tooltip;
-//}
-
-// ----------------------------------------------------
// class UnoControlTabPageModel
// ----------------------------------------------------
UnoControlTabPageModel::UnoControlTabPageModel( Reference< XMultiServiceFactory > const & i_factory )
diff --git a/toolkit/source/helper/property.cxx b/toolkit/source/helper/property.cxx
index a418b4a00b7b..80ddf6d04fce 100644
--- a/toolkit/source/helper/property.cxx
+++ b/toolkit/source/helper/property.cxx
@@ -292,6 +292,10 @@ ImplPropertyInfo* ImplGetPropertyInfos( sal_uInt16& rElementCount )
DECL_PROP_3 ( "GridLineColor", GRID_LINE_COLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
DECL_PROP_3 ( "RowBackgroundColors", GRID_ROW_BACKGROUND_COLORS, Sequence< sal_Int32 >, BOUND, MAYBEDEFAULT, MAYBEVOID ),
DECL_PROP_2 ( "UseGridLines", USE_GRID_LINES, sal_Bool, BOUND, MAYBEDEFAULT ),
+ DECL_PROP_3 ( "ActiveSelectionBackgroundColor", ACTIVE_SEL_BACKGROUND_COLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "InactiveSelectionBackgroundColor", INACTIVE_SEL_BACKGROUND_COLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "ActiveSelectionTextColor", ACTIVE_SEL_TEXT_COLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
+ DECL_PROP_3 ( "InactiveSelectionTextColor", INACTIVE_SEL_TEXT_COLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID ),
};
pPropertyInfos = aImplPropertyInfos;
nElements = sizeof( aImplPropertyInfos ) / sizeof( ImplPropertyInfo );
diff --git a/toolkit/source/helper/registerservices.cxx b/toolkit/source/helper/registerservices.cxx
index 8a6b1d8de4b9..fa3afbe87af8 100644
--- a/toolkit/source/helper/registerservices.cxx
+++ b/toolkit/source/helper/registerservices.cxx
@@ -128,9 +128,10 @@ namespace toolkit
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL ImplName##_CreateInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_factory ) \
{ return ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface >( ( ::cppu::OWeakObject* ) new ImplName( i_factory ) ); }
-::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL UnoControlDialogModel_CreateInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_factory )
-{
- return ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface >( ( ::cppu::OWeakObject* ) new OGeometryControlModel<UnoControlDialogModel>( i_factory ) );
+#define IMPL_CREATE_INSTANCE_WITH_GEOMETRY( ImplName ) \
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL ImplName##_CreateInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_factory ) \
+{ \
+ return ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface >( ( ::cppu::OWeakObject* ) new OGeometryControlModel< ImplName >( i_factory ) ); \
}
#define GET_FACTORY_WITH_IMPL_PREFIX( ClassName, ImplNamePrefix, ServiceName1, ServiceName2 ) \
@@ -212,6 +213,8 @@ IMPL_CREATEINSTANCE2( AnimatedImagesControl )
IMPL_CREATEINSTANCE2( AnimatedImagesControlModel )
IMPL_CREATEINSTANCE2( SpinningProgressControlModel )
+IMPL_CREATE_INSTANCE_WITH_GEOMETRY( UnoControlDialogModel )
+
extern ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL TreeControl_CreateInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& );
extern ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL TreeControlModel_CreateInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& );
extern ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL MutableTreeDataModel_CreateInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& );
@@ -234,6 +237,7 @@ TOOLKIT_DLLPUBLIC void SAL_CALL component_getImplementationEnvironment( const sa
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
+
TOOLKIT_DLLPUBLIC void* SAL_CALL component_getFactory( const sal_Char* sImplementationName, void* _pServiceManager, void* _pRegistryKey )
{
void* pRet = NULL;
@@ -313,13 +317,13 @@ TOOLKIT_DLLPUBLIC void* SAL_CALL component_getFactory( const sal_Char* sImplemen
GET_FACTORY( DefaultGridColumnModel, szServiceName_DefaultGridColumnModel, NULL );
GET_FACTORY_WITH_IMPL_PREFIX( GridColumn, "org.openoffice.comp.toolkit", szServiceName_GridColumn, NULL );
GET_FACTORY_WITH_IMPL_PREFIX( SortableGridDataModel, "org.openoffice.comp.toolkit", szServiceName_SortableGridDataModel, NULL );
- GET_FACTORY_WITH_IMPL_PREFIX( AnimatedImagesControl, "org.openoffice.comp.toolkit", szServiceName_AnimatedImagesControl, NULL )
- GET_FACTORY_WITH_IMPL_PREFIX( AnimatedImagesControlModel, "org.openoffice.comp.toolkit", szServiceName_AnimatedImagesControlModel, NULL )
- GET_FACTORY_WITH_IMPL_PREFIX( SpinningProgressControlModel, "org.openoffice.comp.toolkit", szServiceName_SpinningProgressControlModel, NULL )
GET_FACTORY( UnoControlTabPageModel, szServiceName_UnoControlTabPageModel, NULL )
GET_FACTORY( UnoControlTabPage, szServiceName_UnoControlTabPage, NULL )
GET_FACTORY( UnoControlTabPageContainerModel, szServiceName_UnoControlTabPageContainerModel, NULL )
GET_FACTORY( UnoControlTabPageContainer, szServiceName_UnoControlTabPageContainer, NULL )
+ GET_FACTORY_WITH_IMPL_PREFIX( AnimatedImagesControl, "org.openoffice.comp.toolkit", szServiceName_AnimatedImagesControl, NULL )
+ GET_FACTORY_WITH_IMPL_PREFIX( AnimatedImagesControlModel, "org.openoffice.comp.toolkit", szServiceName_AnimatedImagesControlModel, NULL )
+ GET_FACTORY_WITH_IMPL_PREFIX( SpinningProgressControlModel, "org.openoffice.comp.toolkit", szServiceName_SpinningProgressControlModel, NULL )
if ( rtl_str_compare( sImplementationName, "com.sun.star.awt.comp.AsyncCallback" ) == 0 )
return comp_AsyncCallback_component_getFactory( sImplementationName, _pServiceManager, _pRegistryKey );
diff --git a/vcl/inc/vcl/ctrl.hxx b/vcl/inc/vcl/ctrl.hxx
index 3bf529ada48b..88a4e1f08362 100644
--- a/vcl/inc/vcl/ctrl.hxx
+++ b/vcl/inc/vcl/ctrl.hxx
@@ -47,7 +47,7 @@ protected:
::vcl::ImplControlData* mpControlData;
private:
- sal_Bool mbHasFocus;
+ bool mbHasControlFocus;
Link maGetFocusHdl;
Link maLoseFocusHdl;
@@ -179,6 +179,10 @@ public:
void SetLoseFocusHdl( const Link& rLink ) { maLoseFocusHdl = rLink; }
const Link& GetLoseFocusHdl() const { return maLoseFocusHdl; }
+ /** determines whether the control currently has the focus
+ */
+ bool HasControlFocus() const { return mbHasControlFocus; }
+
void SetLayoutDataParent( const Control* pParent ) const;
virtual Size GetOptimalSize(WindowSizeType eType) const;
diff --git a/vcl/inc/vcl/help.hxx b/vcl/inc/vcl/help.hxx
index b80b9a86627a..b1e7f05d53a1 100644
--- a/vcl/inc/vcl/help.hxx
+++ b/vcl/inc/vcl/help.hxx
@@ -77,30 +77,30 @@ public:
void SetHelpFile( const String& rFileName ) { maHelpFile = rFileName; }
const String& GetHelpFile() const { return maHelpFile; }
- virtual sal_Bool Start( const XubString& rHelpId, const Window* pWindow );
- virtual sal_Bool SearchKeyword( const XubString& rKeyWord );
+ virtual sal_Bool Start( const XubString& rHelpId, const Window* pWindow );
+ virtual sal_Bool SearchKeyword( const XubString& rKeyWord );
virtual void OpenHelpAgent( const rtl::OString& rHelpId );
virtual XubString GetHelpText( const String& aHelpURL, const Window* pWindow );
static void EnableContextHelp();
static void DisableContextHelp();
- static sal_Bool IsContextHelpEnabled();
- static sal_Bool StartContextHelp();
+ static sal_Bool IsContextHelpEnabled();
+ static sal_Bool StartContextHelp();
static void EnableExtHelp();
static void DisableExtHelp();
- static sal_Bool IsExtHelpEnabled();
- static sal_Bool StartExtHelp();
- static sal_Bool EndExtHelp();
- static sal_Bool IsExtHelpActive();
+ static sal_Bool IsExtHelpEnabled();
+ static sal_Bool StartExtHelp();
+ static sal_Bool EndExtHelp();
+ static sal_Bool IsExtHelpActive();
static void EnableBalloonHelp();
static void DisableBalloonHelp();
- static sal_Bool IsBalloonHelpEnabled();
- static sal_Bool ShowBalloon( Window* pParent,
+ static sal_Bool IsBalloonHelpEnabled();
+ static sal_Bool ShowBalloon( Window* pParent,
const Point& rScreenPos,
const XubString& rHelpText );
- static sal_Bool ShowBalloon( Window* pParent,
+ static sal_Bool ShowBalloon( Window* pParent,
const Point& rScreenPos,
const Rectangle&,
const XubString& rHelpText );
@@ -119,6 +119,8 @@ public:
sal_uInt16 nStyle = 0 )
{ return Help::ShowQuickHelp( pParent, rScreenRect, rHelpText, XubString(), nStyle ); }
+ static void HideBalloonAndQuickHelp();
+
static sal_uLong ShowTip( Window* pParent,
const Rectangle& rScreenRect,
const XubString& rText, sal_uInt16 nStyle = 0 );
diff --git a/vcl/inc/vcl/window.hxx b/vcl/inc/vcl/window.hxx
index f367be85051d..219bd4328b1b 100755..100644
--- a/vcl/inc/vcl/window.hxx
+++ b/vcl/inc/vcl/window.hxx
@@ -270,6 +270,7 @@ typedef sal_uInt16 StateChangedType;
#define STATE_CHANGE_FORMAT ((StateChangedType)17)
#define STATE_CHANGE_EXTENDEDSTYLE ((StateChangedType)18)
#define STATE_CHANGE_MIRRORING ((StateChangedType)19)
+#define STATE_CHANGE_CONTROL_FOCUS ((StateChangedType)20)
#define STATE_CHANGE_USER ((StateChangedType)10000)
// GetFocusFlags
diff --git a/vcl/source/app/help.cxx b/vcl/source/app/help.cxx
index ce582916ea62..231b1df8e36c 100644
--- a/vcl/source/app/help.cxx
+++ b/vcl/source/app/help.cxx
@@ -277,6 +277,15 @@ sal_Bool Help::ShowQuickHelp( Window* pParent,
// -----------------------------------------------------------------------
+void Help::HideBalloonAndQuickHelp()
+{
+ HelpTextWindow const * pHelpWin = ImplGetSVData()->maHelpData.mpHelpWin;
+ bool const bIsVisible = ( pHelpWin != NULL ) && pHelpWin->IsVisible();
+ ImplDestroyHelpWindow( bIsVisible );
+}
+
+// -----------------------------------------------------------------------
+
sal_uIntPtr Help::ShowTip( Window* pParent, const Rectangle& rScreenRect,
const XubString& rText, sal_uInt16 nStyle )
{
@@ -303,6 +312,7 @@ void Help::UpdateTip( sal_uIntPtr nId, Window* pParent, const Rectangle& rScreen
pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), &rScreenRect );
pHelpWin->SetHelpText( rText );
+ pHelpWin->Invalidate();
}
// -----------------------------------------------------------------------
diff --git a/vcl/source/control/ctrl.cxx b/vcl/source/control/ctrl.cxx
index 26ef9b076d8c..dd887276ca5b 100644
--- a/vcl/source/control/ctrl.cxx
+++ b/vcl/source/control/ctrl.cxx
@@ -50,7 +50,7 @@ using namespace vcl;
void Control::ImplInitControlData()
{
- mbHasFocus = sal_False;
+ mbHasControlFocus = sal_False;
mpControlData = new ImplControlData;
}
@@ -304,9 +304,10 @@ long Control::Notify( NotifyEvent& rNEvt )
{
if ( rNEvt.GetType() == EVENT_GETFOCUS )
{
- if ( !mbHasFocus )
+ if ( !mbHasControlFocus )
{
- mbHasFocus = sal_True;
+ mbHasControlFocus = sal_True;
+ StateChanged( STATE_CHANGE_CONTROL_FOCUS );
if ( ImplCallEventListenersAndHandler( VCLEVENT_CONTROL_GETFOCUS, maGetFocusHdl, this ) )
// been destroyed within the handler
return sal_True;
@@ -319,7 +320,8 @@ long Control::Notify( NotifyEvent& rNEvt )
Window* pFocusWin = Application::GetFocusWindow();
if ( !pFocusWin || !ImplIsWindowOrChild( pFocusWin ) )
{
- mbHasFocus = sal_False;
+ mbHasControlFocus = sal_False;
+ StateChanged( STATE_CHANGE_CONTROL_FOCUS );
if ( ImplCallEventListenersAndHandler( VCLEVENT_CONTROL_LOSEFOCUS, maLoseFocusHdl, this ) )
// been destroyed within the handler
return sal_True;