diff options
Diffstat (limited to '')
-rw-r--r-- | sfx2/source/control/objface.cxx | 443 |
1 files changed, 443 insertions, 0 deletions
diff --git a/sfx2/source/control/objface.cxx b/sfx2/source/control/objface.cxx new file mode 100644 index 000000000..5938b68f0 --- /dev/null +++ b/sfx2/source/control/objface.cxx @@ -0,0 +1,443 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <assert.h> +#include <stdlib.h> + +#include <sal/log.hxx> + +#include <sfx2/module.hxx> +#include <sfx2/objface.hxx> +#include <sfx2/msg.hxx> +#include <sfx2/app.hxx> +#include <sfx2/msgpool.hxx> + +extern "C" { + +static int +SfxCompareSlots_qsort( const void* pSmaller, const void* pBigger ) +{ + return static_cast<int>(static_cast<SfxSlot const *>(pSmaller)->GetSlotId()) - + static_cast<int>(static_cast<SfxSlot const *>(pBigger)->GetSlotId()); +} + +static int +SfxCompareSlots_bsearch( const void* pSmaller, const void* pBigger ) +{ + return static_cast<int>(*static_cast<sal_uInt16 const *>(pSmaller)) - + static_cast<int>(static_cast<SfxSlot const *>(pBigger)->GetSlotId()); +} + +} + +namespace { + +struct SfxObjectUI_Impl +{ + sal_uInt16 nPos; + SfxVisibilityFlags nFlags; + sal_uInt32 nObjId; + bool bContext; + SfxShellFeature nFeature; + + SfxObjectUI_Impl(sal_uInt16 n, SfxVisibilityFlags f, sal_uInt32 nId, SfxShellFeature nFeat) : + nPos(n), + nFlags(f), + nObjId(nId), + bContext(false), + nFeature(nFeat) + { + } +}; + +} + +struct SfxInterface_Impl +{ + std::vector<SfxObjectUI_Impl> + aObjectBars; // registered ObjectBars + std::vector<SfxObjectUI_Impl> + aChildWindows; // registered ChildWindows + OUString aPopupName; // registered PopupMenu + StatusBarId eStatBarResId; // registered StatusBar + + SfxInterface_Impl() + : eStatBarResId(StatusBarId::None) + { + } +}; + +static SfxObjectUI_Impl CreateObjectBarUI_Impl(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId, SfxShellFeature nFeature); + +// constructor, registers a new unit +SfxInterface::SfxInterface( const char *pClassName, + bool bUsableSuperClass, + SfxInterfaceId nId, + const SfxInterface* pParent, + SfxSlot &rSlotMap, sal_uInt16 nSlotCount ): + pName(pClassName), + pGenoType(pParent), + nClassId(nId), + bSuperClass(bUsableSuperClass), + pImplData(new SfxInterface_Impl) +{ + SetSlotMap( rSlotMap, nSlotCount ); +} + +void SfxInterface::Register( const SfxModule* pMod ) +{ + if ( pMod ) + pMod->GetSlotPool()->RegisterInterface(*this); + else + SfxGetpApp()->GetAppSlotPool_Impl().RegisterInterface(*this); +} + +void SfxInterface::SetSlotMap( SfxSlot& rSlotMap, sal_uInt16 nSlotCount ) +{ + pSlots = &rSlotMap; + nCount = nSlotCount; + SfxSlot* pIter = pSlots; + if ( 1 == nCount && !pIter->pNextSlot ) + pIter->pNextSlot = pIter; + + if ( !pIter->pNextSlot ) + { + // sort the SfxSlots by id + qsort( pSlots, nCount, sizeof(SfxSlot), SfxCompareSlots_qsort ); + + // link masters and slaves + sal_uInt16 nIter = 1; + for ( pIter = pSlots; nIter <= nCount; ++pIter, ++nIter ) + { + + assert( nIter == nCount || + pIter->GetSlotId() != (pIter+1)->GetSlotId() ); + + if ( nullptr == pIter->GetNextSlot() ) + { + // Slots referring in circle to the next with the same + // Status method. + SfxSlot *pLastSlot = pIter; + for ( sal_uInt16 n = nIter; n < Count(); ++n ) + { + SfxSlot *pCurSlot = pSlots+n; + if ( pCurSlot->GetStateFnc() == pIter->GetStateFnc() ) + { + pLastSlot->pNextSlot = pCurSlot; + pLastSlot = pCurSlot; + } + } + pLastSlot->pNextSlot = pIter; + } + } + } +#ifdef DBG_UTIL + else + { + sal_uInt16 nIter = 1; + for ( SfxSlot *pNext = pIter+1; nIter < nCount; ++pNext, ++nIter ) + { + + if ( pNext->GetSlotId() <= pIter->GetSlotId() ) + SAL_WARN( "sfx.control", "Wrong order" ); + + const SfxSlot *pCurSlot = pIter; + do + { + pCurSlot = pCurSlot->pNextSlot; + if ( pCurSlot->GetStateFnc() != pIter->GetStateFnc() ) + { + SAL_WARN("sfx.control", "Linked Slots with different State Methods : " + << pCurSlot->GetSlotId() + << " , " << pIter->GetSlotId() ); + } + } + while ( pCurSlot != pIter ); + + pIter = pNext; + } + } +#endif +} + + +SfxInterface::~SfxInterface() +{ +} + + +// searches for the specified func + +const SfxSlot* SfxInterface::GetSlot( sal_uInt16 nFuncId ) const +{ + + assert( pSlots ); + assert( nCount ); + + // find the id using binary search + void* p = bsearch( &nFuncId, pSlots, nCount, sizeof(SfxSlot), + SfxCompareSlots_bsearch ); + if ( !p && pGenoType ) + return pGenoType->GetSlot( nFuncId ); + + return static_cast<const SfxSlot*>(p); +} + +const SfxSlot* SfxInterface::GetSlot( const OUString& rCommand ) const +{ + static const char UNO_COMMAND[] = ".uno:"; + + OUString aCommand( rCommand ); + if ( aCommand.startsWith( UNO_COMMAND ) ) + aCommand = aCommand.copy( sizeof( UNO_COMMAND )-1 ); + + for ( sal_uInt16 n=0; n<nCount; n++ ) + { + if ( (pSlots+n)->pUnoName && + aCommand.compareToIgnoreAsciiCaseAscii( (pSlots+n)->GetUnoName() ) == 0 ) + return pSlots+n; + } + + return pGenoType ? pGenoType->GetSlot( aCommand ) : nullptr; +} + + +const SfxSlot* SfxInterface::GetRealSlot( const SfxSlot *pSlot ) const +{ + + assert( pSlots ); + assert( nCount ); + + if ( !ContainsSlot_Impl(pSlot) ) + { + if(pGenoType) + return pGenoType->GetRealSlot(pSlot); + SAL_WARN( "sfx.control", "unknown Slot" ); + return nullptr; + } + + return nullptr; +} + + +void SfxInterface::RegisterPopupMenu( const OUString& rResourceName ) +{ + pImplData->aPopupName = rResourceName; +} + +void SfxInterface::RegisterObjectBar(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId) +{ + RegisterObjectBar(nPos, nFlags, eId, SfxShellFeature::NONE); +} + +void SfxInterface::RegisterObjectBar(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId, SfxShellFeature nFeature) +{ + pImplData->aObjectBars.emplace_back( CreateObjectBarUI_Impl(nPos, nFlags, eId, nFeature) ); +} + +SfxObjectUI_Impl CreateObjectBarUI_Impl(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId, SfxShellFeature nFeature) +{ + if (nFlags == SfxVisibilityFlags::Invisible) + nFlags |= SfxVisibilityFlags::Standard; + + return SfxObjectUI_Impl(nPos, nFlags, static_cast<sal_uInt32>(eId), nFeature); +} + +ToolbarId SfxInterface::GetObjectBarId(sal_uInt16 nNo) const +{ + bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass()); + if ( bGenoType ) + { + // Are there toolbars in the super class? + sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount(); + if ( nNo < nBaseCount ) + // The Super class comes first + return pGenoType->GetObjectBarId(nNo); + else + nNo = nNo - nBaseCount; + } + + assert( nNo<pImplData->aObjectBars.size() ); + + return static_cast<ToolbarId>(pImplData->aObjectBars[nNo].nObjId); +} + +sal_uInt16 SfxInterface::GetObjectBarPos( sal_uInt16 nNo ) const +{ + bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass()); + if ( bGenoType ) + { + // Are there toolbars in the super class? + sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount(); + if ( nNo < nBaseCount ) + // The Super class comes first + return pGenoType->GetObjectBarPos( nNo ); + else + nNo = nNo - nBaseCount; + } + + assert( nNo<pImplData->aObjectBars.size() ); + + return pImplData->aObjectBars[nNo].nPos; +} + +SfxVisibilityFlags SfxInterface::GetObjectBarFlags( sal_uInt16 nNo ) const +{ + bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass()); + if ( bGenoType ) + { + // Are there toolbars in the super class? + sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount(); + if ( nNo < nBaseCount ) + // The Super class comes first + return pGenoType->GetObjectBarFlags( nNo ); + else + nNo = nNo - nBaseCount; + } + + assert( nNo<pImplData->aObjectBars.size() ); + + return pImplData->aObjectBars[nNo].nFlags; +} + +sal_uInt16 SfxInterface::GetObjectBarCount() const +{ + if (pGenoType && pGenoType->UseAsSuperClass()) + return pImplData->aObjectBars.size() + pGenoType->GetObjectBarCount(); + else + return pImplData->aObjectBars.size(); +} + +void SfxInterface::RegisterChildWindow(sal_uInt16 nId, bool bContext) +{ + RegisterChildWindow(nId, bContext, SfxShellFeature::NONE); +} + +void SfxInterface::RegisterChildWindow(sal_uInt16 nId, bool bContext, SfxShellFeature nFeature) +{ + SfxObjectUI_Impl aUI(0, SfxVisibilityFlags::Invisible, nId, nFeature); + aUI.bContext = bContext; + pImplData->aChildWindows.emplace_back(aUI); +} + +void SfxInterface::RegisterStatusBar(StatusBarId eId) +{ + pImplData->eStatBarResId = eId; +} + +sal_uInt32 SfxInterface::GetChildWindowId (sal_uInt16 nNo) const +{ + if ( pGenoType ) + { + // Are there ChildWindows in the superclass? + sal_uInt16 nBaseCount = pGenoType->GetChildWindowCount(); + if ( nNo < nBaseCount ) + // The Super class comes first + return pGenoType->GetChildWindowId( nNo ); + else + nNo = nNo - nBaseCount; + } + + assert( nNo<pImplData->aChildWindows.size() ); + + sal_uInt32 nRet = pImplData->aChildWindows[nNo].nObjId; + if ( pImplData->aChildWindows[nNo].bContext ) + nRet += sal_uInt16( nClassId ) << 16; + return nRet; +} + +SfxShellFeature SfxInterface::GetChildWindowFeature (sal_uInt16 nNo) const +{ + if ( pGenoType ) + { + // Are there ChildWindows in the superclass? + sal_uInt16 nBaseCount = pGenoType->GetChildWindowCount(); + if ( nNo < nBaseCount ) + // The Super class comes first + return pGenoType->GetChildWindowFeature( nNo ); + else + nNo = nNo - nBaseCount; + } + + assert( nNo<pImplData->aChildWindows.size() ); + + return pImplData->aChildWindows[nNo].nFeature; +} + + +sal_uInt16 SfxInterface::GetChildWindowCount() const +{ + if (pGenoType) + return pImplData->aChildWindows.size() + pGenoType->GetChildWindowCount(); + else + return pImplData->aChildWindows.size(); +} + +const OUString& SfxInterface::GetPopupMenuName() const +{ + return pImplData->aPopupName; +} + +StatusBarId SfxInterface::GetStatusBarId() const +{ + if (pImplData->eStatBarResId == StatusBarId::None && pGenoType) + return pGenoType->GetStatusBarId(); + else + return pImplData->eStatBarResId; +} + +SfxShellFeature SfxInterface::GetObjectBarFeature ( sal_uInt16 nNo ) const +{ + bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass()); + if ( bGenoType ) + { + // Are there toolbars in the super class? + sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount(); + if ( nNo < nBaseCount ) + // The Super class comes first + return pGenoType->GetObjectBarFeature( nNo ); + else + nNo = nNo - nBaseCount; + } + + assert( nNo<pImplData->aObjectBars.size() ); + + return pImplData->aObjectBars[nNo].nFeature; +} + +bool SfxInterface::IsObjectBarVisible(sal_uInt16 nNo) const +{ + bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass()); + if ( bGenoType ) + { + // Are there toolbars in the super class? + sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount(); + if ( nNo < nBaseCount ) + // The Super class comes first + return pGenoType->IsObjectBarVisible( nNo ); + else + nNo = nNo - nBaseCount; + } + + assert( nNo<pImplData->aObjectBars.size() ); + + return true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |