Kaydet (Commit) 2660d24a authored tarafından Noel Grandin's avatar Noel Grandin Kaydeden (comit) Noel Grandin

new loplugin: refcounting

This was a feature requested by mmeeks, as a result of
tdf#92611.

It validates that things that extend XInterface are not
directly heap/stack-allocated, but have their lifecycle managed
via css::uno::Reference or rtl::Reference.

Change-Id: I28e3b8b236f6a4a56d0a6d6f26ad54e44b36e692
Reviewed-on: https://gerrit.libreoffice.org/16924Reviewed-by: 's avatarNoel Grandin <noelgrandin@gmail.com>
Tested-by: 's avatarNoel Grandin <noelgrandin@gmail.com>
üst baba1d14
......@@ -47,11 +47,11 @@ namespace unocontrols{
// construct/destruct
FrameControl::FrameControl( const Reference< XComponentContext >& rxContext)
: BaseControl ( rxContext )
, OBroadcastHelper ( m_aMutex )
, OPropertySetHelper ( *(static_cast< OBroadcastHelper * >(this)) )
, m_aInterfaceContainer ( m_aMutex )
, m_aConnectionPointContainer ( m_aMutex )
: BaseControl ( rxContext )
, OBroadcastHelper ( m_aMutex )
, OPropertySetHelper ( *(static_cast< OBroadcastHelper * >(this)) )
, m_aInterfaceContainer ( m_aMutex )
, m_aConnectionPointContainer ( new OConnectionPointContainerHelper(m_aMutex) )
{
}
......@@ -233,7 +233,7 @@ Reference< XGraphics > SAL_CALL FrameControl::getGraphics() throw( RuntimeExcept
Sequence< Type > SAL_CALL FrameControl::getConnectionPointTypes() throw( RuntimeException, std::exception )
{
// Forwarded to helper class
return m_aConnectionPointContainer.getConnectionPointTypes();
return m_aConnectionPointContainer->getConnectionPointTypes();
}
// XConnectionPointContainer
......@@ -241,7 +241,7 @@ Sequence< Type > SAL_CALL FrameControl::getConnectionPointTypes() throw( Runtime
Reference< XConnectionPoint > SAL_CALL FrameControl::queryConnectionPoint( const Type& aType ) throw( RuntimeException, std::exception )
{
// Forwarded to helper class
return m_aConnectionPointContainer.queryConnectionPoint( aType );
return m_aConnectionPointContainer->queryConnectionPoint( aType );
}
// XConnectionPointContainer
......@@ -250,7 +250,7 @@ void SAL_CALL FrameControl::advise( const Type& aType
const Reference< XInterface >& xListener ) throw( RuntimeException, std::exception )
{
// Forwarded to helper class
m_aConnectionPointContainer.advise( aType, xListener );
m_aConnectionPointContainer->advise( aType, xListener );
}
// XConnectionPointContainer
......@@ -259,7 +259,7 @@ void SAL_CALL FrameControl::unadvise( const Type& aTyp
const Reference< XInterface >& xListener ) throw( RuntimeException, std::exception )
{
// Forwarded to helper class
m_aConnectionPointContainer.unadvise( aType, xListener );
m_aConnectionPointContainer->unadvise( aType, xListener );
}
// impl but public method to register service
......
......@@ -211,10 +211,10 @@ private:
private:
::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame2 > m_xFrame;
OUString m_sComponentURL;
OUString m_sComponentURL;
::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > m_seqLoaderArguments;
::cppu::OMultiTypeInterfaceContainerHelper m_aInterfaceContainer;
OConnectionPointContainerHelper m_aConnectionPointContainer;
::cppu::OMultiTypeInterfaceContainerHelper m_aInterfaceContainer;
css::uno::Reference<OConnectionPointContainerHelper> m_aConnectionPointContainer;
}; // class FrameControl
......
......@@ -231,7 +231,7 @@ protected:
::osl::Mutex maMutex;
ModifiableHelper maModifiable;
NameContainer maNameContainer;
css::uno::Reference<NameContainer> maNameContainer;
bool mbOldInfoFormat;
bool mbOasis2OOoFormat;
......@@ -560,11 +560,11 @@ class SfxLibrary
friend class SfxDialogLibraryContainer;
friend class SfxScriptLibraryContainer;
css::uno::Reference< css::uno::XComponentContext > mxContext;
css::uno::Reference< css::ucb::XSimpleFileAccess3 > mxSFI;
css::uno::Reference< css::uno::XComponentContext > mxContext;
css::uno::Reference< css::ucb::XSimpleFileAccess3 > mxSFI;
ModifiableHelper& mrModifiable;
NameContainer maNameContainer;
ModifiableHelper& mrModifiable;
css::uno::Reference<NameContainer> maNameContainer;
bool mbLoaded;
bool mbIsModified;
......
......@@ -401,7 +401,7 @@ Reference< css::resource::XStringResourcePersistence >
void SfxDialogLibraryContainer::onNewRootStorage()
{
// the library container is not modified, go through the libraries and check whether they are modified
Sequence< OUString > aNames = maNameContainer.getElementNames();
Sequence< OUString > aNames = maNameContainer->getElementNames();
const OUString* pNames = aNames.getConstArray();
sal_Int32 nNameCount = aNames.getLength();
......
This diff is collapsed.
......@@ -999,12 +999,12 @@ bool SfxScriptLibraryContainer::implLoadPasswordLibrary
{
if( aAny.hasValue() )
{
pLib->maNameContainer.replaceByName( aElementName, aAny );
pLib->maNameContainer->replaceByName( aElementName, aAny );
}
}
else
{
pLib->maNameContainer.insertByName( aElementName, aAny );
pLib->maNameContainer->insertByName( aElementName, aAny );
}
}
}
......@@ -1113,12 +1113,12 @@ bool SfxScriptLibraryContainer::implLoadPasswordLibrary
{
if( aAny.hasValue() )
{
pLib->maNameContainer.replaceByName( aElementName, aAny );
pLib->maNameContainer->replaceByName( aElementName, aAny );
}
}
else
{
pLib->maNameContainer.insertByName( aElementName, aAny );
pLib->maNameContainer->insertByName( aElementName, aAny );
}
}
}
......
/* -*- 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/.
*/
#include <string>
#include <iostream>
#include "plugin.hxx"
#include "compat.hxx"
#include "clang/AST/CXXInheritance.h"
/**
If you have:
class Foo : public css::foo::XBaa {
};
Then XBaa has acquire and release methods inherited from XInterface.
These are hard lifecycle controls.
If you see another class:
class Baz {
Foo aFooMember;
};
this is a bug =) since aFooMember assumes heap allocated lifecycle and
not delete on last 'release'.
TODO check that things that extend SvRefBase are managed by SvRef
TODO fix the SvXMLImportContext class (mentioned below)
TODO fix the slideshow::internal::SlideView class (mentioned below)
*/
namespace {
class RefCounting:
public RecursiveASTVisitor<RefCounting>, public loplugin::Plugin
{
public:
explicit RefCounting(InstantiationData const & data): Plugin(data) {}
virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
bool VisitFieldDecl(const FieldDecl *);
bool VisitVarDecl(const VarDecl *);
};
bool BaseCheckNotSubclass(const CXXRecordDecl *BaseDefinition, void *p) {
if (!BaseDefinition)
return true;
const char *pString = static_cast<const char *>(p);
if (BaseDefinition->getQualifiedNameAsString() == pString) {
return false;
}
return true;
}
bool isDerivedFrom(const CXXRecordDecl *decl, const char *pString) {
if (!decl)
return false;
if (decl->getQualifiedNameAsString() == pString)
return true;
if (!decl->hasDefinition()) {
return false;
}
if (// not sure what hasAnyDependentBases() does,
// but it avoids classes we don't want, e.g. WeakAggComponentImplHelper1
!decl->hasAnyDependentBases() &&
!decl->forallBases(BaseCheckNotSubclass, static_cast<void*>(const_cast<char*>(pString)), true)) {
return true;
}
return false;
}
bool containsXInterfaceSubclass(const Type* pType0);
bool containsXInterfaceSubclass(const QualType& qType) {
return containsXInterfaceSubclass(qType.getTypePtr());
}
static std::vector<std::string> PROBABLY_GOOD_TEMPLATES = {
"(anonymous namespace)::FindUnoInstanceHint",
"abp::OMultiInstanceAutoRegistration",
"com::sun::star::uno::Reference",
"com::sun::star::uno::WeakReference",
"com::sun::star::uno::Sequence",
"accessibility::HardCppRef",
"accessibility::WeakCppRef",
"dba::OAutoRegistration",
"dba::OSingletonRegistration",
"dbp::OMultiInstanceAutoRegistration",
"dbaui::OMultiInstanceAutoRegistration",
"dbaxml::OMultiInstanceAutoRegistration",
"io_acceptor::ReferenceEqual",
"io_acceptor::ReferenceHash",
"comphelper::OAutoRegistration",
"comphelper::OInterfaceCompare",
"comphelper::module::OSingletonRegistration",
"comphelper::WeakBag",
"comphelper::service_decl::class_",
"comphelper::service_decl::vba_service_class_",
"comphelper::service_decl::inheritingClass_",
"comphelper::module::OAutoRegistration",
"comphelper::mem_fun1_t",
"comphelper::OSimpleListenerContainer",
"dbmm::OAutoRegistration",
"pcr::OAutoRegistration",
"logging::ComponentMethodGuard",
"logging::OSingletonRegistration",
"logging::OAutoRegistration",
"rtl::Reference",
"sdbtools::OAutoRegistration",
"stoc_connector::ReferenceEqual",
"stoc_connector::ReferenceHash",
"std::mem_fun_t",
"std::mem_fun1_t",
"SwIterator",
"toolkit::InitGuard",
"utl::SharedUNOComponent",
"utl::OAutoRegistration",
"vcl::DeleteUnoReferenceOnDeinit",
"xmloff::OInterfaceCompare",
};
bool containsXInterfaceSubclass(const Type* pType0) {
if (!pType0)
return false;
const Type* pType = pType0->getUnqualifiedDesugaredType();
if (!pType)
return false;
const CXXRecordDecl* pRecordDecl = pType->getAsCXXRecordDecl();
if (pRecordDecl) {
pRecordDecl = pRecordDecl->getCanonicalDecl();
// these classes override acquire/release and forwards to it's parent
if (isDerivedFrom(pRecordDecl, "ListenerMultiplexerBase")) { // module UnoTools
return false;
}
if (isDerivedFrom(pRecordDecl, "toolkit::GridEventForwarder")) { // module toolkit
return false;
}
if (isDerivedFrom(pRecordDecl, "OWeakSubObject")) { // module svx
return false;
}
if (isDerivedFrom(pRecordDecl, "dbaui::OSbaWeakSubObject")) { // module dbaccess
return false;
}
// FIXME this class extends 2 different ref-counting bases, SvRefBase and XInterface (via. cppu::WeakImplHelper)
// I have no idea how to fix it
if (isDerivedFrom(pRecordDecl, "SvXMLImportContext")) { // module xmloff
return false;
}
// The actual problem child is SlideView, of which this is the parent.
// Everything in the hierarchy above this wants to be managed via boost::shared_ptr
if (isDerivedFrom(pRecordDecl, "slideshow::internal::UnoView")) { // module slideshow
return false;
}
// FIXME This class has private operator new, and I cannot figure out how it can be dynamically instantiated
if (isDerivedFrom(pRecordDecl, "XPropertyList")) { // module svx
return false;
}
}
if (pRecordDecl) {
const ClassTemplateSpecializationDecl* pTemplate = dyn_cast<ClassTemplateSpecializationDecl>(pRecordDecl);
if (pTemplate) {
std::string aName = pTemplate->getQualifiedNameAsString();
if (std::find(PROBABLY_GOOD_TEMPLATES.begin(), PROBABLY_GOOD_TEMPLATES.end(), aName) != PROBABLY_GOOD_TEMPLATES.end())
return false;
for(unsigned i=0; i<pTemplate->getTemplateArgs().size(); ++i) {
const TemplateArgument& rArg = pTemplate->getTemplateArgs()[i];
if (rArg.getKind() == TemplateArgument::ArgKind::Type &&
containsXInterfaceSubclass(rArg.getAsType()))
{
return true;
}
}
}
}
if (pType->isPointerType()) {
// ignore
return false;
} else if (pType->isArrayType()) {
const ArrayType* pArrayType = dyn_cast<ArrayType>(pType);
QualType elementType = pArrayType->getElementType();
return containsXInterfaceSubclass(elementType);
} else {
return isDerivedFrom(pRecordDecl, "com::sun::star::uno::XInterface");
}
}
bool RefCounting::VisitFieldDecl(const FieldDecl * fieldDecl) {
if (ignoreLocation(fieldDecl)) {
return true;
}
if (fieldDecl->isBitField()) {
return true;
}
std::string aParentName = fieldDecl->getParent()->getQualifiedNameAsString();
if ( aParentName == "com::sun::star::uno::BaseReference"
|| aParentName == "cppu::detail::element_alias"
// this is playing some kind of game to avoid circular references
|| aParentName == "ucbhelper::ResultSetDataSupplier")
{
return true;
}
if (containsXInterfaceSubclass(fieldDecl->getType())) {
report(
DiagnosticsEngine::Warning,
"XInterface subclass being directly heap managed, should be managed via uno::Reference, "
+ fieldDecl->getType().getAsString()
+ ", parent is " + aParentName,
fieldDecl->getLocation())
<< fieldDecl->getSourceRange();
return true;
}
return true;
}
bool RefCounting::VisitVarDecl(const VarDecl * varDecl) {
if (ignoreLocation(varDecl)) {
return true;
}
if (containsXInterfaceSubclass(varDecl->getType())) {
report(
DiagnosticsEngine::Warning,
"XInterface subclass being directly stack managed, should be managed via uno::Reference, "
+ varDecl->getType().getAsString(),
varDecl->getLocation())
<< varDecl->getSourceRange();
}
return true;
}
loplugin::Plugin::Registration< RefCounting > X("refcounting");
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -191,8 +191,9 @@ Reference< XInterface > OComponentDefinition::Create( const Reference< XComponen
void SAL_CALL OComponentDefinition::disposing()
{
OContentHelper::disposing();
if ( m_pColumns.get() )
m_pColumns->disposing();
if ( m_xColumns.is() )
m_xColumns->disposing();
m_xColumns.clear();
m_xColumnPropertyListener->clear();
m_xColumnPropertyListener.clear();
}
......@@ -227,7 +228,7 @@ Reference< XNameAccess> OComponentDefinition::getColumns() throw (RuntimeExcepti
::osl::MutexGuard aGuard(m_aMutex);
::connectivity::checkDisposed(OContentHelper::rBHelper.bDisposed);
if ( !m_pColumns.get() )
if ( !m_xColumns.is() )
{
::std::vector< OUString> aNames;
......@@ -239,10 +240,10 @@ Reference< XNameAccess> OComponentDefinition::getColumns() throw (RuntimeExcepti
for ( ; aIter != aEnd; ++aIter )
aNames.push_back( aIter->first );
m_pColumns.reset( new OColumns( *this, m_aMutex, true, aNames, this, NULL, true, false, false ) );
m_pColumns->setParent( *this );
m_xColumns = new OColumns( *this, m_aMutex, true, aNames, this, NULL, true, false, false );
m_xColumns->setParent( *this );
}
return m_pColumns.get();
return m_xColumns.get();
}
OColumn* OComponentDefinition::createColumn(const OUString& _rName) const
......
......@@ -88,7 +88,7 @@ class OComponentDefinition :public OContentHelper
OComponentDefinition();
protected:
::std::unique_ptr< OColumns > m_pColumns;
css::uno::Reference< OColumns > m_xColumns;
rtl::Reference<OColumnPropertyListener> m_xColumnPropertyListener;
bool m_bTable;
......
......@@ -491,7 +491,7 @@ ODatabaseSource::ODatabaseSource(const ::rtl::Reference<ODatabaseModelImpl>& _pI
:ModelDependentComponent( _pImpl )
,ODatabaseSource_Base( getMutex() )
,OPropertySetHelper( ODatabaseSource_Base::rBHelper )
,m_aBookmarks( *this, getMutex() )
,m_xBookmarks( new OBookmarkContainer( *this, getMutex() ) )
,m_aFlushListeners( getMutex() )
{
// some kind of default
......@@ -1200,7 +1200,7 @@ Reference< XConnection > ODatabaseSource::getConnection(const OUString& user, co
Reference< XNameAccess > SAL_CALL ODatabaseSource::getBookmarks( ) throw (RuntimeException, std::exception)
{
ModelMethodGuard aGuard( *this );
return static_cast< XNameContainer* >(&m_aBookmarks);
return static_cast< XNameContainer* >(m_xBookmarks.get());
}
Reference< XNameAccess > SAL_CALL ODatabaseSource::getQueryDefinitions( ) throw(RuntimeException, std::exception)
......
......@@ -82,7 +82,7 @@ class ODatabaseSource :public ModelDependentComponent // must be first
private:
using ODatabaseSource_Base::rBHelper;
OBookmarkContainer m_aBookmarks;
css::uno::Reference<OBookmarkContainer> m_xBookmarks;
::cppu::OInterfaceContainerHelper m_aFlushListeners;
private:
......
......@@ -54,10 +54,10 @@ namespace dbaui
// OSingleDocumentController_Data
struct OSingleDocumentController_Data
{
::boost::scoped_ptr< UndoManager > m_pUndoManager;
Reference< UndoManager > m_xUndoManager;
OSingleDocumentController_Data( ::cppu::OWeakObject& i_parent, ::osl::Mutex& i_mutex )
:m_pUndoManager( new UndoManager( i_parent, i_mutex ) )
:m_xUndoManager( new UndoManager( i_parent, i_mutex ) )
{
}
};
......@@ -77,7 +77,7 @@ namespace dbaui
{
OSingleDocumentController_Base::disposing();
ClearUndoManager();
m_pData->m_pUndoManager->disposing();
m_pData->m_xUndoManager->disposing();
}
void SAL_CALL OSingleDocumentController::disposing( const EventObject& i_event ) throw( RuntimeException, std::exception )
......@@ -93,7 +93,7 @@ namespace dbaui
SfxUndoManager& OSingleDocumentController::GetUndoManager() const
{
return m_pData->m_pUndoManager->GetSfxUndoManager();
return m_pData->m_xUndoManager->GetSfxUndoManager();
}
void OSingleDocumentController::addUndoActionAndInvalidate(SfxUndoAction *_pAction)
......@@ -111,7 +111,7 @@ namespace dbaui
Reference< XUndoManager > SAL_CALL OSingleDocumentController::getUndoManager( ) throw (RuntimeException, std::exception)
{
return m_pData->m_pUndoManager.get();
return m_pData->m_xUndoManager.get();
}
FeatureState OSingleDocumentController::GetState(sal_uInt16 _nId) const
......
......@@ -1165,11 +1165,11 @@ namespace drawinglayer
// per polygon. If there are more, split the polygon in half and call recursively
basegfx::B2DPolygon aLeft, aRight;
splitLinePolygon(rBasePolygon, aLeft, aRight);
const primitive2d::PolygonHairlinePrimitive2D aPLeft(aLeft, rHairlinePrimitive.getBColor());
const primitive2d::PolygonHairlinePrimitive2D aPRight(aRight, rHairlinePrimitive.getBColor());
uno::Reference< primitive2d::PolygonHairlinePrimitive2D > xPLeft(new primitive2d::PolygonHairlinePrimitive2D(aLeft, rHairlinePrimitive.getBColor()));
uno::Reference< primitive2d::PolygonHairlinePrimitive2D > xPRight(new primitive2d::PolygonHairlinePrimitive2D(aRight, rHairlinePrimitive.getBColor()));
processBasePrimitive2D(aPLeft);
processBasePrimitive2D(aPRight);
processBasePrimitive2D(*xPLeft.get());
processBasePrimitive2D(*xPRight.get());
}
else
{
......@@ -1213,13 +1213,13 @@ namespace drawinglayer
// per polygon. If there are more, split the polygon in half and call recursively
basegfx::B2DPolygon aLeft, aRight;
splitLinePolygon(rBasePolygon, aLeft, aRight);
const primitive2d::PolygonStrokePrimitive2D aPLeft(
aLeft, rStrokePrimitive.getLineAttribute(), rStrokePrimitive.getStrokeAttribute());
const primitive2d::PolygonStrokePrimitive2D aPRight(
aRight, rStrokePrimitive.getLineAttribute(), rStrokePrimitive.getStrokeAttribute());
uno::Reference< primitive2d::PolygonStrokePrimitive2D > xPLeft(new primitive2d::PolygonStrokePrimitive2D(
aLeft, rStrokePrimitive.getLineAttribute(), rStrokePrimitive.getStrokeAttribute()));
uno::Reference< primitive2d::PolygonStrokePrimitive2D > xPRight(new primitive2d::PolygonStrokePrimitive2D(
aRight, rStrokePrimitive.getLineAttribute(), rStrokePrimitive.getStrokeAttribute()));
processBasePrimitive2D(aPLeft);
processBasePrimitive2D(aPRight);
processBasePrimitive2D(*xPLeft.get());
processBasePrimitive2D(*xPRight.get());
}
else
{
......@@ -1294,21 +1294,21 @@ namespace drawinglayer
basegfx::B2DPolygon aLeft, aRight;
splitLinePolygon(rBasePolygon, aLeft, aRight);
const attribute::LineStartEndAttribute aEmpty;
const primitive2d::PolygonStrokeArrowPrimitive2D aPLeft(
uno::Reference< primitive2d::PolygonStrokeArrowPrimitive2D > xPLeft(new primitive2d::PolygonStrokeArrowPrimitive2D(
aLeft,
rStrokeArrowPrimitive.getLineAttribute(),
rStrokeArrowPrimitive.getStrokeAttribute(),
rStrokeArrowPrimitive.getStart(),
aEmpty);
const primitive2d::PolygonStrokeArrowPrimitive2D aPRight(
aEmpty));
uno::Reference< primitive2d::PolygonStrokeArrowPrimitive2D > xPRight(new primitive2d::PolygonStrokeArrowPrimitive2D(
aRight,
rStrokeArrowPrimitive.getLineAttribute(),
rStrokeArrowPrimitive.getStrokeAttribute(),
aEmpty,
rStrokeArrowPrimitive.getEnd());
rStrokeArrowPrimitive.getEnd()));
processBasePrimitive2D(aPLeft);
processBasePrimitive2D(aPRight);
processBasePrimitive2D(*xPLeft.get());
processBasePrimitive2D(*xPRight.get());
}
else
{
......@@ -1372,11 +1372,11 @@ namespace drawinglayer
{
// #i112245# Metafiles use tools Polygon and are not able to have more than 65535 points
// per polygon. If there are more use the splitted polygon and call recursively
const primitive2d::PolyPolygonGraphicPrimitive2D aSplitted(
uno::Reference< primitive2d::PolyPolygonGraphicPrimitive2D > xSplitted(new primitive2d::PolyPolygonGraphicPrimitive2D(
aLocalPolyPolygon,
rBitmapCandidate.getFillGraphic());
rBitmapCandidate.getFillGraphic()));
processBasePrimitive2D(aSplitted);
processBasePrimitive2D(*xSplitted.get());
}
else
{
......
......@@ -110,112 +110,112 @@ void Test::testUnoTextFields()
{
{
// DATE
SvxUnoTextField aField(text::textfield::Type::DATE);
uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
uno::Reference<SvxUnoTextField> xField(new SvxUnoTextField(text::textfield::Type::DATE));
uno::Sequence<OUString> aSvcs = xField->getSupportedServiceNames();
bool bGood = includes(aSvcs, "com.sun.star.text.textfield.DateTime");
CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
}
{
// URL
SvxUnoTextField aField(text::textfield::Type::URL);
uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
uno::Reference<SvxUnoTextField> xField(new SvxUnoTextField(text::textfield::Type::URL));
uno::Sequence<OUString> aSvcs = xField->getSupportedServiceNames();
bool bGood = includes(aSvcs, "com.sun.star.text.textfield.URL");
CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
}
{
// PAGE
SvxUnoTextField aField(text::textfield::Type::PAGE);
uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
uno::Reference<SvxUnoTextField> xField(new SvxUnoTextField(text::textfield::Type::PAGE));
uno::Sequence<OUString> aSvcs = xField->getSupportedServiceNames();
bool bGood = includes(aSvcs, "com.sun.star.text.textfield.PageNumber");
CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
}
{
// PAGES
SvxUnoTextField aField(text::textfield::Type::PAGES);
uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
uno::Reference<SvxUnoTextField> xField(new SvxUnoTextField(text::textfield::Type::PAGES));
uno::Sequence<OUString> aSvcs = xField->getSupportedServiceNames();
bool bGood = includes(aSvcs, "com.sun.star.text.textfield.PageCount");
CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
}
{
// TIME
SvxUnoTextField aField(text::textfield::Type::TIME);
uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
uno::Reference<SvxUnoTextField> xField(new SvxUnoTextField(text::textfield::Type::TIME));
uno::Sequence<OUString> aSvcs = xField->getSupportedServiceNames();
bool bGood = includes(aSvcs, "com.sun.star.text.textfield.DateTime");
CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
}
{
// FILE
SvxUnoTextField aField(text::textfield::Type::DOCINFO_TITLE);
uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
uno::Reference<SvxUnoTextField> xField(new SvxUnoTextField(text::textfield::Type::DOCINFO_TITLE));
uno::Sequence<OUString> aSvcs = xField->getSupportedServiceNames();
bool bGood = includes(aSvcs, "com.sun.star.text.textfield.docinfo.Title");
CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
}
{
// TABLE
SvxUnoTextField aField(text::textfield::Type::TABLE);
uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
uno::Reference<SvxUnoTextField> xField(new SvxUnoTextField(text::textfield::Type::TABLE));
uno::Sequence<OUString> aSvcs = xField->getSupportedServiceNames();
bool bGood = includes(aSvcs, "com.sun.star.text.textfield.SheetName");
CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
}
{
// EXTENDED TIME
SvxUnoTextField aField(text::textfield::Type::EXTENDED_TIME);
uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
uno::Reference<SvxUnoTextField> xField(new SvxUnoTextField(text::textfield::Type::EXTENDED_TIME));
uno::Sequence<OUString> aSvcs = xField->getSupportedServiceNames();
bool bGood = includes(aSvcs, "com.sun.star.text.textfield.DateTime");
CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
}