| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_toolkit.hxx" |
| #include <com/sun/star/io/XMarkableStream.hpp> |
| |
| #include <toolkit/controls/stdtabcontrollermodel.hxx> |
| #include <toolkit/helper/macros.hxx> |
| #include <toolkit/helper/servicenames.hxx> |
| #include <toolkit/helper/property.hxx> |
| #include <cppuhelper/typeprovider.hxx> |
| #include <rtl/memory.h> |
| #include <rtl/uuid.h> |
| |
| #include <tools/debug.hxx> |
| |
| #define UNOCONTROL_STREAMVERSION (short)2 |
| |
| // ---------------------------------------------------- |
| // class UnoControlModelEntryList |
| // ---------------------------------------------------- |
| UnoControlModelEntryList::UnoControlModelEntryList() |
| { |
| } |
| |
| UnoControlModelEntryList::~UnoControlModelEntryList() |
| { |
| Reset(); |
| } |
| |
| void UnoControlModelEntryList::Reset() |
| { |
| for ( sal_uInt32 n = Count(); n; ) |
| DestroyEntry( --n ); |
| } |
| |
| void UnoControlModelEntryList::DestroyEntry( sal_uInt32 nEntry ) |
| { |
| UnoControlModelEntry* pEntry = GetObject( nEntry ); |
| |
| if ( pEntry->bGroup ) |
| delete pEntry->pGroup; |
| else |
| delete pEntry->pxControl; |
| |
| Remove( nEntry ); |
| delete pEntry; |
| } |
| |
| // ---------------------------------------------------- |
| // class StdTabControllerModel |
| // ---------------------------------------------------- |
| StdTabControllerModel::StdTabControllerModel() |
| { |
| mbGroupControl = sal_True; |
| } |
| |
| StdTabControllerModel::~StdTabControllerModel() |
| { |
| } |
| |
| sal_uInt32 StdTabControllerModel::ImplGetControlCount( const UnoControlModelEntryList& rList ) const |
| { |
| sal_uInt32 nCount = 0; |
| sal_uInt32 nEntries = rList.Count(); |
| for ( sal_uInt32 n = 0; n < nEntries; n++ ) |
| { |
| UnoControlModelEntry* pEntry = rList.GetObject( n ); |
| if ( pEntry->bGroup ) |
| nCount += ImplGetControlCount( *pEntry->pGroup ); |
| else |
| nCount++; |
| } |
| return nCount; |
| } |
| |
| void StdTabControllerModel::ImplGetControlModels( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > ** ppRefs, const UnoControlModelEntryList& rList ) const |
| { |
| sal_uInt32 nEntries = rList.Count(); |
| for ( sal_uInt32 n = 0; n < nEntries; n++ ) |
| { |
| UnoControlModelEntry* pEntry = rList.GetObject( n ); |
| if ( pEntry->bGroup ) |
| ImplGetControlModels( ppRefs, *pEntry->pGroup ); |
| else |
| { |
| **ppRefs = *pEntry->pxControl; |
| (*ppRefs)++; |
| } |
| } |
| } |
| |
| void StdTabControllerModel::ImplSetControlModels( UnoControlModelEntryList& rList, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& Controls ) const |
| { |
| const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > * pRefs = Controls.getConstArray(); |
| sal_uInt32 nControls = Controls.getLength(); |
| for ( sal_uInt32 n = 0; n < nControls; n++ ) |
| { |
| UnoControlModelEntry* pNewEntry = new UnoControlModelEntry; |
| pNewEntry->bGroup = sal_False; |
| pNewEntry->pxControl = new ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > ; |
| *pNewEntry->pxControl = pRefs[n]; |
| rList.Insert( pNewEntry, LIST_APPEND ); |
| } |
| } |
| |
| sal_uInt32 StdTabControllerModel::ImplGetControlPos( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xCtrl, const UnoControlModelEntryList& rList ) const |
| { |
| for ( sal_uInt32 n = rList.Count(); n; ) |
| { |
| UnoControlModelEntry* pEntry = rList.GetObject( --n ); |
| if ( !pEntry->bGroup && ( *pEntry->pxControl == xCtrl ) ) |
| return n; |
| } |
| return CONTROLPOS_NOTFOUND; |
| } |
| |
| void ImplWriteControls( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream > & OutStream, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& rCtrls ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( OutStream, ::com::sun::star::uno::UNO_QUERY ); |
| DBG_ASSERT( xMark.is(), "write: no XMarkableStream!" ); |
| |
| sal_uInt32 nStoredControls = 0; |
| sal_Int32 nDataBeginMark = xMark->createMark(); |
| |
| OutStream->writeLong( 0L ); // DataLen |
| OutStream->writeLong( 0L ); // nStoredControls |
| |
| sal_uInt32 nCtrls = rCtrls.getLength(); |
| for ( sal_uInt32 n = 0; n < nCtrls; n++ ) |
| { |
| const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xI = rCtrls.getConstArray()[n]; |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XPersistObject > xPO( xI, ::com::sun::star::uno::UNO_QUERY ); |
| DBG_ASSERT( xPO.is(), "write: Control doesn't support XPersistObject" ); |
| if ( xPO.is() ) |
| { |
| OutStream->writeObject( xPO ); |
| nStoredControls++; |
| } |
| } |
| sal_Int32 nDataLen = xMark->offsetToMark( nDataBeginMark ); |
| xMark->jumpToMark( nDataBeginMark ); |
| OutStream->writeLong( nDataLen ); |
| OutStream->writeLong( nStoredControls ); |
| xMark->jumpToFurthest(); |
| xMark->deleteMark(nDataBeginMark); |
| } |
| |
| ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > ImplReadControls( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream > & InStream ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( InStream, ::com::sun::star::uno::UNO_QUERY ); |
| DBG_ASSERT( xMark.is(), "write: no XMarkableStream!" ); |
| |
| sal_Int32 nDataBeginMark = xMark->createMark(); |
| |
| sal_Int32 nDataLen = InStream->readLong(); |
| sal_uInt32 nCtrls = InStream->readLong(); |
| |
| ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aSeq( nCtrls ); |
| for ( sal_uInt32 n = 0; n < nCtrls; n++ ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XPersistObject > xObj = InStream->readObject(); |
| ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xI( xObj, ::com::sun::star::uno::UNO_QUERY ); |
| aSeq.getArray()[n] = xI; |
| } |
| |
| // Falls bereits mehr drinsteht als diese Version kennt: |
| xMark->jumpToMark( nDataBeginMark ); |
| InStream->skipBytes( nDataLen ); |
| xMark->deleteMark(nDataBeginMark); |
| return aSeq; |
| } |
| |
| |
| // ::com::sun::star::uno::XInterface |
| ::com::sun::star::uno::Any StdTabControllerModel::queryAggregation( 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::XTabControllerModel*, this ), |
| SAL_STATIC_CAST( ::com::sun::star::lang::XServiceInfo*, this ), |
| SAL_STATIC_CAST( ::com::sun::star::io::XPersistObject*, this ), |
| SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) ); |
| return (aRet.hasValue() ? aRet : OWeakAggObject::queryAggregation( rType )); |
| } |
| |
| // ::com::sun::star::lang::XTypeProvider |
| IMPL_XTYPEPROVIDER_START( StdTabControllerModel ) |
| getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabControllerModel>* ) NULL ), |
| getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XServiceInfo>* ) NULL ), |
| getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::io::XPersistObject>* ) NULL ) |
| IMPL_XTYPEPROVIDER_END |
| |
| sal_Bool StdTabControllerModel::getGroupControl( ) throw(::com::sun::star::uno::RuntimeException) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); |
| |
| return mbGroupControl; |
| } |
| |
| void StdTabControllerModel::setGroupControl( sal_Bool GroupControl ) throw(::com::sun::star::uno::RuntimeException) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); |
| |
| mbGroupControl = GroupControl; |
| } |
| |
| void StdTabControllerModel::setControlModels( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& Controls ) throw(::com::sun::star::uno::RuntimeException) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); |
| |
| maControls.Reset(); |
| ImplSetControlModels( maControls, Controls ); |
| } |
| |
| ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > StdTabControllerModel::getControlModels( ) throw(::com::sun::star::uno::RuntimeException) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); |
| |
| ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aSeq( ImplGetControlCount( maControls ) ); |
| ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > * pRefs = aSeq.getArray(); |
| ImplGetControlModels( &pRefs, maControls ); |
| return aSeq; |
| } |
| |
| void StdTabControllerModel::setGroup( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& Group, const ::rtl::OUString& GroupName ) throw(::com::sun::star::uno::RuntimeException) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); |
| |
| // Die Controls stehen eventuel flach in der Liste und werden jetzt gruppiert. |
| // Verschachtelte Gruppen sind erstmal nicht moeglich... |
| // Das erste Element der Gruppe welches auch schon in der flachen Liste |
| // stand bestimmt die Position der Gruppe. |
| |
| UnoControlModelEntry* pNewEntry = new UnoControlModelEntry; |
| pNewEntry->bGroup = sal_True; |
| pNewEntry->pGroup = new UnoControlModelEntryList; |
| pNewEntry->pGroup->SetName( GroupName ); |
| ImplSetControlModels( *pNewEntry->pGroup, Group ); |
| |
| sal_Bool bInserted = sal_False; |
| sal_uInt32 nElements = pNewEntry->pGroup->Count(); |
| for ( sal_uInt32 n = 0; n < nElements; n++ ) |
| { |
| UnoControlModelEntry* pEntry = pNewEntry->pGroup->GetObject( n ); |
| if ( !pEntry->bGroup ) |
| { |
| sal_uInt32 nPos = ImplGetControlPos( *pEntry->pxControl, maControls ); |
| // Eigentlich sollten alle Controls vorher in der flachen Liste stehen |
| DBG_ASSERT( nPos != CONTROLPOS_NOTFOUND, "setGroup - Element not found" ); |
| if ( nPos != CONTROLPOS_NOTFOUND ) |
| { |
| maControls.DestroyEntry( nPos ); |
| if ( !bInserted ) |
| { |
| maControls.Insert( pNewEntry, nPos ); |
| bInserted = sal_True; |
| } |
| } |
| } |
| } |
| if ( !bInserted ) |
| maControls.Insert( pNewEntry, LIST_APPEND ); |
| } |
| |
| sal_Int32 StdTabControllerModel::getGroupCount( ) throw(::com::sun::star::uno::RuntimeException) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); |
| |
| // erstmal nur eine Ebene... |
| // Das Model und die Impl-Methoden arbeiten zwar rekursiv, aber das wird |
| // erstmal nich nach aussen gegeben. |
| |
| sal_Int32 nGroups = 0; |
| sal_uInt32 nEntries = maControls.Count(); |
| for ( sal_uInt32 n = 0; n < nEntries; n++ ) |
| { |
| UnoControlModelEntry* pEntry = maControls.GetObject( n ); |
| if ( pEntry->bGroup ) |
| nGroups++; |
| } |
| return nGroups; |
| } |
| |
| void StdTabControllerModel::getGroup( sal_Int32 nGroup, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& rGroup, ::rtl::OUString& rName ) throw(::com::sun::star::uno::RuntimeException) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); |
| |
| ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aSeq; |
| sal_uInt32 nG = 0; |
| sal_uInt32 nEntries = maControls.Count(); |
| for ( sal_uInt32 n = 0; n < nEntries; n++ ) |
| { |
| UnoControlModelEntry* pEntry = maControls.GetObject( n ); |
| if ( pEntry->bGroup ) |
| { |
| if ( nG == (sal_uInt32)nGroup ) |
| { |
| sal_uInt32 nCount = ImplGetControlCount( *pEntry->pGroup ); |
| aSeq = ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >( nCount ); |
| ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > * pRefs = aSeq.getArray(); |
| ImplGetControlModels( &pRefs, *pEntry->pGroup ); |
| rName = pEntry->pGroup->GetName(); |
| break; |
| } |
| nG++; |
| } |
| } |
| rGroup = aSeq; |
| } |
| |
| void StdTabControllerModel::getGroupByName( const ::rtl::OUString& rName, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& rGroup ) throw(::com::sun::star::uno::RuntimeException) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); |
| |
| sal_uInt32 nGroup = 0; |
| sal_uInt32 nEntries = maControls.Count(); |
| for ( sal_uInt32 n = 0; n < nEntries; n++ ) |
| { |
| UnoControlModelEntry* pEntry = maControls.GetObject( n ); |
| if ( pEntry->bGroup ) |
| { |
| if ( pEntry->pGroup->GetName() == rName ) |
| { |
| ::rtl::OUString Dummy; |
| getGroup( nGroup, rGroup, Dummy ); |
| break; |
| } |
| nGroup++; |
| } |
| } |
| } |
| |
| |
| // ::com::sun::star::io::XPersistObject |
| ::rtl::OUString StdTabControllerModel::getServiceName( ) throw(::com::sun::star::uno::RuntimeException) |
| { |
| return ::rtl::OUString::createFromAscii( szServiceName_TabControllerModel ); |
| } |
| |
| void StdTabControllerModel::write( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& OutStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( OutStream, ::com::sun::star::uno::UNO_QUERY ); |
| DBG_ASSERT( xMark.is(), "write: no XMarkableStream!" ); |
| |
| OutStream->writeShort( UNOCONTROL_STREAMVERSION ); |
| |
| ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aCtrls = getControlModels(); |
| ImplWriteControls( OutStream, aCtrls ); |
| |
| sal_uInt32 nGroups = getGroupCount(); |
| OutStream->writeLong( nGroups ); |
| for ( sal_uInt32 n = 0; n < nGroups; n++ ) |
| { |
| ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aGroupCtrls; |
| ::rtl::OUString aGroupName; |
| getGroup( n, aGroupCtrls, aGroupName ); |
| OutStream->writeUTF( aGroupName ); |
| ImplWriteControls( OutStream, aGroupCtrls ); |
| } |
| } |
| |
| void StdTabControllerModel::read( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& InStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); |
| |
| ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aSeq = ImplReadControls( InStream ); |
| setControlModels( aSeq ); |
| |
| sal_uInt32 nGroups = InStream->readLong(); |
| for ( sal_uInt32 n = 0; n < nGroups; n++ ) |
| { |
| ::rtl::OUString aGroupName = InStream->readUTF(); |
| ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aCtrlSeq = ImplReadControls( InStream ); |
| setGroup( aCtrlSeq, aGroupName ); |
| } |
| } |
| |
| |
| |
| |
| |