diff options
Diffstat (limited to 'svtools/source')
27 files changed, 4907 insertions, 80 deletions
diff --git a/svtools/source/config/optionsdrawinglayer.cxx b/svtools/source/config/optionsdrawinglayer.cxx index 125827d17faf..abb044c7863e 100644 --- a/svtools/source/config/optionsdrawinglayer.cxx +++ b/svtools/source/config/optionsdrawinglayer.cxx @@ -92,6 +92,11 @@ using namespace ::com::sun::star::uno ; #define DEFAULT_QUADRATIC3DRENDERLIMIT 1000000 #define DEFAULT_QUADRATICFORMCONTROLRENDERLIMIT 45000 +// #i97672# selection settings +#define DEFAULT_TRANSPARENTSELECTION sal_True +#define DEFAULT_TRANSPARENTSELECTIONPERCENT 75 +#define DEFAULT_SELECTIONMAXIMUMLUMINANCEPERCENT 70 + #define PROPERTYNAME_OVERLAYBUFFER OUString(RTL_CONSTASCII_USTRINGPARAM("OverlayBuffer" )) #define PROPERTYNAME_PAINTBUFFER OUString(RTL_CONSTASCII_USTRINGPARAM("PaintBuffer" )) #define PROPERTYNAME_STRIPE_COLOR_A OUString(RTL_CONSTASCII_USTRINGPARAM("StripeColorA" )) @@ -125,6 +130,11 @@ using namespace ::com::sun::star::uno ; #define PROPERTYNAME_QUADRATIC3DRENDERLIMIT OUString(RTL_CONSTASCII_USTRINGPARAM("Quadratic3DRenderLimit")) #define PROPERTYNAME_QUADRATICFORMCONTROLRENDERLIMIT OUString(RTL_CONSTASCII_USTRINGPARAM("QuadraticFormControlRenderLimit")) +// #i97672# selection settings +#define PROPERTYNAME_TRANSPARENTSELECTION OUString(RTL_CONSTASCII_USTRINGPARAM("TransparentSelection")) +#define PROPERTYNAME_TRANSPARENTSELECTIONPERCENT OUString(RTL_CONSTASCII_USTRINGPARAM("TransparentSelectionPercent")) +#define PROPERTYNAME_SELECTIONMAXIMUMLUMINANCEPERCENT OUString(RTL_CONSTASCII_USTRINGPARAM("SelectionMaximumLuminancePercent")) + #define PROPERTYHANDLE_OVERLAYBUFFER 0 #define PROPERTYHANDLE_PAINTBUFFER 1 #define PROPERTYHANDLE_STRIPE_COLOR_A 2 @@ -158,7 +168,12 @@ using namespace ::com::sun::star::uno ; #define PROPERTYHANDLE_QUADRATIC3DRENDERLIMIT 22 #define PROPERTYHANDLE_QUADRATICFORMCONTROLRENDERLIMIT 23 -#define PROPERTYCOUNT 24 +// #i97672# selection settings +#define PROPERTYHANDLE_TRANSPARENTSELECTION 24 +#define PROPERTYHANDLE_TRANSPARENTSELECTIONPERCENT 25 +#define PROPERTYHANDLE_SELECTIONMAXIMUMLUMINANCEPERCENT 26 + +#define PROPERTYCOUNT 27 class SvtOptionsDrawinglayer_Impl : public ConfigItem { @@ -248,6 +263,15 @@ public: void SetQuadratic3DRenderLimit(sal_uInt32 nNew); void SetQuadraticFormControlRenderLimit(sal_uInt32 nNew); + // #i97672# selection settings + sal_Bool IsTransparentSelection() const; + sal_uInt16 GetTransparentSelectionPercent() const; + sal_uInt16 GetSelectionMaximumLuminancePercent() const; + + void SetTransparentSelection( sal_Bool bState ); + void SetTransparentSelectionPercent( sal_uInt16 nPercent ); + void SetSelectionMaximumLuminancePercent( sal_uInt16 nPercent ); + //------------------------------------------------------------------------------------------------------------- // private methods //------------------------------------------------------------------------------------------------------------- @@ -295,6 +319,11 @@ private: sal_uInt32 m_nQuadratic3DRenderLimit; sal_uInt32 m_nQuadraticFormControlRenderLimit; + // #i97672# selection settings + sal_uInt16 m_nTransparentSelectionPercent; + sal_uInt16 m_nSelectionMaximumLuminancePercent; + sal_Bool m_bTransparentSelection; + // local values bool m_bAllowAA : 1; bool m_bAllowAAChecked : 1; @@ -342,6 +371,11 @@ SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl() : m_nQuadratic3DRenderLimit(DEFAULT_QUADRATIC3DRENDERLIMIT), m_nQuadraticFormControlRenderLimit(DEFAULT_QUADRATICFORMCONTROLRENDERLIMIT), + // #i97672# selection settings + m_nTransparentSelectionPercent(DEFAULT_TRANSPARENTSELECTIONPERCENT), + m_nSelectionMaximumLuminancePercent(DEFAULT_SELECTIONMAXIMUMLUMINANCEPERCENT), + m_bTransparentSelection(DEFAULT_TRANSPARENTSELECTION), + // local values m_bAllowAA(true), m_bAllowAAChecked(false) @@ -537,6 +571,27 @@ SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl() : seqValues[nProperty] >>= m_nQuadraticFormControlRenderLimit; } break; + + // #i97672# selection settings + case PROPERTYHANDLE_TRANSPARENTSELECTION: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\TransparentSelection\"?" ); + seqValues[nProperty] >>= m_bTransparentSelection; + } + break; + + case PROPERTYHANDLE_TRANSPARENTSELECTIONPERCENT: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SHORT), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\TransparentSelectionPercent\"?" ); + seqValues[nProperty] >>= m_nTransparentSelectionPercent; + } + + case PROPERTYHANDLE_SELECTIONMAXIMUMLUMINANCEPERCENT: + { + DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SHORT), "SvtOptionsDrawinglayer_Impl::SvtOptionsDrawinglayer_Impl()\nWho has changed the value type of \"Office.Common\\Drawinglayer\\SelectionMaximumLuminancePercent\"?" ); + seqValues[nProperty] >>= m_nSelectionMaximumLuminancePercent; + } + break; } } } @@ -661,6 +716,19 @@ void SvtOptionsDrawinglayer_Impl::Commit() case PROPERTYHANDLE_QUADRATICFORMCONTROLRENDERLIMIT: aSeqValues[nProperty] <<= m_nQuadraticFormControlRenderLimit; break; + + // #i97672# selection settings + case PROPERTYHANDLE_TRANSPARENTSELECTION: + aSeqValues[nProperty] <<= m_bTransparentSelection; + break; + + case PROPERTYHANDLE_TRANSPARENTSELECTIONPERCENT: + aSeqValues[nProperty] <<= m_nTransparentSelectionPercent; + break; + + case PROPERTYHANDLE_SELECTIONMAXIMUMLUMINANCEPERCENT: + aSeqValues[nProperty] <<= m_nSelectionMaximumLuminancePercent; + break; } } @@ -1065,6 +1133,49 @@ void SvtOptionsDrawinglayer_Impl::SetQuadraticFormControlRenderLimit(sal_uInt32 } } +// #i97672# selection settings +sal_Bool SvtOptionsDrawinglayer_Impl::IsTransparentSelection() const +{ + return m_bTransparentSelection; +} + +void SvtOptionsDrawinglayer_Impl::SetTransparentSelection( sal_Bool bState ) +{ + if(m_bTransparentSelection != bState) + { + m_bTransparentSelection = bState; + SetModified(); + } +} + +void SvtOptionsDrawinglayer_Impl::SetTransparentSelectionPercent( sal_uInt16 nPercent ) +{ + if(m_nTransparentSelectionPercent != nPercent) + { + m_nTransparentSelectionPercent = nPercent; + SetModified(); + } +} + +sal_uInt16 SvtOptionsDrawinglayer_Impl::GetTransparentSelectionPercent() const +{ + return m_nTransparentSelectionPercent; +} + +void SvtOptionsDrawinglayer_Impl::SetSelectionMaximumLuminancePercent( sal_uInt16 nPercent ) +{ + if(m_nSelectionMaximumLuminancePercent != nPercent) + { + m_nSelectionMaximumLuminancePercent = nPercent; + SetModified(); + } +} + +sal_uInt16 SvtOptionsDrawinglayer_Impl::GetSelectionMaximumLuminancePercent() const +{ + return m_nSelectionMaximumLuminancePercent; +} + //***************************************************************************************************************** // private method //***************************************************************************************************************** @@ -1104,7 +1215,12 @@ Sequence< OUString > SvtOptionsDrawinglayer_Impl::impl_GetPropertyNames() PROPERTYNAME_RENDERDECORATEDTEXTDIRECT, PROPERTYNAME_RENDERSIMPLETEXTDIRECT, PROPERTYNAME_QUADRATIC3DRENDERLIMIT, - PROPERTYNAME_QUADRATICFORMCONTROLRENDERLIMIT + PROPERTYNAME_QUADRATICFORMCONTROLRENDERLIMIT, + + // #i97672# selection settings + PROPERTYNAME_TRANSPARENTSELECTION, + PROPERTYNAME_TRANSPARENTSELECTIONPERCENT, + PROPERTYNAME_SELECTIONMAXIMUMLUMINANCEPERCENT }; // Initialize return sequence with these list ... @@ -1486,6 +1602,83 @@ void SvtOptionsDrawinglayer::SetQuadraticFormControlRenderLimit(sal_uInt32 nNew) m_pDataContainer->SetQuadraticFormControlRenderLimit( nNew ); } +// #i97672# selection settings +sal_Bool SvtOptionsDrawinglayer::IsTransparentSelection() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + return m_pDataContainer->IsTransparentSelection(); +} + +void SvtOptionsDrawinglayer::SetTransparentSelection( sal_Bool bState ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + m_pDataContainer->SetTransparentSelection( bState ); +} + +sal_uInt16 SvtOptionsDrawinglayer::GetTransparentSelectionPercent() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + sal_uInt16 aRetval(m_pDataContainer->GetTransparentSelectionPercent()); + + // crop to range [10% .. 90%] + if(aRetval < 10) + { + aRetval = 10; + } + + if(aRetval > 90) + { + aRetval = 90; + } + + return aRetval; +} + +void SvtOptionsDrawinglayer::SetTransparentSelectionPercent( sal_uInt16 nPercent ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + + // crop to range [10% .. 90%] + if(nPercent < 10) + { + nPercent = 10; + } + + if(nPercent > 90) + { + nPercent = 90; + } + + m_pDataContainer->SetTransparentSelectionPercent( nPercent ); +} + +sal_uInt16 SvtOptionsDrawinglayer::GetSelectionMaximumLuminancePercent() const +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + sal_uInt16 aRetval(m_pDataContainer->GetSelectionMaximumLuminancePercent()); + + // crop to range [0% .. 100%] + if(aRetval > 90) + { + aRetval = 90; + } + + return aRetval; +} + +void SvtOptionsDrawinglayer::SetSelectionMaximumLuminancePercent( sal_uInt16 nPercent ) +{ + MutexGuard aGuard( GetOwnStaticMutex() ); + + // crop to range [0% .. 100%] + if(nPercent > 90) + { + nPercent = 90; + } + + m_pDataContainer->SetSelectionMaximumLuminancePercent( nPercent ); +} + //***************************************************************************************************************** // private method //***************************************************************************************************************** diff --git a/svtools/source/config/useroptions.cxx b/svtools/source/config/useroptions.cxx index aad000a235f1..4eafbefe54a3 100644 --- a/svtools/source/config/useroptions.cxx +++ b/svtools/source/config/useroptions.cxx @@ -49,51 +49,45 @@ #include <rtl/logfile.hxx> #include "itemholder2.hxx" -#ifndef _COM_SUN_STAR_BEANS_PROPERTY_HPP_ #include <com/sun/star/beans/Property.hpp> -#endif - -#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ #include <com/sun/star/beans/XPropertySet.hpp> -#endif - -#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_ #include <com/sun/star/beans/PropertyAttribute.hpp> -#endif - -#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_ #include <com/sun/star/container/XNameAccess.hpp> -#endif - -#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_ #include <com/sun/star/container/XNameContainer.hpp> -#endif - -#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_ #include <com/sun/star/lang/XSingleServiceFactory.hpp> -#endif - -#ifndef _COMPHELPER_CONFIGURATIONHELPER_HXX_ +#include <com/sun/star/util/XChangesListener.hpp> +#include <com/sun/star/util/XChangesNotifier.hpp> +#include <com/sun/star/util/ChangesEvent.hpp> #include <comphelper/configurationhelper.hxx> -#endif - -#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ #include <unotools/processfactory.hxx> -#endif - -#ifndef _SVT_LOGHELPER_HXX -#include "loghelper.hxx" -#endif +#include <loghelper.hxx> using namespace utl; using namespace rtl; +using namespace com::sun::star; using namespace com::sun::star::uno; namespace css = ::com::sun::star; // class SvtUserOptions_Impl --------------------------------------------- +class SvtUserOptions_Impl; +class SvtUserConfigChangeListener_Impl : public cppu::WeakImplHelper1 +< + com::sun::star::util::XChangesListener +> +{ + SvtUserOptions_Impl& m_rParent; + public: + SvtUserConfigChangeListener_Impl(SvtUserOptions_Impl& rParent); + ~SvtUserConfigChangeListener_Impl(); + + //XChangesListener + virtual void SAL_CALL changesOccurred( const util::ChangesEvent& Event ) throw(RuntimeException); + //XEventListener + virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw(RuntimeException); +}; -class SvtUserOptions_Impl +class SvtUserOptions_Impl : public SfxBroadcaster { public: SvtUserOptions_Impl(); @@ -144,8 +138,10 @@ public: sal_Bool IsTokenReadonly( USHORT nToken ) const; ::rtl::OUString GetToken(USHORT nToken) const; + void Notify(); private: + uno::Reference< util::XChangesListener > m_xChangeListener; css::uno::Reference< css::container::XNameAccess > m_xCfg; css::uno::Reference< css::beans::XPropertySet > m_xData; ::rtl::OUString m_aLocale; @@ -158,18 +154,47 @@ static sal_Int32 nRefCount = 0; #define READONLY_DEFAULT sal_False -// functions ------------------------------------------------------------- +/*-- 16.06.2009 14:22:56--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SvtUserConfigChangeListener_Impl::SvtUserConfigChangeListener_Impl(SvtUserOptions_Impl& rParent) : + m_rParent( rParent ) +{ +} +/*-- 16.06.2009 14:22:56--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SvtUserConfigChangeListener_Impl::~SvtUserConfigChangeListener_Impl() +{ +} +/*-- 16.06.2009 14:22:56--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtUserConfigChangeListener_Impl::changesOccurred( const util::ChangesEvent& rEvent ) throw(RuntimeException) +{ + if(rEvent.Changes.getLength()) + m_rParent.Notify(); +} +/*-- 16.06.2009 14:22:56--------------------------------------------------- -namespace + -----------------------------------------------------------------------*/ +void SvtUserConfigChangeListener_Impl::disposing( const lang::EventObject& rSource ) throw(RuntimeException) { - struct PropertyNames - : public rtl::Static< Sequence< rtl::OUString >, PropertyNames> {}; + try + { + uno::Reference< util::XChangesNotifier > xChgNot( rSource.Source, UNO_QUERY_THROW); + xChgNot->removeChangesListener(this); + } + catch(Exception& ) + { + } } // class SvtUserOptions_Impl --------------------------------------------- // ----------------------------------------------------------------------- -SvtUserOptions_Impl::SvtUserOptions_Impl() +SvtUserOptions_Impl::SvtUserOptions_Impl() : + m_xChangeListener( new SvtUserConfigChangeListener_Impl(*this) ) { try { @@ -181,6 +206,14 @@ SvtUserOptions_Impl::SvtUserOptions_Impl() css::uno::UNO_QUERY ); m_xData = css::uno::Reference< css::beans::XPropertySet >(m_xCfg, css::uno::UNO_QUERY); + uno::Reference< util::XChangesNotifier > xChgNot( m_xCfg, UNO_QUERY); + try + { + xChgNot->addChangesListener( m_xChangeListener ); + } + catch(RuntimeException& ) + { + } } catch(const css::uno::Exception& ex) { @@ -743,6 +776,12 @@ void SvtUserOptions_Impl::SetApartment( const ::rtl::OUString& sApartment ) // ----------------------------------------------------------------------- +void SvtUserOptions_Impl::Notify() +{ + Broadcast( SfxSimpleHint( SFX_HINT_USER_OPTIONS_CHANGED ) ); +} +// ----------------------------------------------------------------------- + sal_Bool SvtUserOptions_Impl::IsTokenReadonly( USHORT nToken ) const { css::uno::Reference< css::beans::XPropertySet > xData(m_xCfg, css::uno::UNO_QUERY); @@ -906,7 +945,7 @@ SvtUserOptions::SvtUserOptions() } ++nRefCount; pImp = pOptions; - //StartListening( *pImp); + StartListening( *pImp); } // ----------------------------------------------------------------------- diff --git a/svtools/source/contnr/fileview.cxx b/svtools/source/contnr/fileview.cxx index d56c270fd5a8..274557051c27 100644 --- a/svtools/source/contnr/fileview.cxx +++ b/svtools/source/contnr/fileview.cxx @@ -1065,7 +1065,10 @@ BOOL ViewTabListBox_Impl::DoubleClickHdl() ::rtl::OUString sRet = SvHeaderTabListBox::GetAccessibleObjectDescription( _eType, _nPos ); if ( ::svt::BBTYPE_TABLECELL == _eType ) { - sal_Int32 nRow = _nPos / GetColumnCount(); + sal_Int32 nRow = -1; + const sal_uInt16 nColumnCount = GetColumnCount(); + if (nColumnCount > 0) + nRow = _nPos / nColumnCount; SvLBoxEntry* pEntry = GetEntry( nRow ); if ( pEntry ) { diff --git a/svtools/source/contnr/imivctl1.cxx b/svtools/source/contnr/imivctl1.cxx index da75608a38b3..954c8a7ca179 100644 --- a/svtools/source/contnr/imivctl1.cxx +++ b/svtools/source/contnr/imivctl1.cxx @@ -540,7 +540,13 @@ void SvxIconChoiceCtrl_Impl::EntrySelected( SvxIconChoiceCtrlEntry* pEntry, BOOL ShowCursor( TRUE ); } // if( bUpdateMode ) - CallEventListeners( VCLEVENT_LISTBOX_SELECT, pEntry ); + // --> OD 2009-05-27 #i101012# + // emit vcl event LISTBOX_SELECT only in case that the given entry is selected. + if ( bSelect ) + { + CallEventListeners( VCLEVENT_LISTBOX_SELECT, pEntry ); + } + // <-- } void SvxIconChoiceCtrl_Impl::ResetVirtSize() diff --git a/svtools/source/contnr/svlbox.cxx b/svtools/source/contnr/svlbox.cxx index 1c81343cd84f..e56db398b8fb 100644 --- a/svtools/source/contnr/svlbox.cxx +++ b/svtools/source/contnr/svlbox.cxx @@ -1203,6 +1203,12 @@ void SvLBox::ViewDataInitialized( SvLBoxEntry* ) DBG_CHKTHIS(SvLBox,0); } +void SvLBox::StateChanged( StateChangedType eType ) +{ + if( eType == STATE_CHANGE_ENABLE ) + Invalidate( INVALIDATE_CHILDREN ); + Control::StateChanged( eType ); +} void SvLBox::ImplShowTargetEmphasis( SvLBoxEntry* pEntry, BOOL bShow) { diff --git a/svtools/source/contnr/svtabbx.cxx b/svtools/source/contnr/svtabbx.cxx index 32e8e68facb1..1770810c7a5d 100644 --- a/svtools/source/contnr/svtabbx.cxx +++ b/svtools/source/contnr/svtabbx.cxx @@ -980,14 +980,16 @@ Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleCell( sal_Int32 _nR if ( !AreChildrenTransient() ) { + const sal_uInt16 nColumnCount = GetColumnCount(); + // first call? -> initial list if ( m_aAccessibleChildren.empty() ) { - sal_Int32 nCount = ( GetRowCount() + 1 ) * GetColumnCount(); + sal_Int32 nCount = ( GetRowCount() + 1 ) * nColumnCount; m_aAccessibleChildren.assign( nCount, Reference< XAccessible >() ); } - nIndex = ( _nRow * GetColumnCount() ) + _nColumnPos + GetColumnCount(); + nIndex = ( _nRow * nColumnCount ) + _nColumnPos + nColumnCount; xChild = m_aAccessibleChildren[ nIndex ]; } @@ -1021,8 +1023,9 @@ Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleColumnHeader( sal_u // first call? -> initial list if ( m_aAccessibleChildren.empty() ) { - sal_Int32 nCount = AreChildrenTransient() ? GetColumnCount() - : ( GetRowCount() + 1 ) * GetColumnCount(); + const sal_uInt16 nColumnCount = GetColumnCount(); + sal_Int32 nCount = AreChildrenTransient() ? + nColumnCount : ( GetRowCount() + 1 ) * nColumnCount; m_aAccessibleChildren.assign( nCount, Reference< XAccessible >() ); } @@ -1081,15 +1084,10 @@ sal_Bool SvHeaderTabListBox::ConvertPointToColumnHeader( sal_uInt16&, const Poin switch( _eType ) { case ::svt::BBTYPE_BROWSEBOX: - aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HeaderTabListBox" ) ); - break; - case ::svt::BBTYPE_TABLE: - aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HeaderTabListBoxTable" ) ); - break; - case ::svt::BBTYPE_COLUMNHEADERBAR: - aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ColumnHeaderBar of HeaderTabListBox" ) ); + // should be empty now (see #i63983) + aRetText = ::rtl::OUString(); break; case ::svt::BBTYPE_TABLECELL: @@ -1098,9 +1096,12 @@ sal_Bool SvHeaderTabListBox::ConvertPointToColumnHeader( sal_uInt16&, const Poin if ( _nPos >= 0 ) { sal_uInt16 nColumnCount = GetColumnCount(); - sal_Int32 nRow = _nPos / nColumnCount; - sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount ); - aRetText = GetCellText( nRow, nColumn ); + if (nColumnCount > 0) + { + sal_Int32 nRow = _nPos / nColumnCount; + sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount ); + aRetText = GetCellText( nRow, nColumn ); + } } break; } @@ -1135,16 +1136,19 @@ sal_Bool SvHeaderTabListBox::ConvertPointToColumnHeader( sal_uInt16&, const Poin static const String sVar2( RTL_CONSTASCII_USTRINGPARAM( "%2" ) ); sal_uInt16 nColumnCount = GetColumnCount(); - sal_Int32 nRow = _nPos / nColumnCount; - sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount ); - - String aText( SvtResId( STR_SVT_ACC_DESC_TABLISTBOX ) ); - aText.SearchAndReplace( sVar1, String::CreateFromInt32( nRow ) ); - String sColHeader = m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( nColumn ) ); - if ( sColHeader.Len() == 0 ) - sColHeader = String::CreateFromInt32( nColumn ); - aText.SearchAndReplace( sVar2, sColHeader ); - aRetText = aText; + if (nColumnCount > 0) + { + sal_Int32 nRow = _nPos / nColumnCount; + sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount ); + + String aText( SvtResId( STR_SVT_ACC_DESC_TABLISTBOX ) ); + aText.SearchAndReplace( sVar1, String::CreateFromInt32( nRow ) ); + String sColHeader = m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( nColumn ) ); + if ( sColHeader.Len() == 0 ) + sColHeader = String::CreateFromInt32( nColumn ); + aText.SearchAndReplace( sVar2, sColHeader ); + aRetText = aText; + } } return aRetText; diff --git a/svtools/source/contnr/svtreebx.cxx b/svtools/source/contnr/svtreebx.cxx index 200dd30eda1a..a697928842af 100644 --- a/svtools/source/contnr/svtreebx.cxx +++ b/svtools/source/contnr/svtreebx.cxx @@ -1040,6 +1040,14 @@ BOOL SvTreeListBox::Expand( SvLBoxEntry* pParent ) pParent->SetFlags( nFlags ); GetModel()->InvalidateEntry( pParent ); // neu zeichnen } + + // --> OD 2009-04-01 #i92103# + if ( bExpanded ) + { + pImp->CallEventListeners( VCLEVENT_LISTBOX_ENTRY_EXPANDED, pParent ); + } + // <-- + return bExpanded; } @@ -1059,6 +1067,14 @@ BOOL SvTreeListBox::Collapse( SvLBoxEntry* pParent ) pHdlEntry = pParent; ExpandedHdl(); } + + // --> OD 2009-04-01 #i92103# + if ( bCollapsed ) + { + pImp->CallEventListeners( VCLEVENT_LISTBOX_ENTRY_COLLAPSED, pParent ); + } + // <-- + return bCollapsed; } diff --git a/svtools/source/control/ctrltool.cxx b/svtools/source/control/ctrltool.cxx index 35e86189c352..77bb996584bd 100644 --- a/svtools/source/control/ctrltool.cxx +++ b/svtools/source/control/ctrltool.cxx @@ -161,7 +161,11 @@ static void ImplMakeSearchString( XubString& rStr ) static void ImplMakeSearchStringFromName( XubString& rStr ) { - rStr = rStr.GetToken( 0, ';' ); + // check for features before alternate font separator + if (rStr.Search(':') < rStr.Search(';')) + rStr = rStr.GetToken( 0, ':' ); + else + rStr = rStr.GetToken( 0, ';' ); ImplMakeSearchString( rStr ); } diff --git a/svtools/source/control/scrwin.cxx b/svtools/source/control/scrwin.cxx index 9805110c9254..162f23948385 100644 --- a/svtools/source/control/scrwin.cxx +++ b/svtools/source/control/scrwin.cxx @@ -273,8 +273,8 @@ void __EXPORT ScrollableWindow::Resize() // disable painting in the corner between the scrollbars if ( bVVisible && bHVisible ) { - aCornerWin.SetPosSizePixel( - *((Point*) &aOutPixSz), Size(nScrSize, nScrSize) ); + aCornerWin.SetPosSizePixel(Point(aOutPixSz.Width(), aOutPixSz.Height()), + Size(nScrSize, nScrSize) ); aCornerWin.Show(); } else diff --git a/svtools/source/filter.vcl/filter/filter.cxx b/svtools/source/filter.vcl/filter/filter.cxx index f87fabc7973d..3586ddd02ddd 100644 --- a/svtools/source/filter.vcl/filter/filter.cxx +++ b/svtools/source/filter.vcl/filter/filter.cxx @@ -74,8 +74,8 @@ #include <com/sun/star/ucb/CommandAbortedException.hpp> #include <unotools/ucbstreamhelper.hxx> #include <unotools/localfilehelper.hxx> -#include <svtools/pathoptions.hxx> #include <comphelper/processfactory.hxx> +#include <rtl/bootstrap.hxx> #include <rtl/instance.hxx> #include "SvFilterOptionsDialog.hxx" @@ -1038,8 +1038,13 @@ void GraphicFilter::ImplInit() if( bUseConfig ) { - SvtPathOptions aPathOpt; - aFilterPath = aPathOpt.GetModulePath(); +#if defined WNT + rtl::OUString url(RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/program")); +#else + rtl::OUString url(RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/program")); +#endif + rtl::Bootstrap::expandMacros(url); //TODO: detect failure + utl::LocalFileHelper::ConvertURLToPhysicalName(url, aFilterPath); } pErrorEx = new FilterErrorEx; diff --git a/svtools/source/items1/itemset.cxx b/svtools/source/items1/itemset.cxx index 48fe2877b892..fee00dca854a 100644 --- a/svtools/source/items1/itemset.cxx +++ b/svtools/source/items1/itemset.cxx @@ -541,7 +541,7 @@ SfxItemState SfxItemSet::GetItemState( USHORT nWhich, // Unterschiedlich vorhanden return SFX_ITEM_DONTCARE; - if ( (*ppFnd)->IsA(TYPE(SfxVoidItem)) ) + if ( (*ppFnd)->Type() == TYPE(SfxVoidItem) ) return SFX_ITEM_DISABLED; if (ppItem) diff --git a/svtools/source/misc1/adrparse.cxx b/svtools/source/misc1/adrparse.cxx index d9b389513f80..37c25d6c669f 100644 --- a/svtools/source/misc1/adrparse.cxx +++ b/svtools/source/misc1/adrparse.cxx @@ -172,8 +172,8 @@ inline void SvAddressParser_Impl::addTokenToRealName() if (!m_pRealNameBegin) m_pRealNameBegin = m_pRealNameContentBegin = m_pCurTokenBegin; else if (m_pRealNameEnd < m_pCurTokenBegin - 1 - || m_pRealNameEnd == m_pCurTokenBegin - 1 - && *m_pRealNameEnd != ' ') + || (m_pRealNameEnd == m_pCurTokenBegin - 1 + && *m_pRealNameEnd != ' ')) m_bRealNameReparse = true; m_pRealNameEnd = m_pRealNameContentEnd = m_pCurTokenEnd; } @@ -634,8 +634,8 @@ SvAddressParser_Impl::SvAddressParser_Impl(SvAddressParser * pParser, else { m_pAddrSpec = m_aInnerAddrSpec.isValid() - || !m_aOuterAddrSpec.isValid() - && m_aInnerAddrSpec.isPoorlyValid() ? + || (!m_aOuterAddrSpec.isValid() + && m_aInnerAddrSpec.isPoorlyValid()) ? &m_aInnerAddrSpec : m_aOuterAddrSpec.isPoorlyValid() ? &m_aOuterAddrSpec : 0; @@ -663,11 +663,11 @@ SvAddressParser_Impl::SvAddressParser_Impl(SvAddressParser * pParser, } UniString aTheRealName; if (!m_pRealNameBegin - || m_pAddrSpec == &m_aOuterAddrSpec + || (m_pAddrSpec == &m_aOuterAddrSpec && m_pRealNameBegin == m_aOuterAddrSpec.m_pBegin && m_pRealNameEnd == m_aOuterAddrSpec.m_pEnd - && m_pFirstCommentBegin) + && m_pFirstCommentBegin)) if (!m_pFirstCommentBegin) aTheRealName = aTheAddrSpec; else if (m_bFirstCommentReparse) @@ -820,7 +820,7 @@ bool SvAddressParser::createRFC822Mailbox(String const & rPhrase, return false; if (*p == '"') break; - if (*p == '\x0D' || *p == '\\' && ++p == pEnd + if (*p == '\x0D' || (*p == '\\' && ++p == pEnd) || !INetMIME::isUSASCII(*p)) return false; if (INetMIME::needsQuotedStringEscape(*p)) @@ -868,7 +868,7 @@ bool SvAddressParser::createRFC822Mailbox(String const & rPhrase, return false; if (*p == ']') break; - if (*p == '\x0D' || *p == '[' || *p == '\\' && ++p == pEnd + if (*p == '\x0D' || *p == '[' || (*p == '\\' && ++p == pEnd) || !INetMIME::isUSASCII(*p)) return false; if (*p >= '[' && *p <= ']') diff --git a/svtools/source/misc1/docmspasswdrequest.cxx b/svtools/source/misc1/docmspasswdrequest.cxx new file mode 100644 index 000000000000..e892d3a57d1a --- /dev/null +++ b/svtools/source/misc1/docmspasswdrequest.cxx @@ -0,0 +1,143 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright IBM Corporation 2009. + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: docmspasswdrequest.cxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +#include "docmspasswdrequest.hxx" +#include <com/sun/star/task/XInteractionAbort.hpp> +#include <com/sun/star/task/XInteractionPassword.hpp> + +//========================================================================== + +class MSAbortContinuation : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionAbort > +{ + sal_Bool mbSelected; + +public: + MSAbortContinuation() : mbSelected( sal_False ) {} + + sal_Bool isSelected() { return mbSelected; } + + void reset() { mbSelected = sal_False; } + + virtual void SAL_CALL select() throw(::com::sun::star::uno::RuntimeException) { mbSelected = sal_True; } +}; + +//========================================================================== + +class MSPasswordContinuation : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionPassword > +{ + sal_Bool mbSelected; + ::rtl::OUString maPassword; + +public: + MSPasswordContinuation() : mbSelected( sal_False ) {} + + sal_Bool isSelected() { return mbSelected; } + + void reset() { mbSelected = sal_False; } + + virtual void SAL_CALL select() throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPassword( const ::rtl::OUString& aPass ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getPassword( ) throw (::com::sun::star::uno::RuntimeException); +}; + +void SAL_CALL MSPasswordContinuation::select() + throw(::com::sun::star::uno::RuntimeException) +{ + mbSelected = sal_True; +} + +void SAL_CALL MSPasswordContinuation::setPassword( const ::rtl::OUString& aPass ) + throw (::com::sun::star::uno::RuntimeException) +{ + maPassword = aPass; +} + +::rtl::OUString SAL_CALL MSPasswordContinuation::getPassword() + throw (::com::sun::star::uno::RuntimeException) +{ + return maPassword; +} + +//========================================================================== + +RequestMSDocumentPassword::RequestMSDocumentPassword( ::com::sun::star::task::PasswordRequestMode nMode, ::rtl::OUString aName ) +{ + ::rtl::OUString temp; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > temp2; + ::com::sun::star::task::DocumentMSPasswordRequest + aDocumentMSPasswordRequest( temp, + temp2, + ::com::sun::star::task::InteractionClassification_QUERY, + nMode, + aName ); + + m_aRequest <<= aDocumentMSPasswordRequest; + + m_pAbort = new MSAbortContinuation; + m_pPassword = new MSPasswordContinuation; + + m_lContinuations.realloc( 2 ); + m_lContinuations[0] = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >( m_pAbort ); + m_lContinuations[1] = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >( m_pPassword ); +} + +sal_Bool RequestMSDocumentPassword::isAbort() +{ + return m_pAbort->isSelected(); +} + +sal_Bool RequestMSDocumentPassword::isPassword() +{ + return m_pPassword->isSelected(); +} + +::rtl::OUString RequestMSDocumentPassword::getPassword() +{ + return m_pPassword->getPassword(); +} + +::com::sun::star::uno::Any SAL_CALL RequestMSDocumentPassword::getRequest() + throw( ::com::sun::star::uno::RuntimeException ) +{ + return m_aRequest; +} + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > + SAL_CALL RequestMSDocumentPassword::getContinuations() + throw( ::com::sun::star::uno::RuntimeException ) +{ + return m_lContinuations; +} + + diff --git a/svtools/source/misc1/makefile.mk b/svtools/source/misc1/makefile.mk index 0d1e67fd9021..3ca57ff36f92 100644 --- a/svtools/source/misc1/makefile.mk +++ b/svtools/source/misc1/makefile.mk @@ -50,6 +50,7 @@ SLOFILES=\ $(EXCEPTIONSFILES) \ $(SLO)$/adrparse.obj \ $(SLO)$/docpasswdrequest.obj \ + $(SLO)$/docmspasswdrequest.obj \ $(SLO)$/filenotation.obj \ $(SLO)$/inethist.obj \ $(SLO)$/inettype.obj \ diff --git a/svtools/source/table/defaultinputhandler.cxx b/svtools/source/table/defaultinputhandler.cxx new file mode 100644 index 000000000000..17ee0222857f --- /dev/null +++ b/svtools/source/table/defaultinputhandler.cxx @@ -0,0 +1,210 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +#include "svtools/table/defaultinputhandler.hxx" +#include "svtools/table/abstracttablecontrol.hxx" + +#include <tools/debug.hxx> +#include <vcl/event.hxx> +#include <vcl/cursor.hxx> +#include "svtools/table/tabledatawindow.hxx" + +//........................................................................ +namespace svt { namespace table +{ +//....................................................................... + + struct DefaultInputHandler_Impl + { + }; + + //==================================================================== + //= DefaultInputHandler + //==================================================================== + //-------------------------------------------------------------------- + DefaultInputHandler::DefaultInputHandler() + :m_pImpl( new DefaultInputHandler_Impl ) + { + } + + //-------------------------------------------------------------------- + DefaultInputHandler::~DefaultInputHandler() + { + DELETEZ( m_pImpl ); + } + + //-------------------------------------------------------------------- + bool DefaultInputHandler::MouseMove( IAbstractTableControl& _rControl, const MouseEvent& _rMEvt ) + { + (void)_rControl; + (void)_rMEvt; + return false; + } + + //-------------------------------------------------------------------- + bool DefaultInputHandler::MouseButtonDown( IAbstractTableControl& _rControl, const MouseEvent& _rMEvt ) + { + bool bHandled = false; + Point aPoint = _rMEvt.GetPosPixel(); + if(_rControl.isClickInVisibleArea(aPoint)) + { + if(_rControl.getSelEngine()->GetSelectionMode() == NO_SELECTION) + { + LoseFocus(_rControl); + _rControl.setCursorAtCurrentCell(aPoint); + bHandled = true; + } + else + { + bHandled = _rControl.getSelEngine()->SelMouseButtonDown(_rMEvt); + } + } + return bHandled; + } + + //-------------------------------------------------------------------- + bool DefaultInputHandler::MouseButtonUp( IAbstractTableControl& _rControl, const MouseEvent& _rMEvt ) + { + bool bHandled = false; + Point aPoint = _rMEvt.GetPosPixel(); + if(_rControl.isClickInVisibleArea(aPoint)) + { + if(_rControl.getSelEngine()->GetSelectionMode() == NO_SELECTION) + { + GetFocus(_rControl); + _rControl.setCursorAtCurrentCell(aPoint); + bHandled = true; + } + else + bHandled = _rControl.getSelEngine()->SelMouseButtonUp(_rMEvt); + } + return bHandled; + } + + //-------------------------------------------------------------------- + bool DefaultInputHandler::KeyInput( IAbstractTableControl& _rControl, const KeyEvent& rKEvt ) + { + bool bHandled = false; + + const KeyCode& rKeyCode = rKEvt.GetKeyCode(); + USHORT nKeyCode = rKeyCode.GetCode(); + + struct _ActionMapEntry + { + USHORT nKeyCode; + USHORT nKeyModifier; + TableControlAction eAction; + } + static aKnownActions[] = { + { KEY_DOWN, 0, cursorDown }, + { KEY_UP, 0, cursorUp }, + { KEY_LEFT, 0, cursorLeft }, + { KEY_RIGHT, 0, cursorRight }, + { KEY_HOME, 0, cursorToLineStart }, + { KEY_END, 0, cursorToLineEnd }, + { KEY_PAGEUP, 0, cursorPageUp }, + { KEY_PAGEDOWN, 0, cursorPageDown }, + { KEY_PAGEUP, KEY_MOD1, cursorToFirstLine }, + { KEY_PAGEDOWN, KEY_MOD1, cursorToLastLine }, + { KEY_HOME, KEY_MOD1, cursorTopLeft }, + { KEY_END, KEY_MOD1, cursorBottomRight }, + { KEY_SPACE, KEY_MOD1, cursorSelectRow }, + { KEY_UP, KEY_SHIFT, cursorSelectRowUp }, + { KEY_DOWN, KEY_SHIFT, cursorSelectRowDown }, + { KEY_END, KEY_SHIFT, cursorSelectRowAreaBottom }, + { KEY_HOME, KEY_SHIFT, cursorSelectRowAreaTop }, + + { 0, 0, invalidTableControlAction } + }; + + const _ActionMapEntry* pActions = aKnownActions; + for ( ; pActions->eAction != invalidTableControlAction; ++pActions ) + { + if ( ( pActions->nKeyCode == nKeyCode ) && ( pActions->nKeyModifier == rKeyCode.GetAllModifier() ) ) + { + bHandled = _rControl.dispatchAction( pActions->eAction ); + break; + } + } + + return bHandled; + } + + //-------------------------------------------------------------------- + bool DefaultInputHandler::GetFocus( IAbstractTableControl& _rControl ) + { + _rControl.showCursor(); + return false; // continue processing + } + + //-------------------------------------------------------------------- + bool DefaultInputHandler::LoseFocus( IAbstractTableControl& _rControl ) + { + _rControl.hideCursor(); + return false; // continue processing + } + + //-------------------------------------------------------------------- + bool DefaultInputHandler::RequestHelp( IAbstractTableControl& _rControl, const HelpEvent& _rHEvt ) + { + (void)_rControl; + (void)_rHEvt; + // TODO + return false; + } + + //-------------------------------------------------------------------- + bool DefaultInputHandler::Command( IAbstractTableControl& _rControl, const CommandEvent& _rCEvt ) + { + (void)_rControl; + (void)_rCEvt; + // TODO + return false; + } + + //-------------------------------------------------------------------- + bool DefaultInputHandler::PreNotify( IAbstractTableControl& _rControl, NotifyEvent& _rNEvt ) + { + (void)_rControl; + (void)_rNEvt; + // TODO + return false; + } + + //-------------------------------------------------------------------- + bool DefaultInputHandler::Notify( IAbstractTableControl& _rControl, NotifyEvent& _rNEvt ) + { + (void)_rControl; + (void)_rNEvt; + // TODO + return false; + } + +//........................................................................ +} } // namespace svt::table +//........................................................................ diff --git a/svtools/source/table/gridtablerenderer.cxx b/svtools/source/table/gridtablerenderer.cxx new file mode 100644 index 000000000000..2c4fda711009 --- /dev/null +++ b/svtools/source/table/gridtablerenderer.cxx @@ -0,0 +1,234 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +#include "svtools/table/gridtablerenderer.hxx" + +#include <tools/debug.hxx> +#include <vcl/window.hxx> + +//........................................................................ +namespace svt { namespace table +{ +//........................................................................ + + struct GridTableRenderer_Impl + { + ITableModel& rModel; + RowPos nCurrentRow; + + GridTableRenderer_Impl( ITableModel& _rModel ) + :rModel( _rModel ) + ,nCurrentRow( ROW_INVALID ) + { + } + }; + + //==================================================================== + //= GridTableRenderer + //==================================================================== + //-------------------------------------------------------------------- + GridTableRenderer::GridTableRenderer( ITableModel& _rModel ) + :m_pImpl( new GridTableRenderer_Impl( _rModel ) ) + { + } + + //-------------------------------------------------------------------- + GridTableRenderer::~GridTableRenderer() + { + DELETEZ( m_pImpl ); + } + + //-------------------------------------------------------------------- + RowPos GridTableRenderer::getCurrentRow() + { + return m_pImpl->nCurrentRow; + } + + //-------------------------------------------------------------------- + void GridTableRenderer::PaintHeaderArea( + OutputDevice& _rDevice, const Rectangle& _rArea, bool _bIsColHeaderArea, bool _bIsRowHeaderArea, + const StyleSettings& _rStyle ) + { + OSL_PRECOND( _bIsColHeaderArea || _bIsRowHeaderArea, + "GridTableRenderer::PaintHeaderArea: invalid area flags!" ); + + // fill the rows with alternating background colors + _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR ); + + _rDevice.SetLineColor(); + _rDevice.SetFillColor( _rStyle.GetDialogColor() ); + _rDevice.DrawRect( _rArea ); + + // delimiter lines at bottom/right + _rDevice.SetLineColor( _rStyle.GetDialogTextColor() ); + _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); + _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() ); + + _rDevice.Pop(); + (void)_bIsColHeaderArea; + (void)_bIsRowHeaderArea; + } + + //-------------------------------------------------------------------- + void GridTableRenderer::PaintColumnHeader( ColPos _nCol, bool _bActive, bool _bSelected, + OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle ) + { + _rDevice.Push( PUSH_LINECOLOR ); + + _rDevice.SetLineColor( _rStyle.GetDialogTextColor() ); + _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() ); + + String sHeaderText; + + PColumnModel pColumn = m_pImpl->rModel.getColumnModel( _nCol ); + DBG_ASSERT( !!pColumn, "GridTableRenderer::PaintColumnHeader: invalid column model object!" ); + if ( !!pColumn ) + sHeaderText = pColumn->getName(); + Color aRowBackground = _rStyle.GetFieldColor(); + if ( _bSelected ) + { + aRowBackground = COL_BLUE; + } + _rDevice.DrawText( _rArea, sHeaderText, TEXT_DRAW_LEFT | TEXT_DRAW_TOP ); + _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); + _rDevice.Pop(); + + (void)_bActive; + // no special painting for the active column at the moment + + //(void)_bSelected; + // TODO: selection not yet implemented + } + + //-------------------------------------------------------------------- + void GridTableRenderer::PrepareRow( RowPos _nRow, bool _bActive, bool _bSelected, + OutputDevice& _rDevice, const Rectangle& _rRowArea, const StyleSettings& _rStyle ) + { + // remember the row for subsequent calls to the other ->ITableRenderer methods + m_pImpl->nCurrentRow = _nRow; + + // fill the rows with alternating background colors + _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR ); + + _rDevice.SetLineColor(); + + Color aRowBackground = _rStyle.GetFieldColor(); + + _rDevice.SetFillColor( aRowBackground ); + + _rDevice.DrawRect( _rRowArea ); + + // TODO: active? selected? + + _rDevice.Pop(); + (void) _bSelected; + (void)_bActive; + + // no special painting for the active row at the moment + + //(void)_bSelected; + // TODO: selection not yet implemented + } + + //-------------------------------------------------------------------- + void GridTableRenderer::PaintRowHeader( bool _bActive, bool _bSelected, OutputDevice& _rDevice, const Rectangle& _rArea, + const StyleSettings& _rStyle, rtl::OUString& _rText ) + { + _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR ); + + _rDevice.SetLineColor( _rStyle.GetDialogTextColor() ); + _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); + _rDevice.DrawText( _rArea, _rText, TEXT_DRAW_LEFT); + // TODO: active? selected? + (void)_bActive; + (void)_bSelected; + + _rDevice.Pop(); + } + + //-------------------------------------------------------------------- + void GridTableRenderer::PaintCell( ColPos _nColumn, bool _bSelected, bool _bActive, + OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle, rtl::OUString& _rText ) + { + _rDevice.Push( PUSH_LINECOLOR ); + + // draw the grid + _rDevice.SetLineColor( COL_LIGHTGRAY ); + // TODO: the LIGHTGRAY should probably be a property/setting + _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() ); + _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); + + { + // TODO: remove those temporary place holders + Rectangle aRect( _rArea ); + ++aRect.Left(); --aRect.Right(); + ++aRect.Top(); --aRect.Bottom(); + + String sText; + if(_bSelected) + { + Color aRed(COL_BLUE); + _rDevice.SetFillColor( aRed ); + _rDevice.SetTextColor(COL_WHITE); + } + _rDevice.DrawRect( _rArea ); + (void)_nColumn; + _rDevice.DrawText( aRect, _rText, TEXT_DRAW_LEFT | TEXT_DRAW_TOP); + } + if(_bSelected) + { + _rDevice.SetFillColor( _rStyle.GetFieldColor() ); + _rDevice.SetTextColor(COL_BLACK); + } + + _rDevice.Pop(); + + (void)_bActive; +// // no special painting for the active cell at the moment + (void)_rStyle; +// // TODO: do we need this? + } + + //-------------------------------------------------------------------- + void GridTableRenderer::ShowCellCursor( Window& _rView, const Rectangle& _rCursorRect) + { + _rView.ShowFocus( _rCursorRect ); + } + + //-------------------------------------------------------------------- + void GridTableRenderer::HideCellCursor( Window& _rView, const Rectangle& _rCursorRect) + { + (void)_rCursorRect; + _rView.HideFocus(); + + } + +//........................................................................ +} } // namespace svt::table +//........................................................................ + diff --git a/svtools/source/table/makefile.mk b/svtools/source/table/makefile.mk new file mode 100644 index 000000000000..8feb7fee10d8 --- /dev/null +++ b/svtools/source/table/makefile.mk @@ -0,0 +1,59 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.16 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +ENABLE_EXCEPTIONS=TRUE +PRJNAME=svtools +TARGET=table +#LIBTARGET=NO + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svt.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES=\ + $(SLO)$/tablecontrol.obj \ + $(SLO)$/tablecontrol_impl.obj \ + $(SLO)$/gridtablerenderer.obj \ + $(SLO)$/tablegeometry.obj \ + $(SLO)$/defaultinputhandler.obj \ + $(SLO)$/tabledatawindow.obj + +#LIB1TARGET= $(SLB)$/$(TARGET).lib +#LIB1OBJFILES= $(SLOFILES) + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/svtools/source/table/tablecontrol.cxx b/svtools/source/table/tablecontrol.cxx new file mode 100644 index 000000000000..c8895a19408d --- /dev/null +++ b/svtools/source/table/tablecontrol.cxx @@ -0,0 +1,179 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +#include "svtools/table/tablecontrol.hxx" +#include "tablegeometry.hxx" +#include "tablecontrol_impl.hxx" +#include "svtools/table/tabledatawindow.hxx" +//........................................................................ +namespace svt { namespace table +{ +//........................................................................ + + //==================================================================== + //= TableControl + //==================================================================== + //-------------------------------------------------------------------- + TableControl::TableControl( Window* _pParent, WinBits _nStyle ) + :Control( _pParent, _nStyle ) + ,m_pImpl( new TableControl_Impl( *this ) ) + { + m_pImpl->getDataWindow()->SetMouseButtonDownHdl( LINK( this, TableControl, ImplMouseButtonDownHdl ) ); + m_pImpl->getDataWindow()->SetMouseButtonUpHdl( LINK( this, TableControl, ImplMouseButtonUpHdl ) ); + } + + //-------------------------------------------------------------------- + TableControl::~TableControl() + { + DELETEZ( m_pImpl ); + } + + //-------------------------------------------------------------------- + void TableControl::GetFocus() + { + if ( !m_pImpl->getInputHandler()->GetFocus( *m_pImpl ) ) + { + Control::GetFocus(); + GrabFocus(); + } + } + + //-------------------------------------------------------------------- + void TableControl::LoseFocus() + { + if ( !m_pImpl->getInputHandler()->LoseFocus( *m_pImpl ) ) + Control::LoseFocus(); + } + + //-------------------------------------------------------------------- + void TableControl::KeyInput( const KeyEvent& rKEvt ) + { + if ( !m_pImpl->getInputHandler()->KeyInput( *m_pImpl, rKEvt ) ) + Control::KeyInput( rKEvt ); + } + //-------------------------------------------------------------------- + void TableControl::Resize() + { + Control::Resize(); + m_pImpl->onResize(); + } + + //-------------------------------------------------------------------- + void TableControl::SetModel( PTableModel _pModel ) + { + m_pImpl->setModel( _pModel ); + } + + //-------------------------------------------------------------------- + PTableModel TableControl::GetModel() const + { + return m_pImpl->getModel(); + } + + //-------------------------------------------------------------------- + RowPos TableControl::GetTopRow() const + { + return m_pImpl->getTopRow(); + } + + //-------------------------------------------------------------------- + void TableControl::SetTopRow( RowPos _nRow ) + { + // TODO + (void)_nRow; + } + + //-------------------------------------------------------------------- + RowPos TableControl::GetCurrentRow() const + { + return m_pImpl->getCurRow(); + } + + //-------------------------------------------------------------------- + ColPos TableControl::GetCurrentColumn() const + { + return m_pImpl->getCurColumn(); + } + + //-------------------------------------------------------------------- + bool TableControl::GoTo( ColPos _nColumn, RowPos _nRow ) + { + return m_pImpl->goTo( _nColumn, _nRow ); + } + //-------------------------------------------------------------------- + void TableControl::InvalidateDataWindow(RowPos _nRowStart, bool _bRemoved) + { + Rectangle _rRect; + if(_bRemoved) + return m_pImpl->invalidateRows(_nRowStart, _rRect); + else + return m_pImpl->invalidateRow(_nRowStart, _rRect); + } + //-------------------------------------------------------------------- + std::vector<RowPos> TableControl::getSelectedRows() + { + return m_pImpl->getSelectedRows(); + } + //-------------------------------------------------------------------- + void TableControl::removeSelectedRow(RowPos _nRowPos) + { + m_pImpl->removeSelectedRow(_nRowPos); + } + //-------------------------------------------------------------------- + + RowPos TableControl::GetCurrentRow(const Point& rPoint) + { + return m_pImpl->getCurrentRow( rPoint ); + } + + //-------------------------------------------------------------------- + + IMPL_LINK( TableControl, ImplMouseButtonDownHdl, MouseEvent*, pData ) + { + CallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, pData ); + return 1; + } + + IMPL_LINK( TableControl, ImplMouseButtonUpHdl, MouseEvent*, pData ) + { + CallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, pData ); + return 1; + } + + SelectionEngine* TableControl::getSelEngine() + { + return m_pImpl->getSelEngine(); + } + + TableDataWindow* TableControl::getDataWindow() + { + return m_pImpl->getDataWindow(); + } +//........................................................................ +} } // namespace svt::table +//........................................................................ diff --git a/svtools/source/table/tablecontrol_impl.cxx b/svtools/source/table/tablecontrol_impl.cxx new file mode 100644 index 000000000000..e1ff3aeb7f2a --- /dev/null +++ b/svtools/source/table/tablecontrol_impl.cxx @@ -0,0 +1,2003 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +#include "svtools/table/tablecontrol.hxx" +#include "svtools/table/defaultinputhandler.hxx" +#include "svtools/table/tablemodel.hxx" +#include "tablecontrol_impl.hxx" +#include "tablegeometry.hxx" +#include "svtools/table/tabledatawindow.hxx" + +#include <vcl/scrbar.hxx> +#include <vcl/seleng.hxx> + +#include <functional> +#include <stdlib.h> + +//........................................................................ +namespace svt { namespace table +{ +//........................................................................ + + //==================================================================== + //= TempHideCursor + //==================================================================== + class TempHideCursor + { + private: + IAbstractTableControl& m_rTable; + + public: + TempHideCursor( IAbstractTableControl& _rTable ) + :m_rTable( _rTable ) + { + m_rTable.hideCursor(); + } + ~TempHideCursor() + { + m_rTable.showCursor(); + } + }; + + //==================================================================== + //= EmptyTableModel + //==================================================================== + /** default implementation of an ->ITableModel, used as fallback when no + real model is present + + Instances of this class are static in any way, and provide the least + necessary default functionality for a table model. + */ + class EmptyTableModel : public ITableModel + { + public: + EmptyTableModel() + { + } + + // ITableModel overridables + virtual TableSize getColumnCount() const + { + return 0; + } + virtual TableSize getRowCount() const + { + return 0; + } + virtual bool hasColumnHeaders() const + { + return false; + } + virtual bool hasRowHeaders() const + { + return false; + } + virtual void setRowHeaders(bool _bRowHeaders) + { + (void)_bRowHeaders; + } + virtual void setColumnHeaders(bool _bColumnHeaders) + { + (void)_bColumnHeaders; + } + void setColumnCount(TableSize _nColCount) + { + (void) _nColCount; + } + void setRowCount(TableSize _nRowCount) + { + (void)_nRowCount; + } + virtual bool isCellEditable( ColPos col, RowPos row ) const + { + (void)col; + (void)row; + return false; + } + virtual void addTableModelListener( const PTableModelListener& listener ) + { + (void)listener; + // ignore + } + virtual void removeTableModelListener( const PTableModelListener& listener ) + { + (void)listener; + // ignore + } + virtual PColumnModel getColumnModel( ColPos column ) + { + DBG_ERROR( "EmptyTableModel::getColumnModel: invalid call!" ); + (void)column; + return PColumnModel(); + } + virtual PColumnModel getColumnModelByID( ColumnID id ) + { + DBG_ERROR( "EmptyTableModel::getColumnModel: invalid call!" ); + (void)id; + return PColumnModel(); + } + virtual PTableRenderer getRenderer() const + { + return PTableRenderer(); + } + virtual PTableInputHandler getInputHandler() const + { + return PTableInputHandler(); + } + virtual TableMetrics getRowHeight() const + { + return 5 * 100; + } + virtual void setRowHeight(TableMetrics _nRowHeight) + { + (void)_nRowHeight; + } + virtual TableMetrics getColumnHeaderHeight() const + { + return 0; + } + virtual TableMetrics getRowHeaderWidth() const + { + return 0; + } + virtual ScrollbarVisibility getVerticalScrollbarVisibility(int overAllHeight, int actHeight) const + { + (void)overAllHeight; + (void)actHeight; + return ScrollbarShowNever; + } + virtual ScrollbarVisibility getHorizontalScrollbarVisibility(int overAllWidth, int actWidth) const + { + (void)overAllWidth; + (void)actWidth; + return ScrollbarShowNever; + } + virtual void setCellContent(std::vector<std::vector<rtl::OUString> > pCellEntryType) + { + (void)pCellEntryType; + } + virtual std::vector<std::vector<rtl::OUString> > getCellContent() + { + std::vector<rtl::OUString> cCC; + cCC.push_back(rtl::OUString::createFromAscii("")); + std::vector<std::vector<rtl::OUString> > cC; + cC.push_back(cCC); + return cC; + } + virtual void setRowHeaderName(std::vector<rtl::OUString> pCellEntryType) + { + (void)pCellEntryType; + } + virtual std::vector<rtl::OUString> getRowHeaderName() + { + std::vector<rtl::OUString> cCC; + cCC.push_back(rtl::OUString::createFromAscii("")); + return cCC; + } + }; + + + //==================================================================== + //= TableControl_Impl + //==================================================================== + DBG_NAME( TableControl_Impl ) + +#if DBG_UTIL + //==================================================================== + //= SuspendInvariants + //==================================================================== + class SuspendInvariants + { + private: + const TableControl_Impl& m_rTable; + sal_Int32 m_nSuspendFlags; + + public: + SuspendInvariants( const TableControl_Impl& _rTable, sal_Int32 _nSuspendFlags ) + :m_rTable( _rTable ) + ,m_nSuspendFlags( _nSuspendFlags ) + { + DBG_ASSERT( ( m_rTable.m_nRequiredInvariants & m_nSuspendFlags ) == m_nSuspendFlags, + "SuspendInvariants: cannot suspend what is already suspended!" ); + const_cast< TableControl_Impl& >( m_rTable ).m_nRequiredInvariants &= ~m_nSuspendFlags; + } + ~SuspendInvariants() + { + const_cast< TableControl_Impl& >( m_rTable ).m_nRequiredInvariants |= m_nSuspendFlags; + } + }; + #define DBG_SUSPEND_INV( flags ) \ + SuspendInvariants aSuspendInv( *this, flags ); +#else + #define DBG_SUSPEND_INV( flags ) +#endif + +#if DBG_UTIL + //==================================================================== + const char* TableControl_Impl_checkInvariants( const void* _pInstance ) + { + return static_cast< const TableControl_Impl* >( _pInstance )->impl_checkInvariants(); + } + + namespace + { + template< typename SCALAR_TYPE > + bool lcl_checkLimitsExclusive( SCALAR_TYPE _nValue, SCALAR_TYPE _nMin, SCALAR_TYPE _nMax ) + { + return ( _nValue > _nMin ) && ( _nValue < _nMax ); + } + + template< typename SCALAR_TYPE > + bool lcl_checkLimitsExclusive_OrDefault_OrFallback( SCALAR_TYPE _nValue, SCALAR_TYPE _nMin, SCALAR_TYPE _nMax, + PTableModel _pModel, SCALAR_TYPE _nDefaultOrFallback ) + { + if ( !_pModel ) + return _nValue == _nDefaultOrFallback; + if ( _nMax <= _nMin ) + return _nDefaultOrFallback == _nValue; + return lcl_checkLimitsExclusive( _nValue, _nMin, _nMax ); + } + } + + //-------------------------------------------------------------------- + const sal_Char* TableControl_Impl::impl_checkInvariants() const + { + if ( !m_pModel ) + return "no model, not even an EmptyTableModel"; + + if ( !m_pDataWindow ) + return "invalid data window!"; + + if ( m_pModel->getColumnCount() != m_nColumnCount ) + return "column counts are inconsistent!"; + + if ( m_pModel->getRowCount() != m_nRowCount ) + return "row counts are inconsistent!"; + + if ( ( m_nCurColumn != COL_INVALID ) && !m_aColumnWidthsPixel.empty() && ( m_nCurColumn < 0 ) || ( m_nCurColumn >= (ColPos)m_aColumnWidthsPixel.size() ) ) + return "current column is invalid!"; + + if ( m_aColumnWidthsPixel.size() != m_aAccColumnWidthsPixel.size() ) + return "columnd width caches are inconsistent!"; + + if ( !lcl_checkLimitsExclusive_OrDefault_OrFallback( m_nTopRow, (RowPos)-1, m_nRowCount, getModel(), (RowPos)0 ) ) + return "invalid top row value!"; + + if ( !lcl_checkLimitsExclusive_OrDefault_OrFallback( m_nCurRow, (RowPos)-1, m_nRowCount, getModel(), ROW_INVALID ) ) + return "invalid current row value!"; + + if ( !lcl_checkLimitsExclusive_OrDefault_OrFallback( m_nLeftColumn, (ColPos)-1, m_nColumnCount, getModel(), (ColPos)0 ) ) + return "invalid current column value!"; + + if ( !lcl_checkLimitsExclusive_OrDefault_OrFallback( m_nCurColumn, (ColPos)-1, m_nColumnCount, getModel(), COL_INVALID ) ) + return "invalid current column value!"; + + if ( m_pInputHandler != m_pModel->getInputHandler() ) + return "input handler is not the model-provided one!"; + + // m_nColHeaderHeightPixel consistent with the model's value? + { + TableMetrics nHeaderHeight = m_pModel->hasColumnHeaders() ? m_pModel->getColumnHeaderHeight() : 0; + nHeaderHeight = m_rAntiImpl.LogicToPixel( Size( 0, nHeaderHeight ), MAP_100TH_MM ).Height(); + if ( nHeaderHeight != m_nColHeaderHeightPixel ) + return "column header heights are inconsistent!"; + } + + bool isDummyModel = dynamic_cast< const EmptyTableModel* >( m_pModel.get() ) != NULL; + if ( !isDummyModel ) + { + TableMetrics nRowHeight = m_pModel->getRowHeight(); + nRowHeight = m_rAntiImpl.LogicToPixel( Size( 0, nRowHeight ), MAP_100TH_MM ).Height(); + if ( nRowHeight != m_nRowHeightPixel ) + return "row heights are inconsistent!"; + } + + // m_nRowHeaderWidthPixel consistent with the model's value? + { + TableMetrics nHeaderWidth = m_pModel->hasRowHeaders() ? m_pModel->getRowHeaderWidth() : 0; + nHeaderWidth = m_rAntiImpl.LogicToPixel( Size( nHeaderWidth, 0 ), MAP_100TH_MM ).Width(); + if ( nHeaderWidth != m_nRowHeaderWidthPixel ) + return "row header widths are inconsistent!"; + } + + // TODO: check m_aColumnWidthsPixel and m_aAccColumnWidthsPixel + + if ( m_nCursorHidden < 0 ) + return "invalid hidden count for the cursor!"; + + if ( ( m_nRequiredInvariants & INV_SCROLL_POSITION ) && m_pVScroll ) + { + DBG_SUSPEND_INV( INV_SCROLL_POSITION ); + // prevent infinite recursion + + if ( m_pVScroll->GetThumbPos() != m_nTopRow ) + return "vertical scroll bar |position| is incorrect!"; + if ( m_pVScroll->GetRange().Max() != m_nRowCount ) + return "vertical scroll bar |range| is incorrect!"; + if ( m_pVScroll->GetVisibleSize() != impl_getVisibleRows( false ) ) + return "vertical scroll bar |visible size| is incorrect!"; + } + + if ( ( m_nRequiredInvariants & INV_SCROLL_POSITION ) && m_pHScroll ) + { + DBG_SUSPEND_INV( INV_SCROLL_POSITION ); + // prevent infinite recursion + + if ( m_pHScroll->GetThumbPos() != m_nLeftColumn ) + return "horizontal scroll bar |position| is incorrect!"; + if ( m_pHScroll->GetRange().Max() != m_nColumnCount ) + return "horizontal scroll bar |range| is incorrect!"; + if ( m_pHScroll->GetVisibleSize() != impl_getVisibleColumns( false ) ) + return "horizontal scroll bar |visible size| is incorrect!"; + } + + return NULL; + } +#endif + +#define DBG_CHECK_ME() \ + DBG_CHKTHIS( TableControl_Impl, TableControl_Impl_checkInvariants ) + + //-------------------------------------------------------------------- + TableControl_Impl::TableControl_Impl( TableControl& _rAntiImpl ) + :m_rAntiImpl ( _rAntiImpl ) + ,m_pModel ( new EmptyTableModel ) + ,m_pInputHandler ( ) + ,m_nRowHeightPixel ( 15 ) + ,m_nColHeaderHeightPixel( 0 ) + ,m_nRowHeaderWidthPixel ( 0 ) + ,m_nColumnCount ( 0 ) + ,m_nRowCount ( 0 ) + ,m_nCurColumn ( COL_INVALID ) + ,m_nCurRow ( ROW_INVALID ) + ,m_nLeftColumn ( 0 ) + ,m_nTopRow ( 0 ) + ,m_nCursorHidden ( 1 ) + ,m_pDataWindow ( new TableDataWindow( *this ) ) + ,m_pVScroll ( NULL ) + ,m_pHScroll ( NULL ) + ,m_pScrollCorner ( NULL ) + ,m_pSelEngine ( ) + ,m_nRowSelected ( ) + ,m_pTableFunctionSet ( new TableFunctionSet(this ) ) + ,m_nAnchor (-1 ) +#if DBG_UTIL + ,m_nRequiredInvariants ( INV_SCROLL_POSITION ) +#endif + { + DBG_CTOR( TableControl_Impl, TableControl_Impl_checkInvariants ); + m_pSelEngine = new SelectionEngine(m_pDataWindow, m_pTableFunctionSet); + m_pSelEngine->SetSelectionMode(SINGLE_SELECTION); + m_pDataWindow->SetPosPixel( Point( 0, 0 ) ); + m_pDataWindow->Show(); + } + + //-------------------------------------------------------------------- + TableControl_Impl::~TableControl_Impl() + { + DBG_DTOR( TableControl_Impl, TableControl_Impl_checkInvariants ); + + DELETEZ( m_pVScroll ); + DELETEZ( m_pHScroll ); + DELETEZ( m_pScrollCorner ); + DELETEZ( m_pTableFunctionSet ); + DELETEZ( m_pSelEngine ); + DELETEZ( m_pDataWindow ); + } + + //-------------------------------------------------------------------- + PTableModel TableControl_Impl::getModel() const + { + if ( dynamic_cast< const EmptyTableModel* >( m_pModel.get() ) != NULL ) + // if it's an EmptyTableModel, pretend that there is no model + return PTableModel(); + + return m_pModel; + } + + //-------------------------------------------------------------------- + void TableControl_Impl::setModel( PTableModel _pModel ) + { + DBG_CHECK_ME(); + + TempHideCursor aHideCursor( *this ); + + // TODO: revoke as table listener from the model + + m_pModel = _pModel; + if ( !m_pModel ) + m_pModel.reset( new EmptyTableModel ); + + // TODO: register as table listener + //m_pModel->addTableModelListener(PTableModelListener(m_pTableModelListener)); + m_nCurRow = ROW_INVALID; + m_nCurColumn = COL_INVALID; + + // recalc some model-dependent cached info + impl_ni_updateCachedModelValues(); + + // completely invalidate + m_rAntiImpl.Invalidate(); + + // reset cursor to (0,0) + if ( m_nRowCount ) m_nCurRow = 0; + if ( m_nColumnCount ) m_nCurColumn = 0; + } + + //-------------------------------------------------------------------- + void TableControl_Impl::impl_getAllVisibleCellsArea( Rectangle& _rCellArea ) const + { + DBG_CHECK_ME(); + + _rCellArea.Left() = 0; + _rCellArea.Top() = 0; + + // determine the right-most border of the last column which is + // at least partially visible + _rCellArea.Right() = m_nRowHeaderWidthPixel; + if ( !m_aAccColumnWidthsPixel.empty() ) + { + // the number of pixels which are scroll out of the left hand + // side of the window + long nScrolledOutLeft = m_nLeftColumn == 0 ? 0 : m_aAccColumnWidthsPixel[ m_nLeftColumn - 1 ]; + + ArrayOfLong::const_reverse_iterator loop = m_aAccColumnWidthsPixel.rbegin(); + do + { + _rCellArea.Right() = *loop++ - nScrolledOutLeft + m_nRowHeaderWidthPixel; + } + while ( ( loop != m_aAccColumnWidthsPixel.rend() ) + && ( *loop - nScrolledOutLeft >= _rCellArea.Right() ) + ); + } + // so far, _rCellArea.Right() denotes the first pixel *after* the cell area + --_rCellArea.Right(); + + // determine the last row which is at least partially visible + _rCellArea.Bottom() = + m_nColHeaderHeightPixel + + impl_getVisibleRows( true ) * m_nRowHeightPixel + - 1; + } + + //-------------------------------------------------------------------- + void TableControl_Impl::impl_getAllVisibleDataCellArea( Rectangle& _rCellArea ) const + { + DBG_CHECK_ME(); + + impl_getAllVisibleCellsArea( _rCellArea ); + _rCellArea.Left() = m_nRowHeaderWidthPixel; + _rCellArea.Top() = m_nColHeaderHeightPixel; + } + + //-------------------------------------------------------------------- + void TableControl_Impl::impl_ni_updateCachedModelValues() + { + m_nRowHeightPixel = 15; + m_nColHeaderHeightPixel = 0; + m_nRowHeaderWidthPixel = 0; + m_pInputHandler.reset(); + m_nColumnCount = m_nRowCount = 0; + + m_nRowHeightPixel = m_rAntiImpl.LogicToPixel( Size( 0, m_pModel->getRowHeight() ), MAP_100TH_MM ).Height(); + if ( m_pModel->hasColumnHeaders() ) + m_nColHeaderHeightPixel = m_rAntiImpl.LogicToPixel( Size( 0, m_pModel->getColumnHeaderHeight() ), MAP_100TH_MM ).Height(); + if ( m_pModel->hasRowHeaders() ) + m_nRowHeaderWidthPixel = m_rAntiImpl.LogicToPixel( Size( m_pModel->getRowHeaderWidth(), 0 ), MAP_100TH_MM ).Width(); + + impl_ni_updateColumnWidths(); + + m_pInputHandler = m_pModel->getInputHandler(); + if ( !m_pInputHandler ) + m_pInputHandler.reset( new DefaultInputHandler ); + + m_nColumnCount = m_pModel->getColumnCount(); + m_nRowCount = m_pModel->getRowCount(); + } + + //-------------------------------------------------------------------- + void TableControl_Impl::impl_ni_updateColumnWidths() + { + m_aColumnWidthsPixel.resize( 0 ); + m_aAccColumnWidthsPixel.resize( 0 ); + if ( !m_pModel ) + return; + + TableSize colCount = m_pModel->getColumnCount(); + m_aColumnWidthsPixel.reserve( colCount ); + m_aAccColumnWidthsPixel.reserve( colCount ); + long accumulatedPixelWidth = 0; + for ( ColPos col = 0; col < colCount; ++col ) + { + PColumnModel pColumn = m_pModel->getColumnModel( col ); + DBG_ASSERT( !!pColumn, "TableControl_Impl::impl_ni_updateColumnWidths: invalid column returned by the model!" ); + if ( !pColumn ) + continue; + + TableMetrics colWidth = pColumn->getWidth(); + DBG_ASSERT( ( colWidth == COLWIDTH_FIT_TO_VIEW ) || ( colWidth > 0 ), + "TableControl_Impl::impl_ni_updateColumnWidths: invalid column width!" ); + + long pixelWidth = 0; + if ( colWidth == COLWIDTH_FIT_TO_VIEW ) + { + // TODO + DBG_ERROR( "TableControl_Impl::impl_ni_updateColumnWidths: COLWIDTH_FIT_TO_VIEW not implemented, yet!" ); + } + else + { + pixelWidth = m_rAntiImpl.LogicToPixel( Size( colWidth, 0 ), MAP_100TH_MM ).Width(); + } + + m_aColumnWidthsPixel.push_back( pixelWidth ); + + m_aAccColumnWidthsPixel.push_back( accumulatedPixelWidth += pixelWidth ); + } + } + + //-------------------------------------------------------------------- + namespace + { + //................................................................ + /// determines whether a scrollbar is needed for the given values + bool lcl_determineScrollbarNeed( ScrollbarVisibility _eVisibility, + long _nVisibleUnits, long _nRange ) + { + if ( _eVisibility == ScrollbarShowNever ) + return false; + if ( _eVisibility == ScrollbarShowAlways ) + return true; + return _nVisibleUnits > _nRange; + } + + //................................................................ + void lcl_setButtonRepeat( Window& _rWindow, ULONG _nDelay ) + { + AllSettings aSettings = _rWindow.GetSettings(); + MouseSettings aMouseSettings = aSettings.GetMouseSettings(); + + aMouseSettings.SetButtonRepeat( _nDelay ); + aSettings.SetMouseSettings( aMouseSettings ); + + _rWindow.SetSettings( aSettings, TRUE ); + } + + //................................................................ + void lcl_updateScrollbar( Window& _rParent, ScrollBar*& _rpBar, + ScrollbarVisibility _eVisibility, long _nVisibleUnits, + long _nPosition, long _nLineSize, long _nRange, + bool _bHorizontal, const Link& _rScrollHandler ) + { + // do we need the scrollbar? + bool bNeedBar = lcl_determineScrollbarNeed( _eVisibility, _nVisibleUnits, _nRange ); + + // do we currently have the scrollbar? + bool bHaveBar = _rpBar != NULL; + + // do we need to correct the scrollbar visibility? + if ( bHaveBar && !bNeedBar ) + { + DELETEZ( _rpBar ); + } + else if ( !bHaveBar && bNeedBar ) + { + _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; + + aColumn.moveRight(); + ++visibleColumns; + } + return visibleColumns; + } + + } + + //-------------------------------------------------------------------- + void TableControl_Impl::impl_ni_updateScrollbars() + { + TempHideCursor aHideCursor( *this ); + + // the width/height of a scrollbar, needed several times below + long nScrollbarMetrics = m_rAntiImpl.GetSettings().GetStyleSettings().GetScrollBarSize(); + if ( m_rAntiImpl.IsZoom() ) + nScrollbarMetrics = (long)( nScrollbarMetrics * (double)m_rAntiImpl.GetZoom() ); + + // determine the playground for the data cells (excluding headers) + // TODO: what if the control is smaller than needed for the headers/scrollbars? + Rectangle aDataCellPlayground( Point( 0, 0 ), m_rAntiImpl.GetOutputSizePixel() ); + aDataCellPlayground.Left() = m_nRowHeaderWidthPixel; + aDataCellPlayground.Top() = m_nColHeaderHeightPixel; + + // do we need a vertical scrollbar? + bool bFirstRoundVScrollNeed = false; + if ( lcl_determineScrollbarNeed( + m_pModel->getVerticalScrollbarVisibility(aDataCellPlayground.GetHeight(), m_nRowHeightPixel*m_nRowCount), + lcl_getRowsFittingInto( aDataCellPlayground.GetHeight(), m_nRowHeightPixel ), + m_nRowCount ) ) + { + aDataCellPlayground.Right() -= nScrollbarMetrics; + bFirstRoundVScrollNeed = true; + } + // do we need a horizontal scrollbar? + if ( lcl_determineScrollbarNeed( + m_pModel->getHorizontalScrollbarVisibility(aDataCellPlayground.GetWidth(), m_aAccColumnWidthsPixel[m_nColumnCount-1]), + lcl_getColumnsVisibleWithin( aDataCellPlayground, m_nLeftColumn, *this, false ), + m_nColumnCount ) ) + { + aDataCellPlayground.Bottom() -= nScrollbarMetrics; + + // now that we just found that we need a horizontal scrollbar, + // the need for a vertical one may have changed, since the horizontal + // SB might just occupy enough space so that not all rows do fit + // anymore + if ( !bFirstRoundVScrollNeed && lcl_determineScrollbarNeed( + m_pModel->getVerticalScrollbarVisibility(aDataCellPlayground.GetHeight(),m_nRowHeightPixel*m_nRowCount), + lcl_getRowsFittingInto( aDataCellPlayground.GetHeight(), m_nRowHeightPixel ), + m_nRowCount ) ) + { + aDataCellPlayground.Right() -= nScrollbarMetrics; + } + } + else + { + Size regionWithoutHeader = m_rAntiImpl.PixelToLogic(Size(aDataCellPlayground.Right() - aDataCellPlayground.Left(),0),MAP_100TH_MM); + TableMetrics nColWidth = regionWithoutHeader.Width()/m_nColumnCount; + for ( ColPos col = 0; col < m_nColumnCount; ++col ) + m_pModel->getColumnModel(col)->setWidth(nColWidth); + m_rAntiImpl.SetModel(m_pModel); + } + + // create or destroy the vertical scrollbar, as needed + lcl_updateScrollbar( + m_rAntiImpl, + m_pVScroll, + m_pModel->getVerticalScrollbarVisibility(aDataCellPlayground.GetHeight(),m_nRowHeightPixel*m_nRowCount), + lcl_getRowsFittingInto( aDataCellPlayground.GetHeight(), m_nRowHeightPixel ), + // visible units + m_nTopRow, // current position + 1, // line size + m_nRowCount, // range + 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 ) + ); + m_pVScroll->SetPosSizePixel( + aScrollbarArea.TopLeft(), aScrollbarArea.GetSize() ); + } + + // create or destroy the horizontal scrollbar, as needed + lcl_updateScrollbar( + m_rAntiImpl, + m_pHScroll, + m_pModel->getHorizontalScrollbarVisibility(aDataCellPlayground.GetWidth(), m_aAccColumnWidthsPixel[m_nColumnCount-1]), + lcl_getColumnsVisibleWithin( aDataCellPlayground, m_nLeftColumn, *this, false ), + // visible units + m_nLeftColumn, // current position + 1, // line size + m_nColumnCount, // range + true, // horizontal + LINK( this, TableControl_Impl, OnScroll ) // scroll handler + ); + // position it + if ( m_pHScroll ) + { + Rectangle aScrollbarArea( + Point( 0, aDataCellPlayground.Bottom() + 1 ), + Size( aDataCellPlayground.Right() + 1, nScrollbarMetrics ) + ); + m_pHScroll->SetPosSizePixel( + aScrollbarArea.TopLeft(), aScrollbarArea.GetSize() ); + } + + // the corner window connecting the two scrollbars in the lower right corner + bool bHaveScrollCorner = NULL != m_pScrollCorner; + bool bNeedScrollCorner = ( NULL != m_pHScroll ) && ( NULL != m_pVScroll ); + if ( bHaveScrollCorner && !bNeedScrollCorner ) + { + DELETEZ( m_pScrollCorner ); + } + else if ( !bHaveScrollCorner && bNeedScrollCorner ) + { + m_pScrollCorner = new ScrollBarBox( &m_rAntiImpl ); + m_pScrollCorner->SetSizePixel( Size( nScrollbarMetrics, nScrollbarMetrics ) ); + m_pScrollCorner->SetPosPixel( Point( aDataCellPlayground.Right() + 1, aDataCellPlayground.Bottom() + 1 ) ); + m_pScrollCorner->Show(); + } + + // resize the data window + m_pDataWindow->SetSizePixel( Size( + aDataCellPlayground.GetWidth() + m_nRowHeaderWidthPixel, + aDataCellPlayground.GetHeight() + m_nColHeaderHeightPixel + ) ); + } + + //-------------------------------------------------------------------- + void TableControl_Impl::onResize() + { + DBG_CHECK_ME(); + impl_ni_updateScrollbars(); + //Rectangle aAllCells; + // impl_getAllVisibleCellsArea( aAllCells ); + //m_pSelEngine->SetVisibleArea(aAllCells); + } + + //-------------------------------------------------------------------- + void TableControl_Impl::doPaintContent( const Rectangle& _rUpdateRect ) + { + DBG_CHECK_ME(); + + if ( !getModel() ) + return; + + PTableRenderer pRenderer = getModel()->getRenderer(); + DBG_ASSERT( !!pRenderer, "TableDataWindow::Paint: invalid renderer!" ); + if ( !pRenderer ) + return; + + // our current style settings, to be passed to the renderer + const StyleSettings& rStyle = m_rAntiImpl.GetSettings().GetStyleSettings(); + + // the area occupied by all (at least partially) visible cells, including + // headers + Rectangle aAllCellsWithHeaders; + impl_getAllVisibleCellsArea( aAllCellsWithHeaders ); + + m_nRowCount = m_pModel->getRowCount(); + // ............................ + // draw the header column area + if ( getModel()->hasColumnHeaders() ) + { + TableRowGeometry aHeaderRow( *this, Rectangle( Point( 0, 0 ), + aAllCellsWithHeaders.BottomRight() ), ROW_COL_HEADERS ); + pRenderer->PaintHeaderArea( + *m_pDataWindow, aHeaderRow.getRect(), true, false, rStyle + ); + // Note that strictly, aHeaderRow.getRect() also contains the intersection between column + // and row header area. However, below we go to paint this intersection, again, + // so this hopefully doesn't hurt if we already paint it here. + + for ( TableCellGeometry aCell( aHeaderRow, m_nLeftColumn ); + aCell.isValid(); + aCell.moveRight() + ) + { + if ( _rUpdateRect.GetIntersection( aCell.getRect() ).IsEmpty() ) + continue; + + bool isActiveColumn = ( aCell.getColumn() == getCurColumn() ); + bool isSelectedColumn = false; + pRenderer->PaintColumnHeader( aCell.getColumn(), isActiveColumn, isSelectedColumn, + *m_pDataWindow, aCell.getRect(), rStyle ); + } + } + + // the area occupied by the row header, if any + Rectangle aRowHeaderArea; + if ( getModel()->hasRowHeaders() ) + { + aRowHeaderArea = aAllCellsWithHeaders; + aRowHeaderArea.Right() = m_nRowHeaderWidthPixel - 1; + aRowHeaderArea.Bottom() = m_nRowHeightPixel * m_nRowCount + m_nColHeaderHeightPixel - 1; + pRenderer->PaintHeaderArea( + *m_pDataWindow, aRowHeaderArea, false, true, rStyle + ); + // Note that strictly, aRowHeaderArea also contains the intersection between column + // and row header area. However, below we go to paint this intersection, again, + // so this hopefully doesn't hurt if we already paint it here. + + if ( getModel()->hasColumnHeaders() ) + { + TableCellGeometry aIntersection( *this, Rectangle( Point( 0, 0 ), + aAllCellsWithHeaders.BottomRight() ), COL_ROW_HEADERS, ROW_COL_HEADERS ); + pRenderer->PaintHeaderArea( + *m_pDataWindow, aIntersection.getRect(), true, true, rStyle + ); + } + } + + // ............................ + // draw the table content row by row + + TableSize colCount = getModel()->getColumnCount(); + + // paint all rows + Rectangle aAllDataCellsArea; + impl_getAllVisibleDataCellArea( aAllDataCellsArea ); + + //get the vector, which contains row vectors, each containing the data for the cells in this row + std::vector<std::vector<rtl::OUString> > aCellContent = m_pModel->getCellContent(); + //if the vector is empty, fill it with empty data, so the table can be painted + if(aCellContent.empty()) + { + std::vector<rtl::OUString> emptyCells; + while(m_nRowCount!=0) + { + aCellContent.push_back(emptyCells); + --m_nRowCount; + } + } + std::vector<std::vector<rtl::OUString> >::iterator it = aCellContent.begin()+m_nTopRow; + //get the vector, which contains the row header titles + std::vector<rtl::OUString> aRowHeaderContent; + ::std::vector<rtl::OUString>::iterator itRowName = aRowHeaderContent.begin(); + + if(m_pModel->hasRowHeaders()) + { + aRowHeaderContent = m_pModel->getRowHeaderName(); + //if the vector is empty, fill it with empty strings, so the table can be painted + if(aRowHeaderContent.empty()) + { + while(m_nRowCount!=0) + { + aRowHeaderContent.push_back(rtl::OUString::createFromAscii("")); + --m_nRowCount; + } + } + itRowName = aRowHeaderContent.begin()+m_nTopRow; + } + for ( TableRowGeometry aRowIterator( *this, aAllCellsWithHeaders, getTopRow() ); + aRowIterator.isValid(); + aRowIterator.moveDown() ) + { + if ( _rUpdateRect.GetIntersection( aRowIterator.getRect() ).IsEmpty() ) + { + if(m_pModel->hasRowHeaders()) + ++itRowName; + ++it; + continue; + } + bool isActiveRow = ( aRowIterator.getRow() == getCurRow() ); + bool isSelectedRow = false; + if(!m_nRowSelected.empty()) + { + for(std::vector<RowPos>::iterator itSel=m_nRowSelected.begin(); + itSel!=m_nRowSelected.end();++itSel) + { + if(*itSel == aRowIterator.getRow()) + isSelectedRow = true; + } + } + std::vector<rtl::OUString> aCellData; + if(it != aCellContent.end()) + { + aCellData = *it; + ++it; + } + ::std::vector<rtl::OUString>::iterator iter = aCellData.begin()+m_nLeftColumn; + + // give the redenderer a chance to prepare the row + pRenderer->PrepareRow( aRowIterator.getRow(), isActiveRow, isSelectedRow, + *m_pDataWindow, aRowIterator.getRect().GetIntersection( aAllDataCellsArea ), rStyle ); + + // paint the row header + if ( m_pModel->hasRowHeaders() ) + { + rtl::OUString rowHeaderName; + if(itRowName != aRowHeaderContent.end()) + { + rowHeaderName = *itRowName; + ++itRowName; + } + Rectangle aCurrentRowHeader( aRowHeaderArea.GetIntersection( aRowIterator.getRect() ) ); + pRenderer->PaintRowHeader( isActiveRow, isSelectedRow, *m_pDataWindow, aCurrentRowHeader, + rStyle, rowHeaderName ); + } + if ( !colCount ) + continue; + + // paint all cells in this row + for ( TableCellGeometry aCell( aRowIterator, m_nLeftColumn ); + aCell.isValid(); + aCell.moveRight() + ) + { + // if ( _rUpdateRect.GetIntersection( aCell.getRect() ).IsEmpty() ) + // continue; + + //bool isActiveCell = isActiveRow && ( aCell.getColumn() == getCurColumn() ); + bool isSelectedColumn = false; + rtl::OUString cellData; + if(aCellData.empty()) + cellData=rtl::OUString::createFromAscii(""); + else if(iter != aCellData.end()) + { + cellData = *iter; + ++iter; + } + pRenderer->PaintCell( aCell.getColumn(), isSelectedRow || isSelectedColumn, isActiveRow, + *m_pDataWindow, aCell.getRect(), rStyle, cellData ); + } + } + } + + //-------------------------------------------------------------------- + void TableControl_Impl::hideCursor() + { + DBG_CHECK_ME(); + + if ( ++m_nCursorHidden == 1 ) + impl_ni_doSwitchCursor( false ); + } + + //-------------------------------------------------------------------- + void TableControl_Impl::showCursor() + { + DBG_CHECK_ME(); + + DBG_ASSERT( m_nCursorHidden > 0, "TableControl_Impl::showCursor: cursor not hidden!" ); + if ( --m_nCursorHidden == 0 ) + impl_ni_doSwitchCursor( true ); + } + + //-------------------------------------------------------------------- + bool TableControl_Impl::dispatchAction( TableControlAction _eAction ) + { + DBG_CHECK_ME(); + + bool bSuccess = false; + Rectangle rCells; + switch ( _eAction ) + { + case cursorDown: + if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) + { + //if other rows already selected, deselect them + if(m_nRowSelected.size()>0) + { + for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); + it!=m_nRowSelected.end();++it) + { + invalidateSelectedRow(*it,rCells); + m_pDataWindow->Invalidate(rCells); + } + m_nRowSelected.clear(); + } + if(m_nCurRow < m_nRowCount-1) + { + ++m_nCurRow; + m_nRowSelected.push_back(m_nCurRow); + } + else + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRow(m_nCurRow, rCells); + ensureVisible(m_nCurColumn,m_nCurRow,false); + bSuccess = true; + } + else + { + if ( m_nCurRow < m_nRowCount - 1 ) + bSuccess = goTo( m_nCurColumn, m_nCurRow + 1 ); + } + break; + + case cursorUp: + if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) + { + if(m_nRowSelected.size()>0) + { + for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); + it!=m_nRowSelected.end();++it) + { + invalidateSelectedRow(*it,rCells); + m_pDataWindow->Invalidate(rCells); + } + m_nRowSelected.clear(); + } + if(m_nCurRow>0) + { + --m_nCurRow; + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRow(m_nCurRow, rCells); + } + else + { + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRow(m_nCurRow, rCells); + } + ensureVisible(m_nCurColumn,m_nCurRow,false); + bSuccess = true; + } + else + { + if ( m_nCurRow > 0 ) + bSuccess = goTo( m_nCurColumn, m_nCurRow - 1 ); + } + break; + case cursorLeft: + if ( m_nCurColumn > 0 ) + bSuccess = goTo( m_nCurColumn - 1, m_nCurRow ); + else + if ( ( m_nCurColumn == 0) && ( m_nCurRow > 0 ) ) + bSuccess = goTo( m_nColumnCount - 1, m_nCurRow - 1 ); + break; + + case cursorRight: + if ( m_nCurColumn < m_nColumnCount - 1 ) + bSuccess = goTo( m_nCurColumn + 1, m_nCurRow ); + else + if ( ( m_nCurColumn == m_nColumnCount - 1 ) && ( m_nCurRow < m_nRowCount - 1 ) ) + bSuccess = goTo( 0, m_nCurRow + 1 ); + break; + + case cursorToLineStart: + bSuccess = goTo( 0, m_nCurRow ); + break; + + case cursorToLineEnd: + bSuccess = goTo( m_nColumnCount - 1, m_nCurRow ); + break; + + case cursorToFirstLine: + bSuccess = goTo( m_nCurColumn, 0 ); + break; + + case cursorToLastLine: + bSuccess = goTo( m_nCurColumn, m_nRowCount - 1 ); + break; + + case cursorPageUp: + { + RowPos nNewRow = ::std::max( (RowPos)0, m_nCurRow - impl_getVisibleRows( false ) ); + bSuccess = goTo( m_nCurColumn, nNewRow ); + } + break; + + case cursorPageDown: + { + RowPos nNewRow = ::std::min( m_nRowCount - 1, m_nCurRow + impl_getVisibleRows( false ) ); + bSuccess = goTo( m_nCurColumn, nNewRow ); + } + break; + + case cursorTopLeft: + bSuccess = goTo( 0, 0 ); + break; + + case cursorBottomRight: + bSuccess = goTo( m_nColumnCount - 1, m_nRowCount - 1 ); + break; + + case cursorSelectRow: + { + if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) + return bSuccess = false; + //pos is the position of the current row in the vector of selected rows, if current row is selected + int pos = getRowSelectedNumber(m_nRowSelected, m_nCurRow); + //if current row is selected, it should be deselected, when ALT+SPACE are pressed + if(pos>-1) + m_nRowSelected.erase(m_nRowSelected.begin()+pos); + //else select the row->put it in the vector + else + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRow(m_nCurRow, rCells); + bSuccess = true; + } + break; + case cursorSelectRowUp: + { + if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) + return bSuccess = false; + else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) + { + //if there are other selected rows, deselect them + return false; + } + else + { + //there are other selected rows + if(m_nRowSelected.size()>0) + { + //the anchor wasn't set -> a region is not selected, that's why clear all selection + //and select the current row + if(m_nAnchor==-1) + { + for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); + it!=m_nRowSelected.end();++it) + { + invalidateSelectedRow(*it,rCells); + m_pDataWindow->Invalidate(rCells); + } + m_nRowSelected.clear(); + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRow(m_nCurRow, rCells); + } + else + { + //a region is already selected, prevRow is last selected row and the row above - nextRow - should be selected + int prevRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow); + int nextRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow-1); + if(prevRow>-1) + { + //if m_nCurRow isn't the upper one, can move up, otherwise not + if(m_nCurRow>0) + m_nCurRow--; + else + return bSuccess = true; + //if nextRow already selected, deselect it, otherwise select it + if(m_nRowSelected[nextRow] == m_nCurRow) + { + m_nRowSelected.erase(m_nRowSelected.begin()+prevRow); + invalidateSelectedRow(m_nCurRow+1, rCells); + } + else + { + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRow(m_nCurRow, rCells); + } + } + } + } + else + { + //if nothing is selected and the current row isn't the upper one + //select the current and one row above + //otherwise select only the upper row + if(m_nCurRow>0) + { + m_nRowSelected.push_back(m_nCurRow); + m_nCurRow--; + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow+1, m_nCurRow, rCells); + } + else + { + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRow(m_nCurRow, rCells); + } + } + m_pSelEngine->SetAnchor(TRUE); + m_nAnchor = m_nCurRow; + ensureVisible(m_nCurColumn, m_nCurRow, false); + bSuccess = true; + } + } + break; + case cursorSelectRowDown: + { + if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) + bSuccess = false; + else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) + { + bSuccess = false; + } + else + { + if(m_nRowSelected.size()>0) + { + //the anchor wasn't set -> a region is not selected, that's why clear all selection + //and select the current row + if(m_nAnchor==-1) + { + for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); + it!=m_nRowSelected.end();++it) + { + invalidateSelectedRow(*it,rCells); + m_pDataWindow->Invalidate(rCells); + } + m_nRowSelected.clear(); + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRow(m_nCurRow, rCells); + } + else + { + //a region is already selected, prevRow is last selected row and the row beneath - nextRow - should be selected + int prevRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow); + int nextRow = getRowSelectedNumber(m_nRowSelected, m_nCurRow+1); + if(prevRow>-1) + { + //if m_nCurRow isn't the last one, can move down, otherwise not + if(m_nCurRow<m_nRowCount) + m_nCurRow++; + else + return bSuccess = true; + //if net row already selected, deselect it, otherwise select it + if(m_nRowSelected[nextRow] == m_nCurRow) + { + m_nRowSelected.erase(m_nRowSelected.begin()+prevRow); + invalidateSelectedRow(m_nCurRow-1, rCells); + } + else + { + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRow(m_nCurRow, rCells); + } + } + } + } + else + { + //there wasn't any selection, select curennt and row beneath, otherwise onlyrow beneath + if(m_nCurRow<m_nRowCount-1) + { + m_nRowSelected.push_back(m_nCurRow); + m_nCurRow++; + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRegion(m_nCurRow-1, m_nCurRow, rCells); + } + else + { + m_nRowSelected.push_back(m_nCurRow); + invalidateSelectedRow(m_nCurRow, rCells); + } + } + m_pSelEngine->SetAnchor(TRUE); + m_nAnchor = m_nCurRow; + ensureVisible(m_nCurColumn, m_nCurRow, false); + bSuccess = true; + } + } + break; + case cursorSelectRowAreaTop: + { + if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) + bSuccess = false; + else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) + bSuccess = false; + else + { + //select the region between the current and the upper row + RowPos iter = m_nCurRow; + invalidateSelectedRegion(m_nCurRow, 0, rCells); + //put the rows in vector + while(iter>=0) + { + if(!isRowSelected(m_nRowSelected, iter)) + m_nRowSelected.push_back(iter); + --iter; + } + m_nCurRow = 0; + m_nAnchor = m_nCurRow; + m_pSelEngine->SetAnchor(TRUE); + ensureVisible(m_nCurColumn, 0, false); + bSuccess = true; + } + } + break; + case cursorSelectRowAreaBottom: + { + if(m_pSelEngine->GetSelectionMode() == NO_SELECTION) + return bSuccess = false; + else if(m_pSelEngine->GetSelectionMode() == SINGLE_SELECTION) + return bSuccess = false; + //select the region between the current and the last row + RowPos iter = m_nCurRow; + invalidateSelectedRegion(m_nCurRow, m_nRowCount-1, rCells); + //put the rows in the vector + while(iter<=m_nRowCount) + { + if(!isRowSelected(m_nRowSelected, iter)) + m_nRowSelected.push_back(iter); + ++iter; + } + m_nCurRow = m_nRowCount-1; + m_nAnchor = m_nCurRow; + m_pSelEngine->SetAnchor(TRUE); + ensureVisible(m_nCurColumn, m_nRowCount, false); + bSuccess = true; + } + break; + default: + DBG_ERROR( "TableControl_Impl::dispatchAction: unsupported action!" ); + } + return bSuccess; + } + + //-------------------------------------------------------------------- + void TableControl_Impl::impl_ni_doSwitchCursor( bool _bShow ) + { + PTableRenderer pRenderer = !!m_pModel ? m_pModel->getRenderer() : PTableRenderer(); + if ( !!pRenderer ) + { + Rectangle aCellRect; + impl_getCellRect( m_nCurColumn, m_nCurRow, aCellRect ); + + // const StyleSettings& rStyle = m_rAntiImpl.GetSettings().GetStyleSettings(); + if ( _bShow ) + { + pRenderer->ShowCellCursor( *m_pDataWindow, aCellRect); + } + else + { + pRenderer->HideCellCursor( *m_pDataWindow, aCellRect); + } + } + } + + //-------------------------------------------------------------------- + void TableControl_Impl::impl_getCellRect( ColPos _nColumn, RowPos _nRow, Rectangle& _rCellRect ) const + { + DBG_CHECK_ME(); + + if ( !m_pModel + || ( COL_INVALID == _nColumn ) + || ( ROW_INVALID == _nRow ) + ) + { + _rCellRect.SetEmpty(); + return; + } + + DBG_ASSERT( ( _nColumn >= 0 ) && ( _nColumn < m_pModel->getColumnCount() ), + "TableControl_Impl::impl_getCellRect: invalid column index!" ); + DBG_ASSERT( ( _nRow >= 0 ) && ( _nRow < m_pModel->getRowCount() ), + "TableControl_Impl::impl_getCellRect: invalid row index!" ); + + Rectangle aAllCells; + impl_getAllVisibleCellsArea( aAllCells ); + + TableCellGeometry aCell( *this, aAllCells, _nColumn, _nRow ); + _rCellRect = aCell.getRect(); + } + //------------------------------------------------------------------------------- + RowPos TableControl_Impl::getCurrentRow(const Point& rPoint) + { + DBG_CHECK_ME(); + Rectangle rCellRect; + RowPos newRowPos = -2;//-1 is HeaderRow + ColPos newColPos = 0; + //To Do: when only row position needed, the second loop isn't necessary, Please proove this!!! + for(int i=0;i<m_nRowCount;i++) + { + for(int j=-1;j<m_nColumnCount;j++) + { + impl_getCellRect(j,i,rCellRect); + if((rPoint.X() >= rCellRect.Left() && rPoint.X() <= rCellRect.Right()) && rPoint.Y() >= rCellRect.Top() && rPoint.Y() <= rCellRect.Bottom()) + { + newRowPos = i; + newColPos = j; + if(newColPos == -1) + m_nCurColumn = 0; + else + m_nCurColumn = newColPos; + return newRowPos; + } + } + } + return newRowPos; + } + //------------------------------------------------------------------------------- + void TableControl_Impl::setCursorAtCurrentCell(const Point& rPoint) + { + DBG_CHECK_ME(); + hideCursor(); + Rectangle rCellRect; + RowPos newRowPos = -2;//-1 is HeaderRow + ColPos newColPos = 0; + //To Do: when only row position needed, the second loop isn't necessary, Please proove this!!! + for(int i=0;i<m_nRowCount;i++) + { + for(int j=-1;j<m_nColumnCount;j++) + { + impl_getCellRect(j,i,rCellRect); + if((rPoint.X() >= rCellRect.Left() && rPoint.X() <= rCellRect.Right()) && rPoint.Y() >= rCellRect.Top() && rPoint.Y() <= rCellRect.Bottom()) + { + newRowPos = i; + m_nCurRow = newRowPos; + newColPos = j; + if(newColPos == -1) + m_nCurColumn = 0; + else + m_nCurColumn = newColPos; + } + } + } + showCursor(); + } + + //------------------------------------------------------------------------------- + void TableControl_Impl::invalidateSelectedRegion(RowPos _nPrevRow, RowPos _nCurRow, Rectangle& _rCellRect) + { + DBG_CHECK_ME(); + Rectangle aAllCells; + //get the visible area of the table control and set the Left and right border of the region to be repainted + impl_getAllVisibleCellsArea( aAllCells ); + _rCellRect.Left() = aAllCells.Left(); + _rCellRect.Right() = aAllCells.Right(); + Rectangle rCells; + //if only one row is selected + if(_nPrevRow == _nCurRow) + { + impl_getCellRect(m_nCurColumn,_nCurRow,rCells); + _rCellRect.Top()=rCells.Top(); + _rCellRect.Bottom()=rCells.Bottom(); + } + //if the region is above the current row + else if(_nPrevRow < _nCurRow ) + { + impl_getCellRect(m_nCurColumn,_nPrevRow,rCells); + _rCellRect.Top()=rCells.Top(); + impl_getCellRect(m_nCurColumn,_nCurRow,rCells); + _rCellRect.Bottom()=rCells.Bottom(); + } + //if the region is beneath the current row + else + { + impl_getCellRect(m_nCurColumn,_nCurRow,rCells); + _rCellRect.Top()=rCells.Top(); + impl_getCellRect(m_nCurColumn,_nPrevRow,rCells); + _rCellRect.Bottom()=rCells.Bottom(); + } + m_pDataWindow->Invalidate(_rCellRect); + } + + //------------------------------------------------------------------------------- + //To Do: not really needed, because in method above one row can be invalidate. Please Prove this!!! + void TableControl_Impl::invalidateSelectedRow(RowPos _nCurRow, Rectangle& _rCellRect) + { + DBG_CHECK_ME(); + Rectangle aAllCells; + impl_getAllVisibleCellsArea( aAllCells ); + _rCellRect.Left() = aAllCells.Left(); + _rCellRect.Right() = aAllCells.Right(); + Rectangle rCells; + impl_getCellRect(m_nCurColumn,_nCurRow,rCells); + _rCellRect.Top()=rCells.Top(); + _rCellRect.Bottom()=rCells.Bottom(); + m_pDataWindow->Invalidate(_rCellRect); + } + //------------------------------------------------------------------------------- + //this method is to be called, when a new row is added + void TableControl_Impl::invalidateRow(RowPos _nRowPos, Rectangle& _rCellRect) + { + //DBG_CHECK_ME(); + TempHideCursor aHideCursor( *this ); + impl_getAllVisibleCellsArea( _rCellRect ); + TableRowGeometry _rRow( *this, _rCellRect, _nRowPos); + impl_ni_updateScrollbars(); + m_pDataWindow->Invalidate(_rRow.getRect()); + } + + //------------------------------------------------------------------------------- + std::vector<RowPos> TableControl_Impl::getSelectedRows() + { + return m_nRowSelected; + } + + void TableControl_Impl::removeSelectedRow(RowPos _nRowPos) + { + int i =0; + //if the row is selected, remove it from the selection vector + if(isRowSelected(m_nRowSelected, _nRowPos)) + { + if(m_nRowSelected.size()>1) + m_nRowSelected.erase(m_nRowSelected.begin()+_nRowPos); + else + m_nRowSelected.clear(); + } + //after removing a row, row positions must be updated, so selected rows could stay selected + if(m_nRowSelected.size()>1) + { + for(std::vector<RowPos>::iterator it=m_nRowSelected.begin();it!=m_nRowSelected.end();++it) + { + if(*it > _nRowPos) + m_nRowSelected[i]=*it-1; + ++i; + } + } + if(_nRowPos == 0) + m_nCurRow = 0; + else + m_nCurRow = _nRowPos-1; + } + //------------------------------------------------------------------------------- + void TableControl_Impl::invalidateRows(RowPos _nRowStart, Rectangle& _rCellRect) + { + //DBG_CHECK_ME(); + (void)_nRowStart; + (void)_rCellRect; + /*TempHideCursor aHideCursor(*this); + Rectangle aAllCells; + impl_getAllVisibleCellsArea( aAllCells ); + TableRowGeometry _rRow( *this, aAllCells, _nRowStart); + _rCellRect = _rRow.getRect(); + Rectangle rCells1; + impl_getCellRect(m_nCurColumn,m_nRowCount,rCells1); + _rCellRect.Bottom() = rCells1.Bottom();*/ + /*if(_nRowStart != _nRowEnd) + { + TableRowGeometry _rRow( *this, aAllCells, _nRowEnd); + _rCellRect.Bottom() = _rRow.getRect().Bottom(); + } + */ + //_rCellRect.Right() = aAllCells.Right(); + //_rCellRect.Left() = aAllCells.Left(); + //Rectangle rCells1; + //impl_getCellRect(m_nCurColumn,_nRowStart,rCells1); + //_rCellRect.Top()=rCells1.Top(); + //Rectangle rCells2; + //impl_getCellRect(m_nCurColumn,_nRowEnd,rCells2); + //_rCellRect.Bottom()=rCells2.Bottom(); + impl_ni_updateScrollbars(); + //m_pDataWindow->Invalidate(_rCellRect); + m_pDataWindow->Invalidate(); + } + + + //------------------------------------------------------------------------------- + bool TableControl_Impl::isClickInVisibleArea(const Point& rPoint) + { + DBG_CHECK_ME(); + long nScrollbarMetrics = m_rAntiImpl.GetSettings().GetStyleSettings().GetScrollBarSize(); + //clickable area is in the visible table control area without the scrollbars + Rectangle aDataCellPlayground( Point( 0, 0 ), m_rAntiImpl.GetOutputSizePixel() ); + aDataCellPlayground.Top() = m_nColHeaderHeightPixel; + aDataCellPlayground.Right() -= nScrollbarMetrics; + aDataCellPlayground.Bottom() -= nScrollbarMetrics; + if((rPoint.X() >= aDataCellPlayground.Left() && rPoint.X() <= aDataCellPlayground.Right()) && rPoint.Y() >= aDataCellPlayground.Top() && rPoint.Y() <= aDataCellPlayground.Bottom()) + { + return true; + } + else + return false; + } + //-------------------------------------------------------------------- + TableSize TableControl_Impl::impl_getVisibleRows( bool _bAcceptPartialRow ) const + { + DBG_CHECK_ME(); + + DBG_ASSERT( m_pDataWindow, "TableControl_Impl::impl_getVisibleRows: no data window!" ); + + return lcl_getRowsFittingInto( + m_pDataWindow->GetOutputSizePixel().Height() - m_nColHeaderHeightPixel, + m_nRowHeightPixel, + _bAcceptPartialRow + ); + } + + //-------------------------------------------------------------------- + TableSize TableControl_Impl::impl_getVisibleColumns( bool _bAcceptPartialRow ) const + { + DBG_CHECK_ME(); + + DBG_ASSERT( m_pDataWindow, "TableControl_Impl::impl_getVisibleColumns: no data window!" ); + + return lcl_getColumnsVisibleWithin( + Rectangle( Point( 0, 0 ), m_pDataWindow->GetOutputSizePixel() ), + m_nLeftColumn, + *this, + _bAcceptPartialRow + ); + } + + //-------------------------------------------------------------------- + bool TableControl_Impl::goTo( ColPos _nColumn, RowPos _nRow ) + { + DBG_CHECK_ME(); + + // TODO: give veto listeners a chance + + if ( ( _nColumn < -1 ) || ( _nColumn >= m_nColumnCount ) + || ( _nRow < -1 ) || ( _nRow >= m_nRowCount ) + ) + return false; + + TempHideCursor aHideCursor( *this ); + m_nCurColumn = _nColumn; + m_nCurRow = _nRow; + + // ensure that the new cell is visible + ensureVisible( m_nCurColumn, m_nCurRow, false ); + + // TODO: invalidate all and new column/row header, if present, to enforce + // re-painting them + //if(!m_nRowSelected.empty()) + //{ + // Rectangle rCells; + // for(std::vector<RowPos>::iterator it=m_nRowSelected.begin(); + // it!=m_nRowSelected.end();++it) + // { + // invalidateSelectedRow(*it,rCells); + // } + // m_nRowSelected.clear(); + //} + // TODO: notify listeners about new position + return true; + } + + //-------------------------------------------------------------------- + void TableControl_Impl::ensureVisible( ColPos _nColumn, RowPos _nRow, bool _bAcceptPartialVisibility ) + { + DBG_CHECK_ME(); + DBG_ASSERT( ( _nColumn >= 0 ) && ( _nColumn < m_nColumnCount ) + && ( _nRow >= 0 ) && ( _nRow < m_nRowCount ), + "TableControl_Impl::ensureVisible: invalid coordinates!" ); + + TempHideCursor aHideCursor( *this ); + + if ( _nColumn < m_nLeftColumn ) + impl_ni_ScrollColumns( _nColumn - m_nLeftColumn ); + else + { + TableSize nVisibleColumns = impl_getVisibleColumns( _bAcceptPartialVisibility ); + if ( _nColumn > m_nLeftColumn + nVisibleColumns - 1 ) + { + impl_ni_ScrollColumns( _nColumn - ( m_nLeftColumn + nVisibleColumns - 1 ) ); + // TODO: since not all columns have the same width, this might in theory result + // in the column still not being visible. + } + } + + if ( _nRow < m_nTopRow ) + impl_ni_ScrollRows( _nRow - m_nTopRow ); + else + { + TableSize nVisibleRows = impl_getVisibleRows( _bAcceptPartialVisibility ); + if ( _nRow > m_nTopRow + nVisibleRows - 1 ) + impl_ni_ScrollRows( _nRow - ( m_nTopRow + nVisibleRows - 1 ) ); + } + } + + //-------------------------------------------------------------------- + TableSize TableControl_Impl::impl_ni_ScrollRows( TableSize _nRowDelta ) + { + // compute new top row + RowPos nNewTopRow = + ::std::max( + ::std::min( (RowPos)( m_nTopRow + _nRowDelta ), (RowPos)( m_nRowCount - 1 ) ), + (RowPos)0 + ); + + RowPos nOldTopRow = m_nTopRow; + m_nTopRow = nNewTopRow; + + // if updates are enabled currently, scroll the viewport + if ( m_rAntiImpl.IsUpdateMode() && ( m_nTopRow != nOldTopRow ) ) + { + DBG_SUSPEND_INV( INV_SCROLL_POSITION ); + TempHideCursor aHideCursor( *this ); + // TODO: call a onStartScroll at our listener (or better an own onStartScroll, + // which hides the cursor and then calls the listener) + // Same for onEndScroll + + // scroll the view port, if possible + long nPixelDelta = m_nRowHeightPixel * ( m_nTopRow - nOldTopRow ); + + Rectangle aDataArea( Point( 0, m_nColHeaderHeightPixel ), m_pDataWindow->GetOutputSizePixel() ); + + if ( m_pDataWindow->GetBackground().IsScrollable() + && abs( nPixelDelta ) < aDataArea.GetHeight() + ) + { + m_pDataWindow->Scroll( 0, (long)-nPixelDelta, aDataArea, SCROLL_CLIP | SCROLL_UPDATE ); + } + else + m_pDataWindow->Invalidate( INVALIDATE_UPDATE ); + + // update the position at the vertical scrollbar + m_pVScroll->SetThumbPos( m_nTopRow ); + } + + return (TableSize)( m_nTopRow - nOldTopRow ); + } + + //-------------------------------------------------------------------- + TableSize TableControl_Impl::impl_ni_ScrollColumns( TableSize _nColumnDelta ) + { + // compute new left column + ColPos nNewLeftColumn = + ::std::max( + ::std::min( (ColPos)( m_nLeftColumn + _nColumnDelta ), (ColPos)( m_nColumnCount - 1 ) ), + (ColPos)0 + ); + + ColPos nOldLeftColumn = m_nLeftColumn; + m_nLeftColumn = nNewLeftColumn; + + // if updates are enabled currently, scroll the viewport + if ( m_rAntiImpl.IsUpdateMode() && ( m_nLeftColumn != nOldLeftColumn ) ) + { + DBG_SUSPEND_INV( INV_SCROLL_POSITION ); + TempHideCursor aHideCursor( *this ); + // TODO: call a onStartScroll at our listener (or better an own onStartScroll, + // which hides the cursor and then calls the listener) + // Same for onEndScroll + + // scroll the view port, if possible + Rectangle aDataArea( Point( m_nRowHeaderWidthPixel, 0 ), m_pDataWindow->GetOutputSizePixel() ); + + long nPixelDelta = + ( m_nLeftColumn > 0 ? m_aAccColumnWidthsPixel[ m_nLeftColumn - 1 ] : 0 ) + - ( nOldLeftColumn > 0 ? m_aAccColumnWidthsPixel[ nOldLeftColumn - 1 ] : 0 ); + + if ( m_pDataWindow->GetBackground().IsScrollable() + && abs( nPixelDelta ) < aDataArea.GetWidth() + ) + { + m_pDataWindow->Scroll( (long)-nPixelDelta, 0, aDataArea, SCROLL_CLIP | SCROLL_UPDATE ); + } + else + m_pDataWindow->Invalidate( INVALIDATE_UPDATE ); + + // update the position at the horizontal scrollbar + m_pHScroll->SetThumbPos( m_nLeftColumn ); + } + + return (TableSize)( m_nLeftColumn - nOldLeftColumn ); + } + + SelectionEngine* TableControl_Impl::getSelEngine() + { + return m_pSelEngine; + } + TableDataWindow* TableControl_Impl::getDataWindow() + { + return m_pDataWindow; + } + BOOL TableControl_Impl::isRowSelected(::std::vector<RowPos> selectedRows, RowPos current) + { + for(::std::vector<RowPos>::iterator it=selectedRows.begin(); + it!=selectedRows.end();++it) + { + if(*it == current) + return TRUE; + } + return FALSE; + } + + int TableControl_Impl::getRowSelectedNumber(::std::vector<RowPos> selectedRows, RowPos current) + { + int pos = -1; + int i = 0; + for(std::vector<RowPos>::iterator it=selectedRows.begin();it!=selectedRows.end();++it) + { + if(*it == current) + return pos = i; + ++i; + } + return pos; + } + + void TableControl_Impl::setCellContent(CellEntryType* pCellEntryType) + { + (void)pCellEntryType; + } + + //-------------------------------------------------------------------- + IMPL_LINK( TableControl_Impl, OnScroll, ScrollBar*, _pScrollbar ) + { + DBG_ASSERT( ( _pScrollbar == m_pVScroll ) || ( _pScrollbar == m_pHScroll ), + "TableControl_Impl::OnScroll: where did this come from?" ); + + if ( _pScrollbar == m_pVScroll ) + impl_ni_ScrollRows( _pScrollbar->GetDelta() ); + else + impl_ni_ScrollColumns( _pScrollbar->GetDelta() ); + + return 0L; + } + + //--------------------------------------------------------------------------------------- + TableFunctionSet::TableFunctionSet(TableControl_Impl* _pTableControl): + m_pTableControl( _pTableControl) + ,m_nCurrentRow (-2) + { + } + + TableFunctionSet::~TableFunctionSet() + { + } + + void TableFunctionSet::BeginDrag() + { + } + + void TableFunctionSet::CreateAnchor() + { + m_pTableControl->m_nAnchor = m_pTableControl->m_nCurRow; + } + + void TableFunctionSet::DestroyAnchor() + { + m_pTableControl->m_nAnchor = -1; + } + + BOOL TableFunctionSet::SetCursorAtPoint(const Point& rPoint, BOOL bDontSelectAtCursor) + { + BOOL bHandled = FALSE; + Rectangle rCells; + //curRow is the row where the mouse click happened, m_nCurRow is the last selected row, before the mouse click + RowPos curRow = m_pTableControl->getCurrentRow(rPoint); + if(curRow == -2) + return FALSE; + if( bDontSelectAtCursor ) + { + if(m_pTableControl->m_nRowSelected.size()>1) + m_pTableControl->m_pSelEngine->AddAlways(TRUE); + bHandled = TRUE; + } + else if(m_pTableControl->m_nAnchor == m_pTableControl->m_nCurRow) + { + //selecting region, + int diff = m_pTableControl->m_nCurRow - curRow; + //bool isAlreadySelected = m_pTableControl->isRowSelected(m_pTableControl->m_nRowSelected, m_pTableControl->m_nAnchor); + /* if(!isAlreadySelected && m_nCurrentRow != m_pTableControl->m_nCurRow) + m_pTableControl->m_nRowSelected.push_back(m_nAnchor);*/ + //selected region lies above the last selection + if( diff >= 0) + { + //put selected rows in vector + while(m_pTableControl->m_nAnchor>=curRow) + { + bool isAlreadySelected = m_pTableControl->isRowSelected(m_pTableControl->m_nRowSelected, m_pTableControl->m_nAnchor); + //if row isn't selected, put it in vector, otherwise don't put it there, because it will be twice there + if(!isAlreadySelected) + m_pTableControl->m_nRowSelected.push_back(m_pTableControl->m_nAnchor); + m_pTableControl->m_nAnchor--; + diff--; + } + m_pTableControl->m_nAnchor++; + } + //selected region lies beneath the last selected row + else + { + while(m_pTableControl->m_nAnchor<=curRow) + { + bool isAlreadySelected = m_pTableControl->isRowSelected(m_pTableControl->m_nRowSelected, m_pTableControl->m_nAnchor); + if(!isAlreadySelected) + m_pTableControl->m_nRowSelected.push_back(m_pTableControl->m_nAnchor); + m_pTableControl->m_nAnchor++; + diff++; + } + m_pTableControl->m_nAnchor--; + } + m_pTableControl->invalidateSelectedRegion(m_pTableControl->m_nCurRow, curRow, rCells); + bHandled = TRUE; + } + //no region selected + else + { + if(m_pTableControl->m_nRowSelected.empty()) + { + m_pTableControl->m_nRowSelected.push_back(curRow); + } + else + { + if(m_pTableControl->m_pSelEngine->GetSelectionMode()==SINGLE_SELECTION) + { + DeselectAll(); + m_pTableControl->m_nRowSelected.push_back(curRow); + } + else + { + bool isAlreadySelected = m_pTableControl->isRowSelected(m_pTableControl->m_nRowSelected, curRow); + if(!isAlreadySelected) + m_pTableControl->m_nRowSelected.push_back(curRow); + } + } + if(m_pTableControl->m_nRowSelected.size()>1 && m_pTableControl->m_pSelEngine->GetSelectionMode()!=SINGLE_SELECTION) + m_pTableControl->m_pSelEngine->AddAlways(TRUE); + m_pTableControl->invalidateSelectedRow(curRow,rCells); + bHandled = TRUE; + } + m_pTableControl->m_nCurRow = curRow; + m_pTableControl->ensureVisible(m_pTableControl->m_nCurColumn,m_pTableControl->m_nCurRow,false); + return bHandled; + } + + BOOL TableFunctionSet::IsSelectionAtPoint( const Point& rPoint ) + { + m_pTableControl->m_pSelEngine->AddAlways(FALSE); + if(m_pTableControl->m_nRowSelected.empty()) + return FALSE; + else + { + RowPos curRow = m_pTableControl->getCurrentRow(rPoint); + m_pTableControl->m_nAnchor = -1; + bool selected = m_pTableControl->isRowSelected(m_pTableControl->m_nRowSelected, curRow); + m_nCurrentRow = curRow; + return selected; + } + } + + void TableFunctionSet::DeselectAtPoint( const Point& rPoint ) + { + (void)rPoint; + long pos = 0; + long i = 0; + Rectangle rCells; + for(std::vector<RowPos>::iterator it=m_pTableControl->m_nRowSelected.begin(); + it!=m_pTableControl->m_nRowSelected.end();++it) + { + if(*it == m_nCurrentRow) + { + pos = i; + m_pTableControl->invalidateSelectedRow(*it,rCells); + } + ++i; + } + m_pTableControl->m_nRowSelected.erase(m_pTableControl->m_nRowSelected.begin()+pos); + } + void TableFunctionSet::DeselectAll() + { + if(!m_pTableControl->m_nRowSelected.empty()) + { + Rectangle rCells; + for(std::vector<RowPos>::iterator it=m_pTableControl->m_nRowSelected.begin(); + it!=m_pTableControl->m_nRowSelected.end();++it) + { + m_pTableControl->invalidateSelectedRow(*it,rCells); + } + m_pTableControl->m_nRowSelected.clear(); + } + } + +//........................................................................ +} } // namespace svt::table +//........................................................................ diff --git a/svtools/source/table/tablecontrol_impl.hxx b/svtools/source/table/tablecontrol_impl.hxx new file mode 100644 index 000000000000..410bc8b4c3a1 --- /dev/null +++ b/svtools/source/table/tablecontrol_impl.hxx @@ -0,0 +1,342 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +#ifndef SVTOOLS_TABLECONTROL_IMPL_HXX +#define SVTOOLS_TABLECONTROL_IMPL_HXX + +#ifndef SVTOOLS_INC_TABLE_TABLEMODEL_HXX +#include <svtools/table/tablemodel.hxx> +#endif + +#ifndef SVTOOLS_INC_TABLE_ABSTRACTTABLECONTROL_HXX +#include <svtools/table/abstracttablecontrol.hxx> +#endif + +#include <svtools/table/tablemodel.hxx> +#include <vector> +#include <vcl/seleng.hxx> + +class ScrollBar; +class ScrollBarBox; + +//........................................................................ +namespace svt { namespace table +{ +//........................................................................ + + typedef ::std::vector< long > ArrayOfLong; + + class TableControl; + class TableDataWindow; + class TableFunctionSet; + + //==================================================================== + //= TableControl_Impl + //==================================================================== + class TableControl_Impl : public IAbstractTableControl + { + friend class TableGeometry; + friend class TableRowGeometry; + friend class TableColumnGeometry; + friend class SuspendInvariants; + friend class TableFunctionSet; + private: + /// the control whose impl-instance we implemnt + TableControl& m_rAntiImpl; + /// the model of the table control + PTableModel m_pModel; + /// the input handler to use, usually the input handler as provided by ->m_pModel + PTableInputHandler m_pInputHandler; + /// the widths of the single columns, measured in pixel + ArrayOfLong m_aColumnWidthsPixel; + /** the accumulated widths of the single columns, i.e. their exclusive right borders, + <strong<not</strong> counting the space for a possible row header column + */ + ArrayOfLong m_aAccColumnWidthsPixel; + /// the height of a single row in the table, measured in pixels + long m_nRowHeightPixel; + /// the height of the column header row in the table, measured in pixels + long m_nColHeaderHeightPixel; + /// the width of the row header column in the table, measured in pixels + long m_nRowHeaderWidthPixel; + + /// the number of columns in the table control. Cached model value. + TableSize m_nColumnCount; + /// the number of rows in the table control. Cached model value. + TableSize m_nRowCount; + + ColPos m_nCurColumn; + RowPos m_nCurRow; + ColPos m_nLeftColumn; + RowPos m_nTopRow; + + sal_Int32 m_nCursorHidden; + + /** the window to contain all data content, including header bars + + The window's upper left corner is at position (0,0), relative to the + table control, which is the direct parent of the data window. + */ + TableDataWindow* m_pDataWindow; + /// the vertical scrollbar, if any + ScrollBar* m_pVScroll; + /// the horizontal scrollbar, if any + ScrollBar* m_pHScroll; + ScrollBarBox* m_pScrollCorner; + //selection engine - for determining selection range, e.g. single, multiple + SelectionEngine* m_pSelEngine; + //vector which contains the selected rows + std::vector<RowPos> m_nRowSelected; + //part of selection engine + TableFunctionSet* m_pTableFunctionSet; + //part of selection engine + RowPos m_nAnchor; + + + +#if DBG_UTIL + #define INV_SCROLL_POSITION 1 + /** represents a bitmask of invariants to check + + Actually, impl_checkInvariants checks more invariants than denoted in this + bit mask, but only those present here can be disabled temporarily. + */ + sal_Int32 m_nRequiredInvariants; +#endif + + public: + + + PTableModel getModel() const; + void setModel( PTableModel _pModel ); + + inline const PTableInputHandler& getInputHandler() const { return m_pInputHandler; } + + inline ColPos getCurColumn() const { return m_nCurColumn; } + inline RowPos getCurRow() const { return m_nCurRow; } + inline void setCurRow(RowPos curRow){ m_nCurRow = curRow; } + inline RowPos getTopRow() const { return m_nTopRow; } + + inline long getColHeaderHightPixel() const { return m_nColHeaderHeightPixel; } + + inline const TableControl& getAntiImpl() const { return m_rAntiImpl; } + inline TableControl& getAntiImpl() { return m_rAntiImpl; } + void setCellContent(CellEntryType* pCellEntryType); + + public: + TableControl_Impl( TableControl& _rAntiImpl ); + ~TableControl_Impl(); + +#if DBG_UTIL + const sal_Char* impl_checkInvariants() const; +#endif + /** to be called when the anti-impl instance has been resized + */ + void onResize(); + + /** paints the table control content which intersects with the given rectangle + */ + void doPaintContent( const Rectangle& _rUpdateRect ); + + /** moves the cursor to the cell with the given coordinates + + To ease the caller's code, the coordinates must not necessarily denote a + valid position. If they don't, <FALSE/> will be returned. + */ + bool goTo( ColPos _nColumn, RowPos _nRow ); + + /** ensures that the given coordinate is visible + @param _nColumn + the column position which should be visible. Must be non-negative, and smaller + than the column count. + @param _nRow + the row position which should be visibleMust be non-negative, and smaller + than the row count. + @param _bAcceptPartialVisibility + <TRUE/> if it's okay that the given cooordinate is only partially visible + */ + void ensureVisible( ColPos _nColumn, RowPos _nRow, bool _bAcceptPartialVisibility ); + /** returns the row, which contains the input point*/ + RowPos getCurrentRow (const Point& rPoint); + + void setCursorAtCurrentCell(const Point& rPoint); + /** proves whether the vector with the selected rows contains the current row*/ + BOOL isRowSelected(::std::vector<RowPos> selectedRows, RowPos current); + /** returns the position of the current row in the selecttion vector */ + int getRowSelectedNumber(::std::vector<RowPos> selectedRows, RowPos current); + /** _rCellRect contains the region, which should be invalidate after some action e.g. selectiong row*/ + void invalidateSelectedRegion(RowPos _nPrevRow, RowPos _nCurRow, Rectangle& _rCellRect ); + /** _rCellRect contains the region, which should be invalidate after some action e.g. selectiong row*/ + //vielleicht kann man mit den anderen verschmelzen, mit einer berprfung ob prev==curr? + void invalidateSelectedRow( RowPos _nCurRow, Rectangle& _rCellRect ); + /** to be called when a new row is added to the control*/ + void invalidateRow(RowPos _nRowPos, Rectangle& _rCellRect ); + /** returns the vector, which contains the selected rows*/ + std::vector<RowPos> getSelectedRows(); + /** updates the vector, which contains the selected rows after removing the row nRowPos*/ + void removeSelectedRow(RowPos _nRowPos); + void invalidateRows(RowPos _nRowStart, Rectangle& _rCellRect ); + //virtual void DoubleClick(); + + // IAbstractTableControl + virtual void hideCursor(); + virtual void showCursor(); + virtual bool dispatchAction( TableControlAction _eAction ); + virtual bool isClickInVisibleArea(const Point& rPoint); + virtual SelectionEngine* getSelEngine(); + + TableDataWindow* getDataWindow(); + + private: + /** toggles the cursor visibility + + The method is not bound to the classes public invariants, as it's used in + situations where the they must not necessarily be fullfilled. + */ + void impl_ni_doSwitchCursor( bool _bOn ); + + /** retrieves the area occupied by the totality of (at least partially) visible cells + + The returned area includes row and column headers. Also, it takes into + account the the fact that there might be less columns than would normally + find room in the control. + + As a result of respecting the partial visibility of rows and columns, + the returned area might be larger than the data window's output size. + */ + void impl_getAllVisibleCellsArea( Rectangle& _rCellArea ) const; + + /** retrieves the area occupied by all (at least partially) visible data cells. + + Effectively, the returned area is the same as returned by ->impl_getAllVisibleCellsArea, + minus the row and column header areas. + */ + void impl_getAllVisibleDataCellArea( Rectangle& _rCellArea ) const; + + /** returns the number of visible rows. + + @param _bAcceptPartialRow + specifies whether a possible only partially visible last row is + counted, too. + */ + TableSize impl_getVisibleRows( bool _bAcceptPartialRow ) const; + + /** returns the number of visible columns + + The value may change with different horizontal scroll positions, as + different columns have different widths. For instance, if your control is + 100 pixels wide, and has three columns of width 50, 50, 100, respectively, + then this method will return either "2" or "1", depending on which column + is the first visible one. + + @param _bAcceptPartialRow + specifies whether a possible only partially visible last row is + counted, too. + */ + TableSize impl_getVisibleColumns( bool _bAcceptPartialRow ) const; + + /** determines the rectangle occupied by the given cell + */ + void impl_getCellRect( ColPos _nColumn, RowPos _nRow, Rectangle& _rCellRect ) const; + + /** updates all cached model values + + The method is not bound to the classes public invariants, as it's used in + situations where the they must not necessarily be fullfilled. + */ + void impl_ni_updateCachedModelValues(); + + /** updates ->m_aColumnWidthsPixel with the current pixel widths of all model columns + + The method takes into account the current zoom factor and map mode of the table + control, plus any possible COLWIDTH_FIT_TO_VIEW widths in the model columns. + + The method is not bound to the classes public invariants, as it's used in + situations where the they must not necessarily be fullfilled. + */ + void impl_ni_updateColumnWidths(); + + /** updates the scrollbars of the 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. + + This includes both the existence of the scrollbars, and their + state. + */ + void impl_ni_updateScrollbars(); + + /** scrolls the view by the given number of rows + + The method is not bound to the classes public invariants, as it's used in + situations where the they must not necessarily be fullfilled. + + @return + the number of rows by which the viewport was scrolled. This may differ + from the given numbers to scroll in case the begin or the end of the + row range were reached. + */ + TableSize impl_ni_ScrollRows( TableSize _nRowDelta ); + + /** scrolls the view by the given number of columns + + The method is not bound to the classes public invariants, as it's used in + situations where the they must not necessarily be fullfilled. + + @return + the number of columns by which the viewport was scrolled. This may differ + from the given numbers to scroll in case the begin or the end of the + column range were reached. + */ + TableSize impl_ni_ScrollColumns( TableSize _nRowDelta ); + + DECL_LINK( OnScroll, ScrollBar* ); + }; + //see seleng.hxx, seleng.cxx, FunctionSet overwritables, part of selection engine + class TableFunctionSet : public FunctionSet + { + friend class TableDataWindow; + private: + TableControl_Impl* m_pTableControl; + RowPos m_nCurrentRow; + public: + TableFunctionSet(TableControl_Impl* _pTableControl); + virtual ~TableFunctionSet(); + + virtual void BeginDrag(); + virtual void CreateAnchor(); + virtual void DestroyAnchor(); + virtual BOOL SetCursorAtPoint(const Point& rPoint, BOOL bDontSelectAtCursor); + virtual BOOL IsSelectionAtPoint( const Point& rPoint ); + virtual void DeselectAtPoint( const Point& rPoint ); + virtual void DeselectAll(); + }; + + +//........................................................................ +} } // namespace svt::table +//........................................................................ + +#endif // SVTOOLS_TABLECONTROL_IMPL_HXX diff --git a/svtools/source/table/tabledatawindow.cxx b/svtools/source/table/tabledatawindow.cxx new file mode 100644 index 000000000000..71a313bb2e00 --- /dev/null +++ b/svtools/source/table/tabledatawindow.cxx @@ -0,0 +1,81 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +#include "svtools/table/tablecontrol.hxx" +#include "svtools/table/tabledatawindow.hxx" +#include "tablecontrol_impl.hxx" + +//........................................................................ +namespace svt { namespace table +{ + class TableControl_Impl; +//........................................................................ + + //==================================================================== + //= TableDataWindow + //==================================================================== + //-------------------------------------------------------------------- + TableDataWindow::TableDataWindow( TableControl_Impl& _rTableControl ) + :Window( &_rTableControl.getAntiImpl() ) + ,m_rTableControl ( _rTableControl ) + { + Color backgroundColor = m_rTableControl.getAntiImpl().GetSettings().GetStyleSettings().GetFieldColor(); + SetBackground( backgroundColor ); + SetControlBackground( backgroundColor ); + } + + //-------------------------------------------------------------------- + void TableDataWindow::Paint( const Rectangle& rUpdateRect ) + { + m_rTableControl.doPaintContent( rUpdateRect ); + } + void TableDataWindow::MouseMove( const MouseEvent& rMEvt ) + { + if ( !m_rTableControl.getInputHandler()->MouseMove( m_rTableControl, rMEvt ) ) + Window::MouseMove( rMEvt ); + } + void TableDataWindow::MouseButtonDown( const MouseEvent& rMEvt ) + { + if ( !m_rTableControl.getInputHandler()->MouseButtonDown( m_rTableControl, rMEvt ) ) + Window::MouseButtonDown( rMEvt ); + else + m_aMouseButtonDownHdl.Call( (MouseEvent*) &rMEvt); + m_rTableControl.getAntiImpl().LoseFocus(); + } + void TableDataWindow::MouseButtonUp( const MouseEvent& rMEvt ) + { + if ( !m_rTableControl.getInputHandler()->MouseButtonUp( m_rTableControl, rMEvt ) ) + Window::MouseButtonUp( rMEvt ); + else + m_aMouseButtonUpHdl.Call( (MouseEvent*) &rMEvt); + m_rTableControl.getAntiImpl().GetFocus(); + } + +//........................................................................ +} } // namespace svt::table +//........................................................................ diff --git a/svtools/source/table/tablegeometry.cxx b/svtools/source/table/tablegeometry.cxx new file mode 100644 index 000000000000..569e14c61726 --- /dev/null +++ b/svtools/source/table/tablegeometry.cxx @@ -0,0 +1,130 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + + +#include "tablegeometry.hxx" +#include "tablecontrol_impl.hxx" + +#include <tools/debug.hxx> + +//........................................................................ +namespace svt { namespace table +{ +//........................................................................ + + //==================================================================== + //= TableRowGeometry + //==================================================================== + //-------------------------------------------------------------------- + TableRowGeometry::TableRowGeometry( const TableControl_Impl& _rControl, const Rectangle& _rBoundaries, + RowPos _nRow ) + :TableGeometry( _rControl, _rBoundaries ) + ,m_nRowPos( _nRow ) + { + if ( m_nRowPos == ROW_COL_HEADERS ) + { + DBG_ASSERT( m_rControl.m_pModel->hasColumnHeaders(), + "TableRowGeometry::TableRowGeometry: why asking for the geoemtry of the non-existent column header row?" ); + m_aRect.Top() = 0; + m_aRect.Bottom() = m_rControl.m_nColHeaderHeightPixel - 1; + } + else + { + if ( ( m_nRowPos >= m_rControl.m_nTopRow ) && ( m_nRowPos < m_rControl.m_pModel->getRowCount() ) ) + { + m_aRect.Top() = m_rControl.m_nColHeaderHeightPixel + ( m_nRowPos - m_rControl.m_nTopRow ) * m_rControl.m_nRowHeightPixel; + m_aRect.Bottom() = m_aRect.Top() + m_rControl.m_nRowHeightPixel - 1; + } + else + m_aRect.SetEmpty(); + } + } + + //-------------------------------------------------------------------- + bool TableRowGeometry::moveDown() + { + if ( ++m_nRowPos < m_rControl.m_pModel->getRowCount() ) + m_aRect.Move( 0, m_rControl.m_nRowHeightPixel ); + else + m_aRect.SetEmpty(); + return isValid(); + } + + //==================================================================== + //= TableColumnGeometry + //==================================================================== + //-------------------------------------------------------------------- + TableColumnGeometry::TableColumnGeometry( const TableControl_Impl& _rControl, const Rectangle& _rBoundaries, + ColPos _nCol ) + :TableGeometry( _rControl, _rBoundaries ) + ,m_nColPos( _nCol ) + { + if ( m_nColPos == COL_ROW_HEADERS ) + { + DBG_ASSERT( m_rControl.m_pModel->hasRowHeaders(), + "TableColumnGeometry::TableColumnGeometry: why asking for the geoemtry of the non-existent row header column?" ); + m_aRect.Left() = 0; + m_aRect.Right() = m_rControl.m_nRowHeaderWidthPixel - 1; + } + else + { + ColPos nLeftColumn = m_rControl.m_nLeftColumn; + if ( ( m_nColPos >= nLeftColumn ) && ( m_nColPos < (ColPos)m_rControl.m_aColumnWidthsPixel.size() ) ) + { + m_aRect.Left() = m_rControl.m_nRowHeaderWidthPixel; + // TODO: take into account any possibly frozen columns + + for ( ColPos col = nLeftColumn; col < m_nColPos; ++col ) + m_aRect.Left() += m_rControl.m_aColumnWidthsPixel[ col ]; + m_aRect.Right() = m_aRect.Left() + m_rControl.m_aColumnWidthsPixel[ m_nColPos ] - 1; + } + else + m_aRect.SetEmpty(); + } + } + + //-------------------------------------------------------------------- + bool TableColumnGeometry::moveRight() + { + DBG_ASSERT( m_nColPos != COL_ROW_HEADERS, "TableColumnGeometry::moveRight: cannot move the row header column!" ); + // what would be COL_ROW_HEADERS + 1? + + if ( ++m_nColPos < (ColPos)m_rControl.m_aColumnWidthsPixel.size() ) + { + m_aRect.Left() = m_aRect.Right() + 1; + m_aRect.Right() += m_rControl.m_aColumnWidthsPixel[ m_nColPos ]; + } + else + m_aRect.SetEmpty(); + + return isValid(); + } + +//........................................................................ +} } // namespace svt::table +//........................................................................ diff --git a/svtools/source/table/tablegeometry.hxx b/svtools/source/table/tablegeometry.hxx new file mode 100644 index 000000000000..18b40c1e3781 --- /dev/null +++ b/svtools/source/table/tablegeometry.hxx @@ -0,0 +1,161 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +#ifndef SVTOOLS_TABLEGEOMETRY_HXX +#define SVTOOLS_TABLEGEOMETRY_HXX + +#ifndef SVTOOLS_INC_TABLE_TABLETYPES_HXX +#include <svtools/table/tabletypes.hxx> +#endif + +#ifndef _SV_GEN_HXX +#include <tools/gen.hxx> +#endif + +//........................................................................ +namespace svt { namespace table +{ +//........................................................................ + + class TableControl_Impl; + + //==================================================================== + //= TableGeometry + //==================================================================== + class TableGeometry + { + protected: + const TableControl_Impl& m_rControl; + const Rectangle& m_rBoundaries; + Rectangle m_aRect; + + protected: + TableGeometry( + const TableControl_Impl& _rControl, + const Rectangle& _rBoundaries + ) + :m_rControl( _rControl ) + ,m_rBoundaries( _rBoundaries ) + ,m_aRect( _rBoundaries ) + { + } + + public: + // attribute access + const TableControl_Impl& getControl() const { return m_rControl; } + + // status + const Rectangle& getRect() const { return m_aRect; } + bool isValid() const { return !m_aRect.GetIntersection( m_rBoundaries ).IsEmpty(); } + }; + + //==================================================================== + //= TableRowGeometry + //==================================================================== + class TableRowGeometry : public TableGeometry + { + protected: + RowPos m_nRowPos; + + public: + TableRowGeometry( + const TableControl_Impl& _rControl, + const Rectangle& _rBoundaries, + RowPos _nRow + ); + + // status + RowPos getRow() const { return m_nRowPos; } + // operations + bool moveDown(); + }; + + //==================================================================== + //= TableColumnGeometry + //==================================================================== + class TableColumnGeometry : public TableGeometry + { + protected: + ColPos m_nColPos; + + public: + TableColumnGeometry( + const TableControl_Impl& _rControl, + const Rectangle& _rBoundaries, + ColPos _nCol + ); + + // status + ColPos getCol() const { return m_nColPos; } + // operations + bool moveRight(); + }; + + //==================================================================== + //= TableCellGeometry + //==================================================================== + /** a helper representing geometry information of a cell + */ + class TableCellGeometry + { + private: + TableRowGeometry m_aRow; + TableColumnGeometry m_aCol; + + public: + TableCellGeometry( + const TableControl_Impl& _rControl, + const Rectangle& _rBoundaries, + ColPos _nCol, + RowPos _nRow + ) + :m_aRow( _rControl, _rBoundaries, _nRow ) + ,m_aCol( _rControl, _rBoundaries, _nCol ) + { + } + + TableCellGeometry( + const TableRowGeometry& _rRow, + ColPos _nCol + ) + :m_aRow( _rRow ) + ,m_aCol( _rRow.getControl(), _rRow.getRect(), _nCol ) + { + } + + inline Rectangle getRect() const { return m_aRow.getRect().GetIntersection( m_aCol.getRect() ); } + inline RowPos getRow() const { return m_aRow.getRow(); } + inline ColPos getColumn() const { return m_aCol.getCol(); } + inline bool isValid() const { return !getRect().IsEmpty(); } + + inline bool moveDown() {return m_aRow.moveDown(); } + inline bool moveRight() {return m_aCol.moveRight(); } + }; + +//........................................................................ +} } // namespace svt::table +//........................................................................ + +#endif // SVTOOLS_TABLEGEOMETRY_HXX diff --git a/svtools/source/uno/makefile.mk b/svtools/source/uno/makefile.mk index 76ab335d58d5..51e55a1f9123 100644 --- a/svtools/source/uno/makefile.mk +++ b/svtools/source/uno/makefile.mk @@ -1,4 +1,4 @@ - +#************************************************************************* # # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # @@ -55,6 +55,7 @@ SLOFILES= \ $(SLO)$/genericunodialog.obj \ $(SLO)$/generictoolboxcontroller.obj \ $(SLO)$/treecontrolpeer.obj \ + $(SLO)$/unocontroltablemodel.obj \ $(SLO)$/registerservices.obj\ $(SLO)$/contextmenuhelper.obj diff --git a/svtools/source/uno/unocontroltablemodel.cxx b/svtools/source/uno/unocontroltablemodel.cxx new file mode 100644 index 000000000000..e322dbb8f96e --- /dev/null +++ b/svtools/source/uno/unocontroltablemodel.cxx @@ -0,0 +1,812 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: unocontroltablemodel.cxx,v $ + * $Revision: 1.32 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +#include "unocontroltablemodel.hxx" +#include <com/sun/star/view/SelectionType.hpp> +#include "svtools/table/gridtablerenderer.hxx" +#include "svtools/table/defaultinputhandler.hxx" +#include "svtools/table/tablecontrol.hxx" +#include <comphelper/sequence.hxx> +#include <rtl/ref.hxx> +#include <tools/debug.hxx> +#include <toolkit/helper/property.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/awt/grid/XGridColumn.hpp> + +using ::rtl::OUString; +using namespace ::svt::table; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt::grid; + +using namespace ::svt::table; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::view; +using namespace ::toolkit; + +class UnoControlTableColumn : public IColumnModel + { + private: + ColumnID m_nID; + String m_sName; + bool m_bIsResizable; + TableMetrics m_nWidth; + TableMetrics m_nMinWidth; + TableMetrics m_nMaxWidth; + + public: + UnoControlTableColumn(Reference<XGridColumn>); + + // IColumnModel overridables + virtual ColumnID getID() const; + virtual bool setID( const ColumnID _nID ); + virtual String getName() const; + virtual void setName( const String& _rName ); + virtual bool isResizable() const; + virtual void setResizable( bool _bResizable ); + virtual TableMetrics getWidth() const; + virtual void setWidth( TableMetrics _nWidth ); + virtual TableMetrics getMinWidth() const; + virtual void setMinWidth( TableMetrics _nMinWidth ); + virtual TableMetrics getMaxWidth() const; + virtual void setMaxWidth( TableMetrics _nMaxWidth ); + }; + + //-------------------------------------------------------------------- + UnoControlTableColumn::UnoControlTableColumn(Reference<XGridColumn> m_xGridColumn) + :m_nID( 0 ) + ,m_sName() + ,m_bIsResizable( false ) + ,m_nWidth( 10 * 100 ) // 1 cm + ,m_nMinWidth( 0 ) // no min width + ,m_nMaxWidth( 0 ) // no max width + { + //m_nID = m_xGridColumn->getIdentifier(); + //m_nWidth = m_xGridColumn->getColumnWidth(); + m_sName = m_xGridColumn->getTitle(); + } + + //-------------------------------------------------------------------- + ColumnID UnoControlTableColumn::getID() const + { + return m_nID; + } + + //-------------------------------------------------------------------- + bool UnoControlTableColumn::setID( const ColumnID _nID ) + { + // TODO: conflict check + + m_nID = _nID; + // TODO: notifications? + + return true; + } + + //-------------------------------------------------------------------- + String UnoControlTableColumn::getName() const + { + return m_sName; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setName( const String& _rName ) + { + m_sName = _rName; + // TODO: notifications? + } + + //-------------------------------------------------------------------- + bool UnoControlTableColumn::isResizable() const + { + return m_bIsResizable; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setResizable( bool _bResizable ) + { + m_bIsResizable = _bResizable; + // TODO: notifications? + } + + //-------------------------------------------------------------------- + TableMetrics UnoControlTableColumn::getWidth() const + { + return m_nWidth; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setWidth( TableMetrics _nWidth ) + { + m_nWidth = _nWidth; + // TODO: notifications? + } + + //-------------------------------------------------------------------- + TableMetrics UnoControlTableColumn::getMinWidth() const + { + return m_nMinWidth; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setMinWidth( TableMetrics _nMinWidth ) + { + m_nMinWidth = _nMinWidth; + // TODO: notifications? + } + + //-------------------------------------------------------------------- + TableMetrics UnoControlTableColumn::getMaxWidth() const + { + return m_nMaxWidth; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setMaxWidth( TableMetrics _nMaxWidth ) + { + m_nMaxWidth = _nMaxWidth; + // TODO: notifications? + } + + //==================================================================== + //= DefaultTableModel_Impl + //==================================================================== + struct UnoControlTableModel_Impl + { + ::std::vector< PColumnModel > aColumns; + TableSize nRowCount; + bool bHasColumnHeaders; + bool bHasRowHeaders; + PTableRenderer pRenderer; + PTableInputHandler pInputHandler; + TableMetrics nRowHeight; + TableMetrics nColumnHeaderHeight; + TableMetrics nRowHeaderWidth; + std::vector<rtl::OUString> aRowHeadersTitle; + std::vector<std::vector<rtl::OUString> > aCellContent; + + UnoControlTableModel_Impl() + :nRowCount ( 0 ) + ,bHasColumnHeaders ( false ) + ,bHasRowHeaders ( false ) + ,pRenderer ( ) + ,pInputHandler ( ) + ,nRowHeight ( 4 * 100 ) // 40 mm + ,nColumnHeaderHeight( 5 * 100 ) // 50 mm + ,nRowHeaderWidth ( 10 * 100 ) // 50 mm + ,aRowHeadersTitle ( 0 ) + ,aCellContent ( 0 ) + { + } + }; + + //==================================================================== + //= UnoControlTableModel + //==================================================================== + //-------------------------------------------------------------------- + UnoControlTableModel::UnoControlTableModel() + :m_pImpl( new UnoControlTableModel_Impl ), + m_xDataModel(0), + m_xColumnModel(0), + m_bHasColumnHeaders(false), + m_bHasRowHeaders(false), + m_bVScroll(false), + m_bHScroll(false) + { + m_pImpl->bHasColumnHeaders = m_bHasColumnHeaders; + m_pImpl->bHasRowHeaders = m_bHasRowHeaders; + m_pImpl->pRenderer.reset( new GridTableRenderer( *this ) ); + m_pImpl->pInputHandler.reset( new DefaultInputHandler ); + } + + //-------------------------------------------------------------------- + UnoControlTableModel::~UnoControlTableModel() + { + DELETEZ( m_pImpl ); + } + + //-------------------------------------------------------------------- + TableSize UnoControlTableModel::getColumnCount() const + { + m_pImpl->aColumns.resize( m_xColumnModel->getColumnCount()); + return (TableSize)m_pImpl->aColumns.size(); + } + + //-------------------------------------------------------------------- + TableSize UnoControlTableModel::getRowCount() const + { + return m_pImpl->nRowCount; + } + + //-------------------------------------------------------------------- + bool UnoControlTableModel::hasColumnHeaders() const + { + return m_pImpl->bHasColumnHeaders; + } + + //-------------------------------------------------------------------- + bool UnoControlTableModel::hasRowHeaders() const + { + return m_pImpl->bHasRowHeaders; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setRowHeaders(bool _bRowHeaders) + { + m_pImpl->bHasRowHeaders = _bRowHeaders; + } + //-------------------------------------------------------------------- + void UnoControlTableModel::setColumnHeaders(bool _bColumnHeaders) + { + m_pImpl->bHasColumnHeaders = _bColumnHeaders; + } + + void UnoControlTableModel::setColumnCount(TableSize _nColCount) + { + m_pImpl->aColumns.resize( _nColCount); + } + //-------------------------------------------------------------------- + void UnoControlTableModel::setRowCount(TableSize _nRowCount) + { + m_pImpl->nRowCount = _nRowCount; + } + //-------------------------------------------------------------------- + bool UnoControlTableModel::isCellEditable( ColPos col, RowPos row ) const + { + (void)col; + (void)row; + return false; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::addTableModelListener( const PTableModelListener& listener ) + { + (void) listener; + //listener->onTableModelChanged(PTableModel(this)); + // TODO + DBG_ERROR( "DefaultTableModel::addTableModelListener: not yet implemented!" ); + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::removeTableModelListener( const PTableModelListener& listener ) + { + (void)listener; + // TODO + DBG_ERROR( "DefaultTableModel::removeTableModelListener: not yet implemented!" ); + } + + //-------------------------------------------------------------------- + PColumnModel UnoControlTableModel::getColumnModel( ColPos column ) + { + DBG_ASSERT( ( column >= 0 ) && ( column < getColumnCount() ), + "DefaultTableModel::getColumnModel: invalid index!" ); + return m_pImpl->aColumns[ column ]; + } + + //-------------------------------------------------------------------- + PColumnModel UnoControlTableModel::getColumnModelByID( ColumnID id ) + { + (void)id; + // TODO + DBG_ERROR( "DefaultTableModel::getColumnModelByID: not yet implemented!" ); + return PColumnModel(); + } + + //-------------------------------------------------------------------- + PTableRenderer UnoControlTableModel::getRenderer() const + { + return m_pImpl->pRenderer; + } + + //-------------------------------------------------------------------- + PTableInputHandler UnoControlTableModel::getInputHandler() const + { + return m_pImpl->pInputHandler; + } + + //-------------------------------------------------------------------- + TableMetrics UnoControlTableModel::getRowHeight() const + { + return m_pImpl->nRowHeight; + } + //-------------------------------------------------------------------- + void UnoControlTableModel::setRowHeight(TableMetrics _nRowHeight) + { + m_pImpl->nRowHeight = _nRowHeight; + } + + //-------------------------------------------------------------------- + TableMetrics UnoControlTableModel::getColumnHeaderHeight() const + { + DBG_ASSERT( hasColumnHeaders(), "DefaultTableModel::getColumnHeaderHeight: invalid call!" ); + return m_pImpl->nColumnHeaderHeight; + } + + //-------------------------------------------------------------------- + TableMetrics UnoControlTableModel::getRowHeaderWidth() const + { + DBG_ASSERT( hasRowHeaders(), "DefaultTableModel::getRowHeaderWidth: invalid call!" ); + return m_pImpl->nRowHeaderWidth; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::SetTitleHeight( TableMetrics _nHeight ) + { + DBG_ASSERT( _nHeight > 0, "DefaultTableModel::SetTitleHeight: invalid height value!" ); + m_pImpl->nColumnHeaderHeight = _nHeight; + // TODO: notification + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::SetHandleWidth( TableMetrics _nWidth ) + { + DBG_ASSERT( _nWidth > 0, "DefaultTableModel::SetHandleWidth: invalid width value!" ); + m_pImpl->nRowHeaderWidth = _nWidth; + // TODO: notification + } + + //-------------------------------------------------------------------- + ScrollbarVisibility UnoControlTableModel::getVerticalScrollbarVisibility(int overAllHeight, int actHeight) const + { + if(overAllHeight>=actHeight && !m_bVScroll) + return ScrollbarShowNever; + else + return ScrollbarShowAlways; + } + + //-------------------------------------------------------------------- + ScrollbarVisibility UnoControlTableModel::getHorizontalScrollbarVisibility(int overAllWidth, int actWidth) const + { + if(overAllWidth>=actWidth && !m_bHScroll) + return ScrollbarShowNever; + else + return ScrollbarShowAlways; + } + //-------------------------------------------------------------------- + void UnoControlTableModel::setCellContent(std::vector<std::vector<rtl::OUString> > cellContent) + { + if(cellContent.empty()) + { + unsigned int i = m_pImpl->aColumns.size(); + std::vector<rtl::OUString> emptyCells; + while(i!=0) + { + cellContent.push_back(emptyCells); + --i; + } + } + std::vector<rtl::OUString> cCC; + for(::std::vector<std::vector<rtl::OUString> >::iterator iter = cellContent.begin(); iter!= cellContent.end();++iter) + { + cCC = *iter; + m_pImpl->aCellContent.push_back(cCC); + } + } + + std::vector<std::vector<rtl::OUString> > UnoControlTableModel::getCellContent() + { + return m_pImpl->aCellContent; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setRowHeaderName(std::vector<rtl::OUString> cellColumnContent) + { + if(cellColumnContent.empty()) + { + unsigned int i = m_pImpl->aColumns.size(); + while(i!=0) + { + cellColumnContent.push_back(rtl::OUString::createFromAscii("")); + --i; + } + } + for(::std::vector<rtl::OUString>::iterator iter = cellColumnContent.begin(); iter!= cellColumnContent.end();++iter) + { + rtl::OUString s = *iter; + m_pImpl->aRowHeadersTitle.push_back(*iter); + } + } + + std::vector<rtl::OUString> UnoControlTableModel::getRowHeaderName() + { + return m_pImpl->aRowHeadersTitle; + } + +::com::sun::star::uno::Any UnoControlTableModel::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( ::com::sun::star::awt::grid::XGridControl*, this ), + SAL_STATIC_CAST( ::com::sun::star::awt::grid::XGridDataListener*, this ), + //SAL_STATIC_CAST( com::sun::star::lang::XEventListener*, this ), + //SAL_STATIC_CAST( com::sun::star::awt::XMouseListener*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) ); + return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType )); +} + +// ::com::sun::star::lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( UnoControlTableModel ) + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridControl>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener>* ) NULL ), + VCLXWindow::getTypes() +IMPL_XTYPEPROVIDER_END + +::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel > SAL_CALL UnoControlTableModel::getColumnModel( ) throw (::com::sun::star::uno::RuntimeException) +{ + return NULL; +} +void SAL_CALL UnoControlTableModel::setColumnModel( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel >& model ) throw (::com::sun::star::uno::RuntimeException) +{ + (void)model; +} +::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel > SAL_CALL UnoControlTableModel::getDataModel( ) throw (::com::sun::star::uno::RuntimeException) +{ + return NULL; +} +void SAL_CALL UnoControlTableModel::setDataModel( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel >& model ) throw (::com::sun::star::uno::RuntimeException) +{ + (void)model; +} +sal_Int32 SAL_CALL UnoControlTableModel::getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTableControl = (TableControl*)GetWindow(); + return pTableControl->GetCurrentRow( Point(x,y) ); +} + +/* +void SAL_CALL UnoControlTableModel::addMouseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & listener ) throw(::com::sun::star::uno::RuntimeException) +{ + VCLXWindow::addMouseListener( listener ); +} + +void SAL_CALL UnoControlTableModel::removeMouseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & listener ) throw(::com::sun::star::uno::RuntimeException) +{ + VCLXWindow::removeMouseListener( listener ); +} +*/ +/* +void SAL_CALL UnoControlTableModel::mousePressed( const ::com::sun::star::awt::MouseEvent& rEvent ) throw(::com::sun::star::uno::RuntimeException) +{ + (void)rEvent; +} +void SAL_CALL UnoControlTableModel::mouseReleased( const ::com::sun::star::awt::MouseEvent& rEvent ) throw(::com::sun::star::uno::RuntimeException) +{ + (void)rEvent; +} +void SAL_CALL UnoControlTableModel::mouseEntered( const ::com::sun::star::awt::MouseEvent& rEvent ) throw(::com::sun::star::uno::RuntimeException) +{ + (void) rEvent; +} +void SAL_CALL UnoControlTableModel::mouseExited( const ::com::sun::star::awt::MouseEvent& rEvent ) throw(::com::sun::star::uno::RuntimeException) +{ + (void) rEvent; +} +*/ +void SAL_CALL UnoControlTableModel::addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException) +{ + (void)listener; +} + +void SAL_CALL UnoControlTableModel::removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException) +{ + (void) listener; +} + +void UnoControlTableModel::setProperty( const ::rtl::OUString& PropertyName, const Any& aValue) throw(RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTableControl = (TableControl*)GetWindow(); + + switch( GetPropertyId( PropertyName ) ) + { + case BASEPROPERTY_GRID_SELECTIONMODE: + { + SelectionType eSelectionType; + if( aValue >>= eSelectionType ) + { + SelectionMode eSelMode; + switch( eSelectionType ) + { + case SelectionType_SINGLE: eSelMode = SINGLE_SELECTION; break; + case SelectionType_RANGE: eSelMode = RANGE_SELECTION; break; + case SelectionType_MULTI: eSelMode = MULTIPLE_SELECTION; break; + // case SelectionType_NONE: + default: eSelMode = NO_SELECTION; break; + } + if( pTableControl->getSelEngine()->GetSelectionMode() != eSelMode ) + pTableControl->getSelEngine()->SetSelectionMode( eSelMode ); + } + break; + } + case BASEPROPERTY_HSCROLL: + { + sal_Bool bHScroll = true; + if( aValue >>= bHScroll ) + { + m_bHScroll = bHScroll; + } + break; + } + case BASEPROPERTY_VSCROLL: + { + sal_Bool bVScroll = true; + if( aValue >>= bVScroll ) + { + m_bVScroll = bVScroll; + } + break; + } + case BASEPROPERTY_GRID_SHOWROWHEADER: + { + sal_Bool rowHeader = true; + if( aValue >>= rowHeader ) + { + setRowHeaders(rowHeader); + } + break; + } + + case BASEPROPERTY_GRID_SHOWCOLUMNHEADER: + { + sal_Bool colHeader = true; + if( aValue >>= colHeader ) + { + setColumnHeaders(colHeader); + } + break; + } + case BASEPROPERTY_GRID_DATAMODEL: + { + m_xDataModel = Reference< XGridDataModel >( aValue, UNO_QUERY ); + Sequence<Sequence< ::rtl::OUString > > cellData = m_xDataModel->getData(); + Sequence<rtl::OUString> rowData(0); + for(int i = 0; i< m_xDataModel->getRowCount();++i) + { + rowData = cellData[i]; + std::vector<rtl::OUString> newRow( + comphelper::sequenceToContainer< std::vector<rtl::OUString > >(rowData)); + if(newRow.size()<m_pImpl->aColumns.size()) + newRow.resize(m_pImpl->aColumns.size(),rtl::OUString::createFromAscii("")); + m_pImpl->aCellContent.push_back(newRow); + } + Sequence< ::rtl::OUString > rowHeaders = m_xDataModel->getRowHeaders(); + std::vector< rtl::OUString > newRow( + comphelper::sequenceToContainer< std::vector<rtl::OUString > >(rowHeaders)); + m_pImpl->nRowCount = m_xDataModel->getRowCount(); + setRowHeaderName(newRow); + break; + } + case BASEPROPERTY_GRID_COLUMNMODEL: + { + m_xColumnModel = Reference< XGridColumnModel >( aValue, UNO_QUERY ); + Sequence<Reference< XGridColumn > > columns = m_xColumnModel->getColumns(); + std::vector<Reference< XGridColumn > > aNewColumns( + comphelper::sequenceToContainer<std::vector<Reference< XGridColumn > > >(columns)); + if(!m_pImpl->aColumns.empty()) + m_pImpl->aColumns.clear(); + for ( ::svt::table::ColPos col = 0; col < m_xColumnModel->getColumnCount(); ++col ) + { + UnoControlTableColumn* tableColumn = new UnoControlTableColumn(aNewColumns[col]); + m_pImpl->aColumns.push_back((PColumnModel)tableColumn); + } + break; + } + default: + VCLXWindow::setProperty( PropertyName, aValue ); + break; + } +} + +Any UnoControlTableModel::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + const sal_uInt16 nPropId = GetPropertyId( PropertyName ); + TableControl* pTableControl = (TableControl*)GetWindow(); + if(pTableControl) + { + switch(nPropId) + { + case BASEPROPERTY_GRID_SELECTIONMODE: + { + SelectionType eSelectionType; + + SelectionMode eSelMode = pTableControl->getSelEngine()->GetSelectionMode(); + switch( eSelMode ) + { + case SINGLE_SELECTION: eSelectionType = SelectionType_SINGLE; break; + case RANGE_SELECTION: eSelectionType = SelectionType_RANGE; break; + case MULTIPLE_SELECTION:eSelectionType = SelectionType_MULTI; break; +// case NO_SELECTION: + default: eSelectionType = SelectionType_NONE; break; + } + return Any( eSelectionType ); + } + case BASEPROPERTY_GRID_SHOWROWHEADER: + { + return Any ((sal_Bool) pTableControl->GetModel()->hasRowHeaders()); + } + case BASEPROPERTY_GRID_SHOWCOLUMNHEADER: + return Any ((sal_Bool) pTableControl->GetModel()->hasColumnHeaders()); + case BASEPROPERTY_GRID_DATAMODEL: + return Any ( m_xDataModel ); + case BASEPROPERTY_GRID_COLUMNMODEL: + return Any ( m_xColumnModel); + case BASEPROPERTY_HSCROLL: + return Any ( m_bHScroll); + case BASEPROPERTY_VSCROLL: + return Any ( m_bVScroll); + } + } + return VCLXWindow::getProperty( PropertyName ); +} + +void UnoControlTableModel::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_GRID_SHOWROWHEADER, + BASEPROPERTY_GRID_SHOWCOLUMNHEADER, + BASEPROPERTY_GRID_DATAMODEL, + BASEPROPERTY_GRID_COLUMNMODEL, + BASEPROPERTY_GRID_SELECTIONMODE, + 0); + VCLXWindow::ImplGetPropertyIds( rIds, true ); +} +void SAL_CALL UnoControlTableModel::setVisible( sal_Bool bVisible ) throw(::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + if ( pTable ) + { + pTable->SetModel(PTableModel(this)); + pTable->Show( bVisible ); + } +} +void SAL_CALL UnoControlTableModel::setFocus() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + if ( GetWindow()) + GetWindow()->GrabFocus(); +} +void SAL_CALL UnoControlTableModel::rowAdded(const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + std::vector<OUString> aNewRow( + comphelper::sequenceToContainer< std::vector<rtl::OUString > >(Event.rowData)); + if(aNewRow.size()<m_pImpl->aColumns.size()) + aNewRow.resize(m_pImpl->aColumns.size(),rtl::OUString::createFromAscii("")); + m_pImpl->aCellContent.push_back(aNewRow); + if(hasRowHeaders()) + m_pImpl->aRowHeadersTitle.push_back(Event.headerName); + m_pImpl->nRowCount=m_pImpl->aCellContent.size(); + TableControl* pTable = (TableControl*)GetWindow(); + pTable->InvalidateDataWindow(m_pImpl->nRowCount-1, false); + //pTable->GrabFocus(); +} + +void SAL_CALL UnoControlTableModel::rowRemoved(const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + //unsigned int rows =m_pImpl->aCellContent.size()-1; + if(Event.index == -1) + { + if(hasRowHeaders()) + m_pImpl->aRowHeadersTitle.clear(); + m_pImpl->aCellContent.clear(); + } + else + { + pTable->removeSelectedRow(Event.index); + if(m_pImpl->aCellContent.size()>1) + { + if(hasRowHeaders()) + m_pImpl->aRowHeadersTitle.erase(m_pImpl->aRowHeadersTitle.begin()+Event.index); + m_pImpl->aCellContent.erase(m_pImpl->aCellContent.begin()+Event.index); + + } + else + { + if(hasRowHeaders()) + m_pImpl->aRowHeadersTitle.clear(); + m_pImpl->aCellContent.clear(); + //m_pImpl->nRowCount=0; + } + } + //pTable->InvalidateDataWindow(Event.index, true); + setRowCount(m_pImpl->aCellContent.size()); + pTable->InvalidateDataWindow(Event.index, true); + //pTable->Invalidate(); +} + +void SAL_CALL UnoControlTableModel::dataChanged(const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + (void) Event; +} + + void SAL_CALL UnoControlTableModel::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException) + { + VCLXWindow::disposing( Source ); + } + +::sal_Int32 SAL_CALL UnoControlTableModel::getMinSelectionIndex() throw (::com::sun::star::uno::RuntimeException) +{ + return 0; +} + +::sal_Int32 SAL_CALL UnoControlTableModel::getMaxSelectionIndex() throw (::com::sun::star::uno::RuntimeException) +{ + return 0; +} + +void SAL_CALL UnoControlTableModel::insertIndexIntervall(::sal_Int32 start, ::sal_Int32 length) throw (::com::sun::star::uno::RuntimeException) +{ + (void)length; + (void)start; +} + +void SAL_CALL UnoControlTableModel::removeIndexIntervall(::sal_Int32 start, ::sal_Int32 end) throw (::com::sun::star::uno::RuntimeException) +{ + (void)end; + (void)start; +} + +::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL UnoControlTableModel::getSelection() throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos> selectedRows = pTable->getSelectedRows(); + Sequence<sal_Int32> selectedRowsToSequence(comphelper::containerToSequence(selectedRows)); + return selectedRowsToSequence; +} + +::sal_Bool SAL_CALL UnoControlTableModel::isCellEditable() throw (::com::sun::star::uno::RuntimeException) +{ + return sal_False; +} + +::sal_Bool SAL_CALL UnoControlTableModel::isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException) +{ + return sal_False; +} + +::sal_Bool SAL_CALL UnoControlTableModel::isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException) +{ + (void)index; + return sal_False; +} + +void SAL_CALL UnoControlTableModel::selectRow(::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException) +{ + (void)y; +} + +void SAL_CALL UnoControlTableModel::selectColumn(::sal_Int32 x) throw (::com::sun::star::uno::RuntimeException) +{ + (void)x; +} diff --git a/svtools/source/uno/unocontroltablemodel.hxx b/svtools/source/uno/unocontroltablemodel.hxx new file mode 100644 index 000000000000..5da9cc871756 --- /dev/null +++ b/svtools/source/uno/unocontroltablemodel.hxx @@ -0,0 +1,179 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: unocontroltablemodel.hxx,v $ + * $Revision: 1.32 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _UNOCONTROL_TABLEMODEL_HXX_ +#define _UNOCONTROL_TABLEMODEL_HXX_ + +#include <svtools/table/tablemodel.hxx> +#include <svtools/table/tablecontrol.hxx> +#include <com/sun/star/awt/grid/XGridControl.hpp> +#include <com/sun/star/awt/grid/XGridDataListener.hpp> +#include <com/sun/star/awt/grid/GridDataEvent.hpp> +#include <com/sun/star/awt/grid/XGridColumnModel.hpp> +#include <com/sun/star/awt/grid/XGridDataModel.hpp> +#include <com/sun/star/awt/grid/XGridSelectionListener.hpp> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/awt/vclxwindows.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/implbase2.hxx> +//#include <toolkit/helper/listenermultiplexer.hxx> + + +using namespace ::svt::table; + + struct UnoControlTableModel_Impl; + + class UnoControlTableModel : public ITableModel, public ::cppu::ImplInheritanceHelper2< VCLXWindow, ::com::sun::star::awt::grid::XGridControl, + ::com::sun::star::awt::grid::XGridDataListener> + { + private: + UnoControlTableModel_Impl* m_pImpl; + ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel >m_xDataModel; + ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel >m_xColumnModel; + bool m_bHasColumnHeaders; + bool m_bHasRowHeaders; + bool m_bVScroll; + bool m_bHScroll; + //MouseListenerMultiplexer m_aMouseListeners; + + public: + UnoControlTableModel(); + ~UnoControlTableModel(); + + /// returns the current row height, in 1/100 millimeters + inline TableMetrics GetRowHeight() const { return getRowHeight(); } + /// sets a new row height. + void setRowHeight( TableMetrics _nHeight ); + + /// returns the height of the title row (containing the column headers) + inline TableMetrics GetTitleHeight() const { return getColumnHeaderHeight(); } + /// sets a new height for the title row (containing the column headers) + void SetTitleHeight( TableMetrics _nHeight ); + + /// returns the width of the handle column (containing the row headers) + inline TableMetrics GetHandleWidth() const { return getRowHeaderWidth(); } + /// sets a new width for the handle column (containing the row headers) + void SetHandleWidth( TableMetrics _nWidth ); + + /// sets the width of a column + inline void SetColumnWidth( ColPos _nColumn, TableMetrics _nWidth100thMM ); + /// retrieves the width of a column, in 1/100th millimeters + inline TableMetrics GetColumnWidth( ColPos _nColumn ); + + // TODO: setters and getters for ID, Name, Resizable, MinWidth, MaxWidth + + public: + // ITableModel overridables + virtual TableSize getColumnCount() const; + virtual TableSize getRowCount() const; + virtual void setColumnCount(TableSize _nColCount); + virtual void setRowCount(TableSize _nRowCount); + virtual bool hasColumnHeaders() const; + virtual bool hasRowHeaders() const; + virtual void setRowHeaders(bool _bRowHeaders); + virtual void setColumnHeaders(bool _bColumnHeaders); + virtual bool isCellEditable( ColPos col, RowPos row ) const; + virtual void addTableModelListener( const PTableModelListener& listener ); + virtual void removeTableModelListener( const PTableModelListener& listener ); + virtual PColumnModel getColumnModel( ColPos column ); + virtual PColumnModel getColumnModelByID( ColumnID id ); + virtual PTableRenderer getRenderer() const; + virtual PTableInputHandler getInputHandler() const; + virtual TableMetrics getRowHeight() const; + virtual TableMetrics getColumnHeaderHeight() const; + virtual TableMetrics getRowHeaderWidth() const; + virtual ScrollbarVisibility getVerticalScrollbarVisibility(int overAllHeight, int actHeight) const; + virtual ScrollbarVisibility getHorizontalScrollbarVisibility(int overAllWidth, int actWidth) const; + virtual void setCellContent(std::vector<std::vector<rtl::OUString> > cellContent); + virtual std::vector<std::vector<rtl::OUString> > getCellContent(); + virtual void setRowHeaderName(std::vector<rtl::OUString> cellColumnContent); + virtual std::vector<rtl::OUString> getRowHeaderName(); + + //XGridDataListener overridables + virtual void SAL_CALL rowAdded(const ::com::sun::star::awt::grid::GridDataEvent& Event) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL rowRemoved(const ::com::sun::star::awt::grid::GridDataEvent & Event) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL dataChanged(const ::com::sun::star::awt::grid::GridDataEvent & Event) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::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() { VCLXWindow::acquire(); } + void SAL_CALL release() throw() { VCLXWindow::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::grid::XGridControl + ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel > SAL_CALL getColumnModel( ) throw (::com::sun::star::uno::RuntimeException); + void SAL_CALL setColumnModel( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel >& model ) throw (::com::sun::star::uno::RuntimeException); + ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel > SAL_CALL getDataModel( ) throw (::com::sun::star::uno::RuntimeException); + void SAL_CALL setDataModel( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel >& model ) throw (::com::sun::star::uno::RuntimeException); + + virtual ::sal_Int32 SAL_CALL getMinSelectionIndex() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getMaxSelectionIndex() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL insertIndexIntervall(::sal_Int32 start, ::sal_Int32 length) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeIndexIntervall(::sal_Int32 start, ::sal_Int32 end) 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 isCellEditable() 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 selectRow(::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectColumn(::sal_Int32 x) 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); + virtual ::sal_Int32 SAL_CALL getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException); + + //void SAL_CALL addMouseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & listener ) throw(::com::sun::star::uno::RuntimeException); + //void SAL_CALL removeMouseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & listener ) throw(::com::sun::star::uno::RuntimeException); + //::com::sun::star::awt::XMouseListener + /* + virtual void SAL_CALL mousePressed( const ::com::sun::star::awt::MouseEvent& rEvent ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL mouseReleased( const ::com::sun::star::awt::MouseEvent& rEvent ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL mouseEntered( const ::com::sun::star::awt::MouseEvent& rEvent ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL mouseExited( const ::com::sun::star::awt::MouseEvent& rEvent ) 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); + static void ImplGetPropertyIds( std::list< sal_uInt16 > &aIds ); + void SAL_CALL setVisible(sal_Bool bVisible) throw(::com::sun::star::uno::RuntimeException); + void SAL_CALL setFocus() throw(::com::sun::star::uno::RuntimeException); + }; + + inline void UnoControlTableModel::SetColumnWidth( ColPos _nColumn, TableMetrics _nWidth100thMM ) + { + getColumnModel( _nColumn )->setWidth( _nWidth100thMM ); + } + + inline TableMetrics UnoControlTableModel::GetColumnWidth( ColPos _nColumn ) + { + return getColumnModel( _nColumn )->getWidth(); + } + #endif // _UNOCONTROL_TABLEMODEL_HXX_ diff --git a/svtools/source/uno/unoiface.cxx b/svtools/source/uno/unoiface.cxx index 91a6de4c404d..e6922aa4f099 100644 --- a/svtools/source/uno/unoiface.cxx +++ b/svtools/source/uno/unoiface.cxx @@ -54,6 +54,9 @@ #include <svtools/svtreebx.hxx> #include "treecontrolpeer.hxx" +//#include "vclxgridcontrol.hxx" +#include "unocontroltablemodel.hxx" +#include <svtools/table/tablecontrol.hxx> namespace { @@ -83,8 +86,6 @@ SAL_DLLPUBLIC_EXPORT Window* CreateWindow( VCLXWindow** ppNewComp, const ::com:: if ( pParent ) { pWindow = new MultiLineEdit( pParent, nWinBits|WB_IGNORETAB); - static_cast< MultiLineEdit* >( pWindow )->DisableSelectionOnFocus(); - // #i89821# / 2008-12-17 / frank.schoenheit@sun.com *ppNewComp = new VCLXMultiLineEdit; } else @@ -167,6 +168,21 @@ SAL_DLLPUBLIC_EXPORT Window* CreateWindow( VCLXWindow** ppNewComp, const ::com:: return NULL; } } + else if ( aServiceName.EqualsIgnoreCaseAscii( "Grid" ) ) + { + if ( pParent ) + { + ::svt::table::TableControl* m_pTable = new ::svt::table::TableControl(pParent, nWinBits); + UnoControlTableModel* pModel = new UnoControlTableModel(); + *ppNewComp = pModel; + pWindow = m_pTable; + } + else + { + *ppNewComp = NULL; + return NULL; + } + } return pWindow; } |